diff --git a/UI source code/dns-dev-2.0/.gitignore b/UI source code/dns-dev-2.0/.gitignore new file mode 100644 index 0000000..9acb04a --- /dev/null +++ b/UI source code/dns-dev-2.0/.gitignore @@ -0,0 +1,7 @@ +### IDEA ### +.idea/* +*.iml +*/target/* +*/*.iml +/.gradle/ +/application.pid \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/LICENSE b/UI source code/dns-dev-2.0/LICENSE new file mode 100644 index 0000000..ca38718 --- /dev/null +++ b/UI source code/dns-dev-2.0/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "{}" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2019-2020 Zheng Jie + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/README.md b/UI source code/dns-dev-2.0/README.md new file mode 100644 index 0000000..6284064 --- /dev/null +++ b/UI source code/dns-dev-2.0/README.md @@ -0,0 +1,72 @@ +

DiamondV + + + +#### 项目简介 + +一个基于 Spring Boot 2.1.0 、 Spring Boot Jpa、mybatis-plus、 JWT、Spring Security、Redis、Vue的前后端分离的后台管理系统 + +**账号密码:** `admin / 123456` + +**打包:** `mvn clean install` + +#### 项目源码 + +| | 后端源码 | 前端源码 | +| ---- | ------------------------------ | ----------------------------------------- | +| 地址 | http://192.168.40.125/kjch/dns | http://192.168.40.125/kjch/dns_mapping_ui | + +#### 主要特性 + +- 使用最新技术栈,社区资源丰富。 +- 高效率开发,代码生成器可一键生成前后端代码 +- 支持数据字典,可方便地对一些状态进行管理 +- 支持接口限流,避免恶意请求导致服务层压力过大 +- 支持接口级别的功能权限与数据权限,可自定义操作 +- 自定义权限注解与匿名接口注解,可快速对接口拦截与放行 +- 对一些常用地前端组件封装:表格数据请求、数据字典等 +- 前后端统一异常拦截处理,统一输出异常,避免繁琐的判断 +- 支持在线用户管理与服务器性能监控,支持限制单用户登录 +- 支持运维管理,可方便地对远程服务器的应用进行部署与管理 + +#### 系统功能 + +- 用户管理:提供用户的相关配置,新增用户后,默认密码为123456 +- 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限 +- 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单 +- 部门管理:可配置系统组织架构,树形表格展示 +- 岗位管理:配置各个部门的职位 +- 字典管理:可维护常用一些固定的数据,如:状态,性别等 +- 系统日志:记录用户操作日志与异常日志,方便开发人员定位排错 +- SQL监控:采用druid 监控数据库访问性能,默认用户名admin,密码123456 +- 定时任务:整合Quartz做定时任务,加入任务日志,任务运行情况一目了然 +- 代码生成:高灵活度生成前后端代码,减少大量重复的工作任务 +- 邮件工具:配合富文本,发送html格式的邮件 +- 七牛云存储:可同步七牛云存储的数据到系统,无需登录七牛云直接操作云数据 +- 支付宝支付:整合了支付宝支付并且提供了测试账号,可自行测试 +- 服务监控:监控服务器的负载情况 +- 运维管理:一键部署你的应用 + +#### 项目结构 + +项目采用按功能分模块的开发方式,结构如下 + +- `dns-common` 为系统的公共模块,各种工具类,公共配置存在该模块 +- `dns-system` 为系统核心模块也是项目入口模块,也是最终需要打包部署的模块 +- `dns-logging` 为系统的日志模块,其他模块如果需要记录日志需要引入该模块 +- 详细结构 + +``` +- dns-common 公共模块 + - annotation 为系统自定义注解 + - aspect 自定义注解的切面 + - base 提供了Entity、DTO基类和mapstruct的通用mapper + - config 自定义权限实现、redis配置、swagger配置、Rsa配置等 + - exception 项目统一异常的处理 + - utils 系统通用工具类 +- dns-system 系统核心模块(系统启动入口) + - config 配置跨域与静态资源,与数据权限 + - thread 线程池相关 + - modules 系统相关模块(登录授权、系统监控、定时任务、运维管理,测绘等) +- dns-logging 系统日志模块 +``` diff --git a/UI source code/dns-dev-2.0/dns-common/pom.xml b/UI source code/dns-dev-2.0/dns-common/pom.xml new file mode 100644 index 0000000..33734bb --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/pom.xml @@ -0,0 +1,26 @@ + + + + dns + com.example + 2.6 + + 4.0.0 + + 5.3.4 + + + dns-common + dns-common + + + + + cn.hutool + hutool-all + ${hutool.version} + + + diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/AnonymousAccess.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/AnonymousAccess.java new file mode 100644 index 0000000..9cffb51 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/AnonymousAccess.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.annotation; + +import java.lang.annotation.*; + +/** + * @author jacky + * 用于标记匿名访问方法 + */ +@Inherited +@Documented +@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AnonymousAccess { + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/DataPermission.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/DataPermission.java new file mode 100644 index 0000000..7fa3e3f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/DataPermission.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

+ * 用于判断是否过滤数据权限 + * 1、如果没有用到 @OneToOne 这种关联关系,只需要填写 fieldName [参考:DeptQueryCriteria.class] + * 2、如果用到了 @OneToOne ,fieldName 和 joinName 都需要填写,拿UserQueryCriteria.class举例: + * 应该是 @DataPermission(joinName = "dept", fieldName = "id") + *

+ * + * @website https://el-admin.vip + * 2020-05-07 + **/ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DataPermission { + + /** + * Entity 中的字段名称 + */ + String fieldName() default ""; + + /** + * Entity 中与部门关联的字段名称 + */ + String joinName() default ""; +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Limit.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Limit.java new file mode 100644 index 0000000..ee285de --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Limit.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.annotation; + +import com.example.aspect.LimitType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author jacky + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Limit { + + // 资源名称,用于描述接口功能 + String name() default ""; + + // 资源 key + String key() default ""; + + // key prefix + String prefix() default ""; + + // 时间的,单位秒 + int period(); + + // 限制访问次数 + int count(); + + // 限制类型 + LimitType limitType() default LimitType.CUSTOMER; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Query.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Query.java new file mode 100644 index 0000000..e21d60b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/Query.java @@ -0,0 +1,87 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Query { + + // Dong ZhaoYang 2017/8/7 基本对象的属性名 + String propName() default ""; + // Dong ZhaoYang 2017/8/7 查询方式 + Type type() default Type.EQUAL; + + /** + * 连接查询的属性名,如User类中的dept + */ + String joinName() default ""; + + /** + * 默认左连接 + */ + Join join() default Join.LEFT; + + /** + * 多字段模糊搜索,仅支持String类型字段,多个用逗号隔开, 如@Query(blurry = "email,username") + */ + String blurry() default ""; + + enum Type { + // jie 2019/6/4 相等 + EQUAL + // Dong ZhaoYang 2017/8/7 大于等于 + , GREATER_THAN + // Dong ZhaoYang 2017/8/7 小于等于 + , LESS_THAN + // Dong ZhaoYang 2017/8/7 中模糊查询 + , INNER_LIKE + // Dong ZhaoYang 2017/8/7 左模糊查询 + , LEFT_LIKE + // Dong ZhaoYang 2017/8/7 右模糊查询 + , RIGHT_LIKE + // Dong ZhaoYang 2017/8/7 小于 + , LESS_THAN_NQ + // jie 2019/6/4 包含 + , IN + // 不包含 + , NOT_IN + // 不等于 + ,NOT_EQUAL + // between + ,BETWEEN + // 不为空 + ,NOT_NULL + // 为空 + ,IS_NULL + } + + /** + * + * 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询 + */ + enum Join { + /** jie 2019-6-4 13:18:30 */ + LEFT, RIGHT, INNER + } + +} + diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousDeleteMapping.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousDeleteMapping.java new file mode 100644 index 0000000..10fbef4 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousDeleteMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.example.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code DELETE} requests onto specific handler + * methods. + * 支持匿名访问 DeleteMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousPatchMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.DELETE) +public @interface AnonymousDeleteMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousGetMapping.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousGetMapping.java new file mode 100644 index 0000000..85d6a78 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousGetMapping.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.example.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code GET} requests onto specific handler + * methods. + *

+ * 支持匿名访问 GetMapping + * + * @author liaojinlong + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.GET) +public @interface AnonymousGetMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + * + * @since 4.3.5 + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPatchMapping.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPatchMapping.java new file mode 100644 index 0000000..3281a3b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPatchMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.example.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code PATCH} requests onto specific handler + * methods. + * * 支持匿名访问 PatchMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.PATCH) +public @interface AnonymousPatchMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPostMapping.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPostMapping.java new file mode 100644 index 0000000..977de6c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPostMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.example.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code POST} requests onto specific handler + * methods. + * 支持匿名访问 PostMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.POST) +public @interface AnonymousPostMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPutMapping.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPutMapping.java new file mode 100644 index 0000000..6fc00b2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/annotation/rest/AnonymousPutMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.example.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code PUT} requests onto specific handler + * methods. + * * 支持匿名访问 PutMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.PUT) +public @interface AnonymousPutMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitAspect.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitAspect.java new file mode 100644 index 0000000..1e1856d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitAspect.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.aspect; + +import com.google.common.collect.ImmutableList; +import com.example.annotation.Limit; +import com.example.exception.BadRequestException; +import com.example.utils.RequestHolder; +import com.example.utils.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * @author / + */ +@Aspect +@Component +public class LimitAspect { + + private final RedisTemplate redisTemplate; + private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class); + + public LimitAspect(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + @Pointcut("@annotation(com.example.annotation.Limit)") + public void pointcut() { + } + + @Around("pointcut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method signatureMethod = signature.getMethod(); + Limit limit = signatureMethod.getAnnotation(Limit.class); + LimitType limitType = limit.limitType(); + String key = limit.key(); + if (StringUtils.isEmpty(key)) { + if (limitType == LimitType.IP) { + key = StringUtils.getIp(request); + } else { + key = signatureMethod.getName(); + } + } + + ImmutableList keys = ImmutableList.of(StringUtils.join(limit.prefix(), "_", key, "_", request.getRequestURI().replace("/","_"))); + + String luaScript = buildLuaScript(); + RedisScript redisScript = new DefaultRedisScript<>(luaScript, Number.class); + Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period()); + if (null != count && count.intValue() <= limit.count()) { + logger.info("第{}次访问key为 {},描述为 [{}] 的接口", count, keys, limit.name()); + return joinPoint.proceed(); + } else { + throw new BadRequestException("访问次数受限制"); + } + } + + /** + * 限流脚本 + */ + private String buildLuaScript() { + return "local c" + + "\nc = redis.call('get',KEYS[1])" + + "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + + "\nreturn c;" + + "\nend" + + "\nc = redis.call('incr',KEYS[1])" + + "\nif tonumber(c) == 1 then" + + "\nredis.call('expire',KEYS[1],ARGV[2])" + + "\nend" + + "\nreturn c;"; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitType.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitType.java new file mode 100644 index 0000000..0a6deb6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/aspect/LimitType.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.aspect; + +/** + * 限流枚举 + * @author / + */ +public enum LimitType { + // 默认 + CUSTOMER, + // by ip addr + IP +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseDTO.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseDTO.java new file mode 100644 index 0000000..7802007 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseDTO.java @@ -0,0 +1,40 @@ +package com.example.base; + +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.sql.Timestamp; + +/** + * + * 2019年10月24日20:48:53 + */ +@Getter +@Setter +public class BaseDTO implements Serializable { + + private String createBy; + + private String updateBy; + + private Timestamp createTime; + + private Timestamp updateTime; + + @Override + public String toString() { + ToStringBuilder builder = new ToStringBuilder(this); + Field[] fields = this.getClass().getDeclaredFields(); + try { + for (Field f : fields) { + f.setAccessible(true); + builder.append(f.getName(), f.get(this)).append("\n"); + } + } catch (Exception e) { + builder.append("toString builder encounter an error"); + } + return builder.toString(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseEntity.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseEntity.java new file mode 100644 index 0000000..ba31ddf --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseEntity.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.base; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.sql.Timestamp; + +/** + * 通用字段, is_del 根据需求自行添加 + * + * @Date 2019年10月24日20:46:32 + */ +@Getter +@Setter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public class BaseEntity implements Serializable { + + @CreatedBy + @Column(name = "create_by", updatable = false) + @ApiModelProperty(value = "创建人", hidden = true) + private String createBy; + + @LastModifiedBy + @Column(name = "update_by") + @ApiModelProperty(value = "更新人", hidden = true) + private String updateBy; + + @CreationTimestamp + @Column(name = "create_time", updatable = false) + @ApiModelProperty(value = "创建时间", hidden = true) + private Timestamp createTime; + + @UpdateTimestamp + @Column(name = "update_time") + @ApiModelProperty(value = "更新时间", hidden = true) + private Timestamp updateTime; + + /* 分组校验 */ + public @interface Create {} + + /* 分组校验 */ + public @interface Update {} + + @Override + public String toString() { + ToStringBuilder builder = new ToStringBuilder(this); + Field[] fields = this.getClass().getDeclaredFields(); + try { + for (Field f : fields) { + f.setAccessible(true); + builder.append(f.getName(), f.get(this)).append("\n"); + } + } catch (Exception e) { + builder.append("toString builder encounter an error"); + } + return builder.toString(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseMapper.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseMapper.java new file mode 100644 index 0000000..1c2d38a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/base/BaseMapper.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.base; + +import java.util.List; + + +public interface BaseMapper { + + /** + * DTO转Entity + * @param dto / + * @return / + */ + E toEntity(D dto); + + /** + * Entity转DTO + * @param entity / + * @return / + */ + D toDto(E entity); + + /** + * DTO集合转Entity集合 + * @param dtoList / + * @return / + */ + List toEntity(List dtoList); + + /** + * Entity集合转DTO集合 + * @param entityList / + * @return / + */ + List toDto(List entityList); +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/AuditorConfig.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/AuditorConfig.java new file mode 100644 index 0000000..7d1dcbe --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/AuditorConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import com.example.utils.SecurityUtils; +import org.springframework.data.domain.AuditorAware; +import org.springframework.stereotype.Component; +import java.util.Optional; + +/** + * @description : 设置审计 + * @author : Dong ZhaoYang + * : 2019/10/28 + */ +@Component("auditorAware") +public class AuditorConfig implements AuditorAware { + + /** + * 返回操作员标志信息 + * + * @return / + */ + @Override + public Optional getCurrentAuditor() { + try { + // 这里应根据实际业务情况获取具体信息 + return Optional.of(SecurityUtils.getCurrentUsername()); + }catch (Exception ignored){} + // 用户定时任务,或者无Token调用的情况 + return Optional.of("System"); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElAdminProperties.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElAdminProperties.java new file mode 100644 index 0000000..b7670b3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElAdminProperties.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * + * @description + * 2021-11-22 + **/ +@Data +@Component +public class ElAdminProperties { + + public static Boolean ipLocal; + + @Value("${ip.local-parsing}") + public void setIpLocal(Boolean ipLocal) { + ElAdminProperties.ipLocal = ipLocal; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElPermissionConfig.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElPermissionConfig.java new file mode 100644 index 0000000..7b7c1e7 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/ElPermissionConfig.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import com.example.utils.SecurityUtils; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Service; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * + */ +@Service(value = "el") +public class ElPermissionConfig { + + public Boolean check(String ...permissions){ + // 获取当前用户的所有权限 + List elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); + // 判断当前用户的所有权限是否包含接口上定义的权限 + return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/FileProperties.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/FileProperties.java new file mode 100644 index 0000000..a1c3aff --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/FileProperties.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import lombok.Data; +import com.example.utils.ElAdminConstant; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "file") +public class FileProperties { + + /** 文件大小限制 */ + private Long maxSize; + + /** 头像大小限制 */ + private Long avatarMaxSize; + + private ElPath mac; + + private ElPath linux; + + private ElPath windows; + + public ElPath getPath(){ + String os = System.getProperty("os.name"); + if(os.toLowerCase().startsWith(ElAdminConstant.WIN)) { + return windows; + } else if(os.toLowerCase().startsWith(ElAdminConstant.MAC)){ + return mac; + } + return linux; + } + + @Data + public static class ElPath{ + + private String path; + + private String avatar; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RedisConfig.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RedisConfig.java new file mode 100644 index 0000000..d482e83 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RedisConfig.java @@ -0,0 +1,217 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import cn.hutool.core.lang.Assert; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cache.Cache; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.CacheErrorHandler; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import reactor.util.annotation.Nullable; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + + +/** + * + * 2018-11-24 + */ +@Slf4j +@Configuration +@EnableCaching +@ConditionalOnClass(RedisOperations.class) +@EnableConfigurationProperties(RedisProperties.class) +public class RedisConfig extends CachingConfigurerSupport { + + /** + * 设置 redis 数据默认过期时间,默认2小时 + * 设置@cacheable 序列化方式 + */ + @Bean + public RedisCacheConfiguration redisCacheConfiguration(){ + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); + RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); + configuration = configuration.serializeValuesWith(RedisSerializationContext. + SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(2)); + return configuration; + } + + @SuppressWarnings("all") + @Bean(name = "redisTemplate") + @ConditionalOnMissingBean(name = "redisTemplate") + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + //序列化 + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); + // value值的序列化采用fastJsonRedisSerializer + template.setValueSerializer(fastJsonRedisSerializer); + template.setHashValueSerializer(fastJsonRedisSerializer); + // 全局开启AutoType,这里方便开发,使用全局的方式 + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + // 建议使用这种方式,小范围指定白名单 + // ParserConfig.getGlobalInstance().addAccept("com.example.domain"); + // key的序列化采用StringRedisSerializer + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setConnectionFactory(redisConnectionFactory); + return template; + } + + /** + * 自定义缓存key生成策略,默认将使用该策略 + */ + @Bean + @Override + public KeyGenerator keyGenerator() { + return (target, method, params) -> { + Map container = new HashMap<>(4); + Class targetClassClass = target.getClass(); + // 类地址 + container.put("class",targetClassClass.toGenericString()); + // 方法名称 + container.put("methodName",method.getName()); + // 包名称 + container.put("package",targetClassClass.getPackage()); + // 参数列表 + for (int i = 0; i < params.length; i++) { + container.put(String.valueOf(i),params[i]); + } + // 转为JSON字符串 + String jsonString = JSON.toJSONString(container); + // 做SHA256 Hash计算,得到一个SHA256摘要作为Key + return DigestUtils.sha256Hex(jsonString); + }; + } + + @Bean + @Override + public CacheErrorHandler errorHandler() { + // 异常处理,当Redis发生异常时,打印日志,但是程序正常走 + log.info("初始化 -> [{}]", "Redis CacheErrorHandler"); + return new CacheErrorHandler() { + @Override + public void handleCacheGetError(RuntimeException e, Cache cache, Object key) { + log.error("Redis occur handleCacheGetError:key -> [{}]", key, e); + } + + @Override + public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) { + log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e); + } + + @Override + public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) { + log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e); + } + + @Override + public void handleCacheClearError(RuntimeException e, Cache cache) { + log.error("Redis occur handleCacheClearError:", e); + } + }; + } + +} + +/** + * Value 序列化 + * + * @author / + * @param + */ + class FastJsonRedisSerializer implements RedisSerializer { + + private final Class clazz; + + FastJsonRedisSerializer(Class clazz) { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) { + if (t == null) { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8); + } + + @Override + public T deserialize(byte[] bytes) { + if (bytes == null || bytes.length <= 0) { + return null; + } + String str = new String(bytes, StandardCharsets.UTF_8); + return JSON.parseObject(str, clazz); + } + +} + +/** + * 重写序列化器 + * + * @author / + */ +class StringRedisSerializer implements RedisSerializer { + + private final Charset charset; + + StringRedisSerializer() { + this(StandardCharsets.UTF_8); + } + + private StringRedisSerializer(Charset charset) { + Assert.notNull(charset, "Charset must not be null!"); + this.charset = charset; + } + + @Override + public String deserialize(byte[] bytes) { + return (bytes == null ? null : new String(bytes, charset)); + } + + @Override + public @Nullable byte[] serialize(Object object) { + String string = JSON.toJSONString(object); + + if (org.apache.commons.lang3.StringUtils.isBlank(string)) { + return null; + } + string = string.replace("\"", ""); + return string.getBytes(charset); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RsaProperties.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RsaProperties.java new file mode 100644 index 0000000..7490f71 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/RsaProperties.java @@ -0,0 +1,38 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * + * @website https://el-admin.vip + * @description + * 2020-05-18 + **/ +@Data +@Component +public class RsaProperties { + + public static String privateKey; + + @Value("${rsa.private_key}") + public void setPrivateKey(String privateKey) { + RsaProperties.privateKey = privateKey; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/SwaggerConfig.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/SwaggerConfig.java new file mode 100644 index 0000000..7d0b1c6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/config/SwaggerConfig.java @@ -0,0 +1,148 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import com.fasterxml.classmate.TypeResolver; +import com.google.common.base.Predicates; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.data.domain.Pageable; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.schema.AlternateTypeRule; +import springfox.documentation.schema.AlternateTypeRuleConvention; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; +import java.util.ArrayList; +import java.util.List; +import static com.google.common.collect.Lists.newArrayList; +import static springfox.documentation.schema.AlternateTypeRules.newRule; + +/** + * api页面 /doc.html + * + * 2018-11-23 + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Value("${jwt.header}") + private String tokenHeader; + + @Value("${swagger.enabled}") + private Boolean enabled; + + @Bean + @SuppressWarnings("all") + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .enable(enabled) + .pathMapping("/") + .apiInfo(apiInfo()) + .select() + .paths(Predicates.not(PathSelectors.regex("/error.*"))) + .paths(PathSelectors.any()) + .build() + //添加登陆认证 + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .description("一个简单且易上手的 Spring boot 后台管理框架") + .title("DNS测绘 接口文档") + .version("2.6") + .build(); + } + + private List securitySchemes() { + //设置请求头信息 + List securitySchemes = new ArrayList<>(); + ApiKey apiKey = new ApiKey(tokenHeader, tokenHeader, "header"); + securitySchemes.add(apiKey); + return securitySchemes; + } + + private List securityContexts() { + //设置需要登录认证的路径 + List securityContexts = new ArrayList<>(); + // ^(?!auth).*$ 表示所有包含auth的接口不需要使用securitySchemes即不需要带token + // ^标识开始 ()里是一子表达式 ?!/auth表示匹配不是/auth的位置,匹配上则添加请求头,注意路径已/开头 .表示任意字符 *表示前面的字符匹配多次 $标识结束 + securityContexts.add(getContextByPath()); + return securityContexts; + } + + private SecurityContext getContextByPath() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex("^(?!/auth).*$")) + .build(); + } + + private List defaultAuth() { + List securityReferences = new ArrayList<>(); + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + securityReferences.add(new SecurityReference(tokenHeader, authorizationScopes)); + return securityReferences; + } +} + +/** + * 将Pageable转换展示在swagger中 + */ +@Configuration +class SwaggerDataConfig { + + @Bean + public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) { + return new AlternateTypeRuleConvention() { + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public List rules() { + return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class))); + } + }; + } + + @ApiModel + @Data + private static class Page { + @ApiModelProperty("页码 (0..N)") + private Integer page; + + @ApiModelProperty("每页显示的数目") + private Integer size; + + @ApiModelProperty("以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc") + private List sort; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadConfigurationException.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadConfigurationException.java new file mode 100644 index 0000000..0ca41ad --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadConfigurationException.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception; + +/** + * 统一关于错误配置信息 异常 + * + * @author: liaojinlong + * : 2020/6/10 18:06 + */ +public class BadConfigurationException extends RuntimeException { + /** + * Constructs a new runtime exception with {@code null} as its + * detail message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause}. + */ + public BadConfigurationException() { + super(); + } + + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public BadConfigurationException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a + * detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail + * message, cause, suppression enabled or disabled, and writable + * stack trace enabled or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled + * or disabled + * @param writableStackTrace whether or not the stack trace should + * be writable + * @since 1.7 + */ + protected BadConfigurationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadRequestException.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadRequestException.java new file mode 100644 index 0000000..e8c7474 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/BadRequestException.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception; + +import lombok.Getter; +import org.springframework.http.HttpStatus; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +@Getter +public class BadRequestException extends RuntimeException{ + + private Integer status = BAD_REQUEST.value(); + + public BadRequestException(String msg){ + super(msg); + } + + public BadRequestException(HttpStatus status,String msg){ + super(msg); + this.status = status.value(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityExistException.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityExistException.java new file mode 100644 index 0000000..5af387f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityExistException.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception; + +import org.springframework.util.StringUtils; + + +public class EntityExistException extends RuntimeException { + + public EntityExistException(Class clazz, String field, String val) { + super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val)); + } + + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " existed"; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityNotFoundException.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityNotFoundException.java new file mode 100644 index 0000000..cdfd771 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/EntityNotFoundException.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception; + +import org.springframework.util.StringUtils; + + +public class EntityNotFoundException extends RuntimeException { + + public EntityNotFoundException(Class clazz, String field, String val) { + super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val)); + } + + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " does not exist"; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/ApiError.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/ApiError.java new file mode 100644 index 0000000..82ec628 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/ApiError.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception.handler; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import java.time.LocalDateTime; + + +@Data +class ApiError { + + private Integer status = 400; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime timestamp; + private String message; + + private ApiError() { + timestamp = LocalDateTime.now(); + } + + public static ApiError error(String message){ + ApiError apiError = new ApiError(); + apiError.setMessage(message); + return apiError; + } + + public static ApiError error(Integer status, String message){ + ApiError apiError = new ApiError(); + apiError.setStatus(status); + apiError.setMessage(message); + return apiError; + } +} + + diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/GlobalExceptionHandler.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..ba044d1 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/exception/handler/GlobalExceptionHandler.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.exception.handler; + +import com.example.exception.BadRequestException; +import com.example.exception.EntityExistException; +import com.example.exception.EntityNotFoundException; +import com.example.utils.ThrowableUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import java.util.Objects; +import static org.springframework.http.HttpStatus.*; + + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + /** + * 处理所有不可知的异常 + */ + @ExceptionHandler(Throwable.class) + public ResponseEntity handleException(Throwable e){ + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + return buildResponseEntity(ApiError.error(e.getMessage())); + } + + /** + * BadCredentialsException + */ + @ExceptionHandler(BadCredentialsException.class) + public ResponseEntity badCredentialsException(BadCredentialsException e){ + // 打印堆栈信息 + String message = "坏的凭证".equals(e.getMessage()) ? "用户名或密码不正确" : e.getMessage(); + log.error(message); + return buildResponseEntity(ApiError.error(message)); + } + + /** + * 处理自定义异常 + */ + @ExceptionHandler(value = BadRequestException.class) + public ResponseEntity badRequestException(BadRequestException e) { + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage())); + } + + /** + * 处理 EntityExist + */ + @ExceptionHandler(value = EntityExistException.class) + public ResponseEntity entityExistException(EntityExistException e) { + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + return buildResponseEntity(ApiError.error(e.getMessage())); + } + + /** + * 处理 EntityNotFound + */ + @ExceptionHandler(value = EntityNotFoundException.class) + public ResponseEntity entityNotFoundException(EntityNotFoundException e) { + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + return buildResponseEntity(ApiError.error(NOT_FOUND.value(),e.getMessage())); + } + + /** + * 处理所有接口数据验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e){ + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\."); + String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); + String msg = "不能为空"; + if(msg.equals(message)){ + message = str[1] + ":" + message; + } + return buildResponseEntity(ApiError.error(message)); + } + + /** + * 统一返回 + */ + private ResponseEntity buildResponseEntity(ApiError apiError) { + return new ResponseEntity<>(apiError, valueOf(apiError.getStatus())); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CacheKey.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CacheKey.java new file mode 100644 index 0000000..8e93877 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CacheKey.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +/** + * @author: liaojinlong + * : 2020/6/11 15:49 + * @apiNote: 关于缓存的Key集合 + */ +public interface CacheKey { + + /** + * 用户 + */ + String USER_ID = "user::id:"; + /** + * 数据 + */ + String DATA_USER = "data::user:"; + /** + * 菜单 + */ + String MENU_ID = "menu::id:"; + String MENU_USER = "menu::user:"; + /** + * 角色授权 + */ + String ROLE_AUTH = "role::auth:"; + /** + * 角色信息 + */ + String ROLE_ID = "role::id:"; + /** + * 部门 + */ + String DEPT_ID = "dept::id:"; + /** + * 岗位 + */ + String JOB_ID = "job::id:"; + /** + * 数据字典 + */ + String DICT_NAME = "dict::name:"; +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CallBack.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CallBack.java new file mode 100644 index 0000000..59a7d0b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CallBack.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.utils; + +/** + * @author: liaojinlong + * : 2020/6/9 17:02 + * @since: 1.0 + * @see {@link SpringContextHolder} + * 针对某些初始化方法,在SpringContextHolder 初始化前时,
+ * 可提交一个 提交回调任务。
+ * 在SpringContextHolder 初始化后,进行回调使用 + */ + +public interface CallBack { + /** + * 回调执行方法 + */ + void executor(); + + /** + * 本回调任务名称 + * @return / + */ + default String getCallBackName() { + return Thread.currentThread().getId() + ":" + this.getClass().getName(); + } +} + diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CloseUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CloseUtil.java new file mode 100644 index 0000000..cd515bc --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/CloseUtil.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import java.io.Closeable; + +/** + * + * @website https://el-admin.vip + * @description 用于关闭各种连接,缺啥补啥 + * 2021-03-05 + **/ +public class CloseUtil { + + public static void close(Closeable closeable) { + if (null != closeable) { + try { + closeable.close(); + } catch (Exception e) { + // 静默关闭 + } + } + } + + public static void close(AutoCloseable closeable) { + if (null != closeable) { + try { + closeable.close(); + } catch (Exception e) { + // 静默关闭 + } + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/Constant.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/Constant.java new file mode 100644 index 0000000..402403e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/Constant.java @@ -0,0 +1,62 @@ +package com.example.utils; + +/** + * 常量 + */ +public class Constant { + public static final String DOH = "dns-doh"; + + public static final String DO53 = "dns-do53"; + + public static final String SERVICE = "service"; + + public static final String IP = "ip"; + + public static final String PORT = "port"; + + public static final Integer NONE = 0; + + public static final Integer OPENRDNS = 1; + + public static final Integer FORWARDER = 2; + + public static final Integer FWDRDNS = 3; + + public static final Integer EGRESSRDNS = 4; + + public static final Integer NONSTANDARD = 5; + + public static final String PORT8443 = "8443"; + + public static final String PORT443 = "443"; + + public static final String PORT53 = "53"; + + public static final String DNSTAG = "dns"; + + public static final String DOHTAG = "DNS-DoH"; + + public static final String DO53TAG = "DNS-Do53"; + + public static final String OPENRDNSTAG = "open-rdns"; + + public static final String FORWARDERTAG = "forwarder"; + + public static final String FWDRDNSTAG = "fwd/rdns"; + + public static final String EGRESSRDNSTAG = "egress-dns"; + + public static final String NONSTANDARDTAG = "nonstandard"; + + public static final String PROTOC_TCP = "tcp"; + + public static final String PROTOC_UDP = "udp"; + + public static final String IP_IPV4 = "ipv4"; + + public static final String IP_IPV6 = "ipv6"; + + public static final String POINT = "."; + + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/DateUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/DateUtil.java new file mode 100644 index 0000000..57e9408 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/DateUtil.java @@ -0,0 +1,160 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.utils; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * @author: liaojinlong + * : 2020/6/11 16:28 + * @apiNote: JDK 8 新日期类 格式化与字符串转换 工具类 + */ +public class DateUtil { + + public static final DateTimeFormatter DFY_MD_HMS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + public static final DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + /** + * LocalDateTime 转时间戳 + * + * @param localDateTime / + * @return / + */ + public static Long getTimeStamp(LocalDateTime localDateTime) { + return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond(); + } + + /** + * 时间戳转LocalDateTime + * + * @param timeStamp / + * @return / + */ + public static LocalDateTime fromTimeStamp(Long timeStamp) { + return LocalDateTime.ofEpochSecond(timeStamp, 0, OffsetDateTime.now().getOffset()); + } + + /** + * LocalDateTime 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDateTime / + * @return / + */ + public static Date toDate(LocalDateTime localDateTime) { + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + + /** + * LocalDate 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDate / + * @return / + */ + public static Date toDate(LocalDate localDate) { + return toDate(localDate.atTime(LocalTime.now(ZoneId.systemDefault()))); + } + + + /** + * Date转 LocalDateTime + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param date / + * @return / + */ + public static LocalDateTime toLocalDateTime(Date date) { + return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + } + + /** + * 日期 格式化 + * + * @param localDateTime / + * @param patten / + * @return / + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(patten); + return df.format(localDateTime); + } + + /** + * 日期 格式化 + * + * @param localDateTime / + * @param df / + * @return / + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, DateTimeFormatter df) { + return df.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime / + * @return / + */ + public static String localDateTimeFormatyMdHms(LocalDateTime localDateTime) { + return DFY_MD_HMS.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public String localDateTimeFormatyMd(LocalDateTime localDateTime) { + return DFY_MD.format(localDateTime); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, String pattern) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, DateTimeFormatter dateTimeFormatter) { + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) { + return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime)); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ElAdminConstant.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ElAdminConstant.java new file mode 100644 index 0000000..f46ff3b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ElAdminConstant.java @@ -0,0 +1,70 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import java.util.Arrays; +import java.util.List; + +/** + * 常用静态常量 + * + * + * 2018-12-26 + */ +public class ElAdminConstant { + + private ElAdminConstant() { + throw new IllegalStateException("Utility class"); + } + + /** + * 用于IP定位转换 + */ + public static final String REGION = "内网IP|内网IP"; + /** + * win 系统 + */ + public static final String WIN = "win"; + + /** + * mac 系统 + */ + public static final String MAC = "mac"; + + public static final List openRdnsLabels = Arrays.asList("DNS", "DNS-Do53", "open-rdns"); + + public static final List forwarderLabels = Arrays.asList("DNS", "DNS-Do53", "forwarder"); + + public static final List fwdRdnsLabels = Arrays.asList("DNS", "DNS-Do53", "fwd/rdns"); + + public static final List egressDnsLabels = Arrays.asList("DNS", "DNS-Do53", "egress-dns"); + + public static final List nonstandardLabels = Arrays.asList("DNS", "DNS-Do53", "nonstandard"); + + public static final List dnsLabels = Arrays.asList("DNS"); + + public static final List dohLabels = Arrays.asList("DNS","DNS-DoH"); + + public static final List do53Labels = Arrays.asList(new String[]{"DNS","DNS-Do53"}); + + /** + * 常用接口 + */ + public static class Url { + // IP归属地查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp?ip=%s&json=true"; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/EncryptUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/EncryptUtils.java new file mode 100644 index 0000000..6ee5a49 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/EncryptUtils.java @@ -0,0 +1,100 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; +import java.nio.charset.StandardCharsets; + +/** + * 加密 + * + * 2018-11-23 + */ + +public class EncryptUtils { + + private static final String STR_PARAM = "Passw0rd"; + + private static Cipher cipher; + + private static final IvParameterSpec IV = new IvParameterSpec(STR_PARAM.getBytes(StandardCharsets.UTF_8)); + + private static DESKeySpec getDesKeySpec(String source) throws Exception { + if (source == null || source.length() == 0){ + return null; + } + cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + String strKey = "Passw0rd"; + return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8)); + } + + /** + * 对称加密 + */ + public static String desEncrypt(String source) throws Exception { + DESKeySpec desKeySpec = getDesKeySpec(source); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, IV); + return byte2hex( + cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase(); + } + + /** + * 对称解密 + */ + public static String desDecrypt(String source) throws Exception { + byte[] src = hex2byte(source.getBytes(StandardCharsets.UTF_8)); + DESKeySpec desKeySpec = getDesKeySpec(source); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + cipher.init(Cipher.DECRYPT_MODE, secretKey, IV); + byte[] retByte = cipher.doFinal(src); + return new String(retByte); + } + + private static String byte2hex(byte[] inStr) { + String stmp; + StringBuilder out = new StringBuilder(inStr.length * 2); + for (byte b : inStr) { + stmp = Integer.toHexString(b & 0xFF); + if (stmp.length() == 1) { + // 如果是0至F的单位字符串,则添加0 + out.append("0").append(stmp); + } else { + out.append(stmp); + } + } + return out.toString(); + } + + private static byte[] hex2byte(byte[] b) { + int size = 2; + if ((b.length % size) != 0){ + throw new IllegalArgumentException("长度不是偶数"); + } + byte[] b2 = new byte[b.length / 2]; + for (int n = 0; n < b.length; n += size) { + String item = new String(b, n, 2); + b2[n / 2] = (byte) Integer.parseInt(item, 16); + } + return b2; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/FileUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/FileUtil.java new file mode 100644 index 0000000..dc209a9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/FileUtil.java @@ -0,0 +1,356 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.poi.excel.BigExcelWriter; +import cn.hutool.poi.excel.ExcelUtil; +import com.example.exception.BadRequestException; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.security.MessageDigest; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * File工具类,扩展 hutool 工具包 + * + * + * 2018-12-27 + */ +public class FileUtil extends cn.hutool.core.io.FileUtil { + + private static final Logger log = LoggerFactory.getLogger(FileUtil.class); + + /** + * 系统临时目录 + *
+ * windows 包含路径分割符,但Linux 不包含, + * 在windows \\==\ 前提下, + * 为安全起见 同意拼装 路径分割符, + *

+     *       java.io.tmpdir
+     *       windows : C:\Users/xxx\AppData\Local\Temp\
+     *       linux: /temp
+     * 
+ */ + public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator; + /** + * 定义GB的计算常量 + */ + private static final int GB = 1024 * 1024 * 1024; + /** + * 定义MB的计算常量 + */ + private static final int MB = 1024 * 1024; + /** + * 定义KB的计算常量 + */ + private static final int KB = 1024; + + /** + * 格式化小数 + */ + private static final DecimalFormat DF = new DecimalFormat("0.00"); + + public static final String IMAGE = "图片"; + public static final String TXT = "文档"; + public static final String MUSIC = "音乐"; + public static final String VIDEO = "视频"; + public static final String OTHER = "其他"; + + + /** + * MultipartFile转File + */ + public static File toFile(MultipartFile multipartFile) { + // 获取文件名 + String fileName = multipartFile.getOriginalFilename(); + // 获取文件后缀 + String prefix = "." + getExtensionName(fileName); + File file = null; + try { + // 用uuid作为文件名,防止生成的临时文件重复 + file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix); + // MultipartFile to File + multipartFile.transferTo(file); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return file; + } + + /** + * 获取文件扩展名,不带 . + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } + + /** + * Java文件操作 获取不带扩展名的文件名 + */ + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + /** + * 文件大小转换 + */ + public static String getSize(long size) { + String resultSize; + if (size / GB >= 1) { + //如果当前Byte的值大于等于1GB + resultSize = DF.format(size / (float) GB) + "GB "; + } else if (size / MB >= 1) { + //如果当前Byte的值大于等于1MB + resultSize = DF.format(size / (float) MB) + "MB "; + } else if (size / KB >= 1) { + //如果当前Byte的值大于等于1KB + resultSize = DF.format(size / (float) KB) + "KB "; + } else { + resultSize = size + "B "; + } + return resultSize; + } + + /** + * inputStream 转 File + */ + static File inputStreamToFile(InputStream ins, String name){ + File file = new File(SYS_TEM_DIR + name); + if (file.exists()) { + return file; + } + OutputStream os = null; + try { + os = new FileOutputStream(file); + int bytesRead; + int len = 8192; + byte[] buffer = new byte[len]; + while ((bytesRead = ins.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + CloseUtil.close(os); + CloseUtil.close(ins); + } + return file; + } + + /** + * 将文件名解析成文件的上传路径 + */ + public static File upload(MultipartFile file, String filePath) { + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS"); + String name = getFileNameNoEx(file.getOriginalFilename()); + String suffix = getExtensionName(file.getOriginalFilename()); + String nowStr = "-" + format.format(date); + try { + String fileName = name + nowStr + "." + suffix; + String path = filePath + fileName; + // getCanonicalFile 可解析正确各种路径 + File dest = new File(path).getCanonicalFile(); + // 检测是否存在目录 + if (!dest.getParentFile().exists()) { + if (!dest.getParentFile().mkdirs()) { + System.out.println("was not successful."); + } + } + // 文件写入 + file.transferTo(dest); + return dest; + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 导出excel + */ + public static void downloadExcel(List> list, HttpServletResponse response) throws IOException { + String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer = ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(list, true); + SXSSFSheet sheet = (SXSSFSheet)writer.getSheet(); + //上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法 + sheet.trackAllColumnsForAutoSizing(); + //列宽自适应 + writer.autoSizeColumnAll(); + //response为HttpServletResponse对象 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx"); + ServletOutputStream out = response.getOutputStream(); + // 终止后删除临时文件 + file.deleteOnExit(); + writer.flush(out, true); + //此处记得关闭输出Servlet流 + IoUtil.close(out); + } + + public static String getFileType(String type) { + String documents = "txt doc pdf ppt pps xlsx xls docx"; + String music = "mp3 wav wma mpa ram ra aac aif m4a"; + String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg"; + String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg"; + if (image.contains(type)) { + return IMAGE; + } else if (documents.contains(type)) { + return TXT; + } else if (music.contains(type)) { + return MUSIC; + } else if (video.contains(type)) { + return VIDEO; + } else { + return OTHER; + } + } + + public static void checkSize(long maxSize, long size) { + // 1M + int len = 1024 * 1024; + if (size > (maxSize * len)) { + throw new BadRequestException("文件超出规定大小:" + maxSize + "MB"); + } + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(File file1, File file2) { + String img1Md5 = getMd5(file1); + String img2Md5 = getMd5(file2); + if(img1Md5 != null){ + return img1Md5.equals(img2Md5); + } + return false; + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(String file1Md5, String file2Md5) { + return file1Md5.equals(file2Md5); + } + + private static byte[] getByte(File file) { + // 得到文件长度 + byte[] b = new byte[(int) file.length()]; + InputStream in = null; + try { + in = new FileInputStream(file); + try { + System.out.println(in.read(b)); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } finally { + CloseUtil.close(in); + } + return b; + } + + private static String getMd5(byte[] bytes) { + // 16进制字符 + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(bytes); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + // 移位 输出字符串 + for (byte byte0 : md) { + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 下载文件 + * + * @param request / + * @param response / + * @param file / + */ + public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) { + response.setCharacterEncoding(request.getCharacterEncoding()); + response.setContentType("application/octet-stream"); + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); + IOUtils.copy(fis, response.getOutputStream()); + response.flushBuffer(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + if (fis != null) { + try { + fis.close(); + if (deleteOnExit) { + file.deleteOnExit(); + } + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + } + + public static String getMd5(File file) { + return getMd5(getByte(file)); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/PageUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/PageUtil.java new file mode 100644 index 0000000..5bea120 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/PageUtil.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import org.springframework.data.domain.Page; +import java.util.*; + +/** + * 分页工具 + * + * 2018-12-10 + */ +public class PageUtil extends cn.hutool.core.util.PageUtil { + + /** + * List 分页 + */ + public static List toPage(int page, int size , List list) { + int fromIndex = page * size; + int toIndex = page * size + size; + if(fromIndex > list.size()){ + return new ArrayList(); + } else if(toIndex >= list.size()) { + return list.subList(fromIndex,list.size()); + } else { + return list.subList(fromIndex,toIndex); + } + } + + /** + * Page 数据处理,预防redis反序列化报错 + */ + public static Map toPage(Page page) { + Map map = new LinkedHashMap<>(2); + map.put("content",page.getContent()); + map.put("totalElements",page.getTotalElements()); + return map; + } + + /** + * 自定义分页 + */ + public static Map toPage(Object object, Object totalElements) { + Map map = new LinkedHashMap<>(2); + map.put("content",object); + map.put("totalElements",totalElements); + return map; + } + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/QueryHelp.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/QueryHelp.java new file mode 100644 index 0000000..e9cf239 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/QueryHelp.java @@ -0,0 +1,208 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import com.example.annotation.DataPermission; +import com.example.annotation.Query; +import javax.persistence.criteria.*; +import java.lang.reflect.Field; +import java.util.*; + +/** + * + * 2019-6-4 14:59:48 + */ +@Slf4j +@SuppressWarnings({"unchecked","all"}) +public class QueryHelp { + + public static Predicate getPredicate(Root root, Q query, CriteriaBuilder cb) { + List list = new ArrayList<>(); + if(query == null){ + return cb.and(list.toArray(new Predicate[0])); + } + // 数据权限验证 + DataPermission permission = query.getClass().getAnnotation(DataPermission.class); + if(permission != null){ + // 获取数据权限 + List dataScopes = SecurityUtils.getCurrentUserDataScope(); + if(CollectionUtil.isNotEmpty(dataScopes)){ + if(StringUtils.isNotBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + Join join = root.join(permission.joinName(), JoinType.LEFT); + list.add(getExpression(permission.fieldName(),join, root).in(dataScopes)); + } else if (StringUtils.isBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + list.add(getExpression(permission.fieldName(),null, root).in(dataScopes)); + } + } + } + try { + List fields = getAllFields(query.getClass(), new ArrayList<>()); + for (Field field : fields) { + boolean accessible = field.isAccessible(); + // 设置对象的访问权限,保证对private的属性的访 + field.setAccessible(true); + Query q = field.getAnnotation(Query.class); + if (q != null) { + String propName = q.propName(); + String joinName = q.joinName(); + String blurry = q.blurry(); + String attributeName = isBlank(propName) ? field.getName() : propName; + Class fieldType = field.getType(); + Object val = field.get(query); + if (ObjectUtil.isNull(val) || "".equals(val)) { + continue; + } + Join join = null; + // 模糊多字段 + if (ObjectUtil.isNotEmpty(blurry)) { + String[] blurrys = blurry.split(","); + List orPredicate = new ArrayList<>(); + for (String s : blurrys) { + orPredicate.add(cb.like(root.get(s) + .as(String.class), "%" + val.toString() + "%")); + } + Predicate[] p = new Predicate[orPredicate.size()]; + list.add(cb.or(orPredicate.toArray(p))); + continue; + } + if (ObjectUtil.isNotEmpty(joinName)) { + String[] joinNames = joinName.split(">"); + for (String name : joinNames) { + switch (q.join()) { + case LEFT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.LEFT); + } else { + join = root.join(name, JoinType.LEFT); + } + break; + case RIGHT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.RIGHT); + } else { + join = root.join(name, JoinType.RIGHT); + } + break; + case INNER: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.INNER); + } else { + join = root.join(name, JoinType.INNER); + } + break; + default: break; + } + } + } + switch (q.type()) { + case EQUAL: + list.add(cb.equal(getExpression(attributeName,join,root) + .as((Class) fieldType),val)); + break; + case GREATER_THAN: + list.add(cb.greaterThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN: + list.add(cb.lessThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN_NQ: + list.add(cb.lessThan(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case INNER_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString() + "%")); + break; + case LEFT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString())); + break; + case RIGHT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), val.toString() + "%")); + break; + case IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val)); + } + break; + case NOT_IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val).not()); + } + break; + case NOT_EQUAL: + list.add(cb.notEqual(getExpression(attributeName,join,root), val)); + break; + case NOT_NULL: + list.add(cb.isNotNull(getExpression(attributeName,join,root))); + break; + case IS_NULL: + list.add(cb.isNull(getExpression(attributeName,join,root))); + break; + case BETWEEN: + List between = new ArrayList<>((List)val); + list.add(cb.between(getExpression(attributeName, join, root).as((Class) between.get(0).getClass()), + (Comparable) between.get(0), (Comparable) between.get(1))); + break; + default: break; + } + } + field.setAccessible(accessible); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + int size = list.size(); + return cb.and(list.toArray(new Predicate[size])); + } + + @SuppressWarnings("unchecked") + private static Expression getExpression(String attributeName, Join join, Root root) { + if (ObjectUtil.isNotEmpty(join)) { + return join.get(attributeName); + } else { + return root.get(attributeName); + } + } + + private static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + public static List getAllFields(Class clazz, List fields) { + if (clazz != null) { + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); + getAllFields(clazz.getSuperclass(), fields); + } + return fields; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RedisUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RedisUtils.java new file mode 100644 index 0000000..4de0949 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RedisUtils.java @@ -0,0 +1,708 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Component +@SuppressWarnings({"unchecked", "all"}) +public class RedisUtils { + private static final Logger log = LoggerFactory.getLogger(RedisUtils.class); + private RedisTemplate redisTemplate; + @Value("${jwt.online-key}") + private String onlineKey; + + public RedisUtils(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @param timeUnit 单位 + */ + public boolean expire(String key, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.expire(key, time, timeUnit); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 根据 key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(Object key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 查找匹配key + * + * @param pattern key + * @return / + */ + public List scan(String pattern) { + ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(); + while (cursor.hasNext()) { + result.add(new String(cursor.next())); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 分页查询 key + * + * @param patternKey key + * @param page 页码 + * @param size 每页数目 + * @return / + */ + public List findKeysForPage(String patternKey, int page, int size) { + ScanOptions options = ScanOptions.scanOptions().match(patternKey).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(size); + int tmpIndex = 0; + int fromIndex = page * size; + int toIndex = page * size + size; + while (cursor.hasNext()) { + if (tmpIndex >= fromIndex && tmpIndex < toIndex) { + result.add(new String(cursor.next())); + tmpIndex++; + continue; + } + // 获取到满足条件的数据后,就可以退出了 + if (tmpIndex >= toIndex) { + break; + } + tmpIndex++; + cursor.next(); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + public void del(String... keys) { + if (keys != null && keys.length > 0) { + if (keys.length == 1) { + boolean result = redisTemplate.delete(keys[0]); + log.debug("--------------------------------------------"); + log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString()); + log.debug("--------------------------------------------"); + } else { + Set keySet = new HashSet<>(); + for (String key : keys) { + keySet.addAll(redisTemplate.keys(key)); + } + long count = redisTemplate.delete(keySet); + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keySet.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } + } + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 批量获取 + * + * @param keys + * @return + */ + public List multiGet(List keys) { + List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys)); + List resultList = Lists.newArrayList(); + Optional.ofNullable(list).ifPresent(e-> list.forEach(ele-> Optional.ofNullable(ele).ifPresent(resultList::add))); + return resultList; + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 类型 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, timeUnit); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return / + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + return redisTemplate.opsForList().remove(key, count, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * @param prefix 前缀 + * @param ids id + */ + public void delByKeys(String prefix, Set ids) { + Set keys = new HashSet<>(); + for (Long id : ids) { + keys.addAll(redisTemplate.keys(new StringBuffer(prefix).append(id).toString())); + } + long count = redisTemplate.delete(keys); + // 此处提示可自行删除 + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keys.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RequestHolder.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RequestHolder.java new file mode 100644 index 0000000..09764e4 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RequestHolder.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; + +/** + * 获取 HttpServletRequest + * + * 2018-11-24 + */ +public class RequestHolder { + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RsaUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RsaUtils.java new file mode 100644 index 0000000..4611a15 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/RsaUtils.java @@ -0,0 +1,198 @@ +package com.example.utils; + +import org.apache.commons.codec.binary.Base64; +import javax.crypto.Cipher; +import java.io.ByteArrayOutputStream; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * @author https://www.cnblogs.com/nihaorz/p/10690643.html + * @description Rsa 工具类,公钥私钥生成,加解密 + * 2020-05-18 + **/ +public class RsaUtils { + + private static final String SRC = "123456"; + + public static void main(String[] args) throws Exception { + System.out.println("\n"); + RsaKeyPair keyPair = generateKeyPair(); + System.out.println("公钥:" + keyPair.getPublicKey()); + System.out.println("私钥:" + keyPair.getPrivateKey()); + System.out.println("\n"); + test1(keyPair); + System.out.println("\n"); + test2(keyPair); + System.out.println("\n"); + } + + /** + * 公钥加密私钥解密 + */ + private static void test1(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 公钥加密私钥解密开始 *****************"); + String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC); + String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 公钥加密私钥解密结束 *****************"); + } + + /** + * 私钥加密公钥解密 + * @throws Exception / + */ + private static void test2(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 私钥加密公钥解密开始 *****************"); + String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC); + String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 私钥加密公钥解密结束 *****************"); + } + + /** + * 公钥解密 + * + * @param publicKeyText 公钥 + * @param text 待解密的信息 + * @return / + * @throws Exception / + */ + public static String decryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 私钥加密 + * + * @param privateKeyText 私钥 + * @param text 待加密的信息 + * @return / + * @throws Exception / + */ + public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 私钥解密 + * + * @param privateKeyText 私钥 + * @param text 待解密的文本 + * @return / + * @throws Exception / + */ + public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 公钥加密 + * + * @param publicKeyText 公钥 + * @param text 待加密的文本 + * @return / + */ + public static String encryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + private static byte[] doLongerCipherFinal(int opMode,Cipher cipher, byte[] source) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + if (opMode == Cipher.DECRYPT_MODE) { + out.write(cipher.doFinal(source)); + } else { + int offset = 0; + int totalSize = source.length; + while (totalSize - offset > 0) { + int size = Math.min(cipher.getOutputSize(0) - 11, totalSize - offset); + out.write(cipher.doFinal(source, offset, size)); + offset += size; + } + } + out.close(); + return out.toByteArray(); + } + + /** + * 构建RSA密钥对 + * + * @return / + * @throws NoSuchAlgorithmException / + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair { + + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SecurityUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SecurityUtils.java new file mode 100644 index 0000000..e263130 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SecurityUtils.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.example.utils.enums.DataScopeEnum; +import lombok.extern.slf4j.Slf4j; +import com.example.exception.BadRequestException; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import java.util.List; + +/** + * 获取当前登录的用户 + * + * 2019-01-17 + */ +@Slf4j +public class SecurityUtils { + + /** + * 获取当前登录的用户 + * @return UserDetails + */ + public static UserDetails getCurrentUser() { + UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class); + return userDetailsService.loadUserByUsername(getCurrentUsername()); + } + + /** + * 获取系统用户名称 + * + * @return 系统用户名称 + */ + public static String getCurrentUsername() { + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期"); + } + if (authentication.getPrincipal() instanceof UserDetails) { + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + return userDetails.getUsername(); + } + throw new BadRequestException(HttpStatus.UNAUTHORIZED, "找不到当前登录的信息"); + } + + /** + * 获取系统用户ID + * @return 系统用户ID + */ + public static Long getCurrentUserId() { + UserDetails userDetails = getCurrentUser(); + return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class); + } + + /** + * 获取当前用户的数据权限 + * @return / + */ + public static List getCurrentUserDataScope(){ + UserDetails userDetails = getCurrentUser(); + JSONArray array = JSONUtil.parseArray(new JSONObject(userDetails).get("dataScopes")); + return JSONUtil.toList(array,Long.class); + } + + /** + * 获取数据权限级别 + * @return 级别 + */ + public static String getDataScopeType() { + List dataScopes = getCurrentUserDataScope(); + if(dataScopes.size() != 0){ + return ""; + } + return DataScopeEnum.ALL.getValue(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SpringContextHolder.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SpringContextHolder.java new file mode 100644 index 0000000..454b7c8 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/SpringContextHolder.java @@ -0,0 +1,145 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Jie + * 2019-01-07 + */ +@Slf4j +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { + + private static ApplicationContext applicationContext = null; + private static final List CALL_BACKS = new ArrayList<>(); + private static boolean addCallback = true; + + /** + * 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。 + * 在SpringContextHolder 初始化后,进行回调使用 + * + * @param callBack 回调函数 + */ + public synchronized static void addCallBacks(CallBack callBack) { + if (addCallback) { + SpringContextHolder.CALL_BACKS.add(callBack); + } else { + log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); + callBack.executor(); + } + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) { + assertContextInjected(); + return (T) applicationContext.getBean(name); + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class requiredType) { + assertContextInjected(); + return applicationContext.getBean(requiredType); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param defaultValue 默认值 + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, T defaultValue, Class requiredType) { + T result = defaultValue; + try { + result = getBean(Environment.class).getProperty(property, requiredType); + } catch (Exception ignored) {} + return result; + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @return / + */ + public static String getProperties(String property) { + return getProperties(property, null, String.class); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, Class requiredType) { + return getProperties(property, null, requiredType); + } + + /** + * 检查ApplicationContext不为空. + */ + private static void assertContextInjected() { + if (applicationContext == null) { + throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" + + ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder."); + } + } + + /** + * 清除SpringContextHolder中的ApplicationContext为Null. + */ + private static void clearHolder() { + log.debug("清除SpringContextHolder中的ApplicationContext:" + + applicationContext); + applicationContext = null; + } + + @Override + public void destroy() { + SpringContextHolder.clearHolder(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (SpringContextHolder.applicationContext != null) { + log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); + } + SpringContextHolder.applicationContext = applicationContext; + if (addCallback) { + for (CallBack callBack : SpringContextHolder.CALL_BACKS) { + callBack.executor(); + } + CALL_BACKS.clear(); + } + SpringContextHolder.addCallback = false; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/StringUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/StringUtils.java new file mode 100644 index 0000000..a5fd454 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/StringUtils.java @@ -0,0 +1,264 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import com.example.config.ElAdminProperties; +import net.dreamlu.mica.ip2region.core.Ip2regionSearcher; +import net.dreamlu.mica.ip2region.core.IpInfo; +import nl.basjes.parse.useragent.UserAgent; +import nl.basjes.parse.useragent.UserAgentAnalyzer; +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.Calendar; +import java.util.Date; +import java.util.Enumeration; + +/** + * + * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类 + */ +@Slf4j +public class StringUtils extends org.apache.commons.lang3.StringUtils { + + private static final char SEPARATOR = '_'; + private static final String UNKNOWN = "unknown"; + + /** + * 注入bean + */ + private final static Ip2regionSearcher IP_SEARCHER = SpringContextHolder.getBean(Ip2regionSearcher.class); + + + private static final UserAgentAnalyzer USER_AGENT_ANALYZER = UserAgentAnalyzer + .newBuilder() + .hideMatcherLoadStats() + .withCache(10000) + .withField(UserAgent.AGENT_NAME_VERSION) + .build(); + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + public static String toCamelCase(String s) { + if (s == null) { + return null; + } + + s = s.toLowerCase(); + + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + if (c == SEPARATOR) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(c); + } + } + + return sb.toString(); + } + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + public static String toCapitalizeCamelCase(String s) { + if (s == null) { + return null; + } + s = toCamelCase(s); + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + static String toUnderScoreCase(String s) { + if (s == null) { + return null; + } + + StringBuilder sb = new StringBuilder(); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + boolean nextUpperCase = true; + + if (i < (s.length() - 1)) { + nextUpperCase = Character.isUpperCase(s.charAt(i + 1)); + } + + if ((i > 0) && Character.isUpperCase(c)) { + if (!upperCase || !nextUpperCase) { + sb.append(SEPARATOR); + } + upperCase = true; + } else { + upperCase = false; + } + + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 获取ip地址 + */ + public static String getIp(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + String comma = ","; + String localhost = "127.0.0.1"; + if (ip.contains(comma)) { + ip = ip.split(",")[0]; + } + if (localhost.equals(ip)) { + // 获取本机真正的ip地址 + try { + ip = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + log.error(e.getMessage(), e); + } + } + return ip; + } + + /** + * 根据ip获取详细地址 + */ + public static String getCityInfo(String ip) { + if (ElAdminProperties.ipLocal) { + return getLocalCityInfo(ip); + } else { + return getHttpCityInfo(ip); + } + } + + /** + * 根据ip获取详细地址 + */ + public static String getHttpCityInfo(String ip) { + String api = String.format(ElAdminConstant.Url.IP_URL, ip); + JSONObject object = JSONUtil.parseObj(HttpUtil.get(api)); + return object.get("addr", String.class); + } + + /** + * 根据ip获取详细地址 + */ + public static String getLocalCityInfo(String ip) { + IpInfo ipInfo = IP_SEARCHER.memorySearch(ip); + if(ipInfo != null){ + return ipInfo.getAddress(); + } + return null; + + } + + public static String getBrowser(HttpServletRequest request) { + UserAgent.ImmutableUserAgent userAgent = USER_AGENT_ANALYZER.parse(request.getHeader("User-Agent")); + return userAgent.get(UserAgent.AGENT_NAME_VERSION).getValue(); + } + + /** + * 获得当天是周几 + */ + public static String getWeekDay() { + String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (w < 0) { + w = 0; + } + return weekDays[w]; + } + + /** + * 获取当前机器的IP + * + * @return / + */ + public static String getLocalIp() { + try { + InetAddress candidateAddress = null; + // 遍历所有的网络接口 + for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) { + NetworkInterface anInterface = interfaces.nextElement(); + // 在所有的接口下再遍历IP + for (Enumeration inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements();) { + InetAddress inetAddr = inetAddresses.nextElement(); + // 排除loopback类型地址 + if (!inetAddr.isLoopbackAddress()) { + if (inetAddr.isSiteLocalAddress()) { + // 如果是site-local地址,就是它了 + return inetAddr.getHostAddress(); + } else if (candidateAddress == null) { + // site-local类型的地址未被发现,先记录候选地址 + candidateAddress = inetAddr; + } + } + } + } + if (candidateAddress != null) { + return candidateAddress.getHostAddress(); + } + // 如果没有发现 non-loopback地址.只能用最次选的方案 + InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); + if (jdkSuppliedAddress == null) { + return ""; + } + return jdkSuppliedAddress.getHostAddress(); + } catch (Exception e) { + return ""; + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ThrowableUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ThrowableUtil.java new file mode 100644 index 0000000..0ea7da7 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ThrowableUtil.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 异常工具 2019-01-06 + * + */ +public class ThrowableUtil { + + /** + * 获取堆栈信息 + */ + public static String getStackTrace(Throwable throwable){ + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw)) { + throwable.printStackTrace(pw); + return sw.toString(); + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/TranslatorUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/TranslatorUtil.java new file mode 100644 index 0000000..7d7087d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/TranslatorUtil.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.json.JSONArray; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +/** + * + * 翻译工具类 + */ +public class TranslatorUtil { + + public static String translate(String word){ + try { + String url = "https://translate.googleapis.com/translate_a/single?" + + "client=gtx&" + + "sl=en" + + "&tl=zh-CN" + + "&dt=t&q=" + URLEncoder.encode(word, "UTF-8"); + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestProperty("User-Agent", "Mozilla/5.0"); + + BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + return parseResult(response.toString()); + }catch (Exception e){ + return word; + } + } + + private static String parseResult(String inputJson){ + JSONArray jsonArray2 = (JSONArray) new JSONArray(inputJson).get(0); + StringBuilder result = new StringBuilder(); + for (Object o : jsonArray2) { + result.append(((JSONArray) o).get(0).toString()); + } + return result.toString(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ValidationUtil.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ValidationUtil.java new file mode 100644 index 0000000..689ec6f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/ValidationUtil.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils; + +import cn.hutool.core.util.ObjectUtil; +import com.example.exception.BadRequestException; +import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; + +/** + * 验证工具 + * + * 2018-11-23 + */ +public class ValidationUtil{ + + /** + * 验证空 + */ + public static void isNull(Object obj, String entity, String parameter , Object value){ + if(ObjectUtil.isNull(obj)){ + String msg = entity + " 不存在: "+ parameter +" is "+ value; + throw new BadRequestException(msg); + } + } + + /** + * 验证是否为邮箱 + */ + public static boolean isEmail(String email) { + return new EmailValidator().isValid(email, null); + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeBiEnum.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeBiEnum.java new file mode 100644 index 0000000..4f0147e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeBiEnum.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 验证码业务场景 + *

+ * + * 2020-05-02 + */ +@Getter +@AllArgsConstructor +public enum CodeBiEnum { + + /* 旧邮箱修改邮箱 */ + ONE(1, "旧邮箱修改邮箱"), + + /* 通过邮箱修改密码 */ + TWO(2, "通过邮箱修改密码"); + + private final Integer code; + private final String description; + + public static CodeBiEnum find(Integer code) { + for (CodeBiEnum value : CodeBiEnum.values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeEnum.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeEnum.java new file mode 100644 index 0000000..17a1b2d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/CodeEnum.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 验证码业务场景对应的 Redis 中的 key + *

+ * + * 2020-05-02 + */ +@Getter +@AllArgsConstructor +public enum CodeEnum { + + /* 通过手机号码重置邮箱 */ + PHONE_RESET_EMAIL_CODE("phone_reset_email_code_", "通过手机号码重置邮箱"), + + /* 通过旧邮箱重置邮箱 */ + EMAIL_RESET_EMAIL_CODE("email_reset_email_code_", "通过旧邮箱重置邮箱"), + + /* 通过手机号码重置密码 */ + PHONE_RESET_PWD_CODE("phone_reset_pwd_code_", "通过手机号码重置密码"), + + /* 通过邮箱重置密码 */ + EMAIL_RESET_PWD_CODE("email_reset_pwd_code_", "通过邮箱重置密码"); + + private final String key; + private final String description; +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/DataScopeEnum.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/DataScopeEnum.java new file mode 100644 index 0000000..18330f2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/DataScopeEnum.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 数据权限枚举 + *

+ * + * 2020-05-07 + */ +@Getter +@AllArgsConstructor +public enum DataScopeEnum { + + /* 全部的数据权限 */ + ALL("全部", "全部的数据权限"), + + /* 自己部门的数据权限 */ + THIS_LEVEL("本级", "自己部门的数据权限"), + + /* 自定义的数据权限 */ + CUSTOMIZE("自定义", "自定义的数据权限"); + + private final String value; + private final String description; + + public static DataScopeEnum find(String val) { + for (DataScopeEnum dataScopeEnum : DataScopeEnum.values()) { + if (dataScopeEnum.getValue().equals(val)) { + return dataScopeEnum; + } + } + return null; + } + +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/RequestMethodEnum.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/RequestMethodEnum.java new file mode 100644 index 0000000..2edd703 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/enums/RequestMethodEnum.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * + * @website https://el-admin.vip + * @description + * 2020-06-10 + **/ +@Getter +@AllArgsConstructor +public enum RequestMethodEnum { + + /** + * 搜寻 @AnonymousGetMapping + */ + GET("GET"), + + /** + * 搜寻 @AnonymousPostMapping + */ + POST("POST"), + + /** + * 搜寻 @AnonymousPutMapping + */ + PUT("PUT"), + + /** + * 搜寻 @AnonymousPatchMapping + */ + PATCH("PATCH"), + + /** + * 搜寻 @AnonymousDeleteMapping + */ + DELETE("DELETE"), + + /** + * 否则就是所有 Request 接口都放行 + */ + ALL("All"); + + /** + * Request 类型 + */ + private final String type; + + public static RequestMethodEnum find(String type) { + for (RequestMethodEnum value : RequestMethodEnum.values()) { + if (value.getType().equals(type)) { + return value; + } + } + return ALL; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/PageUtils.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/PageUtils.java new file mode 100644 index 0000000..7f02b02 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/PageUtils.java @@ -0,0 +1,145 @@ +/** + + * + + * + * + */ + +package com.example.utils.page; + + + +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class PageUtils implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 总记录数 + */ + private int total; + /** + * 每页记录数 + */ + private int size; + /** + * 总页数 + */ + private int pages; + /** + * 当前页数 + */ + private int page; + /** + * 列表数据 + */ + private List list; + + private double totalTime; + + private Object independentIpNum; + + private int resultTotal; + + public int getResultTotal() { + return resultTotal; + } + + public void setResultTotal(int resultTotal) { + this.resultTotal = resultTotal; + } + + /** + * 分页 + * @param list 列表数据 + * @param total 总记录数 + * @param size 每页记录数 + * @param page 当前页数 + */ + public PageUtils(List list, int total, int size, int page ,double totalTime,int independentIpNum ,int resultTotal) { + this.list = list; + this.total = total; + this.size = size; + this.page = page; + this.totalTime = totalTime; + this.independentIpNum = independentIpNum; + this.resultTotal = resultTotal; + this.pages = (int)Math.ceil((double)total/size); + } + + /** + * 分页 + */ + public PageUtils(IPage page) { + this.list = page.getRecords(); + this.total = (int)page.getTotal(); + this.size = (int)page.getSize(); + this.page = (int)page.getCurrent(); + this.pages = (int)page.getPages(); + } + + + public Object getIndependentIpNum() { + return independentIpNum; + } + + public void setIndependentIpNum(Object independentIpNum) { + this.independentIpNum = independentIpNum; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + public int getPage() { + return page; + } + + public double getTotalTime() { + return totalTime; + } + + public void setTotalTime(double totalTime) { + this.totalTime = totalTime; + } + + public void setPage(int page) { + this.page = page; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/Query.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/Query.java new file mode 100644 index 0000000..765f2f6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/Query.java @@ -0,0 +1,64 @@ +package com.example.utils.page; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.Map; + +/** + * 查询参数 + */ +public class Query { + + private Class clz; + + public Class getClz() { + return clz; + } + + public void setClz(Class clz) { + this.clz = clz; + } + + public Query(Class clz) { + this.clz = clz; + } + + public IPage getPage(Map params) { + return this.getPage(params, null, false); + } + + public IPage getPage(Map params, String defaultOrderField, boolean isAsc) { + //分页参数 + long curPage = 1; + long limit = 10; + + if(params.get("page") != null && !"".equals(params.get("page"))){ + curPage = Long.parseLong((String)params.get("page")); + } + if(params.get("size") != null && !"".equals(params.get("size"))){ + limit = Long.parseLong((String)params.get("size")); + if(limit == -1){ + limit = Long.MAX_VALUE; + curPage = 0; + } + } + + //分页对象 + Page page = new Page(curPage, limit); + + //分页参数 + params.put("page", page); + + + // 默认排序 + if(isAsc) { + page.setAsc(defaultOrderField); + }else { + page.setDesc(defaultOrderField); + } + + return page; + } +} diff --git a/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/R.java b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/R.java new file mode 100644 index 0000000..92db65a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-common/src/main/java/com/example/utils/page/R.java @@ -0,0 +1,40 @@ +package com.example.utils.page; + +import cn.hutool.core.date.DateUtil; + +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class R extends HashMap { + private static final long serialVersionUID = 1L; + + public R() { + put("status", 200); + put("message", "success"); + put("timestamp", new Date()); + } + + public static R ok(String message) { + R r = new R(); + r.put("message", message); + r.put("timestamp", new Date()); + return r; + } + + public static R ok() { + return new R(); + } + + public static R ok(Object data) { + R r = new R(); + r.put("data", data); + r.put("timestamp", new Date()); + return r; + } + + +} + + diff --git a/UI source code/dns-dev-2.0/dns-logging/pom.xml b/UI source code/dns-dev-2.0/dns-logging/pom.xml new file mode 100644 index 0000000..f3c2cc9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/pom.xml @@ -0,0 +1,22 @@ + + + + dns + com.example + 2.6 + + 4.0.0 + + dns-logging + dns-logging + + + + com.example + dns-common + 2.6 + + + diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/annotation/Log.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/annotation/Log.java new file mode 100644 index 0000000..566b555 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/annotation/Log.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * 2018-11-24 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Log { + String value() default ""; +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/aspect/LogAspect.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/aspect/LogAspect.java new file mode 100644 index 0000000..aaed973 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/aspect/LogAspect.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.aspect; + +import com.example.utils.RequestHolder; +import com.example.utils.SecurityUtils; +import com.example.utils.StringUtils; +import com.example.utils.ThrowableUtil; +import lombok.extern.slf4j.Slf4j; +import com.example.domain.Log; +import com.example.service.LogService; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; + +/** + * + * 2018-11-24 + */ +@Component +@Aspect +@Slf4j +public class LogAspect { + + private final LogService logService; + + ThreadLocal currentTime = new ThreadLocal<>(); + + public LogAspect(LogService logService) { + this.logService = logService; + } + + /** + * 配置切入点 + */ + @Pointcut("@annotation(com.example.annotation.Log)") + public void logPointcut() { + // 该方法无方法体,主要为了让同类中其他方法使用此切入点 + } + + /** + * 配置环绕通知,使用在方法logPointcut()上注册的切入点 + * + * @param joinPoint join point for advice + */ + @Around("logPointcut()") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + Object result; + currentTime.set(System.currentTimeMillis()); + result = joinPoint.proceed(); + Log log = new Log("INFO",System.currentTimeMillis() - currentTime.get()); + currentTime.remove(); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request),joinPoint, log); + return result; + } + + /** + * 配置异常通知 + * + * @param joinPoint join point for advice + * @param e exception + */ + @AfterThrowing(pointcut = "logPointcut()", throwing = "e") + public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { + Log log = new Log("ERROR",System.currentTimeMillis() - currentTime.get()); + currentTime.remove(); + log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes()); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, log); + } + + public String getUsername() { + try { + return SecurityUtils.getCurrentUsername(); + }catch (Exception e){ + return ""; + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/domain/Log.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/domain/Log.java new file mode 100644 index 0000000..21529a6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/domain/Log.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * + * 2018-11-24 + */ +@Entity +@Getter +@Setter +@Table(name = "sys_log") +@NoArgsConstructor +public class Log implements Serializable { + + @Id + @Column(name = "log_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** 操作用户 */ + private String username; + + /** 描述 */ + private String description; + + /** 方法名 */ + private String method; + + /** 参数 */ + private String params; + + /** 日志类型 */ + private String logType; + + /** 请求ip */ + private String requestIp; + + /** 地址 */ + private String address; + + /** 浏览器 */ + private String browser; + + /** 请求耗时 */ + private Long time; + + /** 异常详细 */ + private byte[] exceptionDetail; + + /** 创建日期 */ + @CreationTimestamp + private Timestamp createTime; + + public Log(String logType, Long time) { + this.logType = logType; + this.time = time; + } +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/repository/LogRepository.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/repository/LogRepository.java new file mode 100644 index 0000000..d689cfe --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/repository/LogRepository.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.repository; + +import com.example.domain.Log; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +/** + * + * 2018-11-24 + */ +@Repository +public interface LogRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据日志类型删除信息 + * @param logType 日志类型 + */ + @Modifying + @Query(value = "delete from sys_log where log_type = ?1", nativeQuery = true) + void deleteByLogType(String logType); +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/rest/LogController.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/rest/LogController.java new file mode 100644 index 0000000..305f2bb --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/rest/LogController.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.rest; + +import com.example.utils.SecurityUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.service.LogService; +import com.example.service.dto.LogQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * + * 2018-11-24 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/logs") +@Api(tags = "系统:日志管理") +public class LogController { + + private final LogService logService; + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check()") + public void exportLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("INFO"); + logService.download(logService.queryAll(criteria), response); + } + + @Log("导出错误数据") + @ApiOperation("导出错误数据") + @GetMapping(value = "/error/download") + @PreAuthorize("@el.check()") + public void exportErrorLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("ERROR"); + logService.download(logService.queryAll(criteria), response); + } + @GetMapping + @ApiOperation("日志查询") + @PreAuthorize("@el.check()") + public ResponseEntity queryLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/user") + @ApiOperation("用户日志查询") + public ResponseEntity queryUserLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + criteria.setBlurry(SecurityUtils.getCurrentUsername()); + return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/error") + @ApiOperation("错误日志查询") + @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("ERROR"); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/error/{id}") + @ApiOperation("日志异常详情查询") + @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLogDetail(@PathVariable Long id){ + return new ResponseEntity<>(logService.findByErrDetail(id), HttpStatus.OK); + } + @DeleteMapping(value = "/del/error") + @Log("删除所有ERROR日志") + @ApiOperation("删除所有ERROR日志") + @PreAuthorize("@el.check()") + public ResponseEntity delAllErrorLog(){ + logService.delAllByError(); + return new ResponseEntity<>(HttpStatus.OK); + } + + @DeleteMapping(value = "/del/info") + @Log("删除所有INFO日志") + @ApiOperation("删除所有INFO日志") + @PreAuthorize("@el.check()") + public ResponseEntity delAllInfoLog(){ + logService.delAllByInfo(); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/LogService.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/LogService.java new file mode 100644 index 0000000..b640559 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/LogService.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service; + +import com.example.domain.Log; +import com.example.service.dto.LogQueryCriteria; +import org.aspectj.lang.ProceedingJoinPoint; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * + * 2018-11-24 + */ +public interface LogService { + + /** + * 分页查询 + * @param criteria 查询条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(LogQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 查询条件 + * @return / + */ + List queryAll(LogQueryCriteria criteria); + + /** + * 查询用户日志 + * @param criteria 查询条件 + * @param pageable 分页参数 + * @return - + */ + Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable); + + /** + * 保存日志数据 + * @param username 用户 + * @param browser 浏览器 + * @param ip 请求IP + * @param joinPoint / + * @param log 日志实体 + */ + @Async + void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log); + + /** + * 查询异常详情 + * @param id 日志ID + * @return Object + */ + Object findByErrDetail(Long id); + + /** + * 导出日志 + * @param logs 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List logs, HttpServletResponse response) throws IOException; + + /** + * 删除所有错误日志 + */ + void delAllByError(); + + /** + * 删除所有INFO日志 + */ + void delAllByInfo(); +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogErrorDTO.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogErrorDTO.java new file mode 100644 index 0000000..734bda3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogErrorDTO.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.dto; + +import lombok.Data; +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* +* 2019-5-22 +*/ +@Data +public class LogErrorDTO implements Serializable { + + private Long id; + + private String username; + + private String description; + + private String method; + + private String params; + + private String browser; + + private String requestIp; + + private String address; + + private Timestamp createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogQueryCriteria.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogQueryCriteria.java new file mode 100644 index 0000000..9611dfb --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogQueryCriteria.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.dto; + +import lombok.Data; +import com.example.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * 日志查询类 + * + * 2019-6-4 09:23:07 + */ +@Data +public class LogQueryCriteria { + + @Query(blurry = "username,description,address,requestIp,method,params") + private String blurry; + + @Query + private String logType; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogSmallDTO.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogSmallDTO.java new file mode 100644 index 0000000..d78f9d9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/dto/LogSmallDTO.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.dto; + +import lombok.Data; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * + * 2019-5-22 + */ +@Data +public class LogSmallDTO implements Serializable { + + private String description; + + private String requestIp; + + private Long time; + + private String address; + + private String browser; + + private Timestamp createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/impl/LogServiceImpl.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/impl/LogServiceImpl.java new file mode 100644 index 0000000..43b94b8 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/impl/LogServiceImpl.java @@ -0,0 +1,169 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.impl; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.example.domain.Log; +import com.example.service.LogService; +import com.example.service.dto.LogQueryCriteria; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.repository.LogRepository; +import com.example.service.mapstruct.LogErrorMapper; +import com.example.service.mapstruct.LogSmallMapper; +import com.example.utils.*; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +/** + * + * 2018-11-24 + */ +@Service +@RequiredArgsConstructor +public class LogServiceImpl implements LogService { + private final LogRepository logRepository; + private final LogErrorMapper logErrorMapper; + private final LogSmallMapper logSmallMapper; + + @Override + public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + String status = "ERROR"; + if (status.equals(criteria.getLogType())) { + return PageUtil.toPage(page.map(logErrorMapper::toDto)); + } + return page; + } + + @Override + public List queryAll(LogQueryCriteria criteria) { + return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))); + } + + @Override + public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + return PageUtil.toPage(page.map(logSmallMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) { + if (log == null) { + throw new IllegalArgumentException("Log 不能为 null!"); + } + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + com.example.annotation.Log aopLog = method.getAnnotation(com.example.annotation.Log.class); + + // 方法路径 + String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; + + // 描述 + log.setDescription(aopLog.value()); + + log.setRequestIp(ip); + log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); + log.setMethod(methodName); + log.setUsername(username); + log.setParams(getParameter(method, joinPoint.getArgs())); + log.setBrowser(browser); + logRepository.save(log); + } + + /** + * 根据方法和传入的参数获取请求参数 + */ + private String getParameter(Method method, Object[] args) { + List argList = new ArrayList<>(); + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + //将RequestBody注解修饰的参数作为请求参数 + RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); + if (requestBody != null) { + argList.add(args[i]); + } + //将RequestParam注解修饰的参数作为请求参数 + RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); + if (requestParam != null) { + Map map = new HashMap<>(4); + String key = parameters[i].getName(); + if (!StringUtils.isEmpty(requestParam.value())) { + key = requestParam.value(); + } + map.put(key, args[i]); + argList.add(map); + } + } + if (argList.isEmpty()) { + return ""; + } + return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); + } + + @Override + public Object findByErrDetail(Long id) { + Log log = logRepository.findById(id).orElseGet(Log::new); + ValidationUtil.isNull(log.getId(), "Log", "id", id); + byte[] details = log.getExceptionDetail(); + return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); + } + + @Override + public void download(List logs, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (Log log : logs) { + Map map = new LinkedHashMap<>(); + map.put("用户名", log.getUsername()); + map.put("IP", log.getRequestIp()); + map.put("IP来源", log.getAddress()); + map.put("描述", log.getDescription()); + map.put("浏览器", log.getBrowser()); + map.put("请求耗时/毫秒", log.getTime()); + map.put("异常详情", new String(ObjectUtil.isNotNull(log.getExceptionDetail()) ? log.getExceptionDetail() : "".getBytes())); + map.put("创建日期", log.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByError() { + logRepository.deleteByLogType("ERROR"); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByInfo() { + logRepository.deleteByLogType("INFO"); + } +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogErrorMapper.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogErrorMapper.java new file mode 100644 index 0000000..8a19a28 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogErrorMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.mapstruct; + +import com.example.base.BaseMapper; +import com.example.domain.Log; +import com.example.service.dto.LogErrorDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * 2019-5-22 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogErrorMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogSmallMapper.java b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogSmallMapper.java new file mode 100644 index 0000000..8c06ba4 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-logging/src/main/java/com/example/service/mapstruct/LogSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.service.mapstruct; + +import com.example.base.BaseMapper; +import com.example.domain.Log; +import com.example.service.dto.LogSmallDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * 2019-5-22 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogSmallMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/pom.xml b/UI source code/dns-dev-2.0/dns-system/pom.xml new file mode 100644 index 0000000..ea50602 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/pom.xml @@ -0,0 +1,103 @@ + + + + dns + com.example + 2.6 + + 4.0.0 + + dns-system + dns-system + + + 0.11.1 + + 5.8.0 + + + + + + + + com.example + dns-common + 2.6 + + + com.example + dns-logging + 2.6 + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + + + + + org.quartz-scheduler + quartz + + + + + ch.ethz.ganymed + ganymed-ssh2 + build210 + + + com.jcraft + jsch + 0.1.55 + + + + + com.github.oshi + oshi-core + 5.7.1 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/AppRun.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/AppRun.java new file mode 100644 index 0000000..521f939 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/AppRun.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example; + +import com.example.utils.SpringContextHolder; +import io.swagger.annotations.Api; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.ApplicationPidFileWriter; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.bind.annotation.RestController; + +/** + * 开启审计功能 -> @EnableJpaAuditing + * + * 2018/11/15 9:20:19 + */ +@EnableAsync +@RestController +@Api(hidden = true) +@SpringBootApplication +@EnableTransactionManagement +@EnableJpaAuditing(auditorAwareRef = "auditorAware") +public class AppRun { + + public static void main(String[] args) { + SpringApplication springApplication = new SpringApplication(AppRun.class); + // 监控应用的PID,启动时可指定PID路径:--spring.pid.file=/home/dns/app.pid + // 或者在 application.yml 添加文件路径,方便 kill,kill `cat /home/dns/app.pid` + springApplication.addListeners(new ApplicationPidFileWriter()); + springApplication.run(args); + } + + @Bean + public SpringContextHolder springContextHolder() { + return new SpringContextHolder(); + } + + @Bean + public ServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); + fa.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "[]{}")); + return fa; + } + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/ConfigurerAdapter.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/ConfigurerAdapter.java new file mode 100644 index 0000000..b2bcf86 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/ConfigurerAdapter.java @@ -0,0 +1,88 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +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.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * WebMvcConfigurer + * + * + * 2018-11-30 + */ +@Configuration +@EnableWebMvc +public class ConfigurerAdapter implements WebMvcConfigurer { + + /** 文件配置 */ + private final FileProperties properties; + + public ConfigurerAdapter(FileProperties properties) { + this.properties = properties; + } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + FileProperties.ElPath path = properties.getPath(); + String avatarUtl = "file:" + path.getAvatar().replace("\\","/"); + String pathUtl = "file:" + path.getPath().replace("\\","/"); + registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0); + registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0); + registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0); + } + + @Override + public void configureMessageConverters(List> converters) { + // 使用 fastjson 序列化,会导致 @JsonIgnore 失效,可以使用 @JSONField(serialize = false) 替换 + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + List supportMediaTypeList = new ArrayList<>(); + supportMediaTypeList.add(MediaType.APPLICATION_JSON); + FastJsonConfig config = new FastJsonConfig(); + config.setDateFormat("yyyy-MM-dd HH:mm:ss"); + config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); + converter.setFastJsonConfig(config); + converter.setSupportedMediaTypes(supportMediaTypeList); + converter.setDefaultCharset(StandardCharsets.UTF_8); + converters.add(converter); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusConfig.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusConfig.java new file mode 100644 index 0000000..87e8cbf --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusConfig.java @@ -0,0 +1,236 @@ +package com.example.config; + +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; +import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS; +import com.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; +import com.baomidou.mybatisplus.core.injector.ISqlInjector; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.mapping.DatabaseIdProvider; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.mapper.ClassPathMapperScanner; +import org.mybatis.spring.mapper.MapperFactoryBean; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.autoconfigure.AutoConfigurationPackages; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.context.annotation.*; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; +import java.util.List; + +/** + * mybatis-plus 初始化配置 + */ +@Configuration +@EnableConfigurationProperties(MybatisPlusProperties.class) +public class MybatisPlusConfig { + + public MybatisPlusConfig(MybatisPlusProperties properties, ObjectProvider interceptorsProvider, + ResourceLoader resourceLoader, ObjectProvider databaseIdProvider, + ObjectProvider> configurationCustomizersProvider, + ApplicationContext applicationContext) { + this.properties = properties; + this.interceptors = interceptorsProvider.getIfAvailable(); + this.resourceLoader = resourceLoader; + this.databaseIdProvider = databaseIdProvider.getIfAvailable(); + this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable(); + this.applicationContext = applicationContext; + } + + private static final Log logger = Log.get(); + + private final MybatisPlusProperties properties; + + private final Interceptor[] interceptors; + + private final ResourceLoader resourceLoader; + + private final DatabaseIdProvider databaseIdProvider; + + private final List configurationCustomizers; + + private final ApplicationContext applicationContext; + + @PostConstruct + public void checkConfigFileExists() { + if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) { + Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation()); + Assert.state(resource.exists(), "Cannot find config location: " + resource + + " (please add config file or check your Mybatis configuration)"); + } + } + + @Bean + @ConditionalOnMissingBean + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { + MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean(); + factory.setDataSource(dataSource); + factory.setVfs(SpringBootVFS.class); + if (StringUtils.hasText(this.properties.getConfigLocation())) { + factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation())); + } + applyConfiguration(factory); + if (this.properties.getConfigurationProperties() != null) { + factory.setConfigurationProperties(this.properties.getConfigurationProperties()); + } + if (!ObjectUtils.isEmpty(this.interceptors)) { + factory.setPlugins(this.interceptors); + } + if (this.databaseIdProvider != null) { + factory.setDatabaseIdProvider(this.databaseIdProvider); + } + if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { + factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); + } + // TODO 自定义枚举包 + if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) { + factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage()); + } + if (this.properties.getTypeAliasesSuperType() != null) { + factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType()); + } + if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) { + factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); + } + if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { + factory.setMapperLocations(this.properties.resolveMapperLocations()); + } + // TODO 此处必为非 NULL + GlobalConfig globalConfig = this.properties.getGlobalConfig(); + // 注入填充器 + if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class, false, false).length > 0) { + MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class); + globalConfig.setMetaObjectHandler(metaObjectHandler); + } + // 注入主键生成器 + if (this.applicationContext.getBeanNamesForType(IKeyGenerator.class, false, false).length > 0) { + IKeyGenerator keyGenerator = this.applicationContext.getBean(IKeyGenerator.class); + globalConfig.getDbConfig().setKeyGenerator(keyGenerator); + } + // 注入sql注入器 + if (this.applicationContext.getBeanNamesForType(ISqlInjector.class, false, false).length > 0) { + ISqlInjector iSqlInjector = this.applicationContext.getBean(ISqlInjector.class); + globalConfig.setSqlInjector(iSqlInjector); + } + factory.setGlobalConfig(globalConfig); + return factory.getObject(); + } + + private void applyConfiguration(MybatisSqlSessionFactoryBean factory) { + MybatisConfiguration configuration = this.properties.getConfiguration(); + if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) { + configuration = new MybatisConfiguration(); + } + if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) { + for (ConfigurationCustomizer customizer : this.configurationCustomizers) { + customizer.customize(configuration); + } + } + factory.setConfiguration(configuration); + } + + @Bean + @ConditionalOnMissingBean + public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { + ExecutorType executorType = this.properties.getExecutorType(); + if (executorType != null) { + return new SqlSessionTemplate(sqlSessionFactory, executorType); + } else { + return new SqlSessionTemplate(sqlSessionFactory); + } + } + + /** + * This will just scan the same base package as Spring Boot does. If you want + * more power, you can explicitly use + * {@link org.mybatis.spring.annotation.MapperScan} but this will get typed + * mappers working correctly, out-of-the-box, similar to using Spring Data JPA + * repositories. + */ + public static class AutoConfiguredMapperScannerRegistrar + implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware { + + private BeanFactory beanFactory; + + private ResourceLoader resourceLoader; + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, + BeanDefinitionRegistry registry) { + + logger.debug("Searching for mappers annotated with @Mapper"); + + ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); + + try { + if (this.resourceLoader != null) { + scanner.setResourceLoader(this.resourceLoader); + } + + List packages = AutoConfigurationPackages.get(this.beanFactory); + if (logger.isDebugEnabled()) { + packages.forEach(pkg -> logger.debug("Using auto-configuration base package '{}'", pkg)); + } + + scanner.setAnnotationClass(Mapper.class); + scanner.registerFilters(); + scanner.doScan(StringUtils.toStringArray(packages)); + } catch (IllegalStateException ex) { + logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex); + } + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + } + + /** + * {@link org.mybatis.spring.annotation.MapperScan} ultimately ends up creating + * instances of {@link MapperFactoryBean}. If + * {@link org.mybatis.spring.annotation.MapperScan} is used then this + * auto-configuration is not needed. If it is _not_ used, however, then this + * will bring in a bean registrar and automatically register components based on + * the same component-scanning path as Spring Boot itself. + */ + @Configuration + @Import({ AutoConfiguredMapperScannerRegistrar.class }) + @ConditionalOnMissingBean(MapperFactoryBean.class) + public static class MapperScannerRegistrarNotFoundConfiguration { + + @PostConstruct + public void afterPropertiesSet() { + logger.debug("No {} found.", MapperFactoryBean.class.getName()); + } + } + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusPluginsConfig.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusPluginsConfig.java new file mode 100644 index 0000000..cc9739c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/MybatisPlusPluginsConfig.java @@ -0,0 +1,36 @@ +package com.example.config; + +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; +import com.baomidou.mybatisplus.core.injector.ISqlInjector; +import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * mybatis-plus 插件配置 + */ +@Configuration +public class MybatisPlusPluginsConfig { + + private static final Log logger = Log.get(); + + /** + * 分页插件 + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + + @Bean + public ISqlInjector sqlInjector() { + return new LogicSqlInjector(); + } + + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/WebSocketConfig.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/WebSocketConfig.java new file mode 100644 index 0000000..906021c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/WebSocketConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author ZhangHouYing + * 2019-08-24 15:44 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskExecutePool.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskExecutePool.java new file mode 100644 index 0000000..44abd3d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskExecutePool.java @@ -0,0 +1,62 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config.thread; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 异步任务线程池装配类 + * @author https://juejin.im/entry/5abb8f6951882555677e9da2 + * 2019年10月31日15:06:18 + */ +@Slf4j +@Configuration +public class AsyncTaskExecutePool implements AsyncConfigurer { + + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程池大小 + executor.setCorePoolSize(AsyncTaskProperties.corePoolSize); + //最大线程数 + executor.setMaxPoolSize(AsyncTaskProperties.maxPoolSize); + //队列容量 + executor.setQueueCapacity(AsyncTaskProperties.queueCapacity); + //活跃时间 + executor.setKeepAliveSeconds(AsyncTaskProperties.keepAliveSeconds); + //线程名字前缀 + executor.setThreadNamePrefix("el-async-"); + // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 + // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } + + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return (throwable, method, objects) -> { + log.error("===="+throwable.getMessage()+"====", throwable); + log.error("exception method:"+method.getName()); + }; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskProperties.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskProperties.java new file mode 100644 index 0000000..012a127 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/AsyncTaskProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config.thread; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * 线程池配置属性类 + * @author https://juejin.im/entry/5abb8f6951882555677e9da2 + * 2019年10月31日14:58:18 + */ +@Data +@Component +public class AsyncTaskProperties { + + public static int corePoolSize; + + public static int maxPoolSize; + + public static int keepAliveSeconds; + + public static int queueCapacity; + + @Value("${task.pool.core-pool-size}") + public void setCorePoolSize(int corePoolSize) { + AsyncTaskProperties.corePoolSize = corePoolSize; + } + + @Value("${task.pool.max-pool-size}") + public void setMaxPoolSize(int maxPoolSize) { + AsyncTaskProperties.maxPoolSize = maxPoolSize; + } + + @Value("${task.pool.keep-alive-seconds}") + public void setKeepAliveSeconds(int keepAliveSeconds) { + AsyncTaskProperties.keepAliveSeconds = keepAliveSeconds; + } + + @Value("${task.pool.queue-capacity}") + public void setQueueCapacity(int queueCapacity) { + AsyncTaskProperties.queueCapacity = queueCapacity; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/TheadFactoryName.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/TheadFactoryName.java new file mode 100644 index 0000000..b06a723 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/TheadFactoryName.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config.thread; + +import org.springframework.stereotype.Component; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 自定义线程名称 + * + * 2019年10月31日17:49:55 + */ +@Component +public class TheadFactoryName implements ThreadFactory { + + private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + public TheadFactoryName() { + this("el-pool"); + } + + private TheadFactoryName(String name){ + SecurityManager s = System.getSecurityManager(); + group = (s != null) ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + //此时namePrefix就是 name + 第几个用这个工厂创建线程池的 + this.namePrefix = name + + POOL_NUMBER.getAndIncrement(); + } + + @Override + public Thread newThread(Runnable r) { + //此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程 + Thread t = new Thread(group, r, + namePrefix + "-thread-"+threadNumber.getAndIncrement(), + 0); + if (t.isDaemon()) { + t.setDaemon(false); + } + if (t.getPriority() != Thread.NORM_PRIORITY) { + t.setPriority(Thread.NORM_PRIORITY); + } + return t; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/ThreadPoolExecutorUtil.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/ThreadPoolExecutorUtil.java new file mode 100644 index 0000000..db542cf --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/config/thread/ThreadPoolExecutorUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.config.thread; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 用于获取自定义线程池 + * + * 2019年10月31日18:16:47 + */ +public class ThreadPoolExecutorUtil { + + public static ThreadPoolExecutor getPoll(){ + return new ThreadPoolExecutor( + AsyncTaskProperties.corePoolSize, + AsyncTaskProperties.maxPoolSize, + AsyncTaskProperties.keepAliveSeconds, + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(AsyncTaskProperties.queueCapacity), + new TheadFactoryName() + ); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/controller/DnsController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/controller/DnsController.java new file mode 100644 index 0000000..581a46b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/controller/DnsController.java @@ -0,0 +1,48 @@ +package com.example.modules.dns.controller; + +import com.example.modules.dns.service.DnsService; +import com.example.utils.page.PageUtils; +import com.example.utils.page.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.text.DecimalFormat; +import java.util.Map; + +@RestController +@RequestMapping("/dns") +public class DnsController { + @Autowired + private DnsService dnsService; + + @GetMapping + public R queryPage(@RequestParam Map params) { + long startTime = System.currentTimeMillis(); + PageUtils page =dnsService.queryPage(params); + long endTime = System.currentTimeMillis(); + DecimalFormat df = new DecimalFormat("0.000"); + String totalTime = df.format((float) (endTime - startTime) / 1000); + page.setTotalTime(Double.parseDouble(totalTime)); + return R.ok(page); + } + + + //区域数据统计 + @GetMapping("/dataCount") + public R dataCount(@RequestParam Map params) { + return R.ok(dnsService.dataCount(params)); + } + + //区域数据统计 + @GetMapping("/mapData") + public R mapData() { + return R.ok(dnsService.mapData()); + } + + + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DnsType.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DnsType.java new file mode 100644 index 0000000..983c2ee --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DnsType.java @@ -0,0 +1,24 @@ + +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.io.Serializable; + + +@Data +@TableName("dns_type") +public class DnsType implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + + private String ip; + + private String type; + + private int epoch; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DohAttribute.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DohAttribute.java new file mode 100644 index 0000000..5a772e2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/DohAttribute.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +@TableName("doh_attribute") +public class DohAttribute implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + private String ip; + private Integer port; + private String host; + private String path; + private String method; + private Integer connectType; + private Integer statusCode; + private String repHeader; + private String repBody; + private Date timestamp; + + private String component; + + private int rounds; + + @TableField(exist = false) + private List pathList; + + @TableField(exist = false) + private List componentList; + + @TableField(exist = false) + private List ipCert; + + @TableField(exist = false) + private List ipInformation; + + @TableField(exist = false) + private List> vulnerability; + @TableField(exist = false) + private List tags; + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ForwardDns.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ForwardDns.java new file mode 100644 index 0000000..5823a34 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ForwardDns.java @@ -0,0 +1,24 @@ + +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.io.Serializable; + + +@Data +@TableName("forward_dns") +public class ForwardDns implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + + private String forwarder; + + private String upstream; + + private int epoch; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpCert.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpCert.java new file mode 100644 index 0000000..a7f88af --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpCert.java @@ -0,0 +1,51 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.example.modules.system.domain.Dept; +import com.example.modules.system.domain.Job; +import com.example.modules.system.domain.Role; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + +/** + * 2018-11-22 + */ +@Data +@TableName("ip_cert") +public class IpCert implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + + private String ip; + + private String port; + + private String certificate; + + private String ca; + + private Date timestamp; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpInformation.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpInformation.java new file mode 100644 index 0000000..1c61eb5 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/IpInformation.java @@ -0,0 +1,75 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * + * 2018-11-22 + */ +@Data +@TableName("ip_information") +public class IpInformation implements Serializable { + @TableId(type = IdType.AUTO) + private Long id; + + private String ip; + + private String country; + + private String province; + + private String city; + private String district; + private String provider; + private String isp; + private Integer asnumber; + private Date timestamp; + private String zipcode; + private String timezone; + + @TableField(exist = false) + private List ipCert; + + @TableField(exist = false) + private List nonstandardDns; + + + @TableField(exist = false) + private DnsType dnsType; + + @TableField(exist = false) + private List dohAttribute; + + @TableField(exist = false) + private List forwardDns; + + @TableField(exist = false) + private ScanResult scanResult; + + @TableField(exist = false) + private Integer dnsTypeValue; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/NonstandardDns.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/NonstandardDns.java new file mode 100644 index 0000000..11badef --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/NonstandardDns.java @@ -0,0 +1,28 @@ + +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.io.Serializable; + + +/** + * + * 直接响DNS表 + */ +@Data + @TableName("nonstandard_dns") +public class NonstandardDns implements Serializable { + @TableId(type = IdType.AUTO) + private Long id; + + private String ip; + + private String record; + + private int epoch; + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Result.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Result.java new file mode 100644 index 0000000..6047df6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Result.java @@ -0,0 +1,71 @@ +package com.example.modules.dns.domain; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +public class Result implements Serializable { + + private Long id; + private String ip; + + private String protocolType; + private String ipType; + + private Integer port; + private String host; + private String path; + private String method; + private Integer connectType; + private Integer statusCode; + private String repHeader; + private String repBody; + private Date timestamp; + private String component; + + + private Integer flags; + private Integer opcode; + private Integer qr; + //权威标志位 + private Integer aa; + //递归标志位 + private Integer ra; + private Integer rcode; + private String queryName; + private String queryResponse; + + //(预留)ipv4,ipv6,dnssec,tcp,udp等 + private Integer scanType; + + private Date time; + + private Integer epoch; + + private Integer rounds; + + + private Integer dnsType; + + private String uuid; + + private List pathList; + + private List componentList; + + private List ipCert; + + private List vulnerability; + + private List tags; + + private IpInformation ipInformation; + + private List banner; + + private List httpContent; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ScanResult.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ScanResult.java new file mode 100644 index 0000000..8d479dc --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/ScanResult.java @@ -0,0 +1,75 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 2018-11-22 + */ +@Data +@TableName("scan_result") +public class ScanResult implements Serializable { + @TableId(type = IdType.AUTO) + private Long id; + + private String ip; + + private Integer flags; + + private Integer opcode; + + private Integer qr; + //权威标志位 + private Integer aa; + //递归标志位 + private Integer ra; + + private Integer rcode; + + private String queryName; + + private String queryResponse; + + private String component; + + private int epoch; + + private List componentList; + //(预留)ipv4,ipv6,dnssec,tcp,udp等 + private Integer scanType; + + private Date time; + @TableField(exist = false) + private IpInformation IpInformation; + @TableField(exist = false) + private List forwarderBanner; + @TableField(exist = false) + private Integer dnsType; + @TableField(exist = false) + private List nonstandardBanner; + + @TableField(exist = false) + private List tags; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Vulnerability.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Vulnerability.java new file mode 100644 index 0000000..b31ba3e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/domain/Vulnerability.java @@ -0,0 +1,24 @@ +package com.example.modules.dns.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("vulnerability") +public class Vulnerability implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + + private String component; + + private String vulnerability; + + private Date timestamp; + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDo53Dao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDo53Dao.java new file mode 100644 index 0000000..0d1eee5 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDo53Dao.java @@ -0,0 +1,76 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.Result; +import com.example.modules.dns.domain.ScanResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface DnsDo53Dao extends BaseMapper { + + List queryDo53Page(IPage page, @Param("params") Map params); + + int do53IpCount(@Param("params") Map params); + + List> do53ServiceCategoryCount(@Param("params") Map params); + + List> do53ProvinceCount(@Param("params") Map params); + + List> do53ProviderCount(@Param("params") Map params); + + List> do53ComponentCount(@Param("params") Map params); + + List> do53VulnerabilityCount(@Param("params") Map params); + + List> do53CountryCount(); + + List> do53CountryMapCount(); + + + List> do53WorldMapCount(); + + List> do53ChinaMapCount(); + + int pageCount(@Param("params") Map params); + + List queryOpenRdns(@Param("params")Map params); + + int getCountByDnsType(@Param("dnsType")Integer dnsType,@Param("params") Map params); + + int getIndependentIpNum(@Param("dnsType")Integer dnsType, @Param("params")Map params); + + List selectScanResultByUnion(IPage page, @Param("params") Map params); + + Integer selectScanResultCountByUnion(@Param("params") Map params); + + List> getDohAndDo53SrvCategoryCount(@Param("params") Map params); + + /** + * 根据dnsType和其他参数统计ip省份分布 + * @param dnsType + * @param params + * @return + */ + List> getDo53ProvinceCountByDnsType(@Param("dnsType") Integer dnsType, @Param("params") Map params); + + /** + * 根据dnsType和其他参数统计ip运营商分布 + * @param dnsType + * @param params + * @return + */ + List> getDo53ProviderCountByDnsType(@Param("dnsType") Integer dnsType, @Param("params") Map params); + + List> getDo53ComponentCountByDnsType(@Param("dnsType") Integer dnsType, Map params); + + Integer getDo53SrvCategoryCountByDnsType(@Param("dnsType") Integer dnsType, @Param("params") Map params); + + List> getDo53VulnerabCountByDnsType(@Param("dnsType") Integer dnsType, @Param("params") Map params); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDohDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDohDao.java new file mode 100644 index 0000000..29018e6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsDohDao.java @@ -0,0 +1,93 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.DohAttribute; +import com.example.modules.dns.domain.IpInformation; +import com.example.modules.dns.domain.Result; +import com.example.modules.dns.domain.ScanResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface DnsDohDao extends BaseMapper { + + List queryDohPage(IPage page, @Param("params") Map params); + + //省份数据统计 + List> dohProvinceCount(@Param("params") Map params); + + int dohIpCount(@Param("params") Map params); + + List> dohPortCount(@Param("params") Map params); + + List> dohAndDo53ProvinceCount(@Param("params") Map params); + + List> dohProviderCount(@Param("params") Map params); + + List> dohAndDo53ProviderCount(@Param("params") Map params); + + List> dohComponentCount(@Param("params") Map params); + + List> dohAndDo53ComponentCount(@Param("params") Map params); + + Map dohServiceCategoryCount(@Param("params") Map params); + + int dohResultTotalCount(@Param("params") Map params); + + List> dohVulnerabilityCount(@Param("params") Map params); + + List> dohAndDo53VulnerabilityCount(@Param("params") Map params); + + List> dohCountryCount(); + + List> dohChinaMapCount(); + + List getDohRepBody(String ip, Integer port, String host, Integer rounds); + + List selectDohInfoByUnion(@Param("params") Map params); + + Integer selectDohCountByUnion(@Param("params") Map params); + + /** + * 查询 doh 和 do53 交集下的port ip数量 + * @param params + * @return + */ + List> countDohPortUnion(@Param("params") Map params); + + /** + * 统计 doh和do53公共ip的省份分布 + * @param params + * @return + */ + List> getDohAndDo53ProvinceCount(@Param("params") Map params); + + /** + * 统计 doh和do53公共ip的运营商分布 + * @param params + * @return + */ + List> getDohAndDo53ProviderCount(@Param("params") Map params); + + /** + * 统计 doh和do53公共ip的组件分布 + * @param params + * @return + */ + List> getDohAndDo53ComponentCount(@Param("params") Map params); + + /** + * 统计 doh 和 do53公共ip 服务类别统计 + * @param params + * @return + */ + Map getDohServiceCategoryCount(@Param("params") Map params); + + List> getDohAndDo53VulnerabilityCount(@Param("params") Map params); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsTypeDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsTypeDao.java new file mode 100644 index 0000000..e5193e6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/DnsTypeDao.java @@ -0,0 +1,20 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.DnsType; +import com.example.modules.dns.domain.DohAttribute; +import com.example.modules.dns.domain.IpCert; +import com.example.modules.dns.domain.ScanResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface DnsTypeDao extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/ForwardDnsDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/ForwardDnsDao.java new file mode 100644 index 0000000..2986981 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/ForwardDnsDao.java @@ -0,0 +1,20 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.ForwardDns; +import com.example.modules.dns.domain.ScanResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface ForwardDnsDao extends BaseMapper { + + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpCertDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpCertDao.java new file mode 100644 index 0000000..01939f6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpCertDao.java @@ -0,0 +1,32 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.DohAttribute; +import com.example.modules.dns.domain.IpCert; +import com.example.modules.dns.domain.ScanResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface IpCertDao extends BaseMapper { + + List queryDohPage(IPage page, @Param("params") Map params); + + // 国家数据统计 + List> countryCount(); + + //省份数据统计 + List> provinceCount(); + + // 城市数据统计 + List> cityCount(); + + + List queryDo53Page(IPage page, @Param("params") Map params); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpInformationDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpInformationDao.java new file mode 100644 index 0000000..2ed80e3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/IpInformationDao.java @@ -0,0 +1,27 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.IpInformation; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface IpInformationDao extends BaseMapper { + + + List queryIpPage(IPage page, @Param("params") Map params); + + /** + * 根据 forward_dns中的 forwarder查询ip信息 + * @param ip + * @return + */ + List getIpInfoByFwd(@Param("ip")String ip,@Param("epoch")Integer epoch); + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/NonstandardDnsDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/NonstandardDnsDao.java new file mode 100644 index 0000000..7c050ef --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/NonstandardDnsDao.java @@ -0,0 +1,15 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.example.modules.dns.domain.ForwardDns; +import com.example.modules.dns.domain.NonstandardDns; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface NonstandardDnsDao extends BaseMapper { + + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/VulnerabilityDao.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/VulnerabilityDao.java new file mode 100644 index 0000000..5d1c06f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/mapper/VulnerabilityDao.java @@ -0,0 +1,20 @@ +package com.example.modules.dns.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.example.modules.dns.domain.DohAttribute; +import com.example.modules.dns.domain.ScanResult; +import com.example.modules.dns.domain.Vulnerability; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Mapper +@Repository +public interface VulnerabilityDao extends BaseMapper { + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsService.java new file mode 100644 index 0000000..3aad1ca --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsService.java @@ -0,0 +1,19 @@ +package com.example.modules.dns.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.example.modules.dns.domain.DohAttribute; +import com.example.modules.dns.domain.IpInformation; +import com.example.utils.page.PageUtils; + +import java.util.List; +import java.util.Map; + +public interface DnsService extends IService { + + + PageUtils queryPage(Map params); + + Map dataCount(Map params); + + Map>> mapData(); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsTypeService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsTypeService.java new file mode 100644 index 0000000..f9cb1c6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/DnsTypeService.java @@ -0,0 +1,13 @@ +package com.example.modules.dns.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.example.modules.dns.domain.DnsType; +import com.example.modules.dns.domain.DohAttribute; +import com.example.utils.page.PageUtils; + +import java.util.List; +import java.util.Map; + +public interface DnsTypeService extends IService { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/ScanResultService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/ScanResultService.java new file mode 100644 index 0000000..3dcd9dd --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/ScanResultService.java @@ -0,0 +1,13 @@ +package com.example.modules.dns.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.example.modules.dns.domain.ScanResult; + +import java.util.Map; + +public interface ScanResultService extends IService { + + + Map queryDo53DataCountByDnsType(Map params,Integer dnsType); + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsQueryEnum.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsQueryEnum.java new file mode 100644 index 0000000..089a514 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsQueryEnum.java @@ -0,0 +1,108 @@ +package com.example.modules.dns.service.impl; + +import com.example.utils.Constant; +import com.example.utils.ElAdminConstant; + +import java.util.List; + +/** + * @author Lihe + * @version 1 + * @description 查询分类 + * @date 2022/6/22 + */ +public enum DnsQueryEnum { + + OPEN_RDNS(Constant.OPENRDNSTAG, ElAdminConstant.openRdnsLabels, "openRdns", 1), + + FORWARDER(Constant.FORWARDERTAG, ElAdminConstant.forwarderLabels, "forwarder", 2), + + FWD_RDNS(Constant.FWDRDNSTAG, ElAdminConstant.fwdRdnsLabels, "fwdRdns", 3), + + EGRESS_DNS(Constant.EGRESSRDNSTAG, ElAdminConstant.egressDnsLabels, "egressDns", 4), + + NON_STANDARD(Constant.NONSTANDARDTAG, ElAdminConstant.nonstandardLabels, "nonstandard", 5), + + DNS(Constant.DNSTAG, ElAdminConstant.dnsLabels, "queryDnsInfo", 0), + + DOH(Constant.DOH, ElAdminConstant.dohLabels, "queryDohInfo", 0), + + DO53(Constant.DO53, ElAdminConstant.do53Labels, "queryDo53Info", 0), + + DOH_AND_DO53("dohAndDo53", null, "queryDohAndDo53Info", 0), + + IP(Constant.IP, null, "queryPageByIp", 0), + ; + + private final String service; + + private final List labels; + + private final String methodName; + + private final Integer dnsType; + + public static DnsQueryEnum getQueryInfo(String serviceName) { + for (DnsQueryEnum value : DnsQueryEnum.values()) { + if (value.getService().equals(serviceName)) { + return value; + } + } + return null; + } + + + public String getMethodName() { + return methodName; + } + + public String getService() { + return service; + } + + public List getLabels() { + return labels; + } + + public Integer getDnsType() { + return dnsType; + } + + DnsQueryEnum(String service, List labels, String methodName, Integer dnsType) { + this.service = service; + this.labels = labels; + this.methodName = methodName; + this.dnsType = dnsType; + } + + public static List getLabels(String key) { + for (DnsQueryEnum value : DnsQueryEnum.values()) { + if (value.getService().equals(key)) { + return value.getLabels(); + } + } + return null; + } + + public static Integer getDnsType(String key) { + for (DnsQueryEnum value : DnsQueryEnum.values()) { + if (value.getService().equals(key)) { + return value.getDnsType(); + } + } + return null; + } + + public static String getDnsType(Integer type) { + for (DnsQueryEnum value : DnsQueryEnum.values()) { + if (value.getDnsType().equals(type)) { + return value.getService(); + } + } + return null; + } + +} + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsServiceImpl.java new file mode 100644 index 0000000..09cab1a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsServiceImpl.java @@ -0,0 +1,631 @@ +package com.example.modules.dns.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.example.modules.dns.domain.*; +import com.example.modules.dns.mapper.*; +import com.example.modules.dns.service.DnsService; +import com.example.modules.dns.service.ScanResultService; +import com.example.utils.Constant; +import com.example.utils.page.PageUtils; +import com.example.utils.page.Query; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class DnsServiceImpl extends ServiceImpl implements DnsService { + @Autowired + private DnsDohDao dnsDohDao; + + @Autowired + private DnsDo53Dao dnsDo53Dao; + + @Autowired + private IpCertDao ipCertDao; + + @Autowired + private IpInformationDao ipInformationDao; + + @Autowired + private NonstandardDnsDao nonstandardDnsDao; + + @Autowired + private ScanResultService scanResultService; + + + /** + * 添加新service查询逻辑时: + * 1. 在本类中实现该service的查询逻辑 + * 2. DnsQueryEnum 添加该查询逻辑的枚举,包括serviceName,方法名,标签和dnsType可根据需要设置 + * and 查询逻辑需要单独实现 + * @param params + * @return + */ + @Override + public PageUtils queryPage(Map params) { + String service = (String) params.get(Constant.SERVICE); + String port = (String) params.get(Constant.PORT); + String ip = (String) params.get(Constant.IP); + IPage page = new Query(IpInformation.class).getPage(params); + params.put("n", (page.getCurrent() - 1) * page.getSize()); //用作doh查询的分页 + params.put("m", page.getSize()); //用作doh查询的分页 + if(StringUtils.isBlank(service) && StringUtils.isBlank(ip) && StringUtils.isBlank(port)){ + return new PageUtils(page); + } + if(StringUtils.isNotBlank(port)){ + if(Constant.PORT53.equals(port)){ + service = Constant.DO53; + }else if(Constant.PORT443.equals(port) || Constant.PORT8443.equals(port)){ + service = Constant.DOH; + } + } + if(StringUtils.isBlank(port) && StringUtils.isBlank(service) && StringUtils.isNotBlank(ip)){ + service = Constant.IP; + } + if(StringUtils.isNotBlank(service)) { + if(service.toLowerCase().contains("and")){ + return queryDohAndDo53Info(page,params); + }else { + // DnsQueryEnum 枚举类获取service对应的方法名,并通过反射调用 + DnsQueryEnum serviceEnum = DnsQueryEnum.getQueryInfo(service.toLowerCase()); + Class aClass = this.getClass(); + try { + Method method = aClass.getDeclaredMethod(serviceEnum.getMethodName(), IPage.class, Map.class); + return (PageUtils) method.invoke(this, page, params); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return new PageUtils(page); + } + + @Override + public Map dataCount(Map params) { + String service = (String) params.get(Constant.SERVICE); + String port = (String) params.get(Constant.PORT); + String ip = (String) params.get(Constant.IP); + Map resultMap = new HashMap(8); + if(StringUtils.isBlank(service) && StringUtils.isBlank(ip) && StringUtils.isBlank(port)){ + return resultMap; + } + List> portList = new ArrayList<>(); + List> regionList ; + List> providerList ; + List> componentList ; + List> serviceCategoryList = new ArrayList<>(); + List> do53serviceCategoryList ; + List> vulnerabilityCountList ; + if (Constant.DOH.equals(service) || Constant.PORT8443.equals(port) || Constant.PORT443.equals(port)) { + //端口 + portList = dnsDohDao.dohPortCount(params); + //地域 + regionList = dnsDohDao.dohProvinceCount(params); + //运营商 + providerList = dnsDohDao.dohProviderCount(params); + //服务组件 + componentList = dnsDohDao.dohComponentCount(params); + //服务类别 + Map map = dnsDohDao.dohServiceCategoryCount(params); + map.put("key", Constant.DOHTAG); + serviceCategoryList.add(map); + //漏洞威胁 + vulnerabilityCountList = dnsDohDao.dohVulnerabilityCount(params); + + } else if (Constant.DO53.equals(service) || Constant.PORT53.equals(port)) { + //端口 + Map portMap = new HashMap<>(); + int do53PortCount = dnsDo53Dao.do53IpCount(params); + portMap.put("port", Constant.PORT53); + portMap.put("count", do53PortCount); + portList.add(portMap); + //地域 + regionList = dnsDo53Dao.do53ProvinceCount(params); + //运营商 + providerList = dnsDo53Dao.do53ProviderCount(params); + //服务组件 + componentList = dnsDo53Dao.do53ComponentCount(params); + //服务类别 + do53serviceCategoryList = dnsDo53Dao.do53ServiceCategoryCount(params); + serviceCategoryList = transformDo53serviceCategory(do53serviceCategoryList); + //漏洞威胁 + vulnerabilityCountList = dnsDo53Dao.do53VulnerabilityCount(params); + + }else if ("dns".equalsIgnoreCase(service) || StringUtils.isNotBlank(ip)) { + //端口 + portList = dnsDohDao.dohPortCount(params); + Map portMap = new HashMap<>(); + Integer do53PortCount = dnsDo53Dao.do53IpCount(params); + portMap.put("port", Constant.PORT53); + portMap.put("count", do53PortCount); + portList.add(portMap); + //地域 + regionList = dnsDohDao.dohAndDo53ProvinceCount(params); + //运营商 + providerList = dnsDohDao.dohAndDo53ProviderCount(params); + //服务组件 + componentList = dnsDohDao.dohAndDo53ComponentCount(params); + //服务类别 + do53serviceCategoryList = dnsDo53Dao.do53ServiceCategoryCount(params); + serviceCategoryList = transformDo53serviceCategory(do53serviceCategoryList); + Map map = dnsDohDao.dohServiceCategoryCount(params); + map.put("key", Constant.DOHTAG); + serviceCategoryList.add(map); + //漏洞威胁 + vulnerabilityCountList = dnsDohDao.dohAndDo53VulnerabilityCount(params); + }else if(service.toLowerCase().contains("and")){ + // 目前只有 doh AND do53其余条件未实现 + //端口 + portList = dnsDohDao.countDohPortUnion(params); + + //地域 + regionList = dnsDohDao.getDohAndDo53ProvinceCount(params); + //运营商 + providerList = dnsDohDao.getDohAndDo53ProviderCount(params); + //服务组件 + componentList = dnsDohDao.getDohAndDo53ComponentCount(params); + //服务类别 + do53serviceCategoryList = dnsDo53Dao.getDohAndDo53SrvCategoryCount(params); + serviceCategoryList = transformDo53serviceCategory(do53serviceCategoryList); + Map map = dnsDohDao.getDohServiceCategoryCount(params); + map.put("key", Constant.DOHTAG); + map.put("count", dnsDo53Dao.selectScanResultCountByUnion(params)); + serviceCategoryList.add(map); + //漏洞威胁 + vulnerabilityCountList = dnsDohDao.getDohAndDo53VulnerabilityCount(params); + }else{ + // dn53下5种 dns_type 统计 + return scanResultService.queryDo53DataCountByDnsType(params,DnsQueryEnum.getDnsType(service)); + } + resultMap.put("portList", portList); + resultMap.put("regionList", regionList); + resultMap.put("providerList", providerList); + resultMap.put("componentList", componentList); + resultMap.put("serviceCategoryList", serviceCategoryList); + resultMap.put("vulnerabilityCountList", vulnerabilityCountList); + return resultMap; + } + + @Override + public Map>> mapData() { + Map>> resultMap = new HashMap<>(); + List> dohChinaMapList ; + List> dohWorldMapDataList ; + List> do53CountryMapCountList ; + List> do53OpenRdnsList = new ArrayList<>(); + List> do53ForwarderList = new ArrayList<>(); + List> do53FwdRdnsList = new ArrayList<>(); + List> do53EgressDnsList = new ArrayList<>(); + List> do53NonstandardList = new ArrayList<>(); + List> do53WorldMapList ; + List> do53ChinaMapList ; + dohChinaMapList = dnsDohDao.dohChinaMapCount(); + dohWorldMapDataList = dnsDohDao.dohCountryCount(); + do53WorldMapList = dnsDo53Dao.do53WorldMapCount(); + do53ChinaMapList = dnsDo53Dao.do53ChinaMapCount(); + do53CountryMapCountList = dnsDo53Dao.do53CountryMapCount(); + for (Map map : do53CountryMapCountList) { + if (Constant.OPENRDNS == map.get("type")) { + do53OpenRdnsList.add(map); + } else if (Constant.FORWARDER == map.get("type")) { + do53ForwarderList.add(map); + } else if (Constant.FWDRDNS == map.get("type")) { + do53FwdRdnsList.add(map); + } else if (Constant.EGRESSRDNS == map.get("type")) { + do53EgressDnsList.add(map); + } else if (Constant.NONSTANDARD == map.get("type")) { + do53NonstandardList.add(map); + } + } + resultMap.put("dohChinaMapList", dohChinaMapList); + resultMap.put("dohWorldMapDataList", dohWorldMapDataList); + resultMap.put("do53WorldMapDataList", do53WorldMapList); + resultMap.put("do53ChinaMapList", do53ChinaMapList); + resultMap.put("do53OpenRdnsList", do53OpenRdnsList); + resultMap.put("do53ForwarderList", do53ForwarderList); + resultMap.put("do53FwdRdnsList", do53FwdRdnsList); + resultMap.put("do53EgressDnsList", do53EgressDnsList); + resultMap.put("do53NonstandardList", do53NonstandardList); + return resultMap; + } + + public List> transformDo53serviceCategory(List> do53serviceCategoryList) { + List> serviceCategoryList = new ArrayList<>(); + long do53Count = 0; + for (Map map : do53serviceCategoryList) { + Map do53ServiceMap = new HashMap<>(); + long count = (long) map.get("count"); + int dnsType = (int) map.get("type"); + if (Constant.FORWARDER == dnsType) { //2 + do53ServiceMap.put("key", Constant.FORWARDERTAG); + do53ServiceMap.put("count", count); + } else if (Constant.FWDRDNS == dnsType) {//3 + do53ServiceMap.put("key", Constant.FWDRDNSTAG); + do53ServiceMap.put("count", count); + } else if (Constant.EGRESSRDNS == dnsType) { //4 + do53ServiceMap.put("key", Constant.EGRESSRDNSTAG); + do53ServiceMap.put("count", count); + } else if (Constant.NONSTANDARD == dnsType) { //5 + do53ServiceMap.put("key", Constant.NONSTANDARDTAG); + do53ServiceMap.put("count", count); + } else if (Constant.OPENRDNS == dnsType) { //1 + do53ServiceMap.put("key", Constant.OPENRDNSTAG); + do53ServiceMap.put("count", count); + } + do53Count += count; + serviceCategoryList.add(do53ServiceMap); + } + HashMap do53Map = new HashMap<>(); + do53Map.put("key", Constant.DO53TAG); + do53Map.put("count", do53Count); + serviceCategoryList.add(do53Map); + return serviceCategoryList; + + } + + /** + * 设置doh属性 + * @param dohAttributes + */ + public void setDohData(List dohAttributes) { + for (Result dohAttribute : dohAttributes) { + String uuid = UUID.randomUUID().toString().trim().replaceAll("-", ""); + dohAttribute.setUuid(uuid); + String dohIp = dohAttribute.getIp(); + Integer port = dohAttribute.getPort(); + String component = dohAttribute.getComponent(); + String path = dohAttribute.getPath(); + dohAttribute.setProtocolType(Constant.PROTOC_TCP); + dohAttribute.setIpType(getIpType(dohIp)); + if (component != null) + dohAttribute.setComponentList(new ArrayList<>(Arrays.stream(component.split(",")).collect(Collectors.toSet()))); + if (path != null) + dohAttribute.setPathList(new ArrayList<>(Arrays.stream(path.split(",")).collect(Collectors.toSet()))); + ArrayList tagList = new ArrayList<>(); //添加服务类别标签 + tagList.add(Constant.DOHTAG); + List banner = new ArrayList<>(); + List httpHeader = new ArrayList<>(); + // 根据ip,port,host,rounds查询doh_attribute rep_body repHeader信息 + List repList = this.baseMapper.getDohRepBody(dohIp, port, dohAttribute.getHost(), dohAttribute.getRounds()); + for (int i = 0; i < repList.size(); i++) { + Result result = repList.get(i); + if (StringUtils.isNotBlank(result.getRepBody())) { + banner.add(result.getRepBody()); + } + if (StringUtils.isNotBlank(result.getRepHeader())) { + httpHeader.add(result.getRepHeader()); + } + } + dohAttribute.setBanner(banner); + dohAttribute.setHttpContent(httpHeader); + //根据ip和端口查询证书库,获取证书数据 + List ipCertList = ipCertDao.selectList(new LambdaQueryWrapper().eq(IpCert::getIp, dohIp).eq(IpCert::getPort, port)); + dohAttribute.setIpCert(ipCertList); + dohAttribute.setTags(tagList); + } + } + + /** + * 设置do53标签,根据dnsType设置banner + * type = 1 banner list.get(0)为rep + * type = 2,3 banner中的 list.get(0)为 query_rep,列表其余数据为ip信息 + * type = 5 banner list.get(0)为rep,其余为NonstandardDns列表 + * @param scanResultList + */ + public void setdo53Data(List scanResultList) { + for (Result scanResult : scanResultList) { + String uuid = UUID.randomUUID().toString().trim().replaceAll("-", ""); + scanResult.setUuid(uuid); + String do53Ip = scanResult.getIp(); + Integer epoch = scanResult.getEpoch(); + Integer dnsType = scanResult.getDnsType(); + ArrayList tagList = new ArrayList<>(); //添加服务类别标签 + tagList.add(Constant.DO53TAG); + scanResult.setIpType(getIpType(do53Ip)); + scanResult.setProtocolType(getProtocolType(scanResult.getScanType())); + List bannerList = new ArrayList<>(); + if (Constant.FORWARDER.equals(dnsType) || Constant.FWDRDNS.equals(dnsType)) { //2、3 + if (Constant.FWDRDNS.equals(dnsType)) { //3 + tagList.add(Constant.FORWARDERTAG); + } else { + tagList.add(Constant.FWDRDNSTAG); + } + bannerList.add(scanResult.getQueryResponse()); + List forwardDnsList = ipInformationDao.getIpInfoByFwd(do53Ip, epoch); + bannerList.addAll(forwardDnsList); + } else if (Constant.EGRESSRDNS.equals(dnsType)) { //4 + tagList.add(Constant.EGRESSRDNSTAG); + + } else if (Constant.NONSTANDARD.equals(dnsType)) { //5 + bannerList.add(scanResult.getQueryResponse()); + tagList.add(Constant.NONSTANDARDTAG); + List nonstandardDnsList = nonstandardDnsDao.selectList(new LambdaQueryWrapper().eq(NonstandardDns::getIp, do53Ip).eq(NonstandardDns::getEpoch, epoch)); + bannerList.addAll((List) JSONObject.toJSON(nonstandardDnsList)); + } else if (Constant.OPENRDNS.equals(dnsType)) { //1 + tagList.add(Constant.OPENRDNSTAG); + if(StringUtils.isNotBlank(scanResult.getQueryResponse())){ + bannerList.add(scanResult.getQueryResponse()); + } + } + scanResult.setBanner(bannerList); + scanResult.setTags(tagList); + } + } + + /** + * @param dataList 目标list + * @param pageSize 当前页大小 + * @param currentPage 当前页 + * @return 返回当前页的数据集 + * @deprecated 对list进行分页 + */ + public List getPage(List dataList, int pageSize, int currentPage) { + List currentPageList = new ArrayList<>(); + if (!dataList.isEmpty()) { + int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0); + for (int i = 0; i < pageSize && i < dataList.size() - currIdx; i++) { + Result data = dataList.get(currIdx + i); + currentPageList.add(data); + } + } + return currentPageList; + } + + + /** + * 查询dns信息,dnh和do53(scan_result)结果并集 + * + * @param page + * @param params + * @return + */ + private PageUtils queryDnsInfo(IPage page, Map params) { + Map indepentIpMap = new HashMap<>(4); + int resultTotal = 0; + long pageSize = page.getSize(); + params.put("n", 0); //用作doh查询的分页偏移量 + params.put("m", page.getCurrent() * page.getSize()); //用作查询的分页大小 + // 查询doh信息 + //同一轮次,相同ip合并path和component,漏洞信息 + List dohAttributes = dnsDohDao.queryDohPage(null, params); + setDohData(dohAttributes); + int dohResultTotal = dnsDohDao.dohResultTotalCount(params); + indepentIpMap.put("dns-doh", dnsDohDao.dohIpCount(params)); + // 查询do53信息 + List scanResultList = dnsDo53Dao.queryDo53Page(null, params); + setdo53Data(scanResultList); + indepentIpMap.put("dns-do53", dnsDo53Dao.do53IpCount(params)); + int do53ResultTotal = dnsDo53Dao.pageCount(params); + + List resultList = new ArrayList<>(); + resultList.addAll(dohAttributes); + resultList.addAll(scanResultList); + List collect = resultList.stream().sorted(Comparator.comparing(Result::getTimestamp).reversed()).collect(Collectors.toList()); + + page.setTotal(do53ResultTotal + dohResultTotal); + page.setRecords(getPage(collect, (int) pageSize, (int) page.getCurrent())); + + return buildResult(page,indepentIpMap,(do53ResultTotal + dohResultTotal)); + } + + /** + * 查询 do53信息 + * @param page + * @param params + * @return + */ + private PageUtils queryDo53Info(IPage page, Map params){ + // 根据 service=dns-do53, port为53查询 scan_result表 参数:ip,port + List scanResultList = dnsDo53Dao.queryDo53Page(null, params); + setdo53Data(scanResultList); + + int independentIpNum = dnsDo53Dao.do53IpCount(params); + int resultTotal = dnsDo53Dao.pageCount(params); + page.setRecords(scanResultList); + return buildResult(page,independentIpNum,resultTotal); + } + + /** + * 查询doh信息 + * @param page + * @param params + * @return + */ + private PageUtils queryDohInfo(IPage page, Map params){ + // 根据 service=dns-do53, port为53查询 scan_result表 参数:ip,port + List scanResultList = dnsDohDao.queryDohPage(null, params); + setDohData(scanResultList); + + int independentIpNum = dnsDohDao.dohIpCount(params); + int resultTotal = dnsDohDao.dohResultTotalCount(params); + page.setRecords(scanResultList); + return buildResult(page,independentIpNum,resultTotal); + } + + /** + * 只根据ip查询 + * @param page + * @param params + * @return + */ + private PageUtils queryPageByIp(IPage page, Map params){ + // 只根据ip查询 + int independentIpNum = 0; + params.put("n", 0); //用作doh查询的分页 + params.put("m", page.getCurrent() * page.getSize()); //用作doh查询的分页 + long pageSize = page.getSize(); + List dohAttributesList = dnsDohDao.queryDohPage(null, params); + setDohData(dohAttributesList); + List scanResultList = dnsDo53Dao.queryDo53Page(null, params); + setdo53Data(scanResultList); + List resultList = new ArrayList<>(); + resultList.addAll(dohAttributesList); + resultList.addAll(scanResultList); + int resultTotal = resultList.size(); + List collect = resultList.stream().sorted(Comparator.comparing(Result::getTimestamp).reversed()).collect(Collectors.toList()); + if (!collect.isEmpty()) { + independentIpNum = 1; + } + page.setTotal(collect.size()); + page.setRecords(getPage(collect, (int) pageSize, (int) page.getCurrent())); + return buildResult(page,independentIpNum,resultTotal); + } + + /** + * 查询 dnh和do53(scan_result)结果交集 service = dns-doh AND dns-do53 + * + * @param page + * @param params + * @return + */ + private PageUtils queryDohAndDo53Info(IPage page, Map params) { + params.put("offset", 0); //用作doh查询的分页偏移量 + params.put("limit", page.getCurrent() * page.getSize()); //用作查询的分页大小 + Map indepentIpMap = new HashMap<>(4); + + // 查询doh信息 + List dohAttributes = dnsDohDao.selectDohInfoByUnion(params); + Integer dohCount = dnsDohDao.selectDohCountByUnion(params); + setDohData(dohAttributes); + // 查询do53(scan_result)信息 + List do53Infos = dnsDo53Dao.selectScanResultByUnion(null,params); + Integer do53Count = dnsDo53Dao.selectScanResultCountByUnion(params); + setdo53Data(do53Infos); + do53Infos.addAll(dohAttributes); + + page.setTotal(dohCount + do53Count); + page.setRecords(getPage(do53Infos, (int) page.getSize(), (int) page.getCurrent())); + indepentIpMap.put("dns-doh",do53Count); + indepentIpMap.put("dns-do53",do53Count); + + return buildResult(page,indepentIpMap,(dohCount + do53Count)); + + } + + private String getIpType(String ip){ + if(ip.contains(Constant.POINT)){ + return Constant.IP_IPV4; + } + return Constant.IP_IPV6; + } + + private String getProtocolType(Integer scanType){ + // dnsType 为2为udp,1或者空为tcp + if(scanType == null || scanType < 2){ + return Constant.PROTOC_TCP; + } + return Constant.PROTOC_UDP; + } + + private PageUtils buildResult(IPage page,Object independentIpNum,Integer resultTotal ){ + PageUtils pageUtils = new PageUtils(page); + // 添加独立IP个数 + pageUtils.setIndependentIpNum(independentIpNum); + pageUtils.setResultTotal(resultTotal); + return pageUtils; + } + + + private PageUtils openRdns(IPage page, Map params) { + List results = dnsDo53Dao.queryOpenRdns(params); + int totalCount = dnsDo53Dao.getCountByDnsType(Constant.OPENRDNS, params); + setDo53Label(results, Constant.OPENRDNSTAG); + page.setRecords(results); + // 添加独立IP个数 + Integer independentIpNum = dnsDo53Dao.getIndependentIpNum(Constant.OPENRDNS, params); + + return buildResult(page,independentIpNum,totalCount); + } + + private PageUtils forwarder(IPage page, Map params) { + int totalCount = dnsDo53Dao.getCountByDnsType(Constant.FORWARDER, params); + List results = dnsDo53Dao.queryOpenRdns(params); + for (Result result : results) { + List ipInfos = ipInformationDao.getIpInfoByFwd(result.getIp(),null); + result.setBanner(ipInfos); + result.setProtocolType(getProtocolType(result.getScanType())); + result.setIpType(getIpType(result.getIp())); + addLabels(result, Constant.FORWARDERTAG); + } + + page.setRecords(results); + // 添加独立IP个数 + Integer independentIpNum = dnsDo53Dao.getIndependentIpNum(Constant.FORWARDER, params); + + return buildResult(page,independentIpNum,totalCount); + } + + private PageUtils fwdRdns(IPage page, Map params) { + int totalCount = dnsDo53Dao.getCountByDnsType(Constant.FWDRDNS, params); + List results = dnsDo53Dao.queryOpenRdns(params); + for (Result result : results) { + List ipInfos = ipInformationDao.getIpInfoByFwd(result.getIp(),null); + result.setBanner(ipInfos); + result.setProtocolType(getProtocolType(result.getScanType())); + result.setIpType(getIpType(result.getIp())); + addLabels(result, Constant.FWDRDNSTAG); + } + page.setRecords(results); + // 添加独立IP个数 + Integer independentIpNum = dnsDo53Dao.getIndependentIpNum(Constant.FWDRDNS, params); + + return buildResult(page,independentIpNum,totalCount); + } + + private PageUtils egressDns(IPage page, Map params) { + int totalCount = dnsDo53Dao.getCountByDnsType(Constant.EGRESSRDNS, params); + List results = dnsDo53Dao.queryOpenRdns(params); + setDo53Label(results, Constant.EGRESSRDNSTAG); + page.setRecords(results); + // 添加独立IP个数 + Integer independentIpNum = dnsDo53Dao.getIndependentIpNum(Constant.EGRESSRDNS, params); + + return buildResult(page,independentIpNum,totalCount); + } + + private PageUtils nonstandard(IPage page, Map params) { + int totalCount = dnsDo53Dao.getCountByDnsType(Constant.NONSTANDARD, params); + List results = dnsDo53Dao.queryOpenRdns(params); + for (Result result : results) { + List ipInfos = ipInformationDao.getIpInfoByFwd(result.getIp(),null); + result.setBanner(ipInfos); + result.setProtocolType(getProtocolType(result.getScanType())); + result.setIpType(getIpType(result.getIp())); + addLabels(result, Constant.NONSTANDARDTAG); + } + + page.setRecords(results); + // 添加独立IP个数 + Integer independentIpNum = dnsDo53Dao.getIndependentIpNum(Constant.NONSTANDARD, params); + + return buildResult(page,independentIpNum,totalCount); + } + + + + private void setDo53Label(List results, String serviceType) { + List labels = DnsQueryEnum.getLabels(serviceType); + for (Result result : results) { + // result.setBanner(result.getQueryResponse()); + result.setProtocolType(getProtocolType(result.getScanType())); + result.setIpType(getIpType(result.getIp())); + result.setTags(labels); + } + } + + private void addLabels(Result result, String serviceType) { + List labels = DnsQueryEnum.getLabels(serviceType); + result.setTags(labels); + } + +} + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsTypeServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsTypeServiceImpl.java new file mode 100644 index 0000000..8bd6d89 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/DnsTypeServiceImpl.java @@ -0,0 +1,15 @@ +package com.example.modules.dns.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.example.modules.dns.domain.DnsType; +import com.example.modules.dns.mapper.DnsTypeDao; +import com.example.modules.dns.service.DnsTypeService; +import org.springframework.stereotype.Service; + +@Service +public class DnsTypeServiceImpl extends ServiceImpl implements DnsTypeService { + +} + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/ScanResultServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/ScanResultServiceImpl.java new file mode 100644 index 0000000..5b832c9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/dns/service/impl/ScanResultServiceImpl.java @@ -0,0 +1,66 @@ +package com.example.modules.dns.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.example.modules.dns.domain.ScanResult; +import com.example.modules.dns.mapper.DnsDo53Dao; +import com.example.modules.dns.service.ScanResultService; +import com.example.utils.Constant; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Lihe + * @version 1 + * @description + * @date 2022/6/8 + */ +@Service +public class ScanResultServiceImpl extends ServiceImpl implements ScanResultService { + + + @Override + public Map queryDo53DataCountByDnsType(Map params, Integer dnsType) { + + Map resultMap = new HashMap(8); + List> portList = new ArrayList<>(); + + List> serviceCategoryList = new ArrayList<>(); + //端口 + Map portMap = new HashMap<>(); + int count = this.baseMapper.getCountByDnsType(dnsType,params); + portMap.put("port", Constant.PORT53); + portMap.put("count", count); + portList.add(portMap); + resultMap.put("portList", portList); + + //地域 + resultMap.put("regionList", this.baseMapper.getDo53ProvinceCountByDnsType(dnsType,params)); + + //运营商 + resultMap.put("providerList", this.baseMapper.getDo53ProviderCountByDnsType(dnsType,params)); + + //服务组件 + resultMap.put("componentList", this.baseMapper.getDo53ComponentCountByDnsType(dnsType,params)); + + //服务类别 + Integer serviceCount = this.baseMapper.getDo53SrvCategoryCountByDnsType(dnsType,params); + Map dnsTypeMap = new HashMap<>(2); + dnsTypeMap.put("key",DnsQueryEnum.getDnsType(dnsType)); + dnsTypeMap.put("count",serviceCount); + serviceCategoryList.add(dnsTypeMap); + Map do53ServiceMap = new HashMap<>(2); + do53ServiceMap.put("key",Constant.DO53TAG); + do53ServiceMap.put("count",serviceCount); + serviceCategoryList.add(do53ServiceMap); + resultMap.put("serviceCategoryList", serviceCategoryList); + + //漏洞威胁 + resultMap.put("vulnerabilityCountList", this.baseMapper.getDo53VulnerabCountByDnsType(dnsType,params)); + + return resultMap; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/ConfigBeanConfiguration.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/ConfigBeanConfiguration.java new file mode 100644 index 0000000..1c01c10 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/ConfigBeanConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config; + +import com.example.modules.security.config.bean.LoginProperties; +import com.example.modules.security.config.bean.SecurityProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @apiNote 配置文件转换Pojo类的 统一配置 类 + * @author: liaojinlong + * : 2020/6/10 19:04 + */ +@Configuration +public class ConfigBeanConfiguration { + + @Bean + @ConfigurationProperties(prefix = "login") + public LoginProperties loginProperties() { + return new LoginProperties(); + } + + @Bean + @ConfigurationProperties(prefix = "jwt") + public SecurityProperties securityProperties() { + return new SecurityProperties(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/SpringSecurityConfig.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/SpringSecurityConfig.java new file mode 100644 index 0000000..aa9fddf --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/SpringSecurityConfig.java @@ -0,0 +1,192 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config; + +import com.example.modules.security.security.JwtAccessDeniedHandler; +import com.example.modules.security.security.JwtAuthenticationEntryPoint; +import com.example.modules.security.security.TokenConfigurer; +import com.example.modules.security.security.TokenProvider; +import lombok.RequiredArgsConstructor; +import com.example.annotation.AnonymousAccess; +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.modules.security.security.*; +import com.example.modules.security.service.OnlineUserService; +import com.example.modules.security.service.UserCacheClean; +import com.example.utils.enums.RequestMethodEnum; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.core.GrantedAuthorityDefaults; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import java.util.*; + +/** + * + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final CorsFilter corsFilter; + private final JwtAuthenticationEntryPoint authenticationErrorHandler; + private final JwtAccessDeniedHandler jwtAccessDeniedHandler; + private final ApplicationContext applicationContext; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + @Bean + GrantedAuthorityDefaults grantedAuthorityDefaults() { + // 去除 ROLE_ 前缀 + return new GrantedAuthorityDefaults(""); + } + + @Bean + public PasswordEncoder passwordEncoder() { + // 密码加密方式 + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + // 搜寻匿名标记 url: @AnonymousAccess + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); + Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); + // 获取匿名标记 + Map> anonymousUrls = getAnonymousUrl(handlerMethodMap); + httpSecurity + // 禁用 CSRF + .csrf().disable() + .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) + // 授权异常 + .exceptionHandling() + .authenticationEntryPoint(authenticationErrorHandler) + .accessDeniedHandler(jwtAccessDeniedHandler) + // 防止iframe 造成跨域 + .and() + .headers() + .frameOptions() + .disable() + // 不创建会话 + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + // 静态资源等等 + .antMatchers( + HttpMethod.GET, + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/webSocket/**" + ).permitAll() + // swagger 文档 + .antMatchers("/swagger-ui.html").permitAll() + .antMatchers("/swagger-resources/**").permitAll() + .antMatchers("/webjars/**").permitAll() + .antMatchers("/*/api-docs").permitAll() + // 文件 + .antMatchers("/avatar/**").permitAll() + .antMatchers("/file/**").permitAll() + // 阿里巴巴 druid + .antMatchers("/druid/**").permitAll() + // 放行OPTIONS请求 + .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() + // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 + // GET + .antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() + // POST + .antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() + // PUT + .antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() + // PATCH + .antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() + // DELETE + .antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() + // 所有类型的接口都放行 + .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() + // 所有请求都需要认证 + .anyRequest().authenticated() + .and().apply(securityConfigurerAdapter()); + } + + private TokenConfigurer securityConfigurerAdapter() { + return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheClean); + } + + private Map> getAnonymousUrl(Map handlerMethodMap) { + Map> anonymousUrls = new HashMap<>(8); + Set get = new HashSet<>(); + Set post = new HashSet<>(); + Set put = new HashSet<>(); + Set patch = new HashSet<>(); + Set delete = new HashSet<>(); + Set all = new HashSet<>(); + for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = infoEntry.getValue(); + AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); + if (null != anonymousAccess) { + List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); + RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); + switch (Objects.requireNonNull(request)) { + case GET: + get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case POST: + post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PUT: + put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PATCH: + patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case DELETE: + delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + default: + all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + } + } + } + anonymousUrls.put(RequestMethodEnum.GET.getType(), get); + anonymousUrls.put(RequestMethodEnum.POST.getType(), post); + anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); + anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); + anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); + anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); + return anonymousUrls; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCode.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCode.java new file mode 100644 index 0000000..02fbc23 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCode.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config.bean; + +import lombok.Data; + +/** + * 登录验证码配置信息 + * + * @author liaojinlong + * 2020/6/10 18:53 + */ +@Data +public class LoginCode { + + /** + * 验证码配置 + */ + private LoginCodeEnum codeType; + /** + * 验证码有效期 分钟 + */ + private Long expiration = 2L; + /** + * 验证码内容长度 + */ + private int length = 2; + /** + * 验证码宽度 + */ + private int width = 111; + /** + * 验证码高度 + */ + private int height = 36; + /** + * 验证码字体 + */ + private String fontName; + /** + * 字体大小 + */ + private int fontSize = 25; + + public LoginCodeEnum getCodeType() { + return codeType; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCodeEnum.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCodeEnum.java new file mode 100644 index 0000000..d9fe369 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginCodeEnum.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config.bean; + +/** + * 验证码配置枚举 + * + * @author: liaojinlong + * : 2020/6/10 17:40 + */ + +public enum LoginCodeEnum { + /** + * 算数 + */ + ARITHMETIC, + /** + * 中文 + */ + CHINESE, + /** + * 中文闪图 + */ + CHINESE_GIF, + /** + * 闪图 + */ + GIF, + SPEC +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginProperties.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginProperties.java new file mode 100644 index 0000000..f4b6754 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/LoginProperties.java @@ -0,0 +1,135 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version loginCode.length.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-loginCode.length.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config.bean; + +import com.wf.captcha.*; +import com.wf.captcha.base.Captcha; +import lombok.Data; +import com.example.exception.BadConfigurationException; +import com.example.utils.StringUtils; + +import java.awt.*; +import java.util.Objects; + +/** + * 配置文件读取 + * + * @author liaojinlong + * loginCode.length0loginCode.length0/6/10 17:loginCode.length6 + */ +@Data +public class LoginProperties { + + /** + * 账号单用户 登录 + */ + private boolean singleLogin = false; + + private LoginCode loginCode; + + /** + * 用户登录信息缓存 + */ + private boolean cacheEnable; + + public boolean isSingleLogin() { + return singleLogin; + } + + public boolean isCacheEnable() { + return cacheEnable; + } + + /** + * 获取验证码生产类 + * + * @return / + */ + public Captcha getCaptcha() { + if (Objects.isNull(loginCode)) { + loginCode = new LoginCode(); + if (Objects.isNull(loginCode.getCodeType())) { + loginCode.setCodeType(LoginCodeEnum.ARITHMETIC); + } + } + return switchCaptcha(loginCode); + } + + /** + * 依据配置信息生产验证码 + * + * @param loginCode 验证码配置信息 + * @return / + */ + private Captcha switchCaptcha(LoginCode loginCode) { + Captcha captcha; + synchronized (this) { + switch (loginCode.getCodeType()) { + case ARITHMETIC: + // 算术类型 https://gitee.com/whvse/EasyCaptcha + captcha = new FixedArithmeticCaptcha(loginCode.getWidth(), loginCode.getHeight()); + // 几位数运算,默认是两位 + captcha.setLen(loginCode.getLength()); + break; + case CHINESE: + captcha = new ChineseCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case CHINESE_GIF: + captcha = new ChineseGifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case GIF: + captcha = new GifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case SPEC: + captcha = new SpecCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + default: + throw new BadConfigurationException("验证码配置信息错误!正确配置查看 LoginCodeEnum "); + } + } + if(StringUtils.isNotBlank(loginCode.getFontName())){ + captcha.setFont(new Font(loginCode.getFontName(), Font.PLAIN, loginCode.getFontSize())); + } + return captcha; + } + + static class FixedArithmeticCaptcha extends ArithmeticCaptcha { + public FixedArithmeticCaptcha(int width, int height) { + super(width, height); + } + + @Override + protected char[] alphas() { + // 生成随机数字和运算符 + int n1 = num(1, 10), n2 = num(1, 10); + int opt = num(3); + + // 计算结果 + int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt]; + // 转换为字符运算符 + char optChar = "+-x".charAt(opt); + + this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2)); + this.chars = String.valueOf(res); + + return chars.toCharArray(); + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/SecurityProperties.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/SecurityProperties.java new file mode 100644 index 0000000..f341003 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/config/bean/SecurityProperties.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.config.bean; + +import lombok.Data; + +/** + * Jwt参数配置 + * + * + * 2019年11月28日 + */ +@Data +public class SecurityProperties { + + /** + * Request Headers : Authorization + */ + private String header; + + /** + * 令牌前缀,最后留个空格 Bearer + */ + private String tokenStartWith; + + /** + * 必须使用最少88位的Base64对该令牌进行编码 + */ + private String base64Secret; + + /** + * 令牌过期时间 此处单位/毫秒 + */ + private Long tokenValidityInSeconds; + + /** + * 在线用户 key,根据 key 查询 redis 中在线用户的数据 + */ + private String onlineKey; + + /** + * 验证码 key + */ + private String codeKey; + + /** + * token 续期检查 + */ + private Long detect; + + /** + * 续期时间 + */ + private Long renew; + + public String getTokenStartWith() { + return tokenStartWith + " "; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/AuthorizationController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/AuthorizationController.java new file mode 100644 index 0000000..7e2148b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/AuthorizationController.java @@ -0,0 +1,146 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.rest; + +import cn.hutool.core.util.IdUtil; +import com.wf.captcha.base.Captcha; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import com.example.annotation.rest.AnonymousDeleteMapping; +import com.example.annotation.rest.AnonymousGetMapping; +import com.example.annotation.rest.AnonymousPostMapping; +import com.example.config.RsaProperties; +import com.example.exception.BadRequestException; +import com.example.modules.security.config.bean.LoginCodeEnum; +import com.example.modules.security.config.bean.LoginProperties; +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.modules.security.security.TokenProvider; +import com.example.modules.security.service.dto.AuthUserDto; +import com.example.modules.security.service.dto.JwtUserDto; +import com.example.modules.security.service.OnlineUserService; +import com.example.utils.RsaUtils; +import com.example.utils.RedisUtils; +import com.example.utils.SecurityUtils; +import com.example.utils.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * + * 2018-11-23 + * 授权、根据token获取用户详细信息 + */ +@Slf4j +@RestController +@RequestMapping("/auth") +@RequiredArgsConstructor +@Api(tags = "系统:系统授权接口") +public class AuthorizationController { + private final SecurityProperties properties; + private final RedisUtils redisUtils; + private final OnlineUserService onlineUserService; + private final TokenProvider tokenProvider; + private final AuthenticationManagerBuilder authenticationManagerBuilder; + @Resource + private LoginProperties loginProperties; + + @ApiOperation("登录授权") + @AnonymousPostMapping(value = "/login") + public ResponseEntity login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { + // 密码解密 + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword()); + //去除验证码功能 +/* // 查询验证码 + String code = (String) redisUtils.get(authUser.getUuid()); + // 清除验证码 + redisUtils.del(authUser.getUuid()); + if (StringUtils.isBlank(code)) { + throw new BadRequestException("验证码不存在或已过期"); + } + if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) { + throw new BadRequestException("验证码错误"); + }*/ + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(authUser.getUsername(), password); + Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + // 生成令牌与第三方系统获取令牌方式 + // UserDetails userDetails = userDetailsService.loadUserByUsername(userInfo.getUsername()); + // Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + // SecurityContextHolder.getContext().setAuthentication(authentication); + String token = tokenProvider.createToken(authentication); + final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal(); + // 保存在线信息 + onlineUserService.save(jwtUserDto, token, request); + // 返回 token 与 用户信息 + Map authInfo = new HashMap(2) {{ + put("token", properties.getTokenStartWith() + token); + put("user", jwtUserDto); + }}; + if (loginProperties.isSingleLogin()) { + //踢掉之前已经登录的token + onlineUserService.checkLoginOnUser(authUser.getUsername(), token); + } + return ResponseEntity.ok(authInfo); + } + + @ApiOperation("获取用户信息") + @GetMapping(value = "/info") + public ResponseEntity getUserInfo() { + return ResponseEntity.ok(SecurityUtils.getCurrentUser()); + } + + @ApiOperation("获取验证码") + @AnonymousGetMapping(value = "/code") + public ResponseEntity getCode() { + // 获取运算的结果 + Captcha captcha = loginProperties.getCaptcha(); + String uuid = properties.getCodeKey() + IdUtil.simpleUUID(); + //当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型 + String captchaValue = captcha.text(); + if (captcha.getCharType() - 1 == LoginCodeEnum.ARITHMETIC.ordinal() && captchaValue.contains(".")) { + captchaValue = captchaValue.split("\\.")[0]; + } + // 保存 + redisUtils.set(uuid, captchaValue, loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES); + // 验证码信息 + Map imgResult = new HashMap(2) {{ + put("img", captcha.toBase64()); + put("uuid", uuid); + }}; + return ResponseEntity.ok(imgResult); + } + + @ApiOperation("退出登录") + @AnonymousDeleteMapping(value = "/logout") + public ResponseEntity logout(HttpServletRequest request) { + onlineUserService.logout(tokenProvider.getToken(request)); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/OnlineController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/OnlineController.java new file mode 100644 index 0000000..c4962a3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/rest/OnlineController.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.modules.security.service.OnlineUserService; +import com.example.utils.EncryptUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** + * + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/auth/online") +@Api(tags = "系统:在线用户管理") +public class OnlineController { + + private final OnlineUserService onlineUserService; + + @ApiOperation("查询在线用户") + @GetMapping + @PreAuthorize("@el.check()") + public ResponseEntity queryOnlineUser(String filter, Pageable pageable){ + return new ResponseEntity<>(onlineUserService.getAll(filter, pageable),HttpStatus.OK); + } + + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check()") + public void exportOnlineUser(HttpServletResponse response, String filter) throws IOException { + onlineUserService.download(onlineUserService.getAll(filter), response); + } + + @ApiOperation("踢出用户") + @DeleteMapping + @PreAuthorize("@el.check()") + public ResponseEntity deleteOnlineUser(@RequestBody Set keys) throws Exception { + for (String key : keys) { + // 解密Key + key = EncryptUtils.desDecrypt(key); + onlineUserService.kickOut(key); + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAccessDeniedHandler.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAccessDeniedHandler.java new file mode 100644 index 0000000..c0b6f86 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAccessDeniedHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.security; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * + */ +@Component +public class JwtAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { + //当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应 + response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage()); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAuthenticationEntryPoint.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..9fa256e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.security; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * + */ +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException { + // 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应 + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage()); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenConfigurer.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenConfigurer.java new file mode 100644 index 0000000..2a1ad1c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenConfigurer.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.security; + +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.modules.security.service.OnlineUserService; +import com.example.modules.security.service.UserCacheClean; +import lombok.RequiredArgsConstructor; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * @author / + */ +@RequiredArgsConstructor +public class TokenConfigurer extends SecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + @Override + public void configure(HttpSecurity http) { + TokenFilter customFilter = new TokenFilter(tokenProvider, properties, onlineUserService, userCacheClean); + http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenFilter.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenFilter.java new file mode 100644 index 0000000..dc1369e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenFilter.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.security; + +import cn.hutool.core.util.StrUtil; +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.modules.security.service.OnlineUserService; +import com.example.modules.security.service.UserCacheClean; +import com.example.modules.security.service.dto.OnlineUserDto; +import io.jsonwebtoken.ExpiredJwtException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Objects; + +/** + * @author / + */ +public class TokenFilter extends GenericFilterBean { + private static final Logger log = LoggerFactory.getLogger(TokenFilter.class); + + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + /** + * @param tokenProvider Token + * @param properties JWT + * @param onlineUserService 用户在线 + * @param userCacheClean 用户缓存清理工具 + */ + public TokenFilter(TokenProvider tokenProvider, SecurityProperties properties, OnlineUserService onlineUserService, UserCacheClean userCacheClean) { + this.properties = properties; + this.onlineUserService = onlineUserService; + this.tokenProvider = tokenProvider; + this.userCacheClean = userCacheClean; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + String token = resolveToken(httpServletRequest); + // 对于 Token 为空的不需要去查 Redis + if (StrUtil.isNotBlank(token)) { + OnlineUserDto onlineUserDto = null; + boolean cleanUserCache = false; + try { + onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token); + } catch (ExpiredJwtException e) { + log.error(e.getMessage()); + cleanUserCache = true; + } finally { + if (cleanUserCache || Objects.isNull(onlineUserDto)) { + userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY))); + } + } + if (onlineUserDto != null && StringUtils.hasText(token)) { + Authentication authentication = tokenProvider.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + // Token 续期 + tokenProvider.checkRenewal(token); + } + } + filterChain.doFilter(servletRequest, servletResponse); + } + + /** + * 初步检测Token + * + * @param request / + * @return / + */ + private String resolveToken(HttpServletRequest request) { + String bearerToken = request.getHeader(properties.getHeader()); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) { + // 去掉令牌前缀 + return bearerToken.replace(properties.getTokenStartWith(), ""); + } else { + log.debug("非法Token:{}", bearerToken); + } + return null; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenProvider.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenProvider.java new file mode 100644 index 0000000..dfe2134 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/security/TokenProvider.java @@ -0,0 +1,123 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.security; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.utils.RedisUtils; +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import java.security.Key; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Slf4j +@Component +public class TokenProvider implements InitializingBean { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + public static final String AUTHORITIES_KEY = "user"; + private JwtParser jwtParser; + private JwtBuilder jwtBuilder; + + public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + @Override + public void afterPropertiesSet() { + byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); + Key key = Keys.hmacShaKeyFor(keyBytes); + jwtParser = Jwts.parserBuilder() + .setSigningKey(key) + .build(); + jwtBuilder = Jwts.builder() + .signWith(key, SignatureAlgorithm.HS512); + } + + /** + * 创建Token 设置永不过期, + * Token 的时间有效性转到Redis 维护 + * + * @param authentication / + * @return / + */ + public String createToken(Authentication authentication) { + return jwtBuilder + // 加入ID确保生成的 Token 都不一致 + .setId(IdUtil.simpleUUID()) + .claim(AUTHORITIES_KEY, authentication.getName()) + .setSubject(authentication.getName()) + .compact(); + } + + /** + * 依据Token 获取鉴权信息 + * + * @param token / + * @return / + */ + Authentication getAuthentication(String token) { + Claims claims = getClaims(token); + User principal = new User(claims.getSubject(), "******", new ArrayList<>()); + return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>()); + } + + public Claims getClaims(String token) { + return jwtParser + .parseClaimsJws(token) + .getBody(); + } + + /** + * @param token 需要检查的token + */ + public void checkRenewal(String token) { + // 判断是否续期token,计算token的过期时间 + long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000; + Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time); + // 判断当前时间与过期时间的时间差 + long differ = expireDate.getTime() - System.currentTimeMillis(); + // 如果在续期检查的范围内,则续期 + if (differ <= properties.getDetect()) { + long renew = time + properties.getRenew(); + redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS); + } + } + + public String getToken(HttpServletRequest request) { + final String requestHeader = request.getHeader(properties.getHeader()); + if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) { + return requestHeader.substring(7); + } + return null; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/OnlineUserService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/OnlineUserService.java new file mode 100644 index 0000000..9cfda04 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/OnlineUserService.java @@ -0,0 +1,192 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.service; + +import com.example.modules.security.config.bean.SecurityProperties; +import com.example.utils.*; +import lombok.extern.slf4j.Slf4j; +import com.example.modules.security.service.dto.JwtUserDto; +import com.example.modules.security.service.dto.OnlineUserDto; +import com.example.utils.*; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * + * 2019年10月26日21:56:27 + */ +@Service +@Slf4j +public class OnlineUserService { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + + public OnlineUserService(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + /** + * 保存在线用户信息 + * @param jwtUserDto / + * @param token / + * @param request / + */ + public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){ + String dept = jwtUserDto.getUser().getDept().getName(); + String ip = StringUtils.getIp(request); + String browser = StringUtils.getBrowser(request); + String address = StringUtils.getCityInfo(ip); + OnlineUserDto onlineUserDto = null; + try { + onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + redisUtils.set(properties.getOnlineKey() + token, onlineUserDto, properties.getTokenValidityInSeconds()/1000); + } + + /** + * 查询全部数据 + * @param filter / + * @param pageable / + * @return / + */ + public Map getAll(String filter, Pageable pageable){ + List onlineUserDtos = getAll(filter); + return PageUtil.toPage( + PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(), onlineUserDtos), + onlineUserDtos.size() + ); + } + + /** + * 查询全部数据,不分页 + * @param filter / + * @return / + */ + public List getAll(String filter){ + List keys = redisUtils.scan(properties.getOnlineKey() + "*"); + Collections.reverse(keys); + List onlineUserDtos = new ArrayList<>(); + for (String key : keys) { + OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key); + if(StringUtils.isNotBlank(filter)){ + if(onlineUserDto.toString().contains(filter)){ + onlineUserDtos.add(onlineUserDto); + } + } else { + onlineUserDtos.add(onlineUserDto); + } + } + onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime())); + return onlineUserDtos; + } + + /** + * 踢出用户 + * @param key / + */ + public void kickOut(String key){ + key = properties.getOnlineKey() + key; + redisUtils.del(key); + } + + /** + * 退出登录 + * @param token / + */ + public void logout(String token) { + String key = properties.getOnlineKey() + token; + redisUtils.del(key); + } + + /** + * 导出 + * @param all / + * @param response / + * @throws IOException / + */ + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (OnlineUserDto user : all) { + Map map = new LinkedHashMap<>(); + map.put("用户名", user.getUserName()); + map.put("部门", user.getDept()); + map.put("登录IP", user.getIp()); + map.put("登录地点", user.getAddress()); + map.put("浏览器", user.getBrowser()); + map.put("登录日期", user.getLoginTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 查询用户 + * @param key / + * @return / + */ + public OnlineUserDto getOne(String key) { + return (OnlineUserDto)redisUtils.get(key); + } + + /** + * 检测用户是否在之前已经登录,已经登录踢下线 + * @param userName 用户名 + */ + public void checkLoginOnUser(String userName, String igoreToken){ + List onlineUserDtos = getAll(userName); + if(onlineUserDtos ==null || onlineUserDtos.isEmpty()){ + return; + } + for(OnlineUserDto onlineUserDto : onlineUserDtos){ + if(onlineUserDto.getUserName().equals(userName)){ + try { + String token =EncryptUtils.desDecrypt(onlineUserDto.getKey()); + if(StringUtils.isNotBlank(igoreToken)&&!igoreToken.equals(token)){ + this.kickOut(token); + }else if(StringUtils.isBlank(igoreToken)){ + this.kickOut(token); + } + } catch (Exception e) { + log.error("checkUser is error",e); + } + } + } + } + + /** + * 根据用户名强退用户 + * @param username / + */ + @Async + public void kickOutForUsername(String username) throws Exception { + List onlineUsers = getAll(username); + for (OnlineUserDto onlineUser : onlineUsers) { + if (onlineUser.getUserName().equals(username)) { + String token =EncryptUtils.desDecrypt(onlineUser.getKey()); + kickOut(token); + } + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheClean.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheClean.java new file mode 100644 index 0000000..aa1ef9c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheClean.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.modules.security.service; + +import lombok.AllArgsConstructor; +import com.example.utils.StringUtils; +import org.springframework.stereotype.Component; + +/** + * @author: liaojinlong + * : 2020/6/11 18:01 + * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 + */ +@Component +@AllArgsConstructor +public class UserCacheClean { + + private final UserCacheManager userCacheManager; + + /** + * 清理特定用户缓存信息
+ * 用户信息变更时 + * + * @param userName / + */ + public void cleanUserCache(String userName) { + if (StringUtils.isNotEmpty(userName)) { + userCacheManager.remove(userName); + } + } + + /** + * 清理所有用户的缓存信息
+ * ,如发生角色授权信息变化,可以简便的全部失效缓存 + */ + public void cleanAll() { + userCacheManager.clear(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheManager.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheManager.java new file mode 100644 index 0000000..9c1f60b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserCacheManager.java @@ -0,0 +1,110 @@ +package com.example.modules.security.service; + +import lombok.extern.slf4j.Slf4j; +import com.example.modules.security.service.dto.JwtUserDto; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * 用户缓存 + * + * @author TikiWong + * 2022/1/27 8:23 + **/ +@Slf4j +@Component +public class UserCacheManager { + + @Value("${user-cache.min-evictable-size}") + private int minEvictableSize; + @Value("${user-cache.min-evictable-interval}") + private long minEvictableInterval; + @Value("${user-cache.min-idle-time}") + private long minIdleTime; + + private final Map cache = new ConcurrentHashMap<>(); + private final AtomicBoolean expelLock = new AtomicBoolean(true); + private long nextMinEvictableTime = 0; + + public Future putIfAbsent(String username, Future ft) { + Node tryNode = new Node(ft); + Node node = cache.putIfAbsent(username, tryNode); + expel(); + return nodeToDate(node); + } + + /** + * 缓存回收 + * 为避免超过边界后回收热点数据设置了最小生存时间 + * 回收时会保留在最小生存时间内的数据 + **/ + public void expel() { + long now = System.currentTimeMillis(); + if (cache.size() < minEvictableSize || + now < nextMinEvictableTime || + !expelLock.compareAndSet(true, false)) { + return; + } + long oldestTime = now; + int evictedCount = 0; + try { + Iterator> iterator = cache.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + long nodeTime = entry.getValue().getTime(); + if (nodeTime + minIdleTime < now) { + iterator.remove(); + evictedCount++; + } + oldestTime = Math.min(oldestTime, nodeTime); + } + } finally { + this.nextMinEvictableTime = Math.max(now + minEvictableInterval, oldestTime); + expelLock.set(true); + log.info("回收掉【{}】条用户缓存, 剩余缓存数为【{}】,下次可回收时间为【{}】秒后", + evictedCount, + cache.size(), + (this.nextMinEvictableTime - now) / 1000); + } + } + + public Future get(String username) { + return nodeToDate(cache.get(username)); + } + + public void clear() { + cache.clear(); + } + + public void remove(String username) { + cache.remove(username); + } + + private Future nodeToDate(Node node) { + return node == null ? null : node.getData(); + } + + private static class Node { + private final Future data; + private final long time; + + public Node(Future data) { + this.data = data; + this.time = System.currentTimeMillis(); + } + + public Future getData() { + return data; + } + + public long getTime() { + return time; + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserDetailsServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..8d368f2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/UserDetailsServiceImpl.java @@ -0,0 +1,159 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.service; + +import com.example.modules.security.config.bean.LoginProperties; +import com.example.modules.system.service.DataService; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.UserService; +import com.example.modules.system.service.dto.UserDto; +import lombok.RequiredArgsConstructor; +import com.example.exception.BadRequestException; +import com.example.exception.EntityNotFoundException; +import com.example.modules.security.service.dto.JwtUserDto; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * + * 2018-11-22 + */ +@RequiredArgsConstructor +@Service("userDetailsService") +public class UserDetailsServiceImpl implements UserDetailsService { + private final UserService userService; + private final RoleService roleService; + private final DataService dataService; + private final LoginProperties loginProperties; + + private final UserCacheManager USER_DTO_CACHE; + + public void setEnableCache(boolean enableCache) { + this.loginProperties.setCacheEnable(enableCache); + } + + public static ExecutorService executor = newThreadPool(); + + @Override + public JwtUserDto loadUserByUsername(String username) { + JwtUserDto jwtUserDto = null; + Future future = USER_DTO_CACHE.get(username); + if (!loginProperties.isCacheEnable()) { + UserDto user; + try { + user = userService.findByName(username); + } catch (EntityNotFoundException e) { + // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException + throw new UsernameNotFoundException(username, e); + } + if (user == null) { + throw new UsernameNotFoundException(""); + } else { + if (!user.getEnabled()) { + throw new BadRequestException("账号未激活!"); + } + jwtUserDto = new JwtUserDto( + user, + dataService.getDeptIds(user), + roleService.mapToGrantedAuthorities(user) + ); + } + return jwtUserDto; + } + + if (future == null) { + Callable call = () -> getJwtBySearchDb(username); + FutureTask ft = new FutureTask<>(call); + future = USER_DTO_CACHE.putIfAbsent(username, ft); + if (future == null) { + future = ft; + executor.submit(ft); + } + try { + return future.get(); + } catch (CancellationException e) { + USER_DTO_CACHE.remove(username); + System.out.println("error" + Thread.currentThread().getName()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + jwtUserDto = future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e.getMessage()); + } + // 检查dataScope是否修改 + List dataScopes = jwtUserDto.getDataScopes(); + dataScopes.clear(); + dataScopes.addAll(dataService.getDeptIds(jwtUserDto.getUser())); + + } + return jwtUserDto; + + } + + private JwtUserDto getJwtBySearchDb(String username) { + UserDto user; + try { + user = userService.findByName(username); + } catch (EntityNotFoundException e) { + // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException + throw new UsernameNotFoundException("", e); + } + if (user == null) { + throw new UsernameNotFoundException(""); + } else { + if (!user.getEnabled()) { + throw new BadRequestException("账号未激活!"); + } + return new JwtUserDto( + user, + dataService.getDeptIds(user), + roleService.mapToGrantedAuthorities(user) + ); + } + + } + + public static ExecutorService newThreadPool() { + ThreadFactory namedThreadFactory = new ThreadFactory() { + final AtomicInteger sequence = new AtomicInteger(1); + + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r); + int seq = this.sequence.getAndIncrement(); + thread.setName("future-task-thread" + (seq > 1 ? "-" + seq : "")); + if (!thread.isDaemon()) { + thread.setDaemon(true); + } + + return thread; + } + }; + return new ThreadPoolExecutor(10, 200, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(1024), + namedThreadFactory, + new ThreadPoolExecutor.AbortPolicy()); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/AuthUserDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/AuthUserDto.java new file mode 100644 index 0000000..983d690 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/AuthUserDto.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.service.dto; + +import lombok.Getter; +import lombok.Setter; +import javax.validation.constraints.NotBlank; + +/** + * + * 2018-11-30 + */ +@Getter +@Setter +public class AuthUserDto { + + @NotBlank + private String username; + + @NotBlank + private String password; + + private String code; + + private String uuid = ""; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/JwtUserDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/JwtUserDto.java new file mode 100644 index 0000000..20e1bc6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/JwtUserDto.java @@ -0,0 +1,79 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import com.example.modules.system.service.dto.UserDto; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + + +@Getter +@AllArgsConstructor +public class JwtUserDto implements UserDetails { + + private final UserDto user; + + private final List dataScopes; + + @JSONField(serialize = false) + private final List authorities; + + public Set getRoles() { + return authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); + } + + @Override + @JSONField(serialize = false) + public String getPassword() { + return user.getPassword(); + } + + @Override + @JSONField(serialize = false) + public String getUsername() { + return user.getUsername(); + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + @JSONField(serialize = false) + public boolean isEnabled() { + return user.getEnabled(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/OnlineUserDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/OnlineUserDto.java new file mode 100644 index 0000000..77ba3bc --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/security/service/dto/OnlineUserDto.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.security.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.Date; + +/** + * 在线用户 + * + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OnlineUserDto { + + /** + * 用户名 + */ + private String userName; + + /** + * 昵称 + */ + private String nickName; + + /** + * 岗位 + */ + private String dept; + + /** + * 浏览器 + */ + private String browser; + + /** + * IP + */ + private String ip; + + /** + * 地址 + */ + private String address; + + /** + * token + */ + private String key; + + /** + * 登录时间 + */ + private Date loginTime; + + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DeptController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DeptController.java new file mode 100644 index 0000000..0bef112 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DeptController.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import cn.hutool.core.collection.CollectionUtil; +import com.example.modules.system.domain.Dept; +import com.example.modules.system.service.DeptService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.dto.DeptDto; +import com.example.modules.system.service.dto.DeptQueryCriteria; +import com.example.utils.PageUtil; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +/** +* +* 2019-03-25 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:部门管理") +@RequestMapping("/api/dept") +public class DeptController { + + private final DeptService deptService; + private static final String ENTITY_NAME = "dept"; + + @ApiOperation("导出部门数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dept:list')") + public void exportDept(HttpServletResponse response, DeptQueryCriteria criteria) throws Exception { + deptService.download(deptService.queryAll(criteria, false), response); + } + + @ApiOperation("查询部门") + @GetMapping + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity queryDept(DeptQueryCriteria criteria) throws Exception { + List deptDtos = deptService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(deptDtos, deptDtos.size()),HttpStatus.OK); + } + + @ApiOperation("查询部门:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity getDeptSuperior(@RequestBody List ids) { + Set deptDtos = new LinkedHashSet<>(); + for (Long id : ids) { + DeptDto deptDto = deptService.findById(id); + List depts = deptService.getSuperior(deptDto, new ArrayList<>()); + deptDtos.addAll(depts); + } + return new ResponseEntity<>(deptService.buildTree(new ArrayList<>(deptDtos)),HttpStatus.OK); + } + + @Log("新增部门") + @ApiOperation("新增部门") + @PostMapping + @PreAuthorize("@el.check('dept:add')") + public ResponseEntity createDept(@Validated @RequestBody Dept resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + deptService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改部门") + @ApiOperation("修改部门") + @PutMapping + @PreAuthorize("@el.check('dept:edit')") + public ResponseEntity updateDept(@Validated(Dept.Update.class) @RequestBody Dept resources){ + deptService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除部门") + @ApiOperation("删除部门") + @DeleteMapping + @PreAuthorize("@el.check('dept:del')") + public ResponseEntity deleteDept(@RequestBody Set ids){ + Set deptDtos = new HashSet<>(); + for (Long id : ids) { + List deptList = deptService.findByPid(id); + deptDtos.add(deptService.findById(id)); + if(CollectionUtil.isNotEmpty(deptList)){ + deptDtos = deptService.getDeleteDepts(deptList, deptDtos); + } + } + // 验证是否被角色或用户关联 + deptService.verification(deptDtos); + deptService.delete(deptDtos); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictController.java new file mode 100644 index 0000000..8f4dec7 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictController.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import com.example.modules.system.domain.Dict; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.DictService; +import com.example.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* +* 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典管理") +@RequestMapping("/api/dict") +public class DictController { + + private final DictService dictService; + private static final String ENTITY_NAME = "dict"; + + @ApiOperation("导出字典数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dict:list')") + public void exportDict(HttpServletResponse response, DictQueryCriteria criteria) throws IOException { + dictService.download(dictService.queryAll(criteria), response); + } + + @ApiOperation("查询字典") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity queryAllDict(){ + return new ResponseEntity<>(dictService.queryAll(new DictQueryCriteria()),HttpStatus.OK); + } + + @ApiOperation("查询字典") + @GetMapping + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity queryDict(DictQueryCriteria resources, Pageable pageable){ + return new ResponseEntity<>(dictService.queryAll(resources,pageable),HttpStatus.OK); + } + + @Log("新增字典") + @ApiOperation("新增字典") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity createDict(@Validated @RequestBody Dict resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典") + @ApiOperation("修改字典") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity updateDict(@Validated(Dict.Update.class) @RequestBody Dict resources){ + dictService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典") + @ApiOperation("删除字典") + @DeleteMapping + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity deleteDict(@RequestBody Set ids){ + dictService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictDetailController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictDetailController.java new file mode 100644 index 0000000..e3c5891 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/DictDetailController.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import com.example.modules.system.domain.DictDetail; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.DictDetailService; +import com.example.modules.system.service.dto.DictDetailDto; +import com.example.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* +* 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典详情管理") +@RequestMapping("/api/dictDetail") +public class DictDetailController { + + private final DictDetailService dictDetailService; + private static final String ENTITY_NAME = "dictDetail"; + + @ApiOperation("查询字典详情") + @GetMapping + public ResponseEntity queryDictDetail(DictDetailQueryCriteria criteria, + @PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable){ + return new ResponseEntity<>(dictDetailService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("查询多个字典详情") + @GetMapping(value = "/map") + public ResponseEntity getDictDetailMaps(@RequestParam String dictName){ + String[] names = dictName.split("[,,]"); + Map> dictMap = new HashMap<>(16); + for (String name : names) { + dictMap.put(name, dictDetailService.getDictByName(name)); + } + return new ResponseEntity<>(dictMap, HttpStatus.OK); + } + + @Log("新增字典详情") + @ApiOperation("新增字典详情") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity createDictDetail(@Validated @RequestBody DictDetail resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictDetailService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典详情") + @ApiOperation("修改字典详情") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity updateDictDetail(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){ + dictDetailService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典详情") + @ApiOperation("删除字典详情") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity deleteDictDetail(@PathVariable Long id){ + dictDetailService.delete(id); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/JobController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/JobController.java new file mode 100644 index 0000000..6106f0d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/JobController.java @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import com.example.modules.system.domain.Job; +import com.example.modules.system.service.JobService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* +* 2019-03-29 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:岗位管理") +@RequestMapping("/api/job") +public class JobController { + + private final JobService jobService; + private static final String ENTITY_NAME = "job"; + + @ApiOperation("导出岗位数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('job:list')") + public void exportJob(HttpServletResponse response, JobQueryCriteria criteria) throws IOException { + jobService.download(jobService.queryAll(criteria), response); + } + + @ApiOperation("查询岗位") + @GetMapping + @PreAuthorize("@el.check('job:list','user:list')") + public ResponseEntity queryJob(JobQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(jobService.queryAll(criteria, pageable),HttpStatus.OK); + } + + @Log("新增岗位") + @ApiOperation("新增岗位") + @PostMapping + @PreAuthorize("@el.check('job:add')") + public ResponseEntity createJob(@Validated @RequestBody Job resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + jobService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改岗位") + @ApiOperation("修改岗位") + @PutMapping + @PreAuthorize("@el.check('job:edit')") + public ResponseEntity updateJob(@Validated(Job.Update.class) @RequestBody Job resources){ + jobService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除岗位") + @ApiOperation("删除岗位") + @DeleteMapping + @PreAuthorize("@el.check('job:del')") + public ResponseEntity deleteJob(@RequestBody Set ids){ + // 验证是否被用户关联 + jobService.verification(ids); + jobService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/LimitController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/LimitController.java new file mode 100644 index 0000000..636ec91 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/LimitController.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.example.annotation.Limit; +import com.example.annotation.rest.AnonymousGetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author / + * 接口限流测试类 + */ +@RestController +@RequestMapping("/api/limit") +@Api(tags = "系统:限流测试管理") +public class LimitController { + + private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(); + + /** + * 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test, + */ + @AnonymousGetMapping + @ApiOperation("测试") + @Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit") + public int testLimit() { + return ATOMIC_INTEGER.incrementAndGet(); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MenuController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MenuController.java new file mode 100644 index 0000000..26a2f1a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MenuController.java @@ -0,0 +1,147 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import cn.hutool.core.collection.CollectionUtil; +import com.example.modules.system.domain.Menu; +import com.example.modules.system.service.MenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.dto.MenuDto; +import com.example.modules.system.service.dto.MenuQueryCriteria; +import com.example.modules.system.service.mapstruct.MenuMapper; +import com.example.utils.PageUtil; +import com.example.utils.SecurityUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; + +/** + * + * 2018-12-03 + */ + +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:菜单管理") +@RequestMapping("/api/menus") +public class MenuController { + + private final MenuService menuService; + private final MenuMapper menuMapper; + private static final String ENTITY_NAME = "menu"; + + @ApiOperation("导出菜单数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('menu:list')") + public void exportMenu(HttpServletResponse response, MenuQueryCriteria criteria) throws Exception { + menuService.download(menuService.queryAll(criteria, false), response); + } + + @GetMapping(value = "/build") + @ApiOperation("获取前端所需菜单") + public ResponseEntity buildMenus(){ + List menuDtoList = menuService.findByUser(SecurityUtils.getCurrentUserId()); + List menuDtos = menuService.buildTree(menuDtoList); + return new ResponseEntity<>(menuService.buildMenus(menuDtos),HttpStatus.OK); + } + + @ApiOperation("返回全部的菜单") + @GetMapping(value = "/lazy") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity queryAllMenu(@RequestParam Long pid){ + return new ResponseEntity<>(menuService.getMenus(pid),HttpStatus.OK); + } + + @ApiOperation("根据菜单ID返回所有子节点ID,包含自身ID") + @GetMapping(value = "/child") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity childMenu(@RequestParam Long id){ + Set menuSet = new HashSet<>(); + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + Set ids = menuSet.stream().map(Menu::getId).collect(Collectors.toSet()); + return new ResponseEntity<>(ids,HttpStatus.OK); + } + + @GetMapping + @ApiOperation("查询菜单") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity queryMenu(MenuQueryCriteria criteria) throws Exception { + List menuDtoList = menuService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(menuDtoList, menuDtoList.size()),HttpStatus.OK); + } + + @ApiOperation("查询菜单:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity getMenuSuperior(@RequestBody List ids) { + Set menuDtos = new LinkedHashSet<>(); + if(CollectionUtil.isNotEmpty(ids)){ + for (Long id : ids) { + MenuDto menuDto = menuService.findById(id); + menuDtos.addAll(menuService.getSuperior(menuDto, new ArrayList<>())); + } + return new ResponseEntity<>(menuService.buildTree(new ArrayList<>(menuDtos)),HttpStatus.OK); + } + return new ResponseEntity<>(menuService.getMenus(null),HttpStatus.OK); + } + + @Log("新增菜单") + @ApiOperation("新增菜单") + @PostMapping + @PreAuthorize("@el.check('menu:add')") + public ResponseEntity createMenu(@Validated @RequestBody Menu resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + menuService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改菜单") + @ApiOperation("修改菜单") + @PutMapping + @PreAuthorize("@el.check('menu:edit')") + public ResponseEntity updateMenu(@Validated(Menu.Update.class) @RequestBody Menu resources){ + menuService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除菜单") + @ApiOperation("删除菜单") + @DeleteMapping + @PreAuthorize("@el.check('menu:del')") + public ResponseEntity deleteMenu(@RequestBody Set ids){ + Set menuSet = new HashSet<>(); + for (Long id : ids) { + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + } + menuService.delete(menuSet); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MonitorController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MonitorController.java new file mode 100644 index 0000000..bb7bf02 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/MonitorController.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.modules.system.service.MonitorService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +/** + * + * 2020-05-02 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统-服务监控管理") +@RequestMapping("/api/monitor") +public class MonitorController { + + private final MonitorService serverService; + + @GetMapping + @ApiOperation("查询服务监控") + @PreAuthorize("@el.check('monitor:list')") + public ResponseEntity queryMonitor(){ + return new ResponseEntity<>(serverService.getServers(),HttpStatus.OK); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/RoleController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/RoleController.java new file mode 100644 index 0000000..8f4fae8 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/RoleController.java @@ -0,0 +1,154 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import cn.hutool.core.lang.Dict; +import com.example.modules.system.domain.Role; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.dto.RoleDto; +import com.example.modules.system.service.dto.RoleQueryCriteria; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * + * 2018-12-03 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:角色管理") +@RequestMapping("/api/roles") +public class RoleController { + + private final RoleService roleService; + + private static final String ENTITY_NAME = "role"; + + @ApiOperation("获取单个role") + @GetMapping(value = "/{id}") + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity findRoleById(@PathVariable Long id){ + return new ResponseEntity<>(roleService.findById(id), HttpStatus.OK); + } + + @ApiOperation("导出角色数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('role:list')") + public void exportRole(HttpServletResponse response, RoleQueryCriteria criteria) throws IOException { + roleService.download(roleService.queryAll(criteria), response); + } + + @ApiOperation("返回全部的角色") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('roles:list','user:add','user:edit')") + public ResponseEntity queryAllRole(){ + return new ResponseEntity<>(roleService.queryAll(),HttpStatus.OK); + } + + @ApiOperation("查询角色") + @GetMapping + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity queryRole(RoleQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(roleService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("获取用户级别") + @GetMapping(value = "/level") + public ResponseEntity getRoleLevel(){ + return new ResponseEntity<>(Dict.create().set("level", getLevels(null)),HttpStatus.OK); + } + + @Log("新增角色") + @ApiOperation("新增角色") + @PostMapping + @PreAuthorize("@el.check('roles:add')") + public ResponseEntity createRole(@Validated @RequestBody Role resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + getLevels(resources.getLevel()); + roleService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改角色") + @ApiOperation("修改角色") + @PutMapping + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity updateRole(@Validated(Role.Update.class) @RequestBody Role resources){ + getLevels(resources.getLevel()); + roleService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改角色菜单") + @ApiOperation("修改角色菜单") + @PutMapping(value = "/menu") + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity updateRoleMenu(@RequestBody Role resources){ + RoleDto role = roleService.findById(resources.getId()); + getLevels(role.getLevel()); + roleService.updateMenu(resources,role); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除角色") + @ApiOperation("删除角色") + @DeleteMapping + @PreAuthorize("@el.check('roles:del')") + public ResponseEntity deleteRole(@RequestBody Set ids){ + for (Long id : ids) { + RoleDto role = roleService.findById(id); + getLevels(role.getLevel()); + } + // 验证是否被用户关联 + roleService.verification(ids); + roleService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 获取用户的角色级别 + * @return / + */ + private int getLevels(Integer level){ + List levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); + int min = Collections.min(levels); + if(level != null){ + if(level < min){ + throw new BadRequestException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + level); + } + } + return min; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/UserController.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/UserController.java new file mode 100644 index 0000000..393a878 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/controller/UserController.java @@ -0,0 +1,196 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.controller; + +import cn.hutool.core.collection.CollectionUtil; +import com.example.modules.system.domain.Dept; +import com.example.modules.system.domain.vo.UserPassVo; +import com.example.modules.system.service.DataService; +import com.example.modules.system.service.DeptService; +import com.example.modules.system.service.UserService; +import com.example.utils.PageUtil; +import com.example.utils.RsaUtils; +import com.example.utils.SecurityUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import com.example.annotation.Log; +import com.example.config.RsaProperties; +import com.example.modules.system.domain.User; +import com.example.exception.BadRequestException; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.modules.system.service.dto.UserDto; +import com.example.modules.system.service.dto.UserQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + + +@Api(tags = "系统:用户管理") +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +public class UserController { + + private final PasswordEncoder passwordEncoder; + private final UserService userService; + private final DataService dataService; + private final DeptService deptService; + private final RoleService roleService; + + @ApiOperation("导出用户数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('user:list')") + public void exportUser(HttpServletResponse response, UserQueryCriteria criteria) throws IOException { + userService.download(userService.queryAll(criteria), response); + } + + @ApiOperation("查询用户") + @GetMapping + @PreAuthorize("@el.check('user:list')") + public ResponseEntity queryUser(UserQueryCriteria criteria, Pageable pageable){ + if (!ObjectUtils.isEmpty(criteria.getDeptId())) { + criteria.getDeptIds().add(criteria.getDeptId()); + // 先查找是否存在子节点 + List data = deptService.findByPid(criteria.getDeptId()); + // 然后把子节点的ID都加入到集合中 + criteria.getDeptIds().addAll(deptService.getDeptChildren(data)); + } + // 数据权限 + List dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername())); + // criteria.getDeptIds() 不为空并且数据权限不为空则取交集 + if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){ + // 取交集 + criteria.getDeptIds().retainAll(dataScopes); + if(!CollectionUtil.isEmpty(criteria.getDeptIds())){ + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + } else { + // 否则取并集 + criteria.getDeptIds().addAll(dataScopes); + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK); + } + + @Log("新增用户") + @ApiOperation("新增用户") + @PostMapping + @PreAuthorize("@el.check('user:add')") + public ResponseEntity createUser(@Validated @RequestBody User resources){ +// checkLevel(resources); + // 默认密码 123456 + resources.setPassword(passwordEncoder.encode("123456")); + userService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改用户") + @ApiOperation("修改用户") + @PutMapping + @PreAuthorize("@el.check('user:edit')") + public ResponseEntity updateUser(@Validated(User.Update.class) @RequestBody User resources) throws Exception { + checkLevel(resources); + userService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改用户:个人中心") + @ApiOperation("修改用户:个人中心") + @PutMapping(value = "center") + public ResponseEntity centerUser(@Validated(User.Update.class) @RequestBody User resources){ + if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){ + throw new BadRequestException("不能修改他人资料"); + } + userService.updateCenter(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除用户") + @ApiOperation("删除用户") + @DeleteMapping + @PreAuthorize("@el.check('user:del')") + public ResponseEntity deleteUser(@RequestBody Set ids){ + for (Long id : ids) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足,不能删除:" + userService.findById(id).getUsername()); + } + } + userService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("修改密码") + @PostMapping(value = "/updatePass") + public ResponseEntity updateUserPass(@RequestBody UserPassVo passVo) throws Exception { + String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass()); + String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass()); + UserDto user = userService.findByName(SecurityUtils.getCurrentUsername()); + if(!passwordEncoder.matches(oldPass, user.getPassword())){ + throw new BadRequestException("修改失败,旧密码错误"); + } + if(passwordEncoder.matches(newPass, user.getPassword())){ + throw new BadRequestException("新密码不能与旧密码相同"); + } + userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass)); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("修改头像") + @PostMapping(value = "/updateAvatar") + public ResponseEntity updateUserAvatar(@RequestParam MultipartFile avatar){ + return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK); + } + + @Log("修改邮箱") + @ApiOperation("修改邮箱") + @PostMapping(value = "/updateEmail/{code}") + public ResponseEntity updateUserEmail(@PathVariable String code,@RequestBody User user) throws Exception { + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword()); + UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername()); + if(!passwordEncoder.matches(password, userDto.getPassword())){ + throw new BadRequestException("密码错误"); + } + userService.updateEmail(userDto.getUsername(),user.getEmail()); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 + * @param resources / + */ + private void checkLevel(User resources) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = roleService.findByRoles(resources.getRoles()); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足"); + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dept.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dept.java new file mode 100644 index 0000000..4ef6ac1 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dept.java @@ -0,0 +1,86 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** +* +* 2019-03-25 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dept") +public class Dept extends BaseEntity implements Serializable { + + @Id + @Column(name = "dept_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "depts") + @ApiModelProperty(value = "角色") + private Set roles; + + @ApiModelProperty(value = "排序") + private Integer deptSort; + + @NotBlank + @ApiModelProperty(value = "部门名称") + private String name; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "上级部门") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Dept dept = (Dept) o; + return Objects.equals(id, dept.id) && + Objects.equals(name, dept.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dict.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dict.java new file mode 100644 index 0000000..de65392 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Dict.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.List; + +/** +* +* 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict") +public class Dict extends BaseEntity implements Serializable { + + @Id + @Column(name = "dict_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany(mappedBy = "dict",cascade={CascadeType.PERSIST,CascadeType.REMOVE}) + private List dictDetails; + + @NotBlank + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "描述") + private String description; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/DictDetail.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/DictDetail.java new file mode 100644 index 0000000..538743e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/DictDetail.java @@ -0,0 +1,56 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** +* +* 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict_detail") +public class DictDetail extends BaseEntity implements Serializable { + + @Id + @Column(name = "detail_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JoinColumn(name = "dict_id") + @ManyToOne(fetch=FetchType.LAZY) + @ApiModelProperty(value = "字典", hidden = true) + private Dict dict; + + @ApiModelProperty(value = "字典标签") + private String label; + + @ApiModelProperty(value = "字典值") + private String value; + + @ApiModelProperty(value = "排序") + private Integer dictSort = 999; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Job.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Job.java new file mode 100644 index 0000000..f3f47b3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Job.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; + +/** +* +* 2019-03-29 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_job") +public class Job extends BaseEntity implements Serializable { + + @Id + @Column(name = "job_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @ApiModelProperty(value = "岗位名称") + private String name; + + @NotNull + @ApiModelProperty(value = "岗位排序") + private Long jobSort; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Job job = (Job) o; + return Objects.equals(id, job.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Menu.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Menu.java new file mode 100644 index 0000000..0989055 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Menu.java @@ -0,0 +1,110 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * + * 2018-12-17 + */ +@Entity +@Getter +@Setter +@Table(name = "sys_menu") +public class Menu extends BaseEntity implements Serializable { + + @Id + @Column(name = "menu_id") + @NotNull(groups = {Update.class}) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "menus") + @ApiModelProperty(value = "菜单角色") + private Set roles; + + @ApiModelProperty(value = "菜单标题") + private String title; + + @Column(name = "name") + @ApiModelProperty(value = "菜单组件名称") + private String componentName; + + @ApiModelProperty(value = "排序") + private Integer menuSort = 999; + + @ApiModelProperty(value = "组件路径") + private String component; + + @ApiModelProperty(value = "路由地址") + private String path; + + @ApiModelProperty(value = "菜单类型,目录、菜单、按钮") + private Integer type; + + @ApiModelProperty(value = "权限标识") + private String permission; + + @ApiModelProperty(value = "菜单图标") + private String icon; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "缓存") + private Boolean cache; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "是否隐藏") + private Boolean hidden; + + @ApiModelProperty(value = "上级菜单") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @ApiModelProperty(value = "外链菜单") + private Boolean iFrame; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Menu menu = (Menu) o; + return Objects.equals(id, menu.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Role.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Role.java new file mode 100644 index 0000000..b600f46 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/Role.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import com.example.utils.enums.DataScopeEnum; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * 角色 + * + * 2018-11-22 + */ +@Getter +@Setter +@Entity +@Table(name = "sys_role") +public class Role extends BaseEntity implements Serializable { + + @Id + @Column(name = "role_id") + @NotNull(groups = {Update.class}) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "roles") + @ApiModelProperty(value = "用户", hidden = true) + private Set users; + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "sys_roles_menus", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "menu_id")}) + @ApiModelProperty(value = "菜单", hidden = true) + private Set menus; + + @ManyToMany + @JoinTable(name = "sys_roles_depts", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "dept_id",referencedColumnName = "dept_id")}) + @ApiModelProperty(value = "部门", hidden = true) + private Set depts; + + @NotBlank + @ApiModelProperty(value = "名称", hidden = true) + private String name; + + @ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义") + private String dataScope = DataScopeEnum.THIS_LEVEL.getValue(); + + @Column(name = "level") + @ApiModelProperty(value = "级别,数值越小,级别越大") + private Integer level = 3; + + @ApiModelProperty(value = "描述") + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Role role = (Role) o; + return Objects.equals(id, role.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/User.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/User.java new file mode 100644 index 0000000..fcbba83 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/User.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.util.Objects; +import java.util.Set; + +/** + * + * 2018-11-22 + */ +@Entity +@Getter +@Setter +@Table(name="sys_user") +public class User extends BaseEntity implements Serializable { + + @Id + @Column(name = "user_id") + @NotNull(groups = Update.class) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @ManyToMany(fetch = FetchType.EAGER) + @ApiModelProperty(value = "用户角色") + @JoinTable(name = "sys_users_roles", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}) + private Set roles; + + @ManyToMany(fetch = FetchType.EAGER) + @ApiModelProperty(value = "用户岗位") + @JoinTable(name = "sys_users_jobs", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "job_id",referencedColumnName = "job_id")}) + private Set jobs; + + @OneToOne + @JoinColumn(name = "dept_id") + @ApiModelProperty(value = "用户部门") + private Dept dept; + + @NotBlank + @Column(unique = true) + @ApiModelProperty(value = "用户名称") + private String username; + + @NotBlank + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @Email + @NotBlank + @ApiModelProperty(value = "邮箱") + private String email; + + @NotBlank + @ApiModelProperty(value = "电话号码") + private String phone; + + @ApiModelProperty(value = "用户性别") + private String gender; + + @ApiModelProperty(value = "头像真实名称",hidden = true) + private String avatarName; + + @ApiModelProperty(value = "头像存储的路径", hidden = true) + private String avatarPath; + + @ApiModelProperty(value = "密码") + private String password; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "是否为admin账号", hidden = true) + private Boolean isAdmin = false; + + @Column(name = "pwd_reset_time") + @ApiModelProperty(value = "最后修改密码的时间", hidden = true) + private Date pwdResetTime; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(id, user.id) && + Objects.equals(username, user.username); + } + + @Override + public int hashCode() { + return Objects.hash(id, username); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuMetaVo.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuMetaVo.java new file mode 100644 index 0000000..68944cc --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuMetaVo.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import java.io.Serializable; + +/** + * + * 2018-12-20 + */ +@Data +@AllArgsConstructor +public class MenuMetaVo implements Serializable { + + private String title; + + private String icon; + + private Boolean noCache; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuVo.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuVo.java new file mode 100644 index 0000000..71c6161 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/MenuVo.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 构建前端路由时用到 + * + * 2018-12-20 + */ +@Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class MenuVo implements Serializable { + + private String name; + + private String path; + + private Boolean hidden; + + private String redirect; + + private String component; + + private Boolean alwaysShow; + + private MenuMetaVo meta; + + private List children; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/UserPassVo.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/UserPassVo.java new file mode 100644 index 0000000..66869b2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/domain/vo/UserPassVo.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.domain.vo; + +import lombok.Data; + +/** + * 修改密码的 Vo 类 + * + * 2019年7月11日13:59:49 + */ +@Data +public class UserPassVo { + + private String oldPass; + + private String newPass; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DeptRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DeptRepository.java new file mode 100644 index 0000000..5952659 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DeptRepository.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.Dept; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.List; +import java.util.Set; + +/** +* +* 2019-03-25 +*/ +public interface DeptRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据 PID 查询 + * @param id pid + * @return / + */ + List findByPid(Long id); + + /** + * 获取顶级部门 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID 查询 + * @param roleId 角色ID + * @return / + */ + @Query(value = "select d.* from sys_dept d, sys_roles_depts r where " + + "d.dept_id = r.dept_id and r.role_id = ?1", nativeQuery = true) + Set findByRoleId(Long roleId); + + /** + * 判断是否存在子节点 + * @param pid / + * @return / + */ + int countByPid(Long pid); + + /** + * 根据ID更新sub_count + * @param count / + * @param id / + */ + @Modifying + @Query(value = " update sys_dept set sub_count = ?1 where dept_id = ?2 ",nativeQuery = true) + void updateSubCntById(Integer count, Long id); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictDetailRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictDetailRepository.java new file mode 100644 index 0000000..315be98 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictDetailRepository.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.DictDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; + +/** +* +* 2019-04-10 +*/ +public interface DictDetailRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据字典名称查询 + * @param name / + * @return / + */ + List findByDictName(String name); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictRepository.java new file mode 100644 index 0000000..c2d1a49 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/DictRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.Dict; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; +import java.util.Set; + +/** +* +* 2019-04-10 +*/ +public interface DictRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 删除 + * @param ids / + */ + void deleteByIdIn(Set ids); + + /** + * 查询 + * @param ids / + * @return / + */ + List findByIdIn(Set ids); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/JobRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/JobRepository.java new file mode 100644 index 0000000..d804309 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/JobRepository.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.Job; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.Set; + +/** +* +* 2019-03-29 +*/ +public interface JobRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name 名称 + * @return / + */ + Job findByName(String name); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/MenuRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/MenuRepository.java new file mode 100644 index 0000000..ac1e524 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/MenuRepository.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.Menu; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * + * 2018-12-17 + */ +public interface MenuRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据菜单标题查询 + * @param title 菜单标题 + * @return / + */ + Menu findByTitle(String title); + + /** + * 根据组件名称查询 + * @param name 组件名称 + * @return / + */ + Menu findByComponentName(String name); + + /** + * 根据菜单的 PID 查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 查询顶级菜单 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID与菜单类型查询菜单 + * @param roleIds roleIDs + * @param type 类型 + * @return / + */ + @Query(value = "SELECT m.* FROM sys_menu m, sys_roles_menus r WHERE " + + "m.menu_id = r.menu_id AND r.role_id IN ?1 AND type != ?2 order by m.menu_sort asc",nativeQuery = true) + LinkedHashSet findByRoleIdsAndTypeNot(Set roleIds, int type); + + /** + * 获取节点数量 + * @param id / + * @return / + */ + int countByPid(Long id); + + /** + * 更新节点数目 + * @param count / + * @param menuId / + */ + @Modifying + @Query(value = " update sys_menu set sub_count = ?1 where menu_id = ?2 ",nativeQuery = true) + void updateSubCntById(int count, Long menuId); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/RoleRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/RoleRepository.java new file mode 100644 index 0000000..dd6e48b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/RoleRepository.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.Role; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Set; + +/** + * + * 2018-12-03 + */ +public interface RoleRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name / + * @return / + */ + Role findByName(String name); + + /** + * 删除多个角色 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_users_roles u WHERE " + + "r.role_id = u.role_id AND u.user_id = ?1",nativeQuery = true) + Set findByUserId(Long id); + + /** + * 解绑角色菜单 + * @param id 菜单ID + */ + @Modifying + @Query(value = "delete from sys_roles_menus where menu_id = ?1",nativeQuery = true) + void untiedMenu(Long id); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "select count(1) from sys_role r, sys_roles_depts d where " + + "r.role_id = d.role_id and d.dept_id in ?1",nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_roles_menus m WHERE " + + "r.role_id = m.role_id AND m.menu_id in ?1",nativeQuery = true) + List findInMenuId(List menuIds); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/UserRepository.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/UserRepository.java new file mode 100644 index 0000000..620b247 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/repository/UserRepository.java @@ -0,0 +1,130 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.repository; + +import com.example.modules.system.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.Date; +import java.util.List; +import java.util.Set; + +/** + * + * 2018-11-22 + */ +public interface UserRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据用户名查询 + * @param username 用户名 + * @return / + */ + User findByUsername(String username); + + /** + * 根据邮箱查询 + * @param email 邮箱 + * @return / + */ + User findByEmail(String email); + + /** + * 根据手机号查询 + * @param phone 手机号 + * @return / + */ + User findByPhone(String phone); + + /** + * 修改密码 + * @param username 用户名 + * @param pass 密码 + * @param lastPasswordResetTime / + */ + @Modifying + @Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where username = ?1",nativeQuery = true) + void updatePass(String username, String pass, Date lastPasswordResetTime); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + @Modifying + @Query(value = "update sys_user set email = ?2 where username = ?1",nativeQuery = true) + void updateEmail(String username, String email); + + /** + * 根据角色查询用户 + * @param roleId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r WHERE" + + " u.user_id = r.user_id AND r.role_id = ?1", nativeQuery = true) + List findByRoleId(Long roleId); + + /** + * 根据角色中的部门查询 + * @param deptId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r, sys_roles_depts d WHERE " + + "u.user_id = r.user_id AND r.role_id = d.role_id AND d.dept_id = ?1 group by u.user_id", nativeQuery = true) + List findByRoleDeptId(Long deptId); + + /** + * 根据菜单查询 + * @param id 菜单ID + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles ur, sys_roles_menus rm WHERE\n" + + "u.user_id = ur.user_id AND ur.role_id = rm.role_id AND rm.menu_id = ?1 group by u.user_id", nativeQuery = true) + List findByMenuId(Long id); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据岗位查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_jobs j WHERE u.user_id = j.user_id AND j.job_id IN ?1", nativeQuery = true) + int countByJobs(Set ids); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u WHERE u.dept_id IN ?1", nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据角色查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_roles r WHERE " + + "u.user_id = r.user_id AND r.role_id in ?1", nativeQuery = true) + int countByRoles(Set ids); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DataService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DataService.java new file mode 100644 index 0000000..de01bd9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DataService.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.service.dto.UserDto; +import java.util.List; + +/** + * 数据权限服务类 + * + * 2020-05-07 + */ +public interface DataService { + + /** + * 获取数据权限 + * @param user / + * @return / + */ + List getDeptIds(UserDto user); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DeptService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DeptService.java new file mode 100644 index 0000000..24f6138 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DeptService.java @@ -0,0 +1,124 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.Dept; +import com.example.modules.system.service.dto.DeptDto; +import com.example.modules.system.service.dto.DeptQueryCriteria; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* +* 2019-03-25 +*/ +public interface DeptService { + + /** + * 查询所有数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DeptDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(Dept resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dept resources); + + /** + * 删除 + * @param deptDtos / + * + */ + void delete(Set deptDtos); + + /** + * 根据PID查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 根据角色ID查询 + * @param id / + * @return / + */ + Set findByRoleId(Long id); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取待删除的部门 + * @param deptList / + * @param deptDtos / + * @return / + */ + Set getDeleteDepts(List deptList, Set deptDtos); + + /** + * 根据ID获取同级与上级数据 + * @param deptDto / + * @param depts / + * @return / + */ + List getSuperior(DeptDto deptDto, List depts); + + /** + * 构建树形数据 + * @param deptDtos / + * @return / + */ + Object buildTree(List deptDtos); + + /** + * 获取 + * @param deptList + * @return + */ + List getDeptChildren(List deptList); + + /** + * 验证是否被角色或用户关联 + * @param deptDtos / + */ + void verification(Set deptDtos); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictDetailService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictDetailService.java new file mode 100644 index 0000000..57e5a7f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictDetailService.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.DictDetail; +import com.example.modules.system.service.dto.DictDetailDto; +import com.example.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; +import java.util.List; +import java.util.Map; + +/** +* +* 2019-04-10 +*/ +public interface DictDetailService { + + /** + * 创建 + * @param resources / + */ + void create(DictDetail resources); + + /** + * 编辑 + * @param resources / + */ + void update(DictDetail resources); + + /** + * 删除 + * @param id / + */ + void delete(Long id); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable); + + /** + * 根据字典名称获取字典详情 + * @param name 字典名称 + * @return / + */ + List getDictByName(String name); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictService.java new file mode 100644 index 0000000..8cf7e9c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/DictService.java @@ -0,0 +1,75 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.Dict; +import com.example.modules.system.service.dto.DictDto; +import com.example.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* +* 2019-04-10 +*/ +public interface DictService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param dict / + * @return / + */ + List queryAll(DictQueryCriteria dict); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Dict resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dict resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/JobService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/JobService.java new file mode 100644 index 0000000..2fc99b6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/JobService.java @@ -0,0 +1,88 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.Job; +import com.example.modules.system.service.dto.JobDto; +import com.example.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* +* 2019-03-29 +*/ +public interface JobService { + + /** + * 根据ID查询 + * @param id / + * @return / + */ + JobDto findById(Long id); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Job resources); + + /** + * 编辑 + * @param resources / + */ + void update(Job resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(JobQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria / + * @return / + */ + List queryAll(JobQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MenuService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MenuService.java new file mode 100644 index 0000000..4706705 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MenuService.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.Menu; +import com.example.modules.system.service.dto.MenuDto; +import com.example.modules.system.service.dto.MenuQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * + * 2018-12-17 + */ +public interface MenuService { + + /** + * 查询全部数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + MenuDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Menu resources); + + /** + * 编辑 + * @param resources / + */ + void update(Menu resources); + + /** + * 获取所有子节点,包含自身ID + * @param menuList / + * @param menuSet / + * @return / + */ + Set getChildMenus(List menuList, Set menuSet); + + /** + * 构建菜单树 + * @param menuDtos 原始数据 + * @return / + */ + List buildTree(List menuDtos); + + /** + * 构建菜单树 + * @param menuDtos / + * @return / + */ + Object buildMenus(List menuDtos); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + Menu findOne(Long id); + + /** + * 删除 + * @param menuSet / + */ + void delete(Set menuSet); + + /** + * 导出 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 懒加载菜单数据 + * @param pid / + * @return / + */ + List getMenus(Long pid); + + /** + * 根据ID获取同级与上级数据 + * @param menuDto / + * @param objects / + * @return / + */ + List getSuperior(MenuDto menuDto, List objects); + + /** + * 根据当前用户获取菜单 + * @param currentUserId / + * @return / + */ + List findByUser(Long currentUserId); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MonitorService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MonitorService.java new file mode 100644 index 0000000..d9f87f9 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/MonitorService.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import java.util.Map; + +/** + * + * 2020-05-02 + */ +public interface MonitorService { + + /** + * 查询数据分页 + * @return Map + */ + Map getServers(); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/RoleService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/RoleService.java new file mode 100644 index 0000000..5fa13ca --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/RoleService.java @@ -0,0 +1,136 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.Role; +import com.example.modules.system.service.dto.RoleDto; +import com.example.modules.system.service.dto.RoleQueryCriteria; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.modules.system.service.dto.UserDto; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.GrantedAuthority; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * + * 2018-12-03 + */ +public interface RoleService { + + /** + * 查询全部数据 + * @return / + */ + List queryAll(); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + RoleDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Role resources); + + /** + * 编辑 + * @param resources / + */ + void update(Role resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + List findByUsersId(Long id); + + /** + * 根据角色查询角色级别 + * @param roles / + * @return / + */ + Integer findByRoles(Set roles); + + /** + * 修改绑定的菜单 + * @param resources / + * @param roleDTO / + */ + void updateMenu(Role resources, RoleDto roleDTO); + + /** + * 解绑菜单 + * @param id / + */ + void untiedMenu(Long id); + + /** + * 待条件分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(RoleQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(RoleQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取用户权限信息 + * @param user 用户信息 + * @return 权限信息 + */ + List mapToGrantedAuthorities(UserDto user); + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + List findInMenuId(List menuIds); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/UserService.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/UserService.java new file mode 100644 index 0000000..10fba88 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/UserService.java @@ -0,0 +1,114 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service; + +import com.example.modules.system.domain.User; +import com.example.modules.system.service.dto.UserDto; +import com.example.modules.system.service.dto.UserQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public interface UserService { + + /** + * 根据ID查询 + * @param id ID + * @return / + */ + UserDto findById(long id); + + /** + * 新增用户 + * @param resources / + */ + void create(User resources); + + /** + * 编辑用户 + * @param resources / + * @throws Exception / + */ + void update(User resources) throws Exception; + + /** + * 删除用户 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户名查询 + * @param userName / + * @return / + */ + UserDto findByName(String userName); + + /** + * 修改密码 + * @param username 用户名 + * @param encryptPassword 密码 + */ + void updatePass(String username, String encryptPassword); + + /** + * 修改头像 + * @param file 文件 + * @return / + */ + Map updateAvatar(MultipartFile file); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + void updateEmail(String username, String email); + + /** + * 查询全部 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(UserQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部不分页 + * @param criteria 条件 + * @return / + */ + List queryAll(UserQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 用户自助修改资料 + * @param resources / + */ + void updateCenter(User resources); +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptDto.java new file mode 100644 index 0000000..02ec1ea --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptDto.java @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** +* +* 2019-03-25 +*/ +@Getter +@Setter +public class DeptDto extends BaseDTO implements Serializable { + + private Long id; + + private String name; + + private Boolean enabled; + + private Integer deptSort; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + private Long pid; + + private Integer subCount; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeptDto deptDto = (DeptDto) o; + return Objects.equals(id, deptDto.id) && + Objects.equals(name, deptDto.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptQueryCriteria.java new file mode 100644 index 0000000..8f8c56b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptQueryCriteria.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.DataPermission; +import com.example.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* +* 2019-03-25 +*/ +@Data +@DataPermission(fieldName = "id") +public class DeptQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query + private Long pid; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptSmallDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptSmallDto.java new file mode 100644 index 0000000..503762b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DeptSmallDto.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import java.io.Serializable; + +/** +* +* 2019-6-10 16:32:18 +*/ +@Data +public class DeptSmallDto implements Serializable { + + private Long id; + + private String name; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailDto.java new file mode 100644 index 0000000..58e826b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailDto.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; + +/** +* +* 2019-04-10 +*/ +@Getter +@Setter +public class DictDetailDto extends BaseDTO implements Serializable { + + private Long id; + + private DictSmallDto dict; + + private String label; + + private String value; + + private Integer dictSort; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailQueryCriteria.java new file mode 100644 index 0000000..2f12c80 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDetailQueryCriteria.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.Query; + +/** +* +* 2019-04-10 +*/ +@Data +public class DictDetailQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String label; + + @Query(propName = "name",joinName = "dict") + private String dictName; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDto.java new file mode 100644 index 0000000..72f704e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictDto.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; +import java.util.List; + +/** +* +* 2019-04-10 +*/ +@Getter +@Setter +public class DictDto extends BaseDTO implements Serializable { + + private Long id; + + private List dictDetails; + + private String name; + + private String description; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictQueryCriteria.java new file mode 100644 index 0000000..3a5da52 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictQueryCriteria.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.Query; + +/** + * + * 公共查询类 + */ +@Data +public class DictQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictSmallDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictSmallDto.java new file mode 100644 index 0000000..a0ed61f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/DictSmallDto.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import java.io.Serializable; + +/** +* +* 2019-04-10 +*/ +@Getter +@Setter +public class DictSmallDto implements Serializable { + + private Long id; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobDto.java new file mode 100644 index 0000000..502176b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobDto.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import com.example.base.BaseDTO; + +import java.io.Serializable; + +/** +* +* 2019-03-29 +*/ +@Getter +@Setter +@NoArgsConstructor +public class JobDto extends BaseDTO implements Serializable { + + private Long id; + + private Integer jobSort; + + private String name; + + private Boolean enabled; + + public JobDto(String name, Boolean enabled) { + this.name = name; + this.enabled = enabled; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobQueryCriteria.java new file mode 100644 index 0000000..215d721 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobQueryCriteria.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import com.example.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* +* 2019-6-4 14:49:34 +*/ +@Data +@NoArgsConstructor +public class JobQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobSmallDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobSmallDto.java new file mode 100644 index 0000000..af9f8a6 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/JobSmallDto.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; + +/** +* +* 2019-6-10 16:32:18 +*/ +@Data +@NoArgsConstructor +public class JobSmallDto implements Serializable { + + private Long id; + + private String name; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuDto.java new file mode 100644 index 0000000..8500654 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuDto.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** + * + * 2018-12-17 + */ +@Getter +@Setter +public class MenuDto extends BaseDTO implements Serializable { + + private Long id; + + private List children; + + private Integer type; + + private String permission; + + private String title; + + private Integer menuSort; + + private String path; + + private String component; + + private Long pid; + + private Integer subCount; + + private Boolean iFrame; + + private Boolean cache; + + private Boolean hidden; + + private String componentName; + + private String icon; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return title; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MenuDto menuDto = (MenuDto) o; + return Objects.equals(id, menuDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuQueryCriteria.java new file mode 100644 index 0000000..1d03860 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/MenuQueryCriteria.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * + * 公共查询类 + */ +@Data +public class MenuQueryCriteria { + + @Query(blurry = "title,component,permission") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query + private Long pid; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleDto.java new file mode 100644 index 0000000..1373b7f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleDto.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + + +@Getter +@Setter +public class RoleDto extends BaseDTO implements Serializable { + + private Long id; + + private Set menus; + + private Set depts; + + private String name; + + private String dataScope; + + private Integer level; + + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RoleDto roleDto = (RoleDto) o; + return Objects.equals(id, roleDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleQueryCriteria.java new file mode 100644 index 0000000..afe3a4e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleQueryCriteria.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * + * 公共查询类 + */ +@Data +public class RoleQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleSmallDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleSmallDto.java new file mode 100644 index 0000000..5c7f184 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/RoleSmallDto.java @@ -0,0 +1,32 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +@Data +public class RoleSmallDto implements Serializable { + + private Long id; + + private String name; + + private Integer level; + + private String dataScope; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserDto.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserDto.java new file mode 100644 index 0000000..a1ecd96 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserDto.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; +import com.example.base.BaseDTO; +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + + +@Getter +@Setter +public class UserDto extends BaseDTO implements Serializable { + + private Long id; + + private Set roles; + + private Set jobs; + + private DeptSmallDto dept; + + private Long deptId; + + private String username; + + private String nickName; + + private String email; + + private String phone; + + private String gender; + + private String avatarName; + + private String avatarPath; + + @JSONField(serialize = false) + private String password; + + private Boolean enabled; + + @JSONField(serialize = false) + private Boolean isAdmin = false; + + private Date pwdResetTime; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserQueryCriteria.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserQueryCriteria.java new file mode 100644 index 0000000..1f862cf --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/dto/UserQueryCriteria.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.dto; + +import lombok.Data; +import com.example.annotation.Query; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +@Data +public class UserQueryCriteria implements Serializable { + + @Query + private Long id; + + @Query(propName = "id", type = Query.Type.IN, joinName = "dept") + private Set deptIds = new HashSet<>(); + + @Query(blurry = "email,username,nickName") + private String blurry; + + @Query + private Boolean enabled; + + private Long deptId; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DataServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DataServiceImpl.java new file mode 100644 index 0000000..e31f26b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DataServiceImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import com.example.modules.system.domain.Dept; +import com.example.modules.system.service.DataService; +import com.example.modules.system.service.DeptService; +import lombok.RequiredArgsConstructor; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.modules.system.service.dto.UserDto; +import com.example.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import java.util.*; + +/** + * + * @website https://el-admin.vip + * @description 数据权限服务实现 + * 2020-05-07 + **/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "data") +public class DataServiceImpl implements DataService { + + private final RoleService roleService; + private final DeptService deptService; + + /** + * 用户角色改变时需清理缓存 + * @param user / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0.id") + public List getDeptIds(UserDto user) { + // 用于存储部门id + Set deptIds = new HashSet<>(); + // 查询用户角色 + List roleSet = roleService.findByUsersId(user.getId()); + // 获取对应的部门ID + for (RoleSmallDto role : roleSet) { + DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope()); + switch (Objects.requireNonNull(dataScopeEnum)) { + case THIS_LEVEL: + deptIds.add(user.getDept().getId()); + break; + case CUSTOMIZE: + deptIds.addAll(getCustomize(deptIds, role)); + break; + default: + return new ArrayList<>(deptIds); + } + } + return new ArrayList<>(deptIds); + } + + /** + * 获取自定义的数据权限 + * @param deptIds 部门ID + * @param role 角色 + * @return 数据权限ID + */ + public Set getCustomize(Set deptIds, RoleSmallDto role){ + Set depts = deptService.findByRoleId(role.getId()); + for (Dept dept : depts) { + deptIds.add(dept.getId()); + List deptChildren = deptService.findByPid(dept.getId()); + if (deptChildren != null && deptChildren.size() != 0) { + deptIds.addAll(deptService.getDeptChildren(deptChildren)); + } + } + return deptIds; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DeptServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DeptServiceImpl.java new file mode 100644 index 0000000..e777319 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DeptServiceImpl.java @@ -0,0 +1,284 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.example.modules.system.domain.Dept; +import com.example.modules.system.domain.User; +import com.example.modules.system.repository.DeptRepository; +import com.example.modules.system.repository.RoleRepository; +import com.example.modules.system.service.DeptService; +import com.example.modules.system.service.dto.DeptDto; +import com.example.modules.system.service.dto.DeptQueryCriteria; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.exception.BadRequestException; +import com.example.modules.system.repository.UserRepository; +import com.example.utils.*; +import com.example.modules.system.service.mapstruct.DeptMapper; +import com.example.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** +* +* 2019-03-25 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dept") +public class DeptServiceImpl implements DeptService { + + private final DeptRepository deptRepository; + private final DeptMapper deptMapper; + private final UserRepository userRepository; + private final RedisUtils redisUtils; + private final RoleRepository roleRepository; + + @Override + public List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "deptSort"); + String dataScopeType = SecurityUtils.getDataScopeType(); + if (isQuery) { + if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){ + criteria.setPidIsNull(true); + } + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + List fieldNames = new ArrayList(){{ add("pidIsNull");add("enabled");}}; + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if(fieldNames.contains(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + List list = deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + // 如果为空,就代表为自定义权限或者本级权限,就需要去重,不理解可以注释掉,看查询结果 + if(StringUtils.isBlank(dataScopeType)){ + return deduplication(list); + } + return list; + } + + @Override + @Cacheable(key = "'id:' + #p0") + public DeptDto findById(Long id) { + Dept dept = deptRepository.findById(id).orElseGet(Dept::new); + ValidationUtil.isNull(dept.getId(),"Dept","id",id); + return deptMapper.toDto(dept); + } + + @Override + public List findByPid(long pid) { + return deptRepository.findByPid(pid); + } + + @Override + public Set findByRoleId(Long id) { + return deptRepository.findByRoleId(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dept resources) { + deptRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 清理缓存 + updateSubCnt(resources.getPid()); + // 清理自定义角色权限的datascope缓存 + delCaches(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dept resources) { + // 旧的部门 + Long oldPid = findById(resources.getId()).getPid(); + Long newPid = resources.getPid(); + if(resources.getPid() != null && resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new); + ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId()); + resources.setId(dept.getId()); + deptRepository.save(resources); + // 更新父节点中子节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set deptDtos) { + for (DeptDto deptDto : deptDtos) { + // 清理缓存 + delCaches(deptDto.getId()); + deptRepository.deleteById(deptDto.getId()); + updateSubCnt(deptDto.getPid()); + } + } + + @Override + public void download(List deptDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DeptDto deptDTO : deptDtos) { + Map map = new LinkedHashMap<>(); + map.put("部门名称", deptDTO.getName()); + map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", deptDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public Set getDeleteDepts(List menuList, Set deptDtos) { + for (Dept dept : menuList) { + deptDtos.add(deptMapper.toDto(dept)); + List depts = deptRepository.findByPid(dept.getId()); + if(depts!=null && depts.size()!=0){ + getDeleteDepts(depts, deptDtos); + } + } + return deptDtos; + } + + @Override + public List getDeptChildren(List deptList) { + List list = new ArrayList<>(); + deptList.forEach(dept -> { + if (dept!=null && dept.getEnabled()) { + List depts = deptRepository.findByPid(dept.getId()); + if (depts.size() != 0) { + list.addAll(getDeptChildren(depts)); + } + list.add(dept.getId()); + } + } + ); + return list; + } + + @Override + public List getSuperior(DeptDto deptDto, List depts) { + if(deptDto.getPid() == null){ + depts.addAll(deptRepository.findByPidIsNull()); + return deptMapper.toDto(depts); + } + depts.addAll(deptRepository.findByPid(deptDto.getPid())); + return getSuperior(findById(deptDto.getPid()), depts); + } + + @Override + public Object buildTree(List deptDtos) { + Set trees = new LinkedHashSet<>(); + Set depts= new LinkedHashSet<>(); + List deptNames = deptDtos.stream().map(DeptDto::getName).collect(Collectors.toList()); + boolean isChild; + for (DeptDto deptDTO : deptDtos) { + isChild = false; + if (deptDTO.getPid() == null) { + trees.add(deptDTO); + } + for (DeptDto it : deptDtos) { + if (it.getPid() != null && deptDTO.getId().equals(it.getPid())) { + isChild = true; + if (deptDTO.getChildren() == null) { + deptDTO.setChildren(new ArrayList<>()); + } + deptDTO.getChildren().add(it); + } + } + if(isChild) { + depts.add(deptDTO); + } else if(deptDTO.getPid() != null && !deptNames.contains(findById(deptDTO.getPid()).getName())) { + depts.add(deptDTO); + } + } + + if (CollectionUtil.isEmpty(trees)) { + trees = depts; + } + Map map = new HashMap<>(2); + map.put("totalElements",deptDtos.size()); + map.put("content",CollectionUtil.isEmpty(trees)? deptDtos :trees); + return map; + } + + @Override + public void verification(Set deptDtos) { + Set deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet()); + if(userRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在用户关联,请解除后再试!"); + } + if(roleRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); + } + } + + private void updateSubCnt(Long deptId){ + if(deptId != null){ + int count = deptRepository.countByPid(deptId); + deptRepository.updateSubCntById(count, deptId); + } + } + + private List deduplication(List list) { + List deptDtos = new ArrayList<>(); + for (DeptDto deptDto : list) { + boolean flag = true; + for (DeptDto dto : list) { + if (dto.getId().equals(deptDto.getPid())) { + flag = false; + break; + } + } + if (flag){ + deptDtos.add(deptDto); + } + } + return deptDtos; + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id){ + List users = userRepository.findByRoleDeptId(id); + // 删除数据权限 + redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + redisUtils.del(CacheKey.DEPT_ID + id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictDetailServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictDetailServiceImpl.java new file mode 100644 index 0000000..672a31a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictDetailServiceImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import com.example.modules.system.domain.Dict; +import com.example.modules.system.domain.DictDetail; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.modules.system.repository.DictRepository; +import com.example.modules.system.service.dto.DictDetailQueryCriteria; +import com.example.utils.*; +import com.example.modules.system.repository.DictDetailRepository; +import com.example.modules.system.service.DictDetailService; +import com.example.modules.system.service.dto.DictDetailDto; +import com.example.modules.system.service.mapstruct.DictDetailMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.Map; + +/** +* +* 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictDetailServiceImpl implements DictDetailService { + + private final DictRepository dictRepository; + private final DictDetailRepository dictDetailRepository; + private final DictDetailMapper dictDetailMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable) { + Page page = dictDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(dictDetailMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(DictDetail resources) { + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(DictDetail resources) { + DictDetail dictDetail = dictDetailRepository.findById(resources.getId()).orElseGet(DictDetail::new); + ValidationUtil.isNull( dictDetail.getId(),"DictDetail","id",resources.getId()); + resources.setId(dictDetail.getId()); + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Cacheable(key = "'name:' + #p0") + public List getDictByName(String name) { + return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new); + // 清理缓存 + delCaches(dictDetail); + dictDetailRepository.deleteById(id); + } + + public void delCaches(DictDetail dictDetail){ + Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new); + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictServiceImpl.java new file mode 100644 index 0000000..79cd9e3 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/DictServiceImpl.java @@ -0,0 +1,122 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.example.modules.system.domain.Dict; +import com.example.modules.system.service.dto.DictDto; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.modules.system.service.dto.DictDetailDto; +import com.example.modules.system.service.dto.DictQueryCriteria; +import com.example.utils.*; +import com.example.modules.system.repository.DictRepository; +import com.example.modules.system.service.DictService; +import com.example.modules.system.service.mapstruct.DictMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* +* 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictServiceImpl implements DictService { + + private final DictRepository dictRepository; + private final DictMapper dictMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictQueryCriteria dict, Pageable pageable){ + Page page = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable); + return PageUtil.toPage(page.map(dictMapper::toDto)); + } + + @Override + public List queryAll(DictQueryCriteria dict) { + List list = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb)); + return dictMapper.toDto(list); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dict resources) { + dictRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dict resources) { + // 清理缓存 + delCaches(resources); + Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new); + ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId()); + dict.setName(resources.getName()); + dict.setDescription(resources.getDescription()); + dictRepository.save(dict); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + // 清理缓存 + List dicts = dictRepository.findByIdIn(ids); + for (Dict dict : dicts) { + delCaches(dict); + } + dictRepository.deleteByIdIn(ids); + } + + @Override + public void download(List dictDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DictDto dictDTO : dictDtos) { + if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){ + for (DictDetailDto dictDetail : dictDTO.getDictDetails()) { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", dictDetail.getLabel()); + map.put("字典值", dictDetail.getValue()); + map.put("创建日期", dictDetail.getCreateTime()); + list.add(map); + } + } else { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", null); + map.put("字典值", null); + map.put("创建日期", dictDTO.getCreateTime()); + list.add(map); + } + } + FileUtil.downloadExcel(list, response); + } + + public void delCaches(Dict dict){ + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/JobServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/JobServiceImpl.java new file mode 100644 index 0000000..73c93c5 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/JobServiceImpl.java @@ -0,0 +1,126 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import com.example.modules.system.domain.Job; +import com.example.modules.system.service.JobService; +import com.example.modules.system.service.dto.JobDto; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.exception.BadRequestException; +import com.example.exception.EntityExistException; +import com.example.modules.system.repository.UserRepository; +import com.example.modules.system.service.dto.JobQueryCriteria; +import com.example.utils.*; +import com.example.modules.system.repository.JobRepository; +import com.example.modules.system.service.mapstruct.JobMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* +* 2019-03-29 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "job") +public class JobServiceImpl implements JobService { + + private final JobRepository jobRepository; + private final JobMapper jobMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + + @Override + public Map queryAll(JobQueryCriteria criteria, Pageable pageable) { + Page page = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(jobMapper::toDto).getContent(),page.getTotalElements()); + } + + @Override + public List queryAll(JobQueryCriteria criteria) { + List list = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + return jobMapper.toDto(list); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public JobDto findById(Long id) { + Job job = jobRepository.findById(id).orElseGet(Job::new); + ValidationUtil.isNull(job.getId(),"Job","id",id); + return jobMapper.toDto(job); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Job resources) { + Job job = jobRepository.findByName(resources.getName()); + if(job != null){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + jobRepository.save(resources); + } + + @Override + @CacheEvict(key = "'id:' + #p0.id") + @Transactional(rollbackFor = Exception.class) + public void update(Job resources) { + Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new); + Job old = jobRepository.findByName(resources.getName()); + if(old != null && !old.getId().equals(resources.getId())){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + ValidationUtil.isNull( job.getId(),"Job","id",resources.getId()); + resources.setId(job.getId()); + jobRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + jobRepository.deleteAllByIdIn(ids); + // 删除缓存 + redisUtils.delByKeys(CacheKey.JOB_ID, ids); + } + + @Override + public void download(List jobDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (JobDto jobDTO : jobDtos) { + Map map = new LinkedHashMap<>(); + map.put("岗位名称", jobDTO.getName()); + map.put("岗位状态", jobDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", jobDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if(userRepository.countByJobs(ids) > 0){ + throw new BadRequestException("所选的岗位中存在用户关联,请解除关联再试!"); + } + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MenuServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MenuServiceImpl.java new file mode 100644 index 0000000..ceacddb --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MenuServiceImpl.java @@ -0,0 +1,356 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.example.modules.system.domain.Menu; +import com.example.modules.system.domain.Role; +import com.example.modules.system.domain.User; +import com.example.modules.system.domain.vo.MenuMetaVo; +import com.example.modules.system.domain.vo.MenuVo; +import com.example.modules.system.repository.MenuRepository; +import com.example.modules.system.service.MenuService; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.dto.MenuDto; +import com.example.modules.system.service.dto.MenuQueryCriteria; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.exception.BadRequestException; +import com.example.exception.EntityExistException; +import com.example.modules.system.repository.UserRepository; +import com.example.modules.system.service.mapstruct.MenuMapper; +import com.example.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "menu") +public class MenuServiceImpl implements MenuService { + + private final MenuRepository menuRepository; + private final UserRepository userRepository; + private final MenuMapper menuMapper; + private final RoleService roleService; + private final RedisUtils redisUtils; + + @Override + public List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "menuSort"); + if(Boolean.TRUE.equals(isQuery)){ + criteria.setPidIsNull(true); + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if("pidIsNull".equals(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public MenuDto findById(long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menuMapper.toDto(menu); + } + + /** + * 用户角色改变时需清理缓存 + * @param currentUserId / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0") + public List findByUser(Long currentUserId) { + List roles = roleService.findByUsersId(currentUserId); + Set roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet()); + LinkedHashSet menus = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2); + return menus.stream().map(menuMapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Menu resources) { + if(menuRepository.findByTitle(resources.getTitle()) != null){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + if(StringUtils.isNotBlank(resources.getComponentName())){ + if(menuRepository.findByComponentName(resources.getComponentName()) != null){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + menuRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 更新父节点菜单数目 + updateSubCnt(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Menu resources) { + if(resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId()); + + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + Menu menu1 = menuRepository.findByTitle(resources.getTitle()); + + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + + // 记录的父节点ID + Long oldPid = menu.getPid(); + Long newPid = resources.getPid(); + + if(StringUtils.isNotBlank(resources.getComponentName())){ + menu1 = menuRepository.findByComponentName(resources.getComponentName()); + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + menu.setTitle(resources.getTitle()); + menu.setComponent(resources.getComponent()); + menu.setPath(resources.getPath()); + menu.setIcon(resources.getIcon()); + menu.setIFrame(resources.getIFrame()); + menu.setPid(resources.getPid()); + menu.setMenuSort(resources.getMenuSort()); + menu.setCache(resources.getCache()); + menu.setHidden(resources.getHidden()); + menu.setComponentName(resources.getComponentName()); + menu.setPermission(resources.getPermission()); + menu.setType(resources.getType()); + menuRepository.save(menu); + // 计算父级菜单节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + public Set getChildMenus(List menuList, Set menuSet) { + for (Menu menu : menuList) { + menuSet.add(menu); + List menus = menuRepository.findByPid(menu.getId()); + if(menus!=null && menus.size()!=0){ + getChildMenus(menus, menuSet); + } + } + return menuSet; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set menuSet) { + for (Menu menu : menuSet) { + // 清理缓存 + delCaches(menu.getId()); + roleService.untiedMenu(menu.getId()); + menuRepository.deleteById(menu.getId()); + updateSubCnt(menu.getPid()); + } + } + + @Override + public List getMenus(Long pid) { + List menus; + if(pid != null && !pid.equals(0L)){ + menus = menuRepository.findByPid(pid); + } else { + menus = menuRepository.findByPidIsNull(); + } + return menuMapper.toDto(menus); + } + + @Override + public List getSuperior(MenuDto menuDto, List menus) { + if(menuDto.getPid() == null){ + menus.addAll(menuRepository.findByPidIsNull()); + return menuMapper.toDto(menus); + } + menus.addAll(menuRepository.findByPid(menuDto.getPid())); + return getSuperior(findById(menuDto.getPid()), menus); + } + + @Override + public List buildTree(List menuDtos) { + List trees = new ArrayList<>(); + Set ids = new HashSet<>(); + for (MenuDto menuDTO : menuDtos) { + if (menuDTO.getPid() == null) { + trees.add(menuDTO); + } + for (MenuDto it : menuDtos) { + if (menuDTO.getId().equals(it.getPid())) { + if (menuDTO.getChildren() == null) { + menuDTO.setChildren(new ArrayList<>()); + } + menuDTO.getChildren().add(it); + ids.add(it.getId()); + } + } + } + if(trees.size() == 0){ + trees = menuDtos.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList()); + } + return trees; + } + + @Override + public List buildMenus(List menuDtos) { + List list = new LinkedList<>(); + menuDtos.forEach(menuDTO -> { + if (menuDTO!=null){ + List menuDtoList = menuDTO.getChildren(); + MenuVo menuVo = new MenuVo(); + menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getTitle()); + // 一级目录需要加斜杠,不然会报警告 + menuVo.setPath(menuDTO.getPid() == null ? "/" + menuDTO.getPath() :menuDTO.getPath()); + menuVo.setHidden(menuDTO.getHidden()); + // 如果不是外链 + if(!menuDTO.getIFrame()){ + if(menuDTO.getPid() == null){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent()); + // 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单 + }else if(menuDTO.getType() == 0){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"ParentView":menuDTO.getComponent()); + }else if(StringUtils.isNoneBlank(menuDTO.getComponent())){ + menuVo.setComponent(menuDTO.getComponent()); + } + } + menuVo.setMeta(new MenuMetaVo(menuDTO.getTitle(),menuDTO.getIcon(),!menuDTO.getCache())); + if(CollectionUtil.isNotEmpty(menuDtoList)){ + menuVo.setAlwaysShow(true); + menuVo.setRedirect("noredirect"); + menuVo.setChildren(buildMenus(menuDtoList)); + // 处理是一级菜单并且没有子菜单的情况 + } else if(menuDTO.getPid() == null){ + MenuVo menuVo1 = new MenuVo(); + menuVo1.setMeta(menuVo.getMeta()); + // 非外链 + if(!menuDTO.getIFrame()){ + menuVo1.setPath("index"); + menuVo1.setName(menuVo.getName()); + menuVo1.setComponent(menuVo.getComponent()); + } else { + menuVo1.setPath(menuDTO.getPath()); + } + menuVo.setName(null); + menuVo.setMeta(null); + menuVo.setComponent("Layout"); + List list1 = new ArrayList<>(); + list1.add(menuVo1); + menuVo.setChildren(list1); + } + list.add(menuVo); + } + } + ); + return list; + } + + @Override + public Menu findOne(Long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menu; + } + + @Override + public void download(List menuDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (MenuDto menuDTO : menuDtos) { + Map map = new LinkedHashMap<>(); + map.put("菜单标题", menuDTO.getTitle()); + map.put("菜单类型", menuDTO.getType() == null ? "目录" : menuDTO.getType() == 1 ? "菜单" : "按钮"); + map.put("权限标识", menuDTO.getPermission()); + map.put("外链菜单", menuDTO.getIFrame() ? "是" : "否"); + map.put("菜单可见", menuDTO.getHidden() ? "否" : "是"); + map.put("是否缓存", menuDTO.getCache() ? "是" : "否"); + map.put("创建日期", menuDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + private void updateSubCnt(Long menuId){ + if(menuId != null){ + int count = menuRepository.countByPid(menuId); + menuRepository.updateSubCntById(count, menuId); + } + } + + /** + * 清理缓存 + * @param id 菜单ID + */ + public void delCaches(Long id){ + List users = userRepository.findByMenuId(id); + redisUtils.del(CacheKey.MENU_ID + id); + redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + // 清除 Role 缓存 + List roles = roleService.findInMenuId(new ArrayList(){{ + add(id); + }}); + redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet())); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MonitorServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MonitorServiceImpl.java new file mode 100644 index 0000000..c279293 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/MonitorServiceImpl.java @@ -0,0 +1,186 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import cn.hutool.core.date.BetweenFormater; +import cn.hutool.core.date.DateUtil; +import com.example.modules.system.service.MonitorService; +import com.example.utils.ElAdminConstant; +import com.example.utils.FileUtil; +import com.example.utils.StringUtils; +import org.springframework.stereotype.Service; +import oshi.SystemInfo; +import oshi.hardware.*; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.FormatUtil; +import oshi.util.Util; +import java.lang.management.ManagementFactory; +import java.text.DecimalFormat; +import java.util.*; + +/** +* +* 2020-05-02 +*/ +@Service +public class MonitorServiceImpl implements MonitorService { + + private final DecimalFormat df = new DecimalFormat("0.00"); + + @Override + public Map getServers(){ + Map resultMap = new LinkedHashMap<>(8); + try { + SystemInfo si = new SystemInfo(); + OperatingSystem os = si.getOperatingSystem(); + HardwareAbstractionLayer hal = si.getHardware(); + // 系统信息 + resultMap.put("sys", getSystemInfo(os)); + // cpu 信息 + resultMap.put("cpu", getCpuInfo(hal.getProcessor())); + // 内存信息 + resultMap.put("memory", getMemoryInfo(hal.getMemory())); + // 交换区信息 + resultMap.put("swap", getSwapInfo(hal.getMemory())); + // 磁盘 + resultMap.put("disk", getDiskInfo(os)); + resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss")); + } catch (Exception e) { + e.printStackTrace(); + } + return resultMap; + } + + /** + * 获取磁盘信息 + * @return / + */ + private Map getDiskInfo(OperatingSystem os) { + Map diskInfo = new LinkedHashMap<>(); + FileSystem fileSystem = os.getFileSystem(); + List fsArray = fileSystem.getFileStores(); + String osName = System.getProperty("os.name"); + long available = 0, total = 0; + for (OSFileStore fs : fsArray){ + // windows 需要将所有磁盘分区累加,linux 和 mac 直接累加会出现磁盘重复的问题,待修复 + if(osName.toLowerCase().startsWith(ElAdminConstant.WIN)) { + available += fs.getUsableSpace(); + total += fs.getTotalSpace(); + } else { + available = fs.getUsableSpace(); + total = fs.getTotalSpace(); + break; + } + } + long used = total - available; + diskInfo.put("total", total > 0 ? FileUtil.getSize(total) : "?"); + diskInfo.put("available", FileUtil.getSize(available)); + diskInfo.put("used", FileUtil.getSize(used)); + if(total != 0){ + diskInfo.put("usageRate", df.format(used/(double)total * 100)); + } else { + diskInfo.put("usageRate", 0); + } + return diskInfo; + } + + /** + * 获取交换区信息 + * @param memory / + * @return / + */ + private Map getSwapInfo(GlobalMemory memory) { + Map swapInfo = new LinkedHashMap<>(); + VirtualMemory virtualMemory = memory.getVirtualMemory(); + long total = virtualMemory.getSwapTotal(); + long used = virtualMemory.getSwapUsed(); + swapInfo.put("total", FormatUtil.formatBytes(total)); + swapInfo.put("used", FormatUtil.formatBytes(used)); + swapInfo.put("available", FormatUtil.formatBytes(total - used)); + if(used == 0){ + swapInfo.put("usageRate", 0); + } else { + swapInfo.put("usageRate", df.format(used/(double)total * 100)); + } + return swapInfo; + } + + /** + * 获取内存信息 + * @param memory / + * @return / + */ + private Map getMemoryInfo(GlobalMemory memory) { + Map memoryInfo = new LinkedHashMap<>(); + memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal())); + memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); + memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); + memoryInfo.put("usageRate", df.format((memory.getTotal() - memory.getAvailable())/(double)memory.getTotal() * 100)); + return memoryInfo; + } + + /** + * 获取Cpu相关信息 + * @param processor / + * @return / + */ + private Map getCpuInfo(CentralProcessor processor) { + Map cpuInfo = new LinkedHashMap<>(); + cpuInfo.put("name", processor.getProcessorIdentifier().getName()); + cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU"); + cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心"); + cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount()); + cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); + // CPU信息 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + // 等待1秒... + Util.sleep(1000); + long[] ticks = processor.getSystemCpuLoadTicks(); + long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; + long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; + long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; + long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; + long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; + long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; + long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; + long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal; + cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu)); + cpuInfo.put("idle", df.format(100d * idle / totalCpu)); + return cpuInfo; + } + + /** + * 获取系统相关信息,系统、运行天数、系统IP + * @param os / + * @return / + */ + private Map getSystemInfo(OperatingSystem os){ + Map systemInfo = new LinkedHashMap<>(); + // jvm 运行时间 + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + Date date = new Date(time); + // 计算项目运行时间 + String formatBetween = DateUtil.formatBetween(date, new Date(),BetweenFormater.Level.HOUR); + // 系统信息 + systemInfo.put("os", os.toString()); + systemInfo.put("day", formatBetween); + systemInfo.put("ip", StringUtils.getLocalIp()); + return systemInfo; + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/RoleServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..4a54a8c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/RoleServiceImpl.java @@ -0,0 +1,227 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.example.modules.system.domain.Menu; +import com.example.modules.system.domain.Role; +import com.example.modules.system.domain.User; +import com.example.modules.system.service.dto.RoleDto; +import com.example.modules.system.service.dto.RoleQueryCriteria; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.exception.BadRequestException; +import com.example.modules.security.service.UserCacheClean; +import com.example.exception.EntityExistException; +import com.example.modules.system.repository.RoleRepository; +import com.example.modules.system.repository.UserRepository; +import com.example.modules.system.service.RoleService; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.modules.system.service.dto.UserDto; +import com.example.modules.system.service.mapstruct.RoleMapper; +import com.example.modules.system.service.mapstruct.RoleSmallMapper; +import com.example.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * + * 2018-12-03 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "role") +public class RoleServiceImpl implements RoleService { + + private final RoleRepository roleRepository; + private final RoleMapper roleMapper; + private final RoleSmallMapper roleSmallMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + private final UserCacheClean userCacheClean; + + @Override + public List queryAll() { + Sort sort = Sort.by(Sort.Direction.ASC, "level"); + return roleMapper.toDto(roleRepository.findAll(sort)); + } + + @Override + public List queryAll(RoleQueryCriteria criteria) { + return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) { + Page page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(roleMapper::toDto)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public RoleDto findById(long id) { + Role role = roleRepository.findById(id).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", id); + return roleMapper.toDto(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Role resources) { + if (roleRepository.findByName(resources.getName()) != null) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + roleRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Role resources) { + Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", resources.getId()); + + Role role1 = roleRepository.findByName(resources.getName()); + + if (role1 != null && !role1.getId().equals(role.getId())) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + role.setName(resources.getName()); + role.setDescription(resources.getDescription()); + role.setDataScope(resources.getDataScope()); + role.setDepts(resources.getDepts()); + role.setLevel(resources.getLevel()); + roleRepository.save(role); + // 更新相关缓存 + delCaches(role.getId(), null); + } + + @Override + public void updateMenu(Role resources, RoleDto roleDTO) { + Role role = roleMapper.toEntity(roleDTO); + List users = userRepository.findByRoleId(role.getId()); + // 更新菜单 + role.setMenus(resources.getMenus()); + delCaches(resources.getId(), users); + roleRepository.save(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void untiedMenu(Long menuId) { + // 更新菜单 + roleRepository.untiedMenu(menuId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 更新相关缓存 + delCaches(id, null); + } + roleRepository.deleteAllByIdIn(ids); + } + + @Override + public List findByUsersId(Long id) { + return roleSmallMapper.toDto(new ArrayList<>(roleRepository.findByUserId(id))); + } + + @Override + public Integer findByRoles(Set roles) { + if (roles.size() == 0) { + return Integer.MAX_VALUE; + } + Set roleDtos = new HashSet<>(); + for (Role role : roles) { + roleDtos.add(findById(role.getId())); + } + return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList())); + } + + @Override + @Cacheable(key = "'auth:' + #p0.id") + public List mapToGrantedAuthorities(UserDto user) { + Set permissions = new HashSet<>(); + // 如果是管理员直接返回 + if (user.getIsAdmin()) { + permissions.add("admin"); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + Set roles = roleRepository.findByUserId(user.getId()); + permissions = roles.stream().flatMap(role -> role.getMenus().stream()) + .filter(menu -> StringUtils.isNotBlank(menu.getPermission())) + .map(Menu::getPermission).collect(Collectors.toSet()); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + + @Override + public void download(List roles, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (RoleDto role : roles) { + Map map = new LinkedHashMap<>(); + map.put("角色名称", role.getName()); + map.put("角色级别", role.getLevel()); + map.put("描述", role.getDescription()); + map.put("创建日期", role.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if (userRepository.countByRoles(ids) > 0) { + throw new BadRequestException("所选角色存在用户关联,请解除关联再试!"); + } + } + + @Override + public List findInMenuId(List menuIds) { + return roleRepository.findInMenuId(menuIds); + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id, List users) { + users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users; + if (CollectionUtil.isNotEmpty(users)) { + users.forEach(item -> userCacheClean.cleanUserCache(item.getUsername())); + Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); + redisUtils.delByKeys(CacheKey.DATA_USER, userIds); + redisUtils.delByKeys(CacheKey.MENU_USER, userIds); + redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + } + redisUtils.del(CacheKey.ROLE_ID + id); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/UserServiceImpl.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..6b86b77 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/impl/UserServiceImpl.java @@ -0,0 +1,255 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.impl; + +import com.example.modules.system.domain.User; +import com.example.modules.system.service.UserService; +import com.example.modules.system.service.dto.JobSmallDto; +import com.example.modules.system.service.dto.UserQueryCriteria; +import com.example.utils.*; +import lombok.RequiredArgsConstructor; +import com.example.config.FileProperties; +import com.example.exception.BadRequestException; +import com.example.modules.security.service.OnlineUserService; +import com.example.modules.security.service.UserCacheClean; +import com.example.exception.EntityExistException; +import com.example.exception.EntityNotFoundException; +import com.example.modules.system.repository.UserRepository; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.modules.system.service.dto.UserDto; +import com.example.modules.system.service.mapstruct.UserMapper; +import com.example.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotBlank; +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + + +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "user") +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + private final UserMapper userMapper; + private final FileProperties properties; + private final RedisUtils redisUtils; + private final UserCacheClean userCacheClean; + private final OnlineUserService onlineUserService; + + @Override + public Object queryAll(UserQueryCriteria criteria, Pageable pageable) { + Page page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(userMapper::toDto)); + } + + @Override + public List queryAll(UserQueryCriteria criteria) { + List users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)); + return userMapper.toDto(users); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public UserDto findById(long id) { + User user = userRepository.findById(id).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", id); + return userMapper.toDto(user); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(User resources) { + if (userRepository.findByUsername(resources.getUsername()) != null) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (userRepository.findByEmail(resources.getEmail()) != null) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (userRepository.findByPhone(resources.getPhone()) != null) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + userRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(User resources) throws Exception { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", resources.getId()); + User user1 = userRepository.findByUsername(resources.getUsername()); + User user2 = userRepository.findByEmail(resources.getEmail()); + User user3 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (user2 != null && !user.getId().equals(user2.getId())) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (user3 != null && !user.getId().equals(user3.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + // 如果用户的角色改变 + if (!resources.getRoles().equals(user.getRoles())) { + redisUtils.del(CacheKey.DATA_USER + resources.getId()); + redisUtils.del(CacheKey.MENU_USER + resources.getId()); + redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); + } + // 如果用户被禁用,则清除用户登录信息 + if(!resources.getEnabled()){ + onlineUserService.kickOutForUsername(resources.getUsername()); + } + user.setUsername(resources.getUsername()); + user.setEmail(resources.getEmail()); + user.setEnabled(resources.getEnabled()); + user.setRoles(resources.getRoles()); + user.setDept(resources.getDept()); + user.setJobs(resources.getJobs()); + user.setPhone(resources.getPhone()); + user.setNickName(resources.getNickName()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清除缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCenter(User resources) { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + User user1 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + user.setNickName(resources.getNickName()); + user.setPhone(resources.getPhone()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清理缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 清理缓存 + UserDto user = findById(id); + delCaches(user.getId(), user.getUsername()); + } + userRepository.deleteAllByIdIn(ids); + } + + @Override + public UserDto findByName(String userName) { + User user = userRepository.findByUsername(userName); + if (user == null) { + throw new EntityNotFoundException(User.class, "name", userName); + } else { + return userMapper.toDto(user); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePass(String username, String pass) { + userRepository.updatePass(username, pass, new Date()); + flushCache(username); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Map updateAvatar(MultipartFile multipartFile) { + // 文件大小验证 + FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize()); + // 验证文件上传的格式 + String image = "gif jpg png jpeg"; + String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); + if(fileType != null && !image.contains(fileType)){ + throw new BadRequestException("文件格式错误!, 仅支持 " + image +" 格式"); + } + User user = userRepository.findByUsername(SecurityUtils.getCurrentUsername()); + String oldPath = user.getAvatarPath(); + File file = FileUtil.upload(multipartFile, properties.getPath().getAvatar()); + user.setAvatarPath(Objects.requireNonNull(file).getPath()); + user.setAvatarName(file.getName()); + userRepository.save(user); + if (StringUtils.isNotBlank(oldPath)) { + FileUtil.del(oldPath); + } + @NotBlank String username = user.getUsername(); + flushCache(username); + return new HashMap(1) {{ + put("avatar", file.getName()); + }}; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateEmail(String username, String email) { + userRepository.updateEmail(username, email); + flushCache(username); + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (UserDto userDTO : queryAll) { + List roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList()); + Map map = new LinkedHashMap<>(); + map.put("用户名", userDTO.getUsername()); + map.put("角色", roles); + map.put("部门", userDTO.getDept().getName()); + map.put("岗位", userDTO.getJobs().stream().map(JobSmallDto::getName).collect(Collectors.toList())); + map.put("邮箱", userDTO.getEmail()); + map.put("状态", userDTO.getEnabled() ? "启用" : "禁用"); + map.put("手机号码", userDTO.getPhone()); + map.put("修改密码的时间", userDTO.getPwdResetTime()); + map.put("创建日期", userDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 清理缓存 + * + * @param id / + */ + public void delCaches(Long id, String username) { + redisUtils.del(CacheKey.USER_ID + id); + flushCache(username); + } + + /** + * 清理 登陆时 用户缓存信息 + * + * @param username / + */ + private void flushCache(String username) { + userCacheClean.cleanUserCache(username); + } +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptMapper.java new file mode 100644 index 0000000..25de23f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Dept; +import com.example.modules.system.service.dto.DeptDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptMapper extends BaseMapper { +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptSmallMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptSmallMapper.java new file mode 100644 index 0000000..01b7c65 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DeptSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Dept; +import com.example.modules.system.service.dto.DeptSmallDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptSmallMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictDetailMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictDetailMapper.java new file mode 100644 index 0000000..42ad48c --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictDetailMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.DictDetail; +import com.example.modules.system.service.dto.DictDetailDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-04-10 +*/ +@Mapper(componentModel = "spring", uses = {DictSmallMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictDetailMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictMapper.java new file mode 100644 index 0000000..24b763e --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Dict; +import com.example.modules.system.service.dto.DictDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictSmallMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictSmallMapper.java new file mode 100644 index 0000000..8f05535 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/DictSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Dict; +import com.example.modules.system.service.dto.DictSmallDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictSmallMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobMapper.java new file mode 100644 index 0000000..90be895 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Job; +import com.example.modules.system.service.dto.JobDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-03-29 +*/ +@Mapper(componentModel = "spring",uses = {DeptMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobMapper extends BaseMapper { +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobSmallMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobSmallMapper.java new file mode 100644 index 0000000..9a36c91 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/JobSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Job; +import com.example.modules.system.service.dto.JobSmallDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* +* 2019-03-29 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobSmallMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/MenuMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/MenuMapper.java new file mode 100644 index 0000000..867cbf2 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/MenuMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Menu; +import com.example.modules.system.service.dto.MenuDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * 2018-12-17 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface MenuMapper extends BaseMapper { +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleMapper.java new file mode 100644 index 0000000..929b14b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Role; +import com.example.modules.system.service.dto.RoleDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + + +@Mapper(componentModel = "spring", uses = {MenuMapper.class, DeptMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleSmallMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleSmallMapper.java new file mode 100644 index 0000000..4d4ecff --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/RoleSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.Role; +import com.example.modules.system.service.dto.RoleSmallDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * 2019-5-23 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleSmallMapper extends BaseMapper { + +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/UserMapper.java b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/UserMapper.java new file mode 100644 index 0000000..68a45dd --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/java/com/example/modules/system/service/mapstruct/UserMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.modules.system.service.mapstruct; + +import com.example.modules.system.domain.User; +import com.example.modules.system.service.dto.UserDto; +import com.example.base.BaseMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + + +@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface UserMapper extends BaseMapper { +} diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/banner.txt b/UI source code/dns-dev-2.0/dns-system/src/main/resources/banner.txt new file mode 100644 index 0000000..d0f401a --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/banner.txt @@ -0,0 +1,8 @@ + _ _ _ + | | | | (_) + ___| |______ __ _ __| |_ __ ___ _ _ __ + / _ | |______/ _` |/ _` | '_ ` _ \| | '_ \ + | __| | | (_| | (_| | | | | | | | | | | + \___|_| \__,_|\__,_|_| |_| |_|_|_| |_| + + :: Spring Boot :: (v2.1.0.RELEASE) \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-dev.yml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..983bf6d --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-dev.yml @@ -0,0 +1,118 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: ${DB_USER:root} + password: ${DB_PWD:root} + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/dns/file/ + avatar: /home/dns/avatar/ + windows: + path: C:\dns\file\ + avatar: C:\dns\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-prod.yml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..8e1993f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application-prod.yml @@ -0,0 +1,126 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: ${DB_USER:root} + password: ${DB_PWD:123456} + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 获取连接超时时间 + max-wait: 5000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + # 控制台管理用户名和密码 + url-pattern: /druid/* + reset-enable: false + login-username: admin + login-password: 123456 + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体,如遇到线上乱码,设置其他字体即可 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 7200000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认 1小时,这里单位毫秒 + renew: 3600000 + +# IP 本地解析 +ip: + local-parsing: false + +#是否允许生成代码,生产环境设置为false +generator: + enabled: false + +#如果生产环境要开启swagger,需要配置请求地址 +#springfox: +# documentation: +# swagger: +# v2: +# host: # 接口域名或外网ip + +#是否开启 swagger-ui +swagger: + enabled: false + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/dns/file/ + avatar: /home/dns/avatar/ + windows: + path: C:\dns\file\ + avatar: C:\dns\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application.yml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application.yml new file mode 100644 index 0000000..a43407b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/config/application.yml @@ -0,0 +1,97 @@ +server: + port: 8888 + +spring: + freemarker: + check-template-location: false + profiles: + active: dev + jackson: + time-zone: GMT+8 + data: + redis: + repositories: + enabled: false +# pid: +# file: /自行指定位置/dns.pid + + #配置 Jpa + jpa: + hibernate: + ddl-auto: none + open-in-view: true + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + + redis: + #数据库索引 + database: ${REDIS_DB:0} + host: ${REDIS_HOST:127.0.0.1} + port: ${REDIS_PORT:6379} + password: ${REDIS_PWD:} + #连接超时时间 + timeout: 5000 + +task: + pool: + # 核心线程池大小 + core-pool-size: 10 + # 最大线程数 + max-pool-size: 30 + # 活跃时间 + keep-alive-seconds: 60 + # 队列容量 + queue-capacity: 50 + +#七牛云 +qiniu: + # 文件大小 /M + max-size: 15 + +#邮箱验证码有效时间/秒 +code: + expiration: 300 + +#密码加密传输,前端公钥加密,后端私钥解密 +rsa: + private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A== + +# 内存用户缓存配置 +user-cache: + # 最小回收数(当缓存数量达到此值时进行回收) + min-evictable-size: 512 + # 最小回收间隔 + min-evictable-interval: 1800000 + # 最小存活时间 (ms) + min-idle-time: 3600000 + + +#mybatis +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.example.modules.*.domain + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: AUTO + #字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断" + field-strategy: NOT_NULL + #驼峰下划线转换 + column-underline: true + logic-delete-value: 1 + logic-not-delete-value: 0 + banner: false + #原生配置 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +#showSql +logging: + level: + com.example.modules.system.mapper: debug diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/generator.properties b/UI source code/dns-dev-2.0/dns-system/src/main/resources/generator.properties new file mode 100644 index 0000000..2ed9370 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/generator.properties @@ -0,0 +1,27 @@ +#数据库类型转Java类型 +tinyint=Integer +smallint=Integer +mediumint=Integer +int=Integer +integer=Integer + +bigint=Long + +float=Float + +double=Double + +decimal=BigDecimal + +bit=Boolean + +char=String +varchar=String +tinytext=String +text=String +mediumtext=String +longtext=String + +date=Timestamp +datetime=Timestamp +timestamp=Timestamp \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/log4jdbc.log4j2.properties b/UI source code/dns-dev-2.0/dns-system/src/main/resources/log4jdbc.log4j2.properties new file mode 100644 index 0000000..302525f --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/log4jdbc.log4j2.properties @@ -0,0 +1,4 @@ +# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger +log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator +log4jdbc.auto.load.popular.drivers=false +log4jdbc.drivers=com.mysql.cj.jdbc.Driver \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/logback.xml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/logback.xml new file mode 100644 index 0000000..8a399c4 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/logback.xml @@ -0,0 +1,45 @@ + + + DiamondV + + + + + + + ${log.pattern} + ${log.charset} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDao.xml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDao.xml new file mode 100644 index 0000000..37d8a3b --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDao.xml @@ -0,0 +1,577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDo53Dao.xml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDo53Dao.xml new file mode 100644 index 0000000..849fc64 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/DnsDo53Dao.xml @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/IpInformationDao.xml b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/IpInformationDao.xml new file mode 100644 index 0000000..f4a0047 --- /dev/null +++ b/UI source code/dns-dev-2.0/dns-system/src/main/resources/mapper/dns/IpInformationDao.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI source code/dns-dev-2.0/pom.xml b/UI source code/dns-dev-2.0/pom.xml new file mode 100644 index 0000000..84d1b52 --- /dev/null +++ b/UI source code/dns-dev-2.0/pom.xml @@ -0,0 +1,266 @@ + + + 4.0.0 + + com.example + dns + pom + 2.6 + + + dns-common + dns-logging + dns-system + + + DNS测绘 + https://el-admin.vip + + + org.springframework.boot + spring-boot-starter-parent + 2.2.10.RELEASE + + + + 2.17.0 + 1.2.9 + UTF-8 + UTF-8 + 1.8 + 1.16 + 2.9.2 + 1.2.70 + 1.1.24 + 2.5.0 + 1.3.1.Final + 3.0.7.1 + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + com.baomidou + mybatis-plus-generator + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.springframework.boot + spring-boot-starter-cache + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + ${commons-pool2.version} + + + org.apache.commons + commons-lang3 + + + + + org.bgee.log4jdbc-log4j2 + log4jdbc-log4j2-jdbc4.1 + ${log4jdbc.version} + + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.swagger + swagger-annotations + + + io.swagger + swagger-models + + + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + io.swagger + swagger-annotations + 1.5.21 + + + io.swagger + swagger-models + 1.5.21 + + + + + mysql + mysql-connector-java + runtime + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + net.dreamlu + mica-ip2region + 2.5.6 + + + + + + org.projectlombok + lombok + true + + + + + org.apache.poi + poi + 3.17 + + + org.apache.poi + poi-ooxml + 3.17 + + + xerces + xercesImpl + 2.12.2 + + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + javax.inject + javax.inject + 1 + + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + + nl.basjes.parse.useragent + yauaa + 5.23 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + + + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + false + + + + diff --git a/UI source code/dns-dev-2.0/sql/DiamondV.sql b/UI source code/dns-dev-2.0/sql/DiamondV.sql new file mode 100644 index 0000000..cfb1dea --- /dev/null +++ b/UI source code/dns-dev-2.0/sql/DiamondV.sql @@ -0,0 +1,1059 @@ +/* +SQLyog Ultimate v13.1.1 (64 bit) +MySQL - 5.7.30-log : Database - eladmin +********************************************************************* +*/ + +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +CREATE DATABASE /*!32312 IF NOT EXISTS*/`diamondv` /*!40100 DEFAULT CHARACTER SET utf8 */; + +USE `diamondv`; + + +/*Table structure for table `code_column_config` */ + +DROP TABLE IF EXISTS `code_column_config`; + +CREATE TABLE `code_column_config` ( + `column_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `table_name` varchar(255) DEFAULT NULL, + `column_name` varchar(255) DEFAULT NULL, + `column_type` varchar(255) DEFAULT NULL, + `dict_name` varchar(255) DEFAULT NULL, + `extra` varchar(255) DEFAULT NULL, + `form_show` bit(1) DEFAULT NULL, + `form_type` varchar(255) DEFAULT NULL, + `key_type` varchar(255) DEFAULT NULL, + `list_show` bit(1) DEFAULT NULL, + `not_null` bit(1) DEFAULT NULL, + `query_type` varchar(255) DEFAULT NULL, + `remark` varchar(255) DEFAULT NULL, + `date_annotation` varchar(255) DEFAULT NULL, + PRIMARY KEY (`column_id`) USING BTREE, + KEY `idx_table_name` (`table_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='代码生成字段信息存储'; + +/*Data for the table `code_column_config` */ + +/*Table structure for table `code_gen_config` */ + +DROP TABLE IF EXISTS `code_gen_config`; + +CREATE TABLE `code_gen_config` ( + `config_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `table_name` varchar(255) DEFAULT NULL COMMENT '表名', + `author` varchar(255) DEFAULT NULL COMMENT '作者', + `cover` bit(1) DEFAULT NULL COMMENT '是否覆盖', + `module_name` varchar(255) DEFAULT NULL COMMENT '模块名称', + `pack` varchar(255) DEFAULT NULL COMMENT '至于哪个包下', + `path` varchar(255) DEFAULT NULL COMMENT '前端代码生成的路径', + `api_path` varchar(255) DEFAULT NULL COMMENT '前端Api文件路径', + `prefix` varchar(255) DEFAULT NULL COMMENT '表前缀', + `api_alias` varchar(255) DEFAULT NULL COMMENT '接口名称', + PRIMARY KEY (`config_id`) USING BTREE, + KEY `idx_table_name` (`table_name`(100)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='代码生成器配置'; + +/*Data for the table `code_gen_config` */ + +/*Table structure for table `component` */ + +DROP TABLE IF EXISTS `component`; + +CREATE TABLE `component` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `component` varchar(128) DEFAULT NULL, + `vulnerability` varchar(128) DEFAULT NULL, + `timestamp` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `component` */ + +/*Table structure for table `dns_type` */ + +DROP TABLE IF EXISTS `dns_type`; + +CREATE TABLE `dns_type` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `type` tinyint(4) DEFAULT NULL, + `epoch` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; + +/*Data for the table `dns_type` */ + +insert into `dns_type`(`id`,`ip`,`type`,`epoch`) values +(1,'1.1.1.1',1,2), +(2,'2.2.2.2',2,2), +(3,'3.3.3.3',3,2), +(4,'4.4.4.4',4,2), +(5,'5.5.5.5',5,2), +(6,'6.6.6.6',1,2), +(7,'7.7.7.7',1,2), +(8,'1.1.1.1',3,1), +(9,'2.2.2.2',5,1); + +/*Table structure for table `doh_attribute` */ + +DROP TABLE IF EXISTS `doh_attribute`; + +CREATE TABLE `doh_attribute` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `port` int(11) DEFAULT NULL, + `host` varchar(128) DEFAULT NULL, + `path` varchar(128) DEFAULT NULL, + `method` varchar(4) DEFAULT NULL, + `connect_type` int(11) DEFAULT NULL, + `status_code` int(11) DEFAULT NULL, + `rep_header` varchar(2048) DEFAULT NULL, + `rep_body` varchar(1024) DEFAULT NULL, + `timestamp` datetime DEFAULT NULL, + `component` varchar(128) DEFAULT NULL, + `rounds` tinyint(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_ip` (`ip`) +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8; + +/*Data for the table `doh_attribute` */ + +insert into `doh_attribute`(`id`,`ip`,`port`,`host`,`path`,`method`,`connect_type`,`status_code`,`rep_header`,`rep_body`,`timestamp`,`component`,`rounds`) values +(1,'1.1.1.1',8443,'192.168.32.46','/test1','post',1,200,'{head1}','{body1}','2022-05-12 14:59:11','nginx',2), +(2,'2.2.2.2',8443,'192.168.77.88','/test2','get',2,400,'{head}','{erro}','2022-05-11 15:00:02','bind',2), +(3,'3.3.3.3',8443,'192.168.74.32','/test3','post',1,404,'{head}','{not found}','2022-04-10 15:00:52','nginx',2), +(4,'1.1.1.1',8443,'192.168.32.46','/test4','get',1,200,'{head2}','{body2}','2022-05-09 11:56:55','bind',2), +(5,'1.1.1.1',443,'192.168.32.47','/test1','post',1,200,'{head1}','{body1}','2022-05-08 16:58:48','nginx',2), +(6,'4.4.4.4',443,'192.168.1.1','/test4','get',1,200,'{head4}','{body4}','2022-05-07 14:37:43','bind',2), +(7,'5.5.5.5',443,'192.168.5.5','/test5','del',3,500,'{head5}','{body5}','2022-05-06 14:38:40','nginx',2), +(8,'6.6.6.6',443,'192.168.5.6','/test6','get',3,500,'{head6}','{body6}','2022-05-05 09:06:47','bind',2), +(9,'2.2.2.2',443,'192.168.77.88','/test2','get',2,400,'{head}','{erro}','2022-04-01 14:21:42','bind',1), +(10,'3.3.3.3',443,'192.168.74.31','/test3','post',1,404,'{head}','{not found}','2022-04-01 14:22:31','bind',1), +(11,'7.7.7.7',443,'192.168.77.77','/test7','post',1,404,'{head}','{not found}','2022-05-06 16:53:13','bind',2), +(12,'8.8.8.8',443,'192.168.88.88','/test8','post',1,404,'{head}','{not found}','2022-05-06 16:54:53','nginx',2), +(13,'9.9.9.9',443,'192.168.99.99','/test9','post',1,404,'{head}','{not found}','2022-05-06 16:54:59','nginx',2), +(14,'9.9.9.8',443,'192.168.99.98','/test98','post',1,404,'{head}','{not found}','2022-05-06 16:55:28','nginx',2), +(15,'9.9.9.7',443,'192.168.99.97','/test97','post',1,404,'{head}','{not found}','2022-05-13 16:59:18',NULL,2); + +/*Table structure for table `forward_dns` */ + +DROP TABLE IF EXISTS `forward_dns`; + +CREATE TABLE `forward_dns` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `forwarder` varchar(128) DEFAULT NULL, + `upstream` varchar(128) DEFAULT NULL, + `epoch` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; + +/*Data for the table `forward_dns` */ + +insert into `forward_dns`(`id`,`forwarder`,`upstream`,`epoch`) values +(1,'1.1.1.1','2.2.2.2',2), +(2,'2.2.2.2','1.1.1.1',2), +(3,'2.2.2.2','2.2.2.2',2), +(4,'3.3.3.3','4.4.4.4',2), +(5,'1.1.1.1','5.5.5.5',1), +(6,'2.2.2.2','6.6.6.6',1); + +/*Table structure for table `ip_cert` */ + +DROP TABLE IF EXISTS `ip_cert`; + +CREATE TABLE `ip_cert` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `port` int(11) DEFAULT NULL, + `certificate` varchar(5120) DEFAULT NULL, + `ca` varchar(128) DEFAULT NULL, + `timestamp` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_ip` (`ip`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; + +/*Data for the table `ip_cert` */ + +insert into `ip_cert`(`id`,`ip`,`port`,`certificate`,`ca`,`timestamp`) values +(1,'1.1.1.1',8443,'t1证书','t1证书颁发者','2022-04-27 15:01:33'), +(2,'2.2.2.2',8443,'t2证书','t2证书颁发者','2022-04-27 15:01:49'), +(3,'3.3.3.3',8443,'t3证书','t3证书颁发者','2022-04-27 15:02:01'), +(4,'1.1.1.1',8443,'t1证书2','t1证书颁发者2','2022-05-06 09:03:22'), +(5,'2.2.2.2',443,'t2证书443','t2证书颁发者443','2022-05-18 13:51:00'), +(6,'3.3.3.3',443,'t3证书443','t3证书颁发者443','2022-05-18 13:51:01'); + +/*Table structure for table `ip_information` */ + +DROP TABLE IF EXISTS `ip_information`; + +CREATE TABLE `ip_information` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `country` varchar(50) DEFAULT NULL, + `province` varchar(50) DEFAULT NULL, + `city` varchar(50) DEFAULT NULL, + `district` varchar(50) DEFAULT NULL, + `provider` varchar(50) DEFAULT NULL, + `isp` varchar(50) DEFAULT NULL, + `asnumber` int(11) DEFAULT NULL, + `timestamp` datetime DEFAULT NULL, + `zipcode` varchar(50) DEFAULT NULL, + `timezone` varchar(50) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_ip` (`ip`) +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; + +/*Data for the table `ip_information` */ + +insert into `ip_information`(`id`,`ip`,`country`,`province`,`city`,`district`,`provider`,`isp`,`asnumber`,`timestamp`,`zipcode`,`timezone`) values +(1,'1.1.1.1','中国','河北','邢台','1','华为','华为',123456789,'2022-04-27 14:55:00','100000','UTC'), +(2,'2.2.2.2','哥伦比亚','德克萨斯州','纽约','2','特斯拉','特斯拉',987654321,'2022-04-27 14:56:27','500000','USA'), +(3,'3.3.3.3','刚果','伦敦省','伦敦市','3','长安','长安',741852963,'2022-04-27 14:57:31','800000','UK'), +(4,'4.4.4.4','日本','北京','怀柔','4','烤鸭','烤鸭',8888888,'2022-04-28 11:16:40','100010','UTC'), +(5,'5.5.5.5','韩国','河南','郑州','5','三星','三星',55555555,'2022-05-06 14:39:53','100010','UTC'), +(6,'6.6.6.6','英国','河北','石家庄','5','苹果','苹果',666666,'2022-05-13 14:25:55','100010','UTC'), +(7,'7.7.7.7','法国','江苏','南京','5','移动','移动',77777777,'2022-05-13 14:30:16','100010','UTC'), +(8,'8.8.8.8','德国','柏林','柏林',NULL,'运营商1','运营商1',8888888,'2022-05-17 16:58:06','100010',NULL), +(9,'9.9.9.9','瑞典','斯德哥尔摩','斯德哥尔摩',NULL,'运营商2','运营商2',999999,'2022-05-17 16:58:10','100010',NULL), +(10,'9.9.9.8','丹麦','哥本哈根','哥本哈根',NULL,'运营商3','运营商3',9999998,'2022-05-17 16:58:12','100010',NULL), +(11,'9.9.9.7','意大利','罗马','罗马',NULL,'运营商4','运营商4',333333,'2022-05-17 16:59:55',NULL,NULL); + +/*Table structure for table `mnt_app` */ + +DROP TABLE IF EXISTS `mnt_app`; + +CREATE TABLE `mnt_app` ( + `app_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) DEFAULT NULL COMMENT '应用名称', + `upload_path` varchar(255) DEFAULT NULL COMMENT '上传目录', + `deploy_path` varchar(255) DEFAULT NULL COMMENT '部署路径', + `backup_path` varchar(255) DEFAULT NULL COMMENT '备份路径', + `port` int(255) DEFAULT NULL COMMENT '应用端口', + `start_script` varchar(4000) DEFAULT NULL COMMENT '启动脚本', + `deploy_script` varchar(4000) DEFAULT NULL COMMENT '部署脚本', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`app_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='应用管理'; + +/*Data for the table `mnt_app` */ + +/*Table structure for table `mnt_database` */ + +DROP TABLE IF EXISTS `mnt_database`; + +CREATE TABLE `mnt_database` ( + `db_id` varchar(50) NOT NULL COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '名称', + `jdbc_url` varchar(255) NOT NULL COMMENT 'jdbc连接', + `user_name` varchar(255) NOT NULL COMMENT '账号', + `pwd` varchar(255) NOT NULL COMMENT '密码', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`db_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据库管理'; + +/*Data for the table `mnt_database` */ + +/*Table structure for table `mnt_deploy` */ + +DROP TABLE IF EXISTS `mnt_deploy`; + +CREATE TABLE `mnt_deploy` ( + `deploy_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `app_id` bigint(20) DEFAULT NULL COMMENT '应用编号', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`deploy_id`) USING BTREE, + KEY `FK6sy157pseoxx4fmcqr1vnvvhy` (`app_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部署管理'; + +/*Data for the table `mnt_deploy` */ + +/*Table structure for table `mnt_deploy_history` */ + +DROP TABLE IF EXISTS `mnt_deploy_history`; + +CREATE TABLE `mnt_deploy_history` ( + `history_id` varchar(50) NOT NULL COMMENT 'ID', + `app_name` varchar(255) NOT NULL COMMENT '应用名称', + `deploy_date` datetime NOT NULL COMMENT '部署日期', + `deploy_user` varchar(50) NOT NULL COMMENT '部署用户', + `ip` varchar(20) NOT NULL COMMENT '服务器IP', + `deploy_id` bigint(20) DEFAULT NULL COMMENT '部署编号', + PRIMARY KEY (`history_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部署历史管理'; + +/*Data for the table `mnt_deploy_history` */ + +/*Table structure for table `mnt_deploy_server` */ + +DROP TABLE IF EXISTS `mnt_deploy_server`; + +CREATE TABLE `mnt_deploy_server` ( + `deploy_id` bigint(20) NOT NULL COMMENT '部署ID', + `server_id` bigint(20) NOT NULL COMMENT '服务ID', + PRIMARY KEY (`deploy_id`,`server_id`) USING BTREE, + KEY `FKeaaha7jew9a02b3bk9ghols53` (`server_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='应用与服务器关联'; + +/*Data for the table `mnt_deploy_server` */ + +/*Table structure for table `mnt_server` */ + +DROP TABLE IF EXISTS `mnt_server`; + +CREATE TABLE `mnt_server` ( + `server_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `account` varchar(50) DEFAULT NULL COMMENT '账号', + `ip` varchar(20) DEFAULT NULL COMMENT 'IP地址', + `name` varchar(100) DEFAULT NULL COMMENT '名称', + `password` varchar(100) DEFAULT NULL COMMENT '密码', + `port` int(11) DEFAULT NULL COMMENT '端口', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`server_id`) USING BTREE, + KEY `idx_ip` (`ip`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='服务器管理'; + +/*Data for the table `mnt_server` */ + +/*Table structure for table `nonstandard_dns` */ + +DROP TABLE IF EXISTS `nonstandard_dns`; + +CREATE TABLE `nonstandard_dns` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `record` varchar(128) DEFAULT NULL, + `epoch` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; + +/*Data for the table `nonstandard_dns` */ + +insert into `nonstandard_dns`(`id`,`ip`,`record`,`epoch`) values +(1,'1.1.1.1','aaaaa',2), +(2,'1.1.1.1','vvvvv',2), +(3,'2.2.2.2','22aaaa',2), +(4,'3.3.3.3','33aaaaa',2), +(5,'4.4.4.4','444aaaa',2), +(6,'5.5.5.5','555aaaa',2); + +/*Table structure for table `scan_result` */ + +DROP TABLE IF EXISTS `scan_result`; + +CREATE TABLE `scan_result` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(128) DEFAULT NULL, + `flags` int(11) DEFAULT NULL, + `opcode` tinyint(4) DEFAULT NULL, + `qr` tinyint(4) DEFAULT NULL, + `aa` tinyint(4) DEFAULT NULL, + `ra` tinyint(4) DEFAULT NULL, + `rcode` int(4) DEFAULT NULL, + `query_name` varchar(256) DEFAULT NULL, + `query_response` varchar(512) DEFAULT NULL, + `component` varchar(128) DEFAULT NULL, + `epoch` int(11) DEFAULT NULL, + `scan_type` tinyint(4) DEFAULT NULL, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8; + +/*Data for the table `scan_result` */ + +insert into `scan_result`(`id`,`ip`,`flags`,`opcode`,`qr`,`aa`,`ra`,`rcode`,`query_name`,`query_response`,`component`,`epoch`,`scan_type`,`time`) values +(1,'1.1.1.1',NULL,NULL,NULL,1,1,200,'1.1.1.1请求域名','1.1.1.1应答结果','bind',2,NULL,'2022-05-17 09:49:53'), +(2,'2.2.2.2',NULL,NULL,NULL,2,2,400,'2.2.2.2请求域名','2.2.2.2应答结果','bind',2,NULL,'2022-05-16 16:26:15'), +(3,'3.3.3.3',NULL,NULL,NULL,3,3,500,'3.3.3.3请求域名','3.3.3.3应答结果','bind',2,NULL,'2022-05-16 16:26:12'), +(4,'4.4.4.4',NULL,NULL,NULL,4,4,404,'4.4.4.4请求域名','4.4.4.4应答结果','unbound',2,NULL,'2022-05-16 16:26:12'), +(5,'5.5.5.5',NULL,NULL,NULL,5,5,500,'5.5.5.5请求域名','5.5.5.5应答结果','unbound',2,NULL,'2022-05-16 16:26:11'), +(6,'1.1.1.1',NULL,NULL,NULL,3,4,404,'1.1.1.1请求域名2','1.1.1.1应答结果2','bind',2,NULL,'2022-05-16 16:26:11'), +(7,'6.6.6.6',NULL,NULL,NULL,6,6,200,'6.6.6.6请求域名','6.6.6.6应答结果','bind',2,NULL,'2022-05-16 16:26:10'), +(8,'7.7.7.7',NULL,NULL,NULL,7,7,400,'7.7.7.7请求域名','7.7.7.7请求域名','bind',2,NULL,'2022-05-16 16:26:09'), +(9,'8.8.8.8',NULL,NULL,NULL,8,8,400,'8.8.8.8请求域名','8.8.8.8请求域名','bind',2,NULL,'2022-05-16 16:26:09'), +(10,'9.9.9.9',NULL,NULL,NULL,9,9,400,'9.9.9.9请求域名','9.9.9.9请求域名','bind',2,NULL,'2022-05-16 16:26:08'), +(11,'9.9.9.8',NULL,NULL,NULL,9,9,400,'9.9.9.9请求域名2','9.9.9.9请求域名2','bind',2,NULL,'2022-05-16 16:26:07'), +(12,'9.9.9.7',NULL,NULL,NULL,9,9,400,'9.9.9.9请求域名3','9.9.9.9请求域名3','bind',2,NULL,'2022-05-16 16:26:07'), +(13,'9.9.9.6',NULL,NULL,NULL,9,9,400,'9.9.9.9请求域名4','9.9.9.9请求域名4','bind',2,NULL,'2022-05-16 16:26:06'), +(14,'1.1.1.1',NULL,NULL,NULL,1,1,200,'1.1.1.1请求域名2','9.9.9.9请求域名4','bind',1,NULL,'2022-05-16 16:26:04'), +(15,'2.2.2.2',NULL,NULL,NULL,2,2,200,'2.2.2.2请求域名2','2.2.2.2请求域名2','bind',1,NULL,'2022-05-16 16:26:02'); + +/*Table structure for table `sys_dept` */ + +DROP TABLE IF EXISTS `sys_dept`; + +CREATE TABLE `sys_dept` ( + `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `pid` bigint(20) DEFAULT NULL COMMENT '上级部门', + `sub_count` int(5) DEFAULT '0' COMMENT '子部门数目', + `name` varchar(255) NOT NULL COMMENT '名称', + `dept_sort` int(5) DEFAULT '999' COMMENT '排序', + `enabled` bit(1) NOT NULL COMMENT '状态', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE, + KEY `inx_pid` (`pid`), + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部门'; + +/*Data for the table `sys_dept` */ + +insert into `sys_dept`(`dept_id`,`pid`,`sub_count`,`name`,`dept_sort`,`enabled`,`create_by`,`update_by`,`create_time`,`update_time`) values +(2,7,1,'研发部',3,'','admin','admin','2019-03-25 09:15:32','2020-08-02 14:48:47'), +(5,7,0,'运维部',4,'','admin','admin','2019-03-25 09:20:44','2020-05-17 14:27:27'), +(6,8,0,'测试部',6,'','admin','admin','2019-03-25 09:52:18','2020-06-08 11:59:21'), +(7,NULL,2,'华南分部',0,'','admin','admin','2019-03-25 11:04:50','2020-06-08 12:08:56'), +(8,NULL,2,'华北分部',1,'','admin','admin','2019-03-25 11:04:53','2020-05-14 12:54:00'), +(15,8,0,'UI部门',7,'','admin','admin','2020-05-13 22:56:53','2020-05-14 12:54:13'), +(17,2,0,'研发一组',999,'','admin','admin','2020-08-02 14:49:07','2020-08-02 14:49:07'); + +/*Table structure for table `sys_dict` */ + +DROP TABLE IF EXISTS `sys_dict`; + +CREATE TABLE `sys_dict` ( + `dict_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '字典名称', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dict_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据字典'; + +/*Data for the table `sys_dict` */ + +insert into `sys_dict`(`dict_id`,`name`,`description`,`create_by`,`update_by`,`create_time`,`update_time`) values +(1,'user_status','用户状态',NULL,NULL,'2019-10-27 20:31:36',NULL), +(4,'dept_status','部门状态',NULL,NULL,'2019-10-27 20:31:36',NULL), +(5,'job_status','岗位状态',NULL,NULL,'2019-10-27 20:31:36',NULL); + +/*Table structure for table `sys_dict_detail` */ + +DROP TABLE IF EXISTS `sys_dict_detail`; + +CREATE TABLE `sys_dict_detail` ( + `detail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `dict_id` bigint(11) DEFAULT NULL COMMENT '字典id', + `label` varchar(255) NOT NULL COMMENT '字典标签', + `value` varchar(255) NOT NULL COMMENT '字典值', + `dict_sort` int(5) DEFAULT NULL COMMENT '排序', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`detail_id`) USING BTREE, + KEY `FK5tpkputc6d9nboxojdbgnpmyb` (`dict_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据字典详情'; + +/*Data for the table `sys_dict_detail` */ + +insert into `sys_dict_detail`(`detail_id`,`dict_id`,`label`,`value`,`dict_sort`,`create_by`,`update_by`,`create_time`,`update_time`) values +(1,1,'激活','true',1,NULL,NULL,'2019-10-27 20:31:36',NULL), +(2,1,'禁用','false',2,NULL,NULL,NULL,NULL), +(3,4,'启用','true',1,NULL,NULL,NULL,NULL), +(4,4,'停用','false',2,NULL,NULL,'2019-10-27 20:31:36',NULL), +(5,5,'启用','true',1,NULL,NULL,NULL,NULL), +(6,5,'停用','false',2,NULL,NULL,'2019-10-27 20:31:36',NULL); + +/*Table structure for table `sys_job` */ + +DROP TABLE IF EXISTS `sys_job`; + +CREATE TABLE `sys_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '岗位名称', + `enabled` bit(1) NOT NULL COMMENT '岗位状态', + `job_sort` int(5) DEFAULT NULL COMMENT '排序', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`job_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`), + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='岗位'; + +/*Data for the table `sys_job` */ + +insert into `sys_job`(`job_id`,`name`,`enabled`,`job_sort`,`create_by`,`update_by`,`create_time`,`update_time`) values +(8,'人事专员','',3,NULL,NULL,'2019-03-29 14:52:28',NULL), +(10,'产品经理','',4,NULL,NULL,'2019-03-29 14:55:51',NULL), +(11,'全栈开发','',2,NULL,'admin','2019-03-31 13:39:30','2020-05-05 11:33:43'), +(12,'软件测试','',5,NULL,'admin','2019-03-31 13:39:43','2020-05-10 19:56:26'); + +/*Table structure for table `sys_log` */ + +DROP TABLE IF EXISTS `sys_log`; + +CREATE TABLE `sys_log` ( + `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `description` varchar(255) DEFAULT NULL, + `log_type` varchar(255) DEFAULT NULL, + `method` varchar(255) DEFAULT NULL, + `params` text, + `request_ip` varchar(255) DEFAULT NULL, + `time` bigint(20) DEFAULT NULL, + `username` varchar(255) DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + `browser` varchar(255) DEFAULT NULL, + `exception_detail` text, + `create_time` datetime DEFAULT NULL, + PRIMARY KEY (`log_id`) USING BTREE, + KEY `log_create_time_index` (`create_time`), + KEY `inx_log_type` (`log_type`) +) ENGINE=InnoDB AUTO_INCREMENT=3549 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统日志'; + +/*Data for the table `sys_log` */ + +insert into `sys_log`(`log_id`,`description`,`log_type`,`method`,`params`,`request_ip`,`time`,`username`,`address`,`browser`,`exception_detail`,`create_time`) values +(3537,'修改用户','INFO','com.example.modules.system.rest.UserController.updateUser()','{\"gender\":\"男\",\"nickName\":\"测试\",\"roles\":[],\"jobs\":[{\"updateTime\":1589111786000,\"enabled\":true,\"jobSort\":5,\"updateBy\":\"admin\",\"createTime\":1554010783000,\"name\":\"软件测试\",\"id\":12}],\"avatarPath\":\"/Users/jie/Documents/work/me/admin/eladmin/~/avatar/avatar-20200806032259161.png\",\"updateTime\":1599273818000,\"dept\":{\"subCount\":0,\"name\":\"研发部\",\"id\":2},\"isAdmin\":false,\"enabled\":true,\"avatarName\":\"avatar-20200806032259161.png\",\"createBy\":\"admin\",\"phone\":\"19999999999\",\"pwdResetTime\":1588495111000,\"updateBy\":\"admin\",\"createTime\":1588648549000,\"id\":2,\"email\":\"231@qq.com\",\"username\":\"test\"}','192.168.32.87',144,'admin','内网IP','Chrome 98.0.4758.102',NULL,'2022-04-24 11:18:20'), +(3538,'新增用户','INFO','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"aaa\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":2}],\"jobs\":[{\"id\":8}],\"updateTime\":1650790301429,\"dept\":{\"subCount\":0,\"id\":8},\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$39eu19DlibPMfC9EEPPErO86uBAZhCzySlhvSn/Evg0gdInNeNB3W\",\"createBy\":\"admin\",\"phone\":\"15014236547\",\"updateBy\":\"admin\",\"createTime\":1650790301429,\"id\":3,\"email\":\"22@qq.com\",\"username\":\"test2\"}','192.168.32.87',171,'admin','内网IP','Chrome 98.0.4758.102',NULL,'2022-04-24 16:51:41'), +(3539,'新增用户','ERROR','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"test3\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":2}],\"jobs\":[{\"id\":8}],\"dept\":{\"subCount\":0,\"id\":7},\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$w8i0HM4aRHvCeVBg/KCx/O0kwDxrFDBpxvDX5ojBJ7xywJWEoDB6S\",\"phone\":\"15033669955\",\"email\":\"22@qq.com\",\"username\":\"test3\"}','192.168.32.87',34422,'admin','内网IP','Chrome 98.0.4758.102','com.example.exception.EntityExistException: User with email 22@qq.com existed\r\n at com.example.modules.system.service.impl.UserServiceImpl.create(UserServiceImpl.java:90)\r\n at com.example.modules.system.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$5003e55c.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$ea52fc62.create()\r\n at com.example.modules.system.controller.UserController.createUser(UserController.java:109)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$9d3d2338.createUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\n','2022-04-24 16:59:29'), +(3540,'修改用户','INFO','com.example.modules.system.controller.UserController.updateUser()','{\"gender\":\"男\",\"nickName\":\"管理员\",\"roles\":[],\"jobs\":[{\"updateTime\":1588649623000,\"enabled\":true,\"jobSort\":2,\"updateBy\":\"admin\",\"createTime\":1554010770000,\"name\":\"全栈开发\",\"id\":11}],\"avatarPath\":\"/Users/jie/Documents/work/me/admin/eladmin/~/avatar/avatar-20200806032259161.png\",\"updateTime\":1599273811000,\"dept\":{\"subCount\":0,\"name\":\"研发部\",\"id\":2},\"isAdmin\":false,\"enabled\":true,\"avatarName\":\"avatar-20200806032259161.png\",\"phone\":\"18888888888\",\"pwdResetTime\":1588495111000,\"updateBy\":\"admin\",\"createTime\":1534986716000,\"id\":1,\"email\":\"201507802@qq.com\",\"username\":\"admin\"}','192.168.32.87',52,'admin','内网IP','Chrome 98.0.4758.102',NULL,'2022-04-24 17:03:00'), +(3541,'新增用户','INFO','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xx\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":2}],\"jobs\":[{\"id\":8}],\"updateTime\":1650793621130,\"dept\":{\"subCount\":0,\"id\":7},\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$NGkgAoFjWGUueMJ81409I.mAJXa2KHf9b9GwgWZOCN8TdL35lLigy\",\"createBy\":\"admin\",\"phone\":\"15044878963\",\"updateBy\":\"admin\",\"createTime\":1650793621130,\"id\":4,\"email\":\"3333@qq.com\",\"username\":\"xx\"}','192.168.32.87',166,'admin','内网IP','Chrome 98.0.4758.102',NULL,'2022-04-24 17:47:01'), +(3542,'新增用户','ERROR','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xxx\",\"isAdmin\":false,\"enabled\":true,\"phone\":\"15044878963\",\"email\":\"33233@qq.com\",\"username\":\"xxx\"}','192.168.32.87',5,'admin','内网IP','PostmanRuntime 7.28.4','java.lang.NullPointerException\r\n at com.example.modules.system.service.impl.RoleServiceImpl.findByRoles(RoleServiceImpl.java:158)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$FastClassBySpringCGLIB$$dc8a47d1.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$EnhancerBySpringCGLIB$$9cac769b.findByRoles()\r\n at com.example.modules.system.controller.UserController.checkLevel(UserController.java:191)\r\n at com.example.modules.system.controller.UserController.createUser(UserController.java:106)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$c18ababd.createUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\n','2022-04-24 17:49:17'), +(3543,'新增用户','ERROR','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xxx\",\"isAdmin\":false,\"enabled\":true,\"phone\":\"15044878963\",\"email\":\"33233@qq.com\",\"username\":\"xxx\"}','192.168.32.87',6,'admin','内网IP','PostmanRuntime 7.28.4','java.lang.NullPointerException\r\n at com.example.modules.system.service.impl.RoleServiceImpl.findByRoles(RoleServiceImpl.java:158)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$FastClassBySpringCGLIB$$dc8a47d1.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$EnhancerBySpringCGLIB$$9cac769b.findByRoles()\r\n at com.example.modules.system.controller.UserController.checkLevel(UserController.java:191)\r\n at com.example.modules.system.controller.UserController.createUser(UserController.java:106)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$c18ababd.createUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\n','2022-04-24 17:49:31'), +(3544,'新增用户','ERROR','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xxx\",\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$yT504iKWln9Oi9ETxlXYe.1emlR9hqIL.utpSTXWrx2iFW51oIyXq\",\"phone\":\"15044878963\",\"email\":\"33233@qq.com\",\"username\":\"xxx\"}','192.168.32.87',102,'admin','内网IP','PostmanRuntime 7.28.4','com.example.exception.EntityExistException: User with phone 15044878963 existed\r\n at com.example.modules.system.service.impl.UserServiceImpl.create(UserServiceImpl.java:93)\r\n at com.example.modules.system.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$5003e55c.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$9777835f.create()\r\n at com.example.modules.system.controller.UserController.createUser(UserController.java:109)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$1e21cf61.createUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\n','2022-04-24 17:52:01'), +(3545,'新增用户','INFO','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xxx\",\"updateTime\":1650793939421,\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$y6hqVUiy6YSLngBuK4v/weonLYkyuIltwG0HTUCMTuCNtnGkFsDpW\",\"createBy\":\"admin\",\"phone\":\"15044878962\",\"updateBy\":\"admin\",\"createTime\":1650793939421,\"id\":5,\"email\":\"33233@qq.com\",\"username\":\"xxx\"}','192.168.32.87',121,'admin','内网IP','PostmanRuntime 7.28.4',NULL,'2022-04-24 17:52:19'), +(3546,'新增用户','INFO','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"ssss\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":1}],\"jobs\":[{\"id\":8}],\"updateTime\":1650873057518,\"dept\":{\"subCount\":0,\"id\":7},\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$P.hvDg2NaJs/kYeLn15u4upYvYxbl4HB4ExNERrU1SM5EqTQF2Hae\",\"createBy\":\"admin\",\"phone\":\"15033698785\",\"updateBy\":\"admin\",\"createTime\":1650873057518,\"id\":6,\"email\":\"sasa@qq.com\",\"username\":\"bbbb\"}','192.168.32.87',14796,'admin','内网IP','Chrome 98.0.4758.102',NULL,'2022-04-25 15:50:59'), +(3547,'修改用户','ERROR','com.example.modules.system.controller.UserController.updateUser()','{\"gender\":\"男\",\"nickName\":\"ssss\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":2}],\"jobs\":[{\"id\":8}],\"updateTime\":1650873058000,\"dept\":{\"subCount\":0,\"name\":\"华南分部\",\"id\":7},\"isAdmin\":false,\"enabled\":true,\"createBy\":\"admin\",\"phone\":\"15033698785\",\"updateBy\":\"admin\",\"createTime\":1650873058000,\"id\":6,\"email\":\"sasa@qq.com\",\"username\":\"bbbb\"}','192.168.32.87',3,'admin','内网IP','Chrome 98.0.4758.102','org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet\r\n at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281)\r\n at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)\r\n at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)\r\n at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)\r\n at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)\r\n at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:154)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)\r\n at com.sun.proxy.$Proxy171.findByUserId(Unknown Source)\r\n at com.example.modules.system.service.impl.RoleServiceImpl.findByUsersId(RoleServiceImpl.java:153)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$FastClassBySpringCGLIB$$dc8a47d1.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)\r\n at com.example.modules.system.service.impl.RoleServiceImpl$$EnhancerBySpringCGLIB$$d77f5b25.findByUsersId()\r\n at com.example.modules.system.controller.UserController.checkLevel(UserController.java:190)\r\n at com.example.modules.system.controller.UserController.updateUser(UserController.java:118)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$111a6b16.updateUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:920)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:89)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\nCaused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet\r\n at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)\r\n at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)\r\n at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)\r\n at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)\r\n at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:67)\r\n at org.hibernate.loader.Loader.getResultSet(Loader.java:2341)\r\n at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2094)\r\n at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2056)\r\n at org.hibernate.loader.Loader.doQuery(Loader.java:953)\r\n at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:350)\r\n at org.hibernate.loader.Loader.doList(Loader.java:2887)\r\n at org.hibernate.loader.Loader.doList(Loader.java:2869)\r\n at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2701)\r\n at org.hibernate.loader.Loader.list(Loader.java:2696)\r\n at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)\r\n at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2142)\r\n at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1163)\r\n at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:173)\r\n at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)\r\n at org.hibernate.query.Query.getResultList(Query.java:165)\r\n at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:126)\r\n at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)\r\n at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)\r\n at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)\r\n at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:618)\r\n at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)\r\n ... 122 more\r\nCaused by: java.sql.SQLSyntaxErrorException: Table \'eladmin.sys_users_roles\' doesn\'t exist\r\n at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)\r\n at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)\r\n at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003)\r\n at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeQuery(PreparedStatementSpy.java:780)\r\n at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3240)\r\n at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:465)\r\n at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3237)\r\n at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeQuery(PreparedStatementProxyImpl.java:181)\r\n at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:227)\r\n at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57)\r\n ... 150 more\r\n','2022-04-25 15:56:34'), +(3548,'新增用户','ERROR','com.example.modules.system.controller.UserController.createUser()','{\"gender\":\"男\",\"nickName\":\"xxxcds\",\"roles\":[{\"level\":3,\"dataScope\":\"本级\",\"id\":1}],\"jobs\":[{\"id\":8}],\"updateTime\":1650873529243,\"dept\":{\"subCount\":0,\"id\":7},\"isAdmin\":false,\"enabled\":true,\"password\":\"$2a$10$960h5w5vd1RMOIdiBp24HO2squJKm0D0EsZN5yMbZ7SF6VJlkaihW\",\"createBy\":\"admin\",\"phone\":\"15032145698\",\"updateBy\":\"admin\",\"createTime\":1650873529243,\"id\":7,\"email\":\"66@qq.com\",\"username\":\"ghjg\"}','192.168.32.87',97,'admin','内网IP','Chrome 98.0.4758.102','org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement\r\n at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281)\r\n at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)\r\n at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:538)\r\n at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)\r\n at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:633)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:386)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$adc982a6.create()\r\n at com.example.modules.system.controller.UserController.createUser(UserController.java:109)\r\n at com.example.modules.system.controller.UserController$$FastClassBySpringCGLIB$$3a3729d2.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)\r\n at com.example.aspect.LogAspect.logAround(LogAspect.java:68)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)\r\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)\r\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\r\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\r\n at com.example.modules.system.controller.UserController$$EnhancerBySpringCGLIB$$111a6b16.createUser()\r\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.lang.reflect.Method.invoke(Method.java:498)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\r\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\r\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)\r\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)\r\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)\r\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at com.example.modules.security.security.TokenFilter.doFilter(TokenFilter.java:89)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)\r\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)\r\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\r\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\r\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)\r\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)\r\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)\r\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n at java.lang.Thread.run(Thread.java:748)\r\nCaused by: org.hibernate.exception.SQLGrammarException: could not execute statement\r\n at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)\r\n at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)\r\n at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)\r\n at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)\r\n at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)\r\n at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46)\r\n at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1357)\r\n at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:52)\r\n at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)\r\n at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)\r\n at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)\r\n at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)\r\n at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)\r\n at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)\r\n at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)\r\n at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1363)\r\n at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:454)\r\n at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3213)\r\n at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2381)\r\n at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)\r\n at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)\r\n at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)\r\n at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)\r\n at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)\r\n at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:534)\r\n ... 118 more\r\nCaused by: java.sql.SQLSyntaxErrorException: Table \'eladmin.sys_users_roles\' doesn\'t exist\r\n at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)\r\n at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)\r\n at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347)\r\n at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)\r\n at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1080)\r\n at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeUpdate(FilterChainImpl.java:3253)\r\n at com.alibaba.druid.filter.FilterAdapter.preparedStatement_executeUpdate(FilterAdapter.java:1092)\r\n at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeUpdate(FilterEventAdapter.java:491)\r\n at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeUpdate(FilterChainImpl.java:3251)\r\n at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeUpdate(PreparedStatementProxyImpl.java:194)\r\n at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeUpdate(DruidPooledPreparedStatement.java:255)\r\n at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)\r\n ... 138 more\r\n','2022-04-25 15:58:49'); + +/*Table structure for table `sys_menu` */ + +DROP TABLE IF EXISTS `sys_menu`; + +CREATE TABLE `sys_menu` ( + `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `pid` bigint(20) DEFAULT NULL COMMENT '上级菜单ID', + `sub_count` int(5) DEFAULT '0' COMMENT '子菜单数目', + `type` int(11) DEFAULT NULL COMMENT '菜单类型', + `title` varchar(255) DEFAULT NULL COMMENT '菜单标题', + `name` varchar(255) DEFAULT NULL COMMENT '组件名称', + `component` varchar(255) DEFAULT NULL COMMENT '组件', + `menu_sort` int(5) DEFAULT NULL COMMENT '排序', + `icon` varchar(255) DEFAULT NULL COMMENT '图标', + `path` varchar(255) DEFAULT NULL COMMENT '链接地址', + `i_frame` bit(1) DEFAULT NULL COMMENT '是否外链', + `cache` bit(1) DEFAULT b'0' COMMENT '缓存', + `hidden` bit(1) DEFAULT b'0' COMMENT '隐藏', + `permission` varchar(255) DEFAULT NULL COMMENT '权限', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`menu_id`) USING BTREE, + UNIQUE KEY `uniq_title` (`title`), + UNIQUE KEY `uniq_name` (`name`), + KEY `inx_pid` (`pid`) +) ENGINE=InnoDB AUTO_INCREMENT=117 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统菜单'; + +/*Data for the table `sys_menu` */ + +INSERT INTO `sys_menu` VALUES (1, NULL, 7, 0, '系统管理', NULL, NULL, 1, 'system', 'system', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:11:29', NULL); +INSERT INTO `sys_menu` VALUES (2, 1, 3, 1, '用户管理', 'User', 'system/user/index', 2, 'peoples', 'user', b'0', b'0', b'0', 'user:list', NULL, NULL, '2018-12-18 15:14:44', NULL); +INSERT INTO `sys_menu` VALUES (3, 1, 3, 1, '角色管理', 'Role', 'system/role/index', 3, 'role', 'role', b'0', b'0', b'0', 'roles:list', NULL, NULL, '2018-12-18 15:16:07', NULL); +INSERT INTO `sys_menu` VALUES (5, 1, 3, 1, '菜单管理', 'Menu', 'system/menu/index', 5, 'menu', 'menu', b'0', b'0', b'0', 'menu:list', NULL, NULL, '2018-12-18 15:17:28', NULL); +INSERT INTO `sys_menu` VALUES (6, NULL, 5, 0, '系统监控', NULL, NULL, 10, 'monitor', 'monitor', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:17:48', NULL); +INSERT INTO `sys_menu` VALUES (7, 6, 0, 1, '操作日志', 'Log', 'monitor/log/index', 11, 'log', 'logs', b'0', b'1', b'0', NULL, NULL, 'admin', '2018-12-18 15:18:26', '2020-06-06 13:11:57'); +INSERT INTO `sys_menu` VALUES (9, 6, 0, 1, 'SQL监控', 'Sql', 'monitor/sql/index', 18, 'sqlMonitor', 'druid', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:19:34', NULL); +INSERT INTO `sys_menu` VALUES (10, NULL, 5, 0, 'DNS研究', NULL, NULL, 50, 'zujian', 'components', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-19 13:38:16', NULL); +INSERT INTO `sys_menu` VALUES (11, 10, 0, 1, '清华大学-NISL', 'Icons', 'components/icons/index', 51, 'icon', 'http://netsec.ccert.edu.cn/chs/', b'1', b'0', b'0', NULL, NULL, NULL, '2018-12-19 13:38:49', NULL); +INSERT INTO `sys_menu` VALUES (14, 36, 0, 1, 'DNS审查', 'Email', 'tools/email/index', 32, 'email', 'email', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-27 10:13:09', NULL); +INSERT INTO `sys_menu` VALUES (15, 10, 0, 1, 'APNIC', 'Editor', 'components/Editor', 52, 'fwb', 'https://blog.apnic.net/', b'1', b'0', b'0', NULL, NULL, NULL, '2018-12-27 11:58:25', NULL); +INSERT INTO `sys_menu` VALUES (18, 36, 0, 1, 'DNS威胁', 'Storage', 'tools/storage/index', 34, 'qiniu', 'storage', b'0', b'0', b'0', 'storage:list', NULL, NULL, '2018-12-31 11:12:15', NULL); +INSERT INTO `sys_menu` VALUES (19, 36, 0, 1, 'DNS集中性', 'AliPay', 'tools/aliPay/index', 35, 'alipay', 'aliPay', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-31 14:52:38', NULL); +INSERT INTO `sys_menu` VALUES (21, NULL, 1, 0, '关于', NULL, '', 900, 'menu', 'nested', b'0', b'0', b'0', NULL, NULL, 'admin', '2019-01-04 16:22:03', '2020-06-21 17:27:35'); +INSERT INTO `sys_menu` VALUES (22, 21, 0, 1, '二级菜单1', '', 'nested/menu2/index', 999, 'menu', 'menu2-1', b'0', b'0', b'1', NULL, NULL, 'admin', '2019-01-04 16:23:29', '2020-06-21 17:27:20'); +INSERT INTO `sys_menu` VALUES (23, 21, 0, 1, 'MESA', NULL, 'nested/menu2/index', 999, 'menu', 'https://www.mesalab.cn/', b'1', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:23:57', NULL); +INSERT INTO `sys_menu` VALUES (24, 22, 0, 1, '三级菜单1', 'Test', 'nested/menu1/menu1-1', 999, 'menu', 'menu1-1', b'0', b'0', b'1', NULL, NULL, NULL, '2019-01-04 16:24:48', NULL); +INSERT INTO `sys_menu` VALUES (27, 22, 0, 1, '三级菜单2', NULL, 'nested/menu1/menu1-2', 999, 'menu', 'menu1-2', b'0', b'0', b'1', NULL, NULL, NULL, '2019-01-07 17:27:32', NULL); +INSERT INTO `sys_menu` VALUES (28, 1, 3, 1, '任务调度', 'Timing', 'system/timing/index', 999, 'timing', 'timing', b'0', b'0', b'0', 'timing:list', NULL, NULL, '2019-01-07 20:34:40', NULL); +INSERT INTO `sys_menu` VALUES (30, 36, 0, 1, '新型DNS协议', 'GeneratorIndex', 'generator/index', 37, 'dev', 'generator', b'0', b'1', b'0', NULL, NULL, NULL, '2019-01-11 15:45:55', NULL); +INSERT INTO `sys_menu` VALUES (32, 6, 0, 1, '异常日志', 'ErrorLog', 'monitor/log/errorLog', 12, 'error', 'errorLog', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-13 13:49:03', NULL); +INSERT INTO `sys_menu` VALUES (33, 10, 0, 1, '南加州大学-ANT Lab', 'Markdown', 'components/MarkDown', 53, 'markdown', 'https://ant.isi.edu/', b'1', b'0', b'0', NULL, NULL, NULL, '2019-03-08 13:46:44', NULL); +INSERT INTO `sys_menu` VALUES (34, 10, 0, 1, '普林斯顿大学-Noise Lab', 'YamlEdit', 'components/YamlEdit', 54, 'dev', 'https://noise.cs.uchicago.edu/security.html', b'1', b'0', b'0', NULL, NULL, NULL, '2019-03-08 15:49:40', NULL); +INSERT INTO `sys_menu` VALUES (35, 1, 3, 1, '部门管理', 'Dept', 'system/dept/index', 6, 'dept', 'dept', b'0', b'0', b'0', 'dept:list', NULL, NULL, '2019-03-25 09:46:00', NULL); +INSERT INTO `sys_menu` VALUES (36, NULL, 7, 0, '专题报告', NULL, '', 30, 'sys-tools', 'sys-tools', b'0', b'0', b'0', NULL, NULL, NULL, '2019-03-29 10:57:35', NULL); +INSERT INTO `sys_menu` VALUES (37, 1, 3, 1, '岗位管理', 'Job', 'system/job/index', 7, 'Steve-Jobs', 'job', b'0', b'0', b'0', 'job:list', NULL, NULL, '2019-03-29 13:51:18', NULL); +INSERT INTO `sys_menu` VALUES (38, 36, 0, 1, '接口文档', 'Swagger', 'tools/swagger/index', 36, 'swagger', 'swagger2', b'0', b'0', b'1', NULL, NULL, NULL, '2019-03-29 19:57:53', NULL); +INSERT INTO `sys_menu` VALUES (39, 1, 3, 1, '字典管理', 'Dict', 'system/dict/index', 8, 'dictionary', 'dict', b'0', b'0', b'0', 'dict:list', NULL, NULL, '2019-04-10 11:49:04', NULL); +INSERT INTO `sys_menu` VALUES (41, 6, 0, 1, '在线用户', 'OnlineUser', 'monitor/online/index', 10, 'Steve-Jobs', 'online', b'0', b'0', b'0', NULL, NULL, NULL, '2019-10-26 22:08:43', NULL); +INSERT INTO `sys_menu` VALUES (44, 2, 0, 2, '用户新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'user:add', NULL, NULL, '2019-10-29 10:59:46', NULL); +INSERT INTO `sys_menu` VALUES (45, 2, 0, 2, '用户编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'user:edit', NULL, NULL, '2019-10-29 11:00:08', NULL); +INSERT INTO `sys_menu` VALUES (46, 2, 0, 2, '用户删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'user:del', NULL, NULL, '2019-10-29 11:00:23', NULL); +INSERT INTO `sys_menu` VALUES (48, 3, 0, 2, '角色创建', NULL, '', 2, '', '', b'0', b'0', b'0', 'roles:add', NULL, NULL, '2019-10-29 12:45:34', NULL); +INSERT INTO `sys_menu` VALUES (49, 3, 0, 2, '角色修改', NULL, '', 3, '', '', b'0', b'0', b'0', 'roles:edit', NULL, NULL, '2019-10-29 12:46:16', NULL); +INSERT INTO `sys_menu` VALUES (50, 3, 0, 2, '角色删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'roles:del', NULL, NULL, '2019-10-29 12:46:51', NULL); +INSERT INTO `sys_menu` VALUES (52, 5, 0, 2, '菜单新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'menu:add', NULL, NULL, '2019-10-29 12:55:07', NULL); +INSERT INTO `sys_menu` VALUES (53, 5, 0, 2, '菜单编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'menu:edit', NULL, NULL, '2019-10-29 12:55:40', NULL); +INSERT INTO `sys_menu` VALUES (54, 5, 0, 2, '菜单删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'menu:del', NULL, NULL, '2019-10-29 12:56:00', NULL); +INSERT INTO `sys_menu` VALUES (56, 35, 0, 2, '部门新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'dept:add', NULL, NULL, '2019-10-29 12:57:09', NULL); +INSERT INTO `sys_menu` VALUES (57, 35, 0, 2, '部门编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'dept:edit', NULL, NULL, '2019-10-29 12:57:27', NULL); +INSERT INTO `sys_menu` VALUES (58, 35, 0, 2, '部门删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'dept:del', NULL, NULL, '2019-10-29 12:57:41', NULL); +INSERT INTO `sys_menu` VALUES (60, 37, 0, 2, '岗位新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'job:add', NULL, NULL, '2019-10-29 12:58:27', NULL); +INSERT INTO `sys_menu` VALUES (61, 37, 0, 2, '岗位编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'job:edit', NULL, NULL, '2019-10-29 12:58:45', NULL); +INSERT INTO `sys_menu` VALUES (62, 37, 0, 2, '岗位删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'job:del', NULL, NULL, '2019-10-29 12:59:04', NULL); +INSERT INTO `sys_menu` VALUES (64, 39, 0, 2, '字典新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'dict:add', NULL, NULL, '2019-10-29 13:00:17', NULL); +INSERT INTO `sys_menu` VALUES (65, 39, 0, 2, '字典编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'dict:edit', NULL, NULL, '2019-10-29 13:00:42', NULL); +INSERT INTO `sys_menu` VALUES (66, 39, 0, 2, '字典删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'dict:del', NULL, NULL, '2019-10-29 13:00:59', NULL); +INSERT INTO `sys_menu` VALUES (73, 28, 0, 2, '任务新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'timing:add', NULL, NULL, '2019-10-29 13:07:28', NULL); +INSERT INTO `sys_menu` VALUES (74, 28, 0, 2, '任务编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'timing:edit', NULL, NULL, '2019-10-29 13:07:41', NULL); +INSERT INTO `sys_menu` VALUES (75, 28, 0, 2, '任务删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'timing:del', NULL, NULL, '2019-10-29 13:07:54', NULL); +INSERT INTO `sys_menu` VALUES (77, 18, 0, 2, '上传文件', NULL, '', 2, '', '', b'0', b'0', b'0', 'storage:add', NULL, NULL, '2019-10-29 13:09:09', NULL); +INSERT INTO `sys_menu` VALUES (78, 18, 0, 2, '文件编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'storage:edit', NULL, NULL, '2019-10-29 13:09:22', NULL); +INSERT INTO `sys_menu` VALUES (79, 18, 0, 2, '文件删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'storage:del', NULL, NULL, '2019-10-29 13:09:34', NULL); +INSERT INTO `sys_menu` VALUES (80, 6, 0, 1, '服务监控', 'ServerMonitor', 'monitor/server/index', 14, 'codeConsole', 'server', b'0', b'0', b'0', 'monitor:list', NULL, 'admin', '2019-11-07 13:06:39', '2020-05-04 18:20:50'); +INSERT INTO `sys_menu` VALUES (82, 36, 0, 1, '生成配置', 'GeneratorConfig', 'generator/config', 33, 'dev', 'generator/config/:tableName', b'0', b'1', b'1', '', NULL, NULL, '2019-11-17 20:08:56', NULL); +INSERT INTO `sys_menu` VALUES (83, 10, 0, 1, '图表库', 'Echarts', 'components/Echarts', 50, 'chart', 'echarts', b'0', b'1', b'1', '', NULL, NULL, '2019-11-21 09:04:32', NULL); +INSERT INTO `sys_menu` VALUES (102, 97, 0, 2, '删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'deployHistory:del', NULL, NULL, '2019-11-17 09:32:48', NULL); +INSERT INTO `sys_menu` VALUES (103, 92, 0, 2, '服务器新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:add', NULL, NULL, '2019-11-17 11:08:33', NULL); +INSERT INTO `sys_menu` VALUES (104, 92, 0, 2, '服务器编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:edit', NULL, NULL, '2019-11-17 11:08:57', NULL); +INSERT INTO `sys_menu` VALUES (105, 92, 0, 2, '服务器删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:del', NULL, NULL, '2019-11-17 11:09:15', NULL); +INSERT INTO `sys_menu` VALUES (106, 93, 0, 2, '应用新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:add', NULL, NULL, '2019-11-17 11:10:03', NULL); +INSERT INTO `sys_menu` VALUES (107, 93, 0, 2, '应用编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:edit', NULL, NULL, '2019-11-17 11:10:28', NULL); +INSERT INTO `sys_menu` VALUES (108, 93, 0, 2, '应用删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:del', NULL, NULL, '2019-11-17 11:10:55', NULL); +INSERT INTO `sys_menu` VALUES (109, 94, 0, 2, '部署新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:add', NULL, NULL, '2019-11-17 11:11:22', NULL); +INSERT INTO `sys_menu` VALUES (110, 94, 0, 2, '部署编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:edit', NULL, NULL, '2019-11-17 11:11:41', NULL); +INSERT INTO `sys_menu` VALUES (111, 94, 0, 2, '部署删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:del', NULL, NULL, '2019-11-17 11:12:01', NULL); +INSERT INTO `sys_menu` VALUES (112, 98, 0, 2, '数据库新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:add', NULL, NULL, '2019-11-17 11:12:43', NULL); +INSERT INTO `sys_menu` VALUES (113, 98, 0, 2, '数据库编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:edit', NULL, NULL, '2019-11-17 11:12:58', NULL); +INSERT INTO `sys_menu` VALUES (114, 98, 0, 2, '数据库删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:del', NULL, NULL, '2019-11-17 11:13:14', NULL); +INSERT INTO `sys_menu` VALUES (116, 36, 0, 1, '生成预览', 'Preview', 'generator/preview', 999, 'java', 'generator/preview/:tableName', b'0', b'1', b'1', NULL, NULL, NULL, '2019-11-26 14:54:36', NULL); + +/*Table structure for table `sys_quartz_job` */ + +DROP TABLE IF EXISTS `sys_quartz_job`; + +CREATE TABLE `sys_quartz_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bean_name` varchar(255) DEFAULT NULL COMMENT 'Spring Bean名称', + `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron 表达式', + `is_pause` bit(1) DEFAULT NULL COMMENT '状态:1暂停、0启用', + `job_name` varchar(255) DEFAULT NULL COMMENT '任务名称', + `method_name` varchar(255) DEFAULT NULL COMMENT '方法名称', + `params` varchar(255) DEFAULT NULL COMMENT '参数', + `description` varchar(255) DEFAULT NULL COMMENT '备注', + `person_in_charge` varchar(100) DEFAULT NULL COMMENT '负责人', + `email` varchar(100) DEFAULT NULL COMMENT '报警邮箱', + `sub_task` varchar(100) DEFAULT NULL COMMENT '子任务ID', + `pause_after_failure` bit(1) DEFAULT NULL COMMENT '任务失败后是否暂停', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`job_id`) USING BTREE, + KEY `inx_is_pause` (`is_pause`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务'; + +/*Data for the table `sys_quartz_job` */ + +insert into `sys_quartz_job`(`job_id`,`bean_name`,`cron_expression`,`is_pause`,`job_name`,`method_name`,`params`,`description`,`person_in_charge`,`email`,`sub_task`,`pause_after_failure`,`create_by`,`update_by`,`create_time`,`update_time`) values +(2,'testTask','0/5 * * * * ?','','测试1','run1','test','带参测试,多参使用json','测试',NULL,NULL,NULL,NULL,'admin','2019-08-22 14:08:29','2020-05-24 13:58:33'), +(3,'testTask','0/5 * * * * ?','','测试','run','','不带参测试','Zheng Jie','','5,6','',NULL,'admin','2019-09-26 16:44:39','2020-05-24 14:48:12'), +(5,'Test','0/5 * * * * ?','','任务告警测试','run',NULL,'测试','test','',NULL,'','admin','admin','2020-05-05 20:32:41','2020-05-05 20:36:13'), +(6,'testTask','0/5 * * * * ?','','测试3','run2',NULL,'测试3','Zheng Jie','',NULL,'','admin','admin','2020-05-05 20:35:41','2020-05-05 20:36:07'); + +/*Table structure for table `sys_quartz_log` */ + +DROP TABLE IF EXISTS `sys_quartz_log`; + +CREATE TABLE `sys_quartz_log` ( + `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bean_name` varchar(255) DEFAULT NULL, + `create_time` datetime DEFAULT NULL, + `cron_expression` varchar(255) DEFAULT NULL, + `exception_detail` text, + `is_success` bit(1) DEFAULT NULL, + `job_name` varchar(255) DEFAULT NULL, + `method_name` varchar(255) DEFAULT NULL, + `params` varchar(255) DEFAULT NULL, + `time` bigint(20) DEFAULT NULL, + PRIMARY KEY (`log_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务日志'; + +/*Data for the table `sys_quartz_log` */ + +/*Table structure for table `sys_role` */ + +DROP TABLE IF EXISTS `sys_role`; + +CREATE TABLE `sys_role` ( + `role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '名称', + `level` int(255) DEFAULT NULL COMMENT '角色级别', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `data_scope` varchar(255) DEFAULT NULL COMMENT '数据权限', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`role_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`), + KEY `role_name_index` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色表'; + +/*Data for the table `sys_role` */ + +INSERT INTO `sys_role` VALUES (1, '超级管理员', 1, '-', '全部', NULL, 'admin', '2018-11-23 11:04:37', '2022-06-13 11:18:51'); +INSERT INTO `sys_role` VALUES (2, '普通用户', 2, '-', '本级', NULL, 'admin', '2018-11-23 13:09:06', '2020-09-05 10:45:12'); +INSERT INTO `sys_role` VALUES (3, '系统管理员', 1, '系统菜单,监控,用户,部门等系统信息管理员', '全部', 'admin', 'sysadmin', '2022-06-13 11:17:59', '2022-06-13 11:36:44'); + +/*Table structure for table `sys_roles_depts` */ + +DROP TABLE IF EXISTS `sys_roles_depts`; + +CREATE TABLE `sys_roles_depts` ( + `role_id` bigint(20) NOT NULL, + `dept_id` bigint(20) NOT NULL, + PRIMARY KEY (`role_id`,`dept_id`) USING BTREE, + KEY `FK7qg6itn5ajdoa9h9o78v9ksur` (`dept_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色部门关联'; + +/*Data for the table `sys_roles_depts` */ + +/*Table structure for table `sys_roles_menus` */ + +DROP TABLE IF EXISTS `sys_roles_menus`; + +CREATE TABLE `sys_roles_menus` ( + `menu_id` bigint(20) NOT NULL COMMENT '菜单ID', + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + PRIMARY KEY (`menu_id`,`role_id`) USING BTREE, + KEY `FKcngg2qadojhi3a651a5adkvbq` (`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色菜单关联'; + +/*Data for the table `sys_roles_menus` */ + +INSERT INTO `sys_roles_menus` VALUES (1, 2); +INSERT INTO `sys_roles_menus` VALUES (1, 3); +INSERT INTO `sys_roles_menus` VALUES (2, 2); +INSERT INTO `sys_roles_menus` VALUES (2, 3); +INSERT INTO `sys_roles_menus` VALUES (3, 3); +INSERT INTO `sys_roles_menus` VALUES (5, 3); +INSERT INTO `sys_roles_menus` VALUES (6, 1); +INSERT INTO `sys_roles_menus` VALUES (6, 2); +INSERT INTO `sys_roles_menus` VALUES (6, 3); +INSERT INTO `sys_roles_menus` VALUES (7, 1); +INSERT INTO `sys_roles_menus` VALUES (7, 2); +INSERT INTO `sys_roles_menus` VALUES (7, 3); +INSERT INTO `sys_roles_menus` VALUES (9, 1); +INSERT INTO `sys_roles_menus` VALUES (9, 2); +INSERT INTO `sys_roles_menus` VALUES (9, 3); +INSERT INTO `sys_roles_menus` VALUES (10, 1); +INSERT INTO `sys_roles_menus` VALUES (10, 2); +INSERT INTO `sys_roles_menus` VALUES (11, 1); +INSERT INTO `sys_roles_menus` VALUES (11, 2); +INSERT INTO `sys_roles_menus` VALUES (14, 1); +INSERT INTO `sys_roles_menus` VALUES (14, 2); +INSERT INTO `sys_roles_menus` VALUES (15, 1); +INSERT INTO `sys_roles_menus` VALUES (15, 2); +INSERT INTO `sys_roles_menus` VALUES (18, 1); +INSERT INTO `sys_roles_menus` VALUES (19, 1); +INSERT INTO `sys_roles_menus` VALUES (19, 2); +INSERT INTO `sys_roles_menus` VALUES (21, 1); +INSERT INTO `sys_roles_menus` VALUES (21, 2); +INSERT INTO `sys_roles_menus` VALUES (22, 1); +INSERT INTO `sys_roles_menus` VALUES (22, 2); +INSERT INTO `sys_roles_menus` VALUES (23, 1); +INSERT INTO `sys_roles_menus` VALUES (23, 2); +INSERT INTO `sys_roles_menus` VALUES (24, 1); +INSERT INTO `sys_roles_menus` VALUES (24, 2); +INSERT INTO `sys_roles_menus` VALUES (27, 1); +INSERT INTO `sys_roles_menus` VALUES (27, 2); +INSERT INTO `sys_roles_menus` VALUES (28, 3); +INSERT INTO `sys_roles_menus` VALUES (30, 1); +INSERT INTO `sys_roles_menus` VALUES (30, 2); +INSERT INTO `sys_roles_menus` VALUES (32, 1); +INSERT INTO `sys_roles_menus` VALUES (32, 2); +INSERT INTO `sys_roles_menus` VALUES (32, 3); +INSERT INTO `sys_roles_menus` VALUES (33, 1); +INSERT INTO `sys_roles_menus` VALUES (33, 2); +INSERT INTO `sys_roles_menus` VALUES (34, 1); +INSERT INTO `sys_roles_menus` VALUES (34, 2); +INSERT INTO `sys_roles_menus` VALUES (35, 3); +INSERT INTO `sys_roles_menus` VALUES (36, 1); +INSERT INTO `sys_roles_menus` VALUES (36, 2); +INSERT INTO `sys_roles_menus` VALUES (37, 3); +INSERT INTO `sys_roles_menus` VALUES (38, 1); +INSERT INTO `sys_roles_menus` VALUES (39, 3); +INSERT INTO `sys_roles_menus` VALUES (41, 1); +INSERT INTO `sys_roles_menus` VALUES (41, 3); +INSERT INTO `sys_roles_menus` VALUES (44, 3); +INSERT INTO `sys_roles_menus` VALUES (45, 3); +INSERT INTO `sys_roles_menus` VALUES (46, 3); +INSERT INTO `sys_roles_menus` VALUES (48, 3); +INSERT INTO `sys_roles_menus` VALUES (49, 3); +INSERT INTO `sys_roles_menus` VALUES (50, 3); +INSERT INTO `sys_roles_menus` VALUES (52, 3); +INSERT INTO `sys_roles_menus` VALUES (53, 3); +INSERT INTO `sys_roles_menus` VALUES (54, 3); +INSERT INTO `sys_roles_menus` VALUES (56, 3); +INSERT INTO `sys_roles_menus` VALUES (57, 3); +INSERT INTO `sys_roles_menus` VALUES (58, 3); +INSERT INTO `sys_roles_menus` VALUES (60, 3); +INSERT INTO `sys_roles_menus` VALUES (61, 3); +INSERT INTO `sys_roles_menus` VALUES (62, 3); +INSERT INTO `sys_roles_menus` VALUES (64, 3); +INSERT INTO `sys_roles_menus` VALUES (65, 3); +INSERT INTO `sys_roles_menus` VALUES (66, 3); +INSERT INTO `sys_roles_menus` VALUES (73, 3); +INSERT INTO `sys_roles_menus` VALUES (74, 3); +INSERT INTO `sys_roles_menus` VALUES (75, 3); +INSERT INTO `sys_roles_menus` VALUES (77, 1); +INSERT INTO `sys_roles_menus` VALUES (78, 1); +INSERT INTO `sys_roles_menus` VALUES (79, 1); +INSERT INTO `sys_roles_menus` VALUES (80, 1); +INSERT INTO `sys_roles_menus` VALUES (80, 2); +INSERT INTO `sys_roles_menus` VALUES (80, 3); +INSERT INTO `sys_roles_menus` VALUES (82, 1); +INSERT INTO `sys_roles_menus` VALUES (82, 2); +INSERT INTO `sys_roles_menus` VALUES (83, 1); +INSERT INTO `sys_roles_menus` VALUES (83, 2); +INSERT INTO `sys_roles_menus` VALUES (90, 1); +INSERT INTO `sys_roles_menus` VALUES (92, 1); +INSERT INTO `sys_roles_menus` VALUES (93, 1); +INSERT INTO `sys_roles_menus` VALUES (94, 1); +INSERT INTO `sys_roles_menus` VALUES (97, 1); +INSERT INTO `sys_roles_menus` VALUES (98, 1); +INSERT INTO `sys_roles_menus` VALUES (102, 1); +INSERT INTO `sys_roles_menus` VALUES (103, 1); +INSERT INTO `sys_roles_menus` VALUES (104, 1); +INSERT INTO `sys_roles_menus` VALUES (105, 1); +INSERT INTO `sys_roles_menus` VALUES (106, 1); +INSERT INTO `sys_roles_menus` VALUES (107, 1); +INSERT INTO `sys_roles_menus` VALUES (108, 1); +INSERT INTO `sys_roles_menus` VALUES (109, 1); +INSERT INTO `sys_roles_menus` VALUES (110, 1); +INSERT INTO `sys_roles_menus` VALUES (111, 1); +INSERT INTO `sys_roles_menus` VALUES (112, 1); +INSERT INTO `sys_roles_menus` VALUES (113, 1); +INSERT INTO `sys_roles_menus` VALUES (114, 1); +INSERT INTO `sys_roles_menus` VALUES (116, 1); +INSERT INTO `sys_roles_menus` VALUES (116, 2); +INSERT INTO `sys_roles_menus` VALUES (120, 1); + +/*Table structure for table `sys_user` */ + +DROP TABLE IF EXISTS `sys_user`; + +CREATE TABLE `sys_user` ( + `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `dept_id` bigint(20) DEFAULT NULL COMMENT '部门名称', + `username` varchar(255) DEFAULT NULL COMMENT '用户名', + `nick_name` varchar(255) DEFAULT NULL COMMENT '昵称', + `gender` varchar(2) DEFAULT NULL COMMENT '性别', + `phone` varchar(255) DEFAULT NULL COMMENT '手机号码', + `email` varchar(255) DEFAULT NULL COMMENT '邮箱', + `avatar_name` varchar(255) DEFAULT NULL COMMENT '头像地址', + `avatar_path` varchar(255) DEFAULT NULL COMMENT '头像真实路径', + `password` varchar(255) DEFAULT NULL COMMENT '密码', + `is_admin` bit(1) DEFAULT b'0' COMMENT '是否为admin账号', + `enabled` bigint(20) DEFAULT NULL COMMENT '状态:1启用、0禁用', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `pwd_reset_time` datetime DEFAULT NULL COMMENT '修改密码的时间', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`user_id`) USING BTREE, + UNIQUE KEY `UK_kpubos9gc2cvtkb0thktkbkes` (`email`) USING BTREE, + UNIQUE KEY `username` (`username`) USING BTREE, + UNIQUE KEY `uniq_username` (`username`), + UNIQUE KEY `uniq_email` (`email`), + KEY `FK5rwmryny6jthaaxkogownknqp` (`dept_id`) USING BTREE, + KEY `FKpq2dhypk2qgt68nauh2by22jb` (`avatar_name`) USING BTREE, + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统用户'; + +/*Data for the table `sys_user` */ + +INSERT INTO `sys_user` VALUES (1, 2, 'admin', '管理员', '男', '18888888888', '201507802@qq.com', 'avatar-20200806032259161.png', '/Users/jie/Documents/work/me/admin/eladmin/~/avatar/avatar-20200806032259161.png', '$2a$10$Egp1/gvFlt7zhlXVfEFw4OfWQCGPw0ClmMcc6FjTnvXNRVf9zdMRa', b'1', 1, NULL, 'admin', '2020-05-03 16:38:31', '2018-08-23 09:11:56', '2022-04-24 17:03:00'); +INSERT INTO `sys_user` VALUES (2, 2, 'test', '测试', '男', '19999999999', '231@qq.com', NULL, NULL, '$2a$10$4XcyudOYTSz6fue6KFNMHeUQnCX5jbBQypLEnGk1PmekXt5c95JcK', b'0', 1, 'admin', 'admin', NULL, '2020-05-05 11:15:49', '2022-04-24 11:18:18'); +INSERT INTO `sys_user` VALUES (3, 8, 'test2', 'aaa', '男', '15014236547', '22@qq.com', NULL, NULL, '$2a$10$39eu19DlibPMfC9EEPPErO86uBAZhCzySlhvSn/Evg0gdInNeNB3W', b'0', 1, 'admin', 'admin', NULL, '2022-04-24 16:51:41', '2022-04-24 16:51:41'); +INSERT INTO `sys_user` VALUES (4, 7, 'xx', 'xx', '男', '15044878963', '3333@qq.com', NULL, NULL, '$2a$10$NGkgAoFjWGUueMJ81409I.mAJXa2KHf9b9GwgWZOCN8TdL35lLigy', b'0', 1, 'admin', 'admin', NULL, '2022-04-24 17:47:01', '2022-04-24 17:47:01'); +INSERT INTO `sys_user` VALUES (5, NULL, 'xxx', 'xxx', '男', '15044878962', '33233@qq.com', NULL, NULL, '$2a$10$y6hqVUiy6YSLngBuK4v/weonLYkyuIltwG0HTUCMTuCNtnGkFsDpW', b'0', 1, 'admin', 'admin', NULL, '2022-04-24 17:52:19', '2022-04-24 17:52:19'); +INSERT INTO `sys_user` VALUES (6, 7, 'bbbb', 'ssss', '男', '15033698785', 'sasa@qq.com', NULL, NULL, '$2a$10$P.hvDg2NaJs/kYeLn15u4upYvYxbl4HB4ExNERrU1SM5EqTQF2Hae', b'0', 1, 'admin', 'admin', NULL, '2022-04-25 15:50:58', '2022-04-25 15:50:58'); +INSERT INTO `sys_user` VALUES (7, 5, 'sysadmin', 'sysadmin', '男', '18765432100', '18765432100@qq.com', NULL, NULL, '$2a$10$Wp0dKiYZpAgNap.0NhK40.LEd2AgDTFC.i/unDcRPmICf9JMEcYzC', b'0', 1, 'admin', 'admin', NULL, '2022-06-13 11:20:03', '2022-06-13 11:20:03'); + +/*Table structure for table `sys_users_jobs` */ + +DROP TABLE IF EXISTS `sys_users_jobs`; + +CREATE TABLE `sys_users_jobs` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `job_id` bigint(20) NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`,`job_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `sys_users_jobs` */ + +insert into `sys_users_jobs`(`user_id`,`job_id`) values +(1,11), +(2,12), +(3,8), +(4,8), +(6,8); + +/*Table structure for table `sys_users_roles` */ + +DROP TABLE IF EXISTS `sys_users_roles`; + +CREATE TABLE `sys_users_roles` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`,`role_id`) USING BTREE, + KEY `FKq4eq273l04bpu4efj0jd0jb98` (`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户角色关联'; + +/*Data for the table `sys_users_roles` */ + +insert into `sys_users_roles`(`user_id`,`role_id`) values +(1,1), +(6,1), +(2,2), +(3,2), +(4,2); + +/*Table structure for table `tool_alipay_config` */ + +DROP TABLE IF EXISTS `tool_alipay_config`; + +CREATE TABLE `tool_alipay_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `app_id` varchar(255) DEFAULT NULL COMMENT '应用ID', + `charset` varchar(255) DEFAULT NULL COMMENT '编码', + `format` varchar(255) DEFAULT NULL COMMENT '类型 固定格式json', + `gateway_url` varchar(255) DEFAULT NULL COMMENT '网关地址', + `notify_url` varchar(255) DEFAULT NULL COMMENT '异步回调', + `private_key` text COMMENT '私钥', + `public_key` text COMMENT '公钥', + `return_url` varchar(255) DEFAULT NULL COMMENT '回调地址', + `sign_type` varchar(255) DEFAULT NULL COMMENT '签名方式', + `sys_service_provider_id` varchar(255) DEFAULT NULL COMMENT '商户号', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='支付宝配置类'; + +/*Data for the table `tool_alipay_config` */ + +insert into `tool_alipay_config`(`config_id`,`app_id`,`charset`,`format`,`gateway_url`,`notify_url`,`private_key`,`public_key`,`return_url`,`sign_type`,`sys_service_provider_id`) values +(1,'2016091700532697','utf-8','JSON','https://openapi.alipaydev.com/gateway.do','http://api.auauz.net/api/aliPay/notify','MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5js8sInU10AJ0cAQ8UMMyXrQ+oHZEkVt5lBwsStmTJ7YikVYgbskx1YYEXTojRsWCb+SH/kDmDU4pK/u91SJ4KFCRMF2411piYuXU/jF96zKrADznYh/zAraqT6hvAIVtQAlMHN53nx16rLzZ/8jDEkaSwT7+HvHiS+7sxSojnu/3oV7BtgISoUNstmSe8WpWHOaWv19xyS+Mce9MY4BfseFhzTICUymUQdd/8hXA28/H6osUfAgsnxAKv7Wil3aJSgaJczWuflYOve0dJ3InZkhw5Cvr0atwpk8YKBQjy5CdkoHqvkOcIB+cYHXJKzOE5tqU7inSwVbHzOLQ3XbnAgMBAAECggEAVJp5eT0Ixg1eYSqFs9568WdetUNCSUchNxDBu6wxAbhUgfRUGZuJnnAll63OCTGGck+EGkFh48JjRcBpGoeoHLL88QXlZZbC/iLrea6gcDIhuvfzzOffe1RcZtDFEj9hlotg8dQj1tS0gy9pN9g4+EBH7zeu+fyv+qb2e/v1l6FkISXUjpkD7RLQr3ykjiiEw9BpeKb7j5s7Kdx1NNIzhkcQKNqlk8JrTGDNInbDM6inZfwwIO2R1DHinwdfKWkvOTODTYa2MoAvVMFT9Bec9FbLpoWp7ogv1JMV9svgrcF9XLzANZ/OQvkbe9TV9GWYvIbxN6qwQioKCWO4GPnCAQKBgQDgW5MgfhX8yjXqoaUy/d1VjI8dHeIyw8d+OBAYwaxRSlCfyQ+tieWcR2HdTzPca0T0GkWcKZm0ei5xRURgxt4DUDLXNh26HG0qObbtLJdu/AuBUuCqgOiLqJ2f1uIbrz6OZUHns+bT/jGW2Ws8+C13zTCZkZt9CaQsrp3QOGDx5wKBgQDTul39hp3ZPwGNFeZdkGoUoViOSd5Lhowd5wYMGAEXWRLlU8z+smT5v0POz9JnIbCRchIY2FAPKRdVTICzmPk2EPJFxYTcwaNbVqL6lN7J2IlXXMiit5QbiLauo55w7plwV6LQmKm9KV7JsZs5XwqF7CEovI7GevFzyD3w+uizAQKBgC3LY1eRhOlpWOIAhpjG6qOoohmeXOphvdmMlfSHq6WYFqbWwmV4rS5d/6LNpNdL6fItXqIGd8I34jzql49taCmi+A2nlR/E559j0mvM20gjGDIYeZUz5MOE8k+K6/IcrhcgofgqZ2ZED1ksHdB/E8DNWCswZl16V1FrfvjeWSNnAoGAMrBplCrIW5xz+J0Hm9rZKrs+AkK5D4fUv8vxbK/KgxZ2KaUYbNm0xv39c+PZUYuFRCz1HDGdaSPDTE6WeWjkMQd5mS6ikl9hhpqFRkyh0d0fdGToO9yLftQKOGE/q3XUEktI1XvXF0xyPwNgUCnq0QkpHyGVZPtGFxwXiDvpvgECgYA5PoB+nY8iDiRaJNko9w0hL4AeKogwf+4TbCw+KWVEn6jhuJa4LFTdSqp89PktQaoVpwv92el/AhYjWOl/jVCm122f9b7GyoelbjMNolToDwe5pF5RnSpEuDdLy9MfE8LnE3PlbE7E5BipQ3UjSebkgNboLHH/lNZA5qvEtvbfvQ==','MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAut9evKRuHJ/2QNfDlLwvN/S8l9hRAgPbb0u61bm4AtzaTGsLeMtScetxTWJnVvAVpMS9luhEJjt+Sbk5TNLArsgzzwARgaTKOLMT1TvWAK5EbHyI+eSrc3s7Awe1VYGwcubRFWDm16eQLv0k7iqiw+4mweHSz/wWyvBJVgwLoQ02btVtAQErCfSJCOmt0Q/oJQjj08YNRV4EKzB19+f5A+HQVAKy72dSybTzAK+3FPtTtNen/+b5wGeat7c32dhYHnGorPkPeXLtsqqUTp1su5fMfd4lElNdZaoCI7osZxWWUo17vBCZnyeXc9fk0qwD9mK6yRAxNbrY72Xx5VqIqwIDAQAB','http://api.auauz.net/api/aliPay/return','RSA2','2088102176044281'); + +/*Table structure for table `tool_email_config` */ + +DROP TABLE IF EXISTS `tool_email_config`; + +CREATE TABLE `tool_email_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `from_user` varchar(255) DEFAULT NULL COMMENT '收件人', + `host` varchar(255) DEFAULT NULL COMMENT '邮件服务器SMTP地址', + `pass` varchar(255) DEFAULT NULL COMMENT '密码', + `port` varchar(255) DEFAULT NULL COMMENT '端口', + `user` varchar(255) DEFAULT NULL COMMENT '发件者用户名', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='邮箱配置'; + +/*Data for the table `tool_email_config` */ + +/*Table structure for table `tool_local_storage` */ + +DROP TABLE IF EXISTS `tool_local_storage`; + +CREATE TABLE `tool_local_storage` ( + `storage_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `real_name` varchar(255) DEFAULT NULL COMMENT '文件真实的名称', + `name` varchar(255) DEFAULT NULL COMMENT '文件名', + `suffix` varchar(255) DEFAULT NULL COMMENT '后缀', + `path` varchar(255) DEFAULT NULL COMMENT '路径', + `type` varchar(255) DEFAULT NULL COMMENT '类型', + `size` varchar(100) DEFAULT NULL COMMENT '大小', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`storage_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='本地存储'; + +/*Data for the table `tool_local_storage` */ + +/*Table structure for table `tool_qiniu_config` */ + +DROP TABLE IF EXISTS `tool_qiniu_config`; + +CREATE TABLE `tool_qiniu_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `access_key` text COMMENT 'accessKey', + `bucket` varchar(255) DEFAULT NULL COMMENT 'Bucket 识别符', + `host` varchar(255) NOT NULL COMMENT '外链域名', + `secret_key` text COMMENT 'secretKey', + `type` varchar(255) DEFAULT NULL COMMENT '空间类型', + `zone` varchar(255) DEFAULT NULL COMMENT '机房', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='七牛云配置'; + +/*Data for the table `tool_qiniu_config` */ + +/*Table structure for table `tool_qiniu_content` */ + +DROP TABLE IF EXISTS `tool_qiniu_content`; + +CREATE TABLE `tool_qiniu_content` ( + `content_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bucket` varchar(255) DEFAULT NULL COMMENT 'Bucket 识别符', + `name` varchar(255) DEFAULT NULL COMMENT '文件名称', + `size` varchar(255) DEFAULT NULL COMMENT '文件大小', + `type` varchar(255) DEFAULT NULL COMMENT '文件类型:私有或公开', + `url` varchar(255) DEFAULT NULL COMMENT '文件url', + `suffix` varchar(255) DEFAULT NULL COMMENT '文件后缀', + `update_time` datetime DEFAULT NULL COMMENT '上传或同步的时间', + PRIMARY KEY (`content_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='七牛云文件存储'; + +/*Data for the table `tool_qiniu_content` */ + +/*Table structure for table `vulnerability` */ + +DROP TABLE IF EXISTS `vulnerability`; + +CREATE TABLE `vulnerability` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `component` varchar(128) DEFAULT NULL, + `vulnerability` varchar(128) DEFAULT NULL, + `timestamp` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `vulnerability` */ + +insert into `vulnerability`(`id`,`component`,`vulnerability`,`timestamp`) values +(1,'nginx','nginx漏洞','2022-05-05 14:09:00'), +(2,'bind','bind漏洞','2022-05-05 14:09:13'), +(3,'unbound','unbound漏洞','2022-05-11 14:49:14'); + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/UI source code/dns-dev-2.0/sql/eladmin.sql b/UI source code/dns-dev-2.0/sql/eladmin.sql new file mode 100644 index 0000000..da53710 --- /dev/null +++ b/UI source code/dns-dev-2.0/sql/eladmin.sql @@ -0,0 +1,825 @@ +/* + Navicat Premium Data Transfer + + Source Server : localhost + Source Server Type : MySQL + Source Server Version : 100505 + Source Host : localhost:3306 + Source Schema : dns + + Target Server Type : MySQL + Target Server Version : 100505 + File Encoding : 65001 + + Date: 05/09/2020 10:49:19 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for code_column_config +-- ---------------------------- +DROP TABLE IF EXISTS `code_column_config`; +CREATE TABLE `code_column_config` ( + `column_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `table_name` varchar(255) DEFAULT NULL, + `column_name` varchar(255) DEFAULT NULL, + `column_type` varchar(255) DEFAULT NULL, + `dict_name` varchar(255) DEFAULT NULL, + `extra` varchar(255) DEFAULT NULL, + `form_show` bit(1) DEFAULT NULL, + `form_type` varchar(255) DEFAULT NULL, + `key_type` varchar(255) DEFAULT NULL, + `list_show` bit(1) DEFAULT NULL, + `not_null` bit(1) DEFAULT NULL, + `query_type` varchar(255) DEFAULT NULL, + `remark` varchar(255) DEFAULT NULL, + `date_annotation` varchar(255) DEFAULT NULL, + PRIMARY KEY (`column_id`) USING BTREE, + KEY `idx_table_name` (`table_name`) +) ENGINE=InnoDB AUTO_INCREMENT=191 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='代码生成字段信息存储'; + +-- ---------------------------- +-- Table structure for code_gen_config +-- ---------------------------- +DROP TABLE IF EXISTS `code_gen_config`; +CREATE TABLE `code_gen_config` ( + `config_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `table_name` varchar(255) DEFAULT NULL COMMENT '表名', + `author` varchar(255) DEFAULT NULL COMMENT '作者', + `cover` bit(1) DEFAULT NULL COMMENT '是否覆盖', + `module_name` varchar(255) DEFAULT NULL COMMENT '模块名称', + `pack` varchar(255) DEFAULT NULL COMMENT '至于哪个包下', + `path` varchar(255) DEFAULT NULL COMMENT '前端代码生成的路径', + `api_path` varchar(255) DEFAULT NULL COMMENT '前端Api文件路径', + `prefix` varchar(255) DEFAULT NULL COMMENT '表前缀', + `api_alias` varchar(255) DEFAULT NULL COMMENT '接口名称', + PRIMARY KEY (`config_id`) USING BTREE, + KEY `idx_table_name` (`table_name`(100)) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='代码生成器配置'; + +-- ---------------------------- +-- Table structure for mnt_app +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_app`; +CREATE TABLE `mnt_app` ( + `app_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) DEFAULT NULL COMMENT '应用名称', + `upload_path` varchar(255) DEFAULT NULL COMMENT '上传目录', + `deploy_path` varchar(255) DEFAULT NULL COMMENT '部署路径', + `backup_path` varchar(255) DEFAULT NULL COMMENT '备份路径', + `port` int(255) DEFAULT NULL COMMENT '应用端口', + `start_script` varchar(4000) DEFAULT NULL COMMENT '启动脚本', + `deploy_script` varchar(4000) DEFAULT NULL COMMENT '部署脚本', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`app_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='应用管理'; + +-- ---------------------------- +-- Records of mnt_app +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for mnt_database +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_database`; +CREATE TABLE `mnt_database` ( + `db_id` varchar(50) NOT NULL COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '名称', + `jdbc_url` varchar(255) NOT NULL COMMENT 'jdbc连接', + `user_name` varchar(255) NOT NULL COMMENT '账号', + `pwd` varchar(255) NOT NULL COMMENT '密码', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`db_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据库管理'; + +-- ---------------------------- +-- Records of mnt_database +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for mnt_deploy +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_deploy`; +CREATE TABLE `mnt_deploy` ( + `deploy_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `app_id` bigint(20) DEFAULT NULL COMMENT '应用编号', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`deploy_id`) USING BTREE, + KEY `FK6sy157pseoxx4fmcqr1vnvvhy` (`app_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部署管理'; + +-- ---------------------------- +-- Records of mnt_deploy +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for mnt_deploy_history +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_deploy_history`; +CREATE TABLE `mnt_deploy_history` ( + `history_id` varchar(50) NOT NULL COMMENT 'ID', + `app_name` varchar(255) NOT NULL COMMENT '应用名称', + `deploy_date` datetime NOT NULL COMMENT '部署日期', + `deploy_user` varchar(50) NOT NULL COMMENT '部署用户', + `ip` varchar(20) NOT NULL COMMENT '服务器IP', + `deploy_id` bigint(20) DEFAULT NULL COMMENT '部署编号', + PRIMARY KEY (`history_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部署历史管理'; + +-- ---------------------------- +-- Records of mnt_deploy_history +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for mnt_deploy_server +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_deploy_server`; +CREATE TABLE `mnt_deploy_server` ( + `deploy_id` bigint(20) NOT NULL COMMENT '部署ID', + `server_id` bigint(20) NOT NULL COMMENT '服务ID', + PRIMARY KEY (`deploy_id`,`server_id`) USING BTREE, + KEY `FKeaaha7jew9a02b3bk9ghols53` (`server_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='应用与服务器关联'; + +-- ---------------------------- +-- Records of mnt_deploy_server +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for mnt_server +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_server`; +CREATE TABLE `mnt_server` ( + `server_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `account` varchar(50) DEFAULT NULL COMMENT '账号', + `ip` varchar(20) DEFAULT NULL COMMENT 'IP地址', + `name` varchar(100) DEFAULT NULL COMMENT '名称', + `password` varchar(100) DEFAULT NULL COMMENT '密码', + `port` int(11) DEFAULT NULL COMMENT '端口', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`server_id`) USING BTREE, + KEY `idx_ip` (`ip`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='服务器管理'; + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `pid` bigint(20) DEFAULT NULL COMMENT '上级部门', + `sub_count` int(5) DEFAULT 0 COMMENT '子部门数目', + `name` varchar(255) NOT NULL COMMENT '名称', + `dept_sort` int(5) DEFAULT 999 COMMENT '排序', + `enabled` bit(1) NOT NULL COMMENT '状态', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE, + KEY `inx_pid` (`pid`), + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='部门'; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +BEGIN; +INSERT INTO `sys_dept` VALUES (2, 7, 1, '研发部', 3, b'1', 'admin', 'admin', '2019-03-25 09:15:32', '2020-08-02 14:48:47'); +INSERT INTO `sys_dept` VALUES (5, 7, 0, '运维部', 4, b'1', 'admin', 'admin', '2019-03-25 09:20:44', '2020-05-17 14:27:27'); +INSERT INTO `sys_dept` VALUES (6, 8, 0, '测试部', 6, b'1', 'admin', 'admin', '2019-03-25 09:52:18', '2020-06-08 11:59:21'); +INSERT INTO `sys_dept` VALUES (7, NULL, 2, '华南分部', 0, b'1', 'admin', 'admin', '2019-03-25 11:04:50', '2020-06-08 12:08:56'); +INSERT INTO `sys_dept` VALUES (8, NULL, 2, '华北分部', 1, b'1', 'admin', 'admin', '2019-03-25 11:04:53', '2020-05-14 12:54:00'); +INSERT INTO `sys_dept` VALUES (15, 8, 0, 'UI部门', 7, b'1', 'admin', 'admin', '2020-05-13 22:56:53', '2020-05-14 12:54:13'); +INSERT INTO `sys_dept` VALUES (17, 2, 0, '研发一组', 999, b'1', 'admin', 'admin', '2020-08-02 14:49:07', '2020-08-02 14:49:07'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_dict +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict`; +CREATE TABLE `sys_dict` ( + `dict_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '字典名称', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dict_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据字典'; + +-- ---------------------------- +-- Records of sys_dict +-- ---------------------------- +BEGIN; +INSERT INTO `sys_dict` VALUES (1, 'user_status', '用户状态', NULL, NULL, '2019-10-27 20:31:36', NULL); +INSERT INTO `sys_dict` VALUES (4, 'dept_status', '部门状态', NULL, NULL, '2019-10-27 20:31:36', NULL); +INSERT INTO `sys_dict` VALUES (5, 'job_status', '岗位状态', NULL, NULL, '2019-10-27 20:31:36', NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_dict_detail +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_detail`; +CREATE TABLE `sys_dict_detail` ( + `detail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `dict_id` bigint(11) DEFAULT NULL COMMENT '字典id', + `label` varchar(255) NOT NULL COMMENT '字典标签', + `value` varchar(255) NOT NULL COMMENT '字典值', + `dict_sort` int(5) DEFAULT NULL COMMENT '排序', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`detail_id`) USING BTREE, + KEY `FK5tpkputc6d9nboxojdbgnpmyb` (`dict_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据字典详情'; + +-- ---------------------------- +-- Records of sys_dict_detail +-- ---------------------------- +BEGIN; +INSERT INTO `sys_dict_detail` VALUES (1, 1, '激活', 'true', 1, NULL, NULL, '2019-10-27 20:31:36', NULL); +INSERT INTO `sys_dict_detail` VALUES (2, 1, '禁用', 'false', 2, NULL, NULL, NULL, NULL); +INSERT INTO `sys_dict_detail` VALUES (3, 4, '启用', 'true', 1, NULL, NULL, NULL, NULL); +INSERT INTO `sys_dict_detail` VALUES (4, 4, '停用', 'false', 2, NULL, NULL, '2019-10-27 20:31:36', NULL); +INSERT INTO `sys_dict_detail` VALUES (5, 5, '启用', 'true', 1, NULL, NULL, NULL, NULL); +INSERT INTO `sys_dict_detail` VALUES (6, 5, '停用', 'false', 2, NULL, NULL, '2019-10-27 20:31:36', NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_job +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job`; +CREATE TABLE `sys_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '岗位名称', + `enabled` bit(1) NOT NULL COMMENT '岗位状态', + `job_sort` int(5) DEFAULT NULL COMMENT '排序', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`job_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`), + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='岗位'; + +-- ---------------------------- +-- Records of sys_job +-- ---------------------------- +BEGIN; +INSERT INTO `sys_job` VALUES (8, '人事专员', b'1', 3, NULL, NULL, '2019-03-29 14:52:28', NULL); +INSERT INTO `sys_job` VALUES (10, '产品经理', b'1', 4, NULL, NULL, '2019-03-29 14:55:51', NULL); +INSERT INTO `sys_job` VALUES (11, '全栈开发', b'1', 2, NULL, 'admin', '2019-03-31 13:39:30', '2020-05-05 11:33:43'); +INSERT INTO `sys_job` VALUES (12, '软件测试', b'1', 5, NULL, 'admin', '2019-03-31 13:39:43', '2020-05-10 19:56:26'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_log`; +CREATE TABLE `sys_log` ( + `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `description` varchar(255) DEFAULT NULL, + `log_type` varchar(255) DEFAULT NULL, + `method` varchar(255) DEFAULT NULL, + `params` text DEFAULT NULL, + `request_ip` varchar(255) DEFAULT NULL, + `time` bigint(20) DEFAULT NULL, + `username` varchar(255) DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + `browser` varchar(255) DEFAULT NULL, + `exception_detail` text DEFAULT NULL, + `create_time` datetime DEFAULT NULL, + PRIMARY KEY (`log_id`) USING BTREE, + KEY `log_create_time_index` (`create_time`), + KEY `inx_log_type` (`log_type`) +) ENGINE=InnoDB AUTO_INCREMENT=3537 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统日志'; + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `pid` bigint(20) DEFAULT NULL COMMENT '上级菜单ID', + `sub_count` int(5) DEFAULT 0 COMMENT '子菜单数目', + `type` int(11) DEFAULT NULL COMMENT '菜单类型', + `title` varchar(255) DEFAULT NULL COMMENT '菜单标题', + `name` varchar(255) DEFAULT NULL COMMENT '组件名称', + `component` varchar(255) DEFAULT NULL COMMENT '组件', + `menu_sort` int(5) DEFAULT NULL COMMENT '排序', + `icon` varchar(255) DEFAULT NULL COMMENT '图标', + `path` varchar(255) DEFAULT NULL COMMENT '链接地址', + `i_frame` bit(1) DEFAULT NULL COMMENT '是否外链', + `cache` bit(1) DEFAULT b'0' COMMENT '缓存', + `hidden` bit(1) DEFAULT b'0' COMMENT '隐藏', + `permission` varchar(255) DEFAULT NULL COMMENT '权限', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`menu_id`) USING BTREE, + UNIQUE KEY `uniq_title` (`title`), + UNIQUE KEY `uniq_name` (`name`), + KEY `inx_pid` (`pid`) +) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统菜单'; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +BEGIN; +INSERT INTO `sys_menu` VALUES (1, NULL, 7, 0, '系统管理', NULL, NULL, 1, 'system', 'system', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:11:29', NULL); +INSERT INTO `sys_menu` VALUES (2, 1, 3, 1, '用户管理', 'User', 'system/user/index', 2, 'peoples', 'user', b'0', b'0', b'0', 'user:list', NULL, NULL, '2018-12-18 15:14:44', NULL); +INSERT INTO `sys_menu` VALUES (3, 1, 3, 1, '角色管理', 'Role', 'system/role/index', 3, 'role', 'role', b'0', b'0', b'0', 'roles:list', NULL, NULL, '2018-12-18 15:16:07', NULL); +INSERT INTO `sys_menu` VALUES (5, 1, 3, 1, '菜单管理', 'Menu', 'system/menu/index', 5, 'menu', 'menu', b'0', b'0', b'0', 'menu:list', NULL, NULL, '2018-12-18 15:17:28', NULL); +INSERT INTO `sys_menu` VALUES (6, NULL, 5, 0, '系统监控', NULL, NULL, 10, 'monitor', 'monitor', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:17:48', NULL); +INSERT INTO `sys_menu` VALUES (7, 6, 0, 1, '操作日志', 'Log', 'monitor/log/index', 11, 'log', 'logs', b'0', b'1', b'0', NULL, NULL, 'admin', '2018-12-18 15:18:26', '2020-06-06 13:11:57'); +INSERT INTO `sys_menu` VALUES (9, 6, 0, 1, 'SQL监控', 'Sql', 'monitor/sql/index', 18, 'sqlMonitor', 'druid', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-18 15:19:34', NULL); +INSERT INTO `sys_menu` VALUES (10, NULL, 5, 0, '组件管理', NULL, NULL, 50, 'zujian', 'components', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-19 13:38:16', NULL); +INSERT INTO `sys_menu` VALUES (11, 10, 0, 1, '图标库', 'Icons', 'components/icons/index', 51, 'icon', 'icon', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-19 13:38:49', NULL); +INSERT INTO `sys_menu` VALUES (14, 36, 0, 1, '邮件工具', 'Email', 'tools/email/index', 35, 'email', 'email', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-27 10:13:09', NULL); +INSERT INTO `sys_menu` VALUES (15, 10, 0, 1, '富文本', 'Editor', 'components/Editor', 52, 'fwb', 'tinymce', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-27 11:58:25', NULL); +INSERT INTO `sys_menu` VALUES (18, 36, 3, 1, '存储管理', 'Storage', 'tools/storage/index', 34, 'qiniu', 'storage', b'0', b'0', b'0', 'storage:list', NULL, NULL, '2018-12-31 11:12:15', NULL); +INSERT INTO `sys_menu` VALUES (19, 36, 0, 1, '支付宝工具', 'AliPay', 'tools/aliPay/index', 37, 'alipay', 'aliPay', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-31 14:52:38', NULL); +INSERT INTO `sys_menu` VALUES (21, NULL, 2, 0, '多级菜单', NULL, '', 900, 'menu', 'nested', b'0', b'0', b'0', NULL, NULL, 'admin', '2019-01-04 16:22:03', '2020-06-21 17:27:35'); +INSERT INTO `sys_menu` VALUES (22, 21, 2, 0, '二级菜单1', NULL, '', 999, 'menu', 'menu1', b'0', b'0', b'0', NULL, NULL, 'admin', '2019-01-04 16:23:29', '2020-06-21 17:27:20'); +INSERT INTO `sys_menu` VALUES (23, 21, 0, 1, '二级菜单2', NULL, 'nested/menu2/index', 999, 'menu', 'menu2', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:23:57', NULL); +INSERT INTO `sys_menu` VALUES (24, 22, 0, 1, '三级菜单1', 'Test', 'nested/menu1/menu1-1', 999, 'menu', 'menu1-1', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:24:48', NULL); +INSERT INTO `sys_menu` VALUES (27, 22, 0, 1, '三级菜单2', NULL, 'nested/menu1/menu1-2', 999, 'menu', 'menu1-2', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-07 17:27:32', NULL); +INSERT INTO `sys_menu` VALUES (28, 1, 3, 1, '任务调度', 'Timing', 'system/timing/index', 999, 'timing', 'timing', b'0', b'0', b'0', 'timing:list', NULL, NULL, '2019-01-07 20:34:40', NULL); +INSERT INTO `sys_menu` VALUES (30, 36, 0, 1, '代码生成', 'GeneratorIndex', 'generator/index', 32, 'dev', 'generator', b'0', b'1', b'0', NULL, NULL, NULL, '2019-01-11 15:45:55', NULL); +INSERT INTO `sys_menu` VALUES (32, 6, 0, 1, '异常日志', 'ErrorLog', 'monitor/log/errorLog', 12, 'error', 'errorLog', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-13 13:49:03', NULL); +INSERT INTO `sys_menu` VALUES (33, 10, 0, 1, 'Markdown', 'Markdown', 'components/MarkDown', 53, 'markdown', 'markdown', b'0', b'0', b'0', NULL, NULL, NULL, '2019-03-08 13:46:44', NULL); +INSERT INTO `sys_menu` VALUES (34, 10, 0, 1, 'Yaml编辑器', 'YamlEdit', 'components/YamlEdit', 54, 'dev', 'yaml', b'0', b'0', b'0', NULL, NULL, NULL, '2019-03-08 15:49:40', NULL); +INSERT INTO `sys_menu` VALUES (35, 1, 3, 1, '部门管理', 'Dept', 'system/dept/index', 6, 'dept', 'dept', b'0', b'0', b'0', 'dept:list', NULL, NULL, '2019-03-25 09:46:00', NULL); +INSERT INTO `sys_menu` VALUES (36, NULL, 7, 0, '系统工具', NULL, '', 30, 'sys-tools', 'sys-tools', b'0', b'0', b'0', NULL, NULL, NULL, '2019-03-29 10:57:35', NULL); +INSERT INTO `sys_menu` VALUES (37, 1, 3, 1, '岗位管理', 'Job', 'system/job/index', 7, 'Steve-Jobs', 'job', b'0', b'0', b'0', 'job:list', NULL, NULL, '2019-03-29 13:51:18', NULL); +INSERT INTO `sys_menu` VALUES (38, 36, 0, 1, '接口文档', 'Swagger', 'tools/swagger/index', 36, 'swagger', 'swagger2', b'0', b'0', b'0', NULL, NULL, NULL, '2019-03-29 19:57:53', NULL); +INSERT INTO `sys_menu` VALUES (39, 1, 3, 1, '字典管理', 'Dict', 'system/dict/index', 8, 'dictionary', 'dict', b'0', b'0', b'0', 'dict:list', NULL, NULL, '2019-04-10 11:49:04', NULL); +INSERT INTO `sys_menu` VALUES (41, 6, 0, 1, '在线用户', 'OnlineUser', 'monitor/online/index', 10, 'Steve-Jobs', 'online', b'0', b'0', b'0', NULL, NULL, NULL, '2019-10-26 22:08:43', NULL); +INSERT INTO `sys_menu` VALUES (44, 2, 0, 2, '用户新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'user:add', NULL, NULL, '2019-10-29 10:59:46', NULL); +INSERT INTO `sys_menu` VALUES (45, 2, 0, 2, '用户编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'user:edit', NULL, NULL, '2019-10-29 11:00:08', NULL); +INSERT INTO `sys_menu` VALUES (46, 2, 0, 2, '用户删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'user:del', NULL, NULL, '2019-10-29 11:00:23', NULL); +INSERT INTO `sys_menu` VALUES (48, 3, 0, 2, '角色创建', NULL, '', 2, '', '', b'0', b'0', b'0', 'roles:add', NULL, NULL, '2019-10-29 12:45:34', NULL); +INSERT INTO `sys_menu` VALUES (49, 3, 0, 2, '角色修改', NULL, '', 3, '', '', b'0', b'0', b'0', 'roles:edit', NULL, NULL, '2019-10-29 12:46:16', NULL); +INSERT INTO `sys_menu` VALUES (50, 3, 0, 2, '角色删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'roles:del', NULL, NULL, '2019-10-29 12:46:51', NULL); +INSERT INTO `sys_menu` VALUES (52, 5, 0, 2, '菜单新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'menu:add', NULL, NULL, '2019-10-29 12:55:07', NULL); +INSERT INTO `sys_menu` VALUES (53, 5, 0, 2, '菜单编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'menu:edit', NULL, NULL, '2019-10-29 12:55:40', NULL); +INSERT INTO `sys_menu` VALUES (54, 5, 0, 2, '菜单删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'menu:del', NULL, NULL, '2019-10-29 12:56:00', NULL); +INSERT INTO `sys_menu` VALUES (56, 35, 0, 2, '部门新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'dept:add', NULL, NULL, '2019-10-29 12:57:09', NULL); +INSERT INTO `sys_menu` VALUES (57, 35, 0, 2, '部门编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'dept:edit', NULL, NULL, '2019-10-29 12:57:27', NULL); +INSERT INTO `sys_menu` VALUES (58, 35, 0, 2, '部门删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'dept:del', NULL, NULL, '2019-10-29 12:57:41', NULL); +INSERT INTO `sys_menu` VALUES (60, 37, 0, 2, '岗位新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'job:add', NULL, NULL, '2019-10-29 12:58:27', NULL); +INSERT INTO `sys_menu` VALUES (61, 37, 0, 2, '岗位编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'job:edit', NULL, NULL, '2019-10-29 12:58:45', NULL); +INSERT INTO `sys_menu` VALUES (62, 37, 0, 2, '岗位删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'job:del', NULL, NULL, '2019-10-29 12:59:04', NULL); +INSERT INTO `sys_menu` VALUES (64, 39, 0, 2, '字典新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'dict:add', NULL, NULL, '2019-10-29 13:00:17', NULL); +INSERT INTO `sys_menu` VALUES (65, 39, 0, 2, '字典编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'dict:edit', NULL, NULL, '2019-10-29 13:00:42', NULL); +INSERT INTO `sys_menu` VALUES (66, 39, 0, 2, '字典删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'dict:del', NULL, NULL, '2019-10-29 13:00:59', NULL); +INSERT INTO `sys_menu` VALUES (73, 28, 0, 2, '任务新增', NULL, '', 2, '', '', b'0', b'0', b'0', 'timing:add', NULL, NULL, '2019-10-29 13:07:28', NULL); +INSERT INTO `sys_menu` VALUES (74, 28, 0, 2, '任务编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'timing:edit', NULL, NULL, '2019-10-29 13:07:41', NULL); +INSERT INTO `sys_menu` VALUES (75, 28, 0, 2, '任务删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'timing:del', NULL, NULL, '2019-10-29 13:07:54', NULL); +INSERT INTO `sys_menu` VALUES (77, 18, 0, 2, '上传文件', NULL, '', 2, '', '', b'0', b'0', b'0', 'storage:add', NULL, NULL, '2019-10-29 13:09:09', NULL); +INSERT INTO `sys_menu` VALUES (78, 18, 0, 2, '文件编辑', NULL, '', 3, '', '', b'0', b'0', b'0', 'storage:edit', NULL, NULL, '2019-10-29 13:09:22', NULL); +INSERT INTO `sys_menu` VALUES (79, 18, 0, 2, '文件删除', NULL, '', 4, '', '', b'0', b'0', b'0', 'storage:del', NULL, NULL, '2019-10-29 13:09:34', NULL); +INSERT INTO `sys_menu` VALUES (80, 6, 0, 1, '服务监控', 'ServerMonitor', 'monitor/server/index', 14, 'codeConsole', 'server', b'0', b'0', b'0', 'monitor:list', NULL, 'admin', '2019-11-07 13:06:39', '2020-05-04 18:20:50'); +INSERT INTO `sys_menu` VALUES (82, 36, 0, 1, '生成配置', 'GeneratorConfig', 'generator/config', 33, 'dev', 'generator/config/:tableName', b'0', b'1', b'1', '', NULL, NULL, '2019-11-17 20:08:56', NULL); +INSERT INTO `sys_menu` VALUES (83, 10, 0, 1, '图表库', 'Echarts', 'components/Echarts', 50, 'chart', 'echarts', b'0', b'1', b'0', '', NULL, NULL, '2019-11-21 09:04:32', NULL); +INSERT INTO `sys_menu` VALUES (90, NULL, 5, 1, '运维管理', 'Mnt', '', 20, 'mnt', 'mnt', b'0', b'0', b'0', NULL, NULL, NULL, '2019-11-09 10:31:08', NULL); +INSERT INTO `sys_menu` VALUES (92, 90, 3, 1, '服务器', 'ServerDeploy', 'mnt/server/index', 22, 'server', 'mnt/serverDeploy', b'0', b'0', b'0', 'serverDeploy:list', NULL, NULL, '2019-11-10 10:29:25', NULL); +INSERT INTO `sys_menu` VALUES (93, 90, 3, 1, '应用管理', 'App', 'mnt/app/index', 23, 'app', 'mnt/app', b'0', b'0', b'0', 'app:list', NULL, NULL, '2019-11-10 11:05:16', NULL); +INSERT INTO `sys_menu` VALUES (94, 90, 3, 1, '部署管理', 'Deploy', 'mnt/deploy/index', 24, 'deploy', 'mnt/deploy', b'0', b'0', b'0', 'deploy:list', NULL, NULL, '2019-11-10 15:56:55', NULL); +INSERT INTO `sys_menu` VALUES (97, 90, 1, 1, '部署备份', 'DeployHistory', 'mnt/deployHistory/index', 25, 'backup', 'mnt/deployHistory', b'0', b'0', b'0', 'deployHistory:list', NULL, NULL, '2019-11-10 16:49:44', NULL); +INSERT INTO `sys_menu` VALUES (98, 90, 3, 1, '数据库管理', 'Database', 'mnt/database/index', 26, 'database', 'mnt/database', b'0', b'0', b'0', 'database:list', NULL, NULL, '2019-11-10 20:40:04', NULL); +INSERT INTO `sys_menu` VALUES (102, 97, 0, 2, '删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'deployHistory:del', NULL, NULL, '2019-11-17 09:32:48', NULL); +INSERT INTO `sys_menu` VALUES (103, 92, 0, 2, '服务器新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:add', NULL, NULL, '2019-11-17 11:08:33', NULL); +INSERT INTO `sys_menu` VALUES (104, 92, 0, 2, '服务器编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:edit', NULL, NULL, '2019-11-17 11:08:57', NULL); +INSERT INTO `sys_menu` VALUES (105, 92, 0, 2, '服务器删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'serverDeploy:del', NULL, NULL, '2019-11-17 11:09:15', NULL); +INSERT INTO `sys_menu` VALUES (106, 93, 0, 2, '应用新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:add', NULL, NULL, '2019-11-17 11:10:03', NULL); +INSERT INTO `sys_menu` VALUES (107, 93, 0, 2, '应用编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:edit', NULL, NULL, '2019-11-17 11:10:28', NULL); +INSERT INTO `sys_menu` VALUES (108, 93, 0, 2, '应用删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'app:del', NULL, NULL, '2019-11-17 11:10:55', NULL); +INSERT INTO `sys_menu` VALUES (109, 94, 0, 2, '部署新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:add', NULL, NULL, '2019-11-17 11:11:22', NULL); +INSERT INTO `sys_menu` VALUES (110, 94, 0, 2, '部署编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:edit', NULL, NULL, '2019-11-17 11:11:41', NULL); +INSERT INTO `sys_menu` VALUES (111, 94, 0, 2, '部署删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'deploy:del', NULL, NULL, '2019-11-17 11:12:01', NULL); +INSERT INTO `sys_menu` VALUES (112, 98, 0, 2, '数据库新增', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:add', NULL, NULL, '2019-11-17 11:12:43', NULL); +INSERT INTO `sys_menu` VALUES (113, 98, 0, 2, '数据库编辑', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:edit', NULL, NULL, '2019-11-17 11:12:58', NULL); +INSERT INTO `sys_menu` VALUES (114, 98, 0, 2, '数据库删除', NULL, '', 999, '', '', b'0', b'0', b'0', 'database:del', NULL, NULL, '2019-11-17 11:13:14', NULL); +INSERT INTO `sys_menu` VALUES (116, 36, 0, 1, '生成预览', 'Preview', 'generator/preview', 999, 'java', 'generator/preview/:tableName', b'0', b'1', b'1', NULL, NULL, NULL, '2019-11-26 14:54:36', NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_quartz_job +-- ---------------------------- +DROP TABLE IF EXISTS `sys_quartz_job`; +CREATE TABLE `sys_quartz_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bean_name` varchar(255) DEFAULT NULL COMMENT 'Spring Bean名称', + `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron 表达式', + `is_pause` bit(1) DEFAULT NULL COMMENT '状态:1暂停、0启用', + `job_name` varchar(255) DEFAULT NULL COMMENT '任务名称', + `method_name` varchar(255) DEFAULT NULL COMMENT '方法名称', + `params` varchar(255) DEFAULT NULL COMMENT '参数', + `description` varchar(255) DEFAULT NULL COMMENT '备注', + `person_in_charge` varchar(100) DEFAULT NULL COMMENT '负责人', + `email` varchar(100) DEFAULT NULL COMMENT '报警邮箱', + `sub_task` varchar(100) DEFAULT NULL COMMENT '子任务ID', + `pause_after_failure` bit(1) DEFAULT NULL COMMENT '任务失败后是否暂停', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`job_id`) USING BTREE, + KEY `inx_is_pause` (`is_pause`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务'; + +-- ---------------------------- +-- Records of sys_quartz_job +-- ---------------------------- +BEGIN; +INSERT INTO `sys_quartz_job` VALUES (2, 'testTask', '0/5 * * * * ?', b'1', '测试1', 'run1', 'test', '带参测试,多参使用json', '测试', NULL, NULL, NULL, NULL, 'admin', '2019-08-22 14:08:29', '2020-05-24 13:58:33'); +INSERT INTO `sys_quartz_job` VALUES (3, 'testTask', '0/5 * * * * ?', b'1', '测试', 'run', '', '不带参测试', 'Zheng Jie', '', '5,6', b'1', NULL, 'admin', '2019-09-26 16:44:39', '2020-05-24 14:48:12'); +INSERT INTO `sys_quartz_job` VALUES (5, 'Test', '0/5 * * * * ?', b'1', '任务告警测试', 'run', NULL, '测试', 'test', '', NULL, b'1', 'admin', 'admin', '2020-05-05 20:32:41', '2020-05-05 20:36:13'); +INSERT INTO `sys_quartz_job` VALUES (6, 'testTask', '0/5 * * * * ?', b'1', '测试3', 'run2', NULL, '测试3', 'Zheng Jie', '', NULL, b'1', 'admin', 'admin', '2020-05-05 20:35:41', '2020-05-05 20:36:07'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_quartz_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_quartz_log`; +CREATE TABLE `sys_quartz_log` ( + `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bean_name` varchar(255) DEFAULT NULL, + `create_time` datetime DEFAULT NULL, + `cron_expression` varchar(255) DEFAULT NULL, + `exception_detail` text DEFAULT NULL, + `is_success` bit(1) DEFAULT NULL, + `job_name` varchar(255) DEFAULT NULL, + `method_name` varchar(255) DEFAULT NULL, + `params` varchar(255) DEFAULT NULL, + `time` bigint(20) DEFAULT NULL, + PRIMARY KEY (`log_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=151 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务日志'; + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) NOT NULL COMMENT '名称', + `level` int(255) DEFAULT NULL COMMENT '角色级别', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `data_scope` varchar(255) DEFAULT NULL COMMENT '数据权限', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`role_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`), + KEY `role_name_index` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色表'; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +BEGIN; +INSERT INTO `sys_role` VALUES (1, '超级管理员', 1, '-', '全部', NULL, 'admin', '2018-11-23 11:04:37', '2020-08-06 16:10:24'); +INSERT INTO `sys_role` VALUES (2, '普通用户', 2, '-', '本级', NULL, 'admin', '2018-11-23 13:09:06', '2020-09-05 10:45:12'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_roles_depts +-- ---------------------------- +DROP TABLE IF EXISTS `sys_roles_depts`; +CREATE TABLE `sys_roles_depts` ( + `role_id` bigint(20) NOT NULL, + `dept_id` bigint(20) NOT NULL, + PRIMARY KEY (`role_id`,`dept_id`) USING BTREE, + KEY `FK7qg6itn5ajdoa9h9o78v9ksur` (`dept_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色部门关联'; + +-- ---------------------------- +-- Table structure for sys_roles_menus +-- ---------------------------- +DROP TABLE IF EXISTS `sys_roles_menus`; +CREATE TABLE `sys_roles_menus` ( + `menu_id` bigint(20) NOT NULL COMMENT '菜单ID', + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + PRIMARY KEY (`menu_id`,`role_id`) USING BTREE, + KEY `FKcngg2qadojhi3a651a5adkvbq` (`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色菜单关联'; + +-- ---------------------------- +-- Records of sys_roles_menus +-- ---------------------------- +BEGIN; +INSERT INTO `sys_roles_menus` VALUES (1, 1); +INSERT INTO `sys_roles_menus` VALUES (2, 1); +INSERT INTO `sys_roles_menus` VALUES (3, 1); +INSERT INTO `sys_roles_menus` VALUES (5, 1); +INSERT INTO `sys_roles_menus` VALUES (6, 1); +INSERT INTO `sys_roles_menus` VALUES (7, 1); +INSERT INTO `sys_roles_menus` VALUES (9, 1); +INSERT INTO `sys_roles_menus` VALUES (10, 1); +INSERT INTO `sys_roles_menus` VALUES (11, 1); +INSERT INTO `sys_roles_menus` VALUES (14, 1); +INSERT INTO `sys_roles_menus` VALUES (15, 1); +INSERT INTO `sys_roles_menus` VALUES (18, 1); +INSERT INTO `sys_roles_menus` VALUES (19, 1); +INSERT INTO `sys_roles_menus` VALUES (21, 1); +INSERT INTO `sys_roles_menus` VALUES (22, 1); +INSERT INTO `sys_roles_menus` VALUES (23, 1); +INSERT INTO `sys_roles_menus` VALUES (24, 1); +INSERT INTO `sys_roles_menus` VALUES (27, 1); +INSERT INTO `sys_roles_menus` VALUES (28, 1); +INSERT INTO `sys_roles_menus` VALUES (30, 1); +INSERT INTO `sys_roles_menus` VALUES (32, 1); +INSERT INTO `sys_roles_menus` VALUES (33, 1); +INSERT INTO `sys_roles_menus` VALUES (34, 1); +INSERT INTO `sys_roles_menus` VALUES (35, 1); +INSERT INTO `sys_roles_menus` VALUES (36, 1); +INSERT INTO `sys_roles_menus` VALUES (37, 1); +INSERT INTO `sys_roles_menus` VALUES (38, 1); +INSERT INTO `sys_roles_menus` VALUES (39, 1); +INSERT INTO `sys_roles_menus` VALUES (41, 1); +INSERT INTO `sys_roles_menus` VALUES (44, 1); +INSERT INTO `sys_roles_menus` VALUES (45, 1); +INSERT INTO `sys_roles_menus` VALUES (46, 1); +INSERT INTO `sys_roles_menus` VALUES (48, 1); +INSERT INTO `sys_roles_menus` VALUES (49, 1); +INSERT INTO `sys_roles_menus` VALUES (50, 1); +INSERT INTO `sys_roles_menus` VALUES (52, 1); +INSERT INTO `sys_roles_menus` VALUES (53, 1); +INSERT INTO `sys_roles_menus` VALUES (54, 1); +INSERT INTO `sys_roles_menus` VALUES (56, 1); +INSERT INTO `sys_roles_menus` VALUES (57, 1); +INSERT INTO `sys_roles_menus` VALUES (58, 1); +INSERT INTO `sys_roles_menus` VALUES (60, 1); +INSERT INTO `sys_roles_menus` VALUES (61, 1); +INSERT INTO `sys_roles_menus` VALUES (62, 1); +INSERT INTO `sys_roles_menus` VALUES (64, 1); +INSERT INTO `sys_roles_menus` VALUES (65, 1); +INSERT INTO `sys_roles_menus` VALUES (66, 1); +INSERT INTO `sys_roles_menus` VALUES (73, 1); +INSERT INTO `sys_roles_menus` VALUES (74, 1); +INSERT INTO `sys_roles_menus` VALUES (75, 1); +INSERT INTO `sys_roles_menus` VALUES (77, 1); +INSERT INTO `sys_roles_menus` VALUES (78, 1); +INSERT INTO `sys_roles_menus` VALUES (79, 1); +INSERT INTO `sys_roles_menus` VALUES (80, 1); +INSERT INTO `sys_roles_menus` VALUES (82, 1); +INSERT INTO `sys_roles_menus` VALUES (83, 1); +INSERT INTO `sys_roles_menus` VALUES (90, 1); +INSERT INTO `sys_roles_menus` VALUES (92, 1); +INSERT INTO `sys_roles_menus` VALUES (93, 1); +INSERT INTO `sys_roles_menus` VALUES (94, 1); +INSERT INTO `sys_roles_menus` VALUES (97, 1); +INSERT INTO `sys_roles_menus` VALUES (98, 1); +INSERT INTO `sys_roles_menus` VALUES (102, 1); +INSERT INTO `sys_roles_menus` VALUES (103, 1); +INSERT INTO `sys_roles_menus` VALUES (104, 1); +INSERT INTO `sys_roles_menus` VALUES (105, 1); +INSERT INTO `sys_roles_menus` VALUES (106, 1); +INSERT INTO `sys_roles_menus` VALUES (107, 1); +INSERT INTO `sys_roles_menus` VALUES (108, 1); +INSERT INTO `sys_roles_menus` VALUES (109, 1); +INSERT INTO `sys_roles_menus` VALUES (110, 1); +INSERT INTO `sys_roles_menus` VALUES (111, 1); +INSERT INTO `sys_roles_menus` VALUES (112, 1); +INSERT INTO `sys_roles_menus` VALUES (113, 1); +INSERT INTO `sys_roles_menus` VALUES (114, 1); +INSERT INTO `sys_roles_menus` VALUES (116, 1); +INSERT INTO `sys_roles_menus` VALUES (120, 1); +INSERT INTO `sys_roles_menus` VALUES (1, 2); +INSERT INTO `sys_roles_menus` VALUES (2, 2); +INSERT INTO `sys_roles_menus` VALUES (6, 2); +INSERT INTO `sys_roles_menus` VALUES (7, 2); +INSERT INTO `sys_roles_menus` VALUES (9, 2); +INSERT INTO `sys_roles_menus` VALUES (10, 2); +INSERT INTO `sys_roles_menus` VALUES (11, 2); +INSERT INTO `sys_roles_menus` VALUES (14, 2); +INSERT INTO `sys_roles_menus` VALUES (15, 2); +INSERT INTO `sys_roles_menus` VALUES (19, 2); +INSERT INTO `sys_roles_menus` VALUES (21, 2); +INSERT INTO `sys_roles_menus` VALUES (22, 2); +INSERT INTO `sys_roles_menus` VALUES (23, 2); +INSERT INTO `sys_roles_menus` VALUES (24, 2); +INSERT INTO `sys_roles_menus` VALUES (27, 2); +INSERT INTO `sys_roles_menus` VALUES (30, 2); +INSERT INTO `sys_roles_menus` VALUES (32, 2); +INSERT INTO `sys_roles_menus` VALUES (33, 2); +INSERT INTO `sys_roles_menus` VALUES (34, 2); +INSERT INTO `sys_roles_menus` VALUES (36, 2); +INSERT INTO `sys_roles_menus` VALUES (80, 2); +INSERT INTO `sys_roles_menus` VALUES (82, 2); +INSERT INTO `sys_roles_menus` VALUES (83, 2); +INSERT INTO `sys_roles_menus` VALUES (116, 2); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `dept_id` bigint(20) DEFAULT NULL COMMENT '部门名称', + `username` varchar(255) DEFAULT NULL COMMENT '用户名', + `nick_name` varchar(255) DEFAULT NULL COMMENT '昵称', + `gender` varchar(2) DEFAULT NULL COMMENT '性别', + `phone` varchar(255) DEFAULT NULL COMMENT '手机号码', + `email` varchar(255) DEFAULT NULL COMMENT '邮箱', + `avatar_name` varchar(255) DEFAULT NULL COMMENT '头像地址', + `avatar_path` varchar(255) DEFAULT NULL COMMENT '头像真实路径', + `password` varchar(255) DEFAULT NULL COMMENT '密码', + `is_admin` bit(1) DEFAULT b'0' COMMENT '是否为admin账号', + `enabled` bigint(20) DEFAULT NULL COMMENT '状态:1启用、0禁用', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `pwd_reset_time` datetime DEFAULT NULL COMMENT '修改密码的时间', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`user_id`) USING BTREE, + UNIQUE KEY `UK_kpubos9gc2cvtkb0thktkbkes` (`email`) USING BTREE, + UNIQUE KEY `username` (`username`) USING BTREE, + UNIQUE KEY `uniq_username` (`username`), + UNIQUE KEY `uniq_email` (`email`), + KEY `FK5rwmryny6jthaaxkogownknqp` (`dept_id`) USING BTREE, + KEY `FKpq2dhypk2qgt68nauh2by22jb` (`avatar_name`) USING BTREE, + KEY `inx_enabled` (`enabled`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统用户'; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +BEGIN; +INSERT INTO `sys_user` VALUES (1, 2, 'admin', '管理员', '男', '18888888888', '201507802@qq.com', 'avatar-20200806032259161.png', '/Users/jie/Documents/work/me/admin/dns/~/avatar/avatar-20200806032259161.png', '$2a$10$Egp1/gvFlt7zhlXVfEFw4OfWQCGPw0ClmMcc6FjTnvXNRVf9zdMRa', b'1', 1, NULL, 'admin', '2020-05-03 16:38:31', '2018-08-23 09:11:56', '2020-09-05 10:43:31'); +INSERT INTO `sys_user` VALUES (2, 2, 'test', '测试', '男', '19999999999', '231@qq.com', NULL, NULL, '$2a$10$4XcyudOYTSz6fue6KFNMHeUQnCX5jbBQypLEnGk1PmekXt5c95JcK', b'0', 1, 'admin', 'admin', NULL, '2020-05-05 11:15:49', '2020-09-05 10:43:38'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_users_jobs +-- ---------------------------- +DROP TABLE IF EXISTS `sys_users_jobs`; +CREATE TABLE `sys_users_jobs` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `job_id` bigint(20) NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`,`job_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of sys_users_jobs +-- ---------------------------- +BEGIN; +INSERT INTO `sys_users_jobs` VALUES (1, 11); +INSERT INTO `sys_users_jobs` VALUES (2, 12); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_users_roles +-- ---------------------------- +DROP TABLE IF EXISTS `sys_users_roles`; +CREATE TABLE `sys_users_roles` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`,`role_id`) USING BTREE, + KEY `FKq4eq273l04bpu4efj0jd0jb98` (`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户角色关联'; + +-- ---------------------------- +-- Records of sys_users_roles +-- ---------------------------- +BEGIN; +INSERT INTO `sys_users_roles` VALUES (1, 1); +INSERT INTO `sys_users_roles` VALUES (2, 2); +COMMIT; + +-- ---------------------------- +-- Table structure for tool_alipay_config +-- ---------------------------- +DROP TABLE IF EXISTS `tool_alipay_config`; +CREATE TABLE `tool_alipay_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `app_id` varchar(255) DEFAULT NULL COMMENT '应用ID', + `charset` varchar(255) DEFAULT NULL COMMENT '编码', + `format` varchar(255) DEFAULT NULL COMMENT '类型 固定格式json', + `gateway_url` varchar(255) DEFAULT NULL COMMENT '网关地址', + `notify_url` varchar(255) DEFAULT NULL COMMENT '异步回调', + `private_key` text DEFAULT NULL COMMENT '私钥', + `public_key` text DEFAULT NULL COMMENT '公钥', + `return_url` varchar(255) DEFAULT NULL COMMENT '回调地址', + `sign_type` varchar(255) DEFAULT NULL COMMENT '签名方式', + `sys_service_provider_id` varchar(255) DEFAULT NULL COMMENT '商户号', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='支付宝配置类'; + +-- ---------------------------- +-- Records of tool_alipay_config +-- ---------------------------- +BEGIN; +INSERT INTO `tool_alipay_config` VALUES (1, '2016091700532697', 'utf-8', 'JSON', 'https://openapi.alipaydev.com/gateway.do', 'http://api.auauz.net/api/aliPay/notify', 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5js8sInU10AJ0cAQ8UMMyXrQ+oHZEkVt5lBwsStmTJ7YikVYgbskx1YYEXTojRsWCb+SH/kDmDU4pK/u91SJ4KFCRMF2411piYuXU/jF96zKrADznYh/zAraqT6hvAIVtQAlMHN53nx16rLzZ/8jDEkaSwT7+HvHiS+7sxSojnu/3oV7BtgISoUNstmSe8WpWHOaWv19xyS+Mce9MY4BfseFhzTICUymUQdd/8hXA28/H6osUfAgsnxAKv7Wil3aJSgaJczWuflYOve0dJ3InZkhw5Cvr0atwpk8YKBQjy5CdkoHqvkOcIB+cYHXJKzOE5tqU7inSwVbHzOLQ3XbnAgMBAAECggEAVJp5eT0Ixg1eYSqFs9568WdetUNCSUchNxDBu6wxAbhUgfRUGZuJnnAll63OCTGGck+EGkFh48JjRcBpGoeoHLL88QXlZZbC/iLrea6gcDIhuvfzzOffe1RcZtDFEj9hlotg8dQj1tS0gy9pN9g4+EBH7zeu+fyv+qb2e/v1l6FkISXUjpkD7RLQr3ykjiiEw9BpeKb7j5s7Kdx1NNIzhkcQKNqlk8JrTGDNInbDM6inZfwwIO2R1DHinwdfKWkvOTODTYa2MoAvVMFT9Bec9FbLpoWp7ogv1JMV9svgrcF9XLzANZ/OQvkbe9TV9GWYvIbxN6qwQioKCWO4GPnCAQKBgQDgW5MgfhX8yjXqoaUy/d1VjI8dHeIyw8d+OBAYwaxRSlCfyQ+tieWcR2HdTzPca0T0GkWcKZm0ei5xRURgxt4DUDLXNh26HG0qObbtLJdu/AuBUuCqgOiLqJ2f1uIbrz6OZUHns+bT/jGW2Ws8+C13zTCZkZt9CaQsrp3QOGDx5wKBgQDTul39hp3ZPwGNFeZdkGoUoViOSd5Lhowd5wYMGAEXWRLlU8z+smT5v0POz9JnIbCRchIY2FAPKRdVTICzmPk2EPJFxYTcwaNbVqL6lN7J2IlXXMiit5QbiLauo55w7plwV6LQmKm9KV7JsZs5XwqF7CEovI7GevFzyD3w+uizAQKBgC3LY1eRhOlpWOIAhpjG6qOoohmeXOphvdmMlfSHq6WYFqbWwmV4rS5d/6LNpNdL6fItXqIGd8I34jzql49taCmi+A2nlR/E559j0mvM20gjGDIYeZUz5MOE8k+K6/IcrhcgofgqZ2ZED1ksHdB/E8DNWCswZl16V1FrfvjeWSNnAoGAMrBplCrIW5xz+J0Hm9rZKrs+AkK5D4fUv8vxbK/KgxZ2KaUYbNm0xv39c+PZUYuFRCz1HDGdaSPDTE6WeWjkMQd5mS6ikl9hhpqFRkyh0d0fdGToO9yLftQKOGE/q3XUEktI1XvXF0xyPwNgUCnq0QkpHyGVZPtGFxwXiDvpvgECgYA5PoB+nY8iDiRaJNko9w0hL4AeKogwf+4TbCw+KWVEn6jhuJa4LFTdSqp89PktQaoVpwv92el/AhYjWOl/jVCm122f9b7GyoelbjMNolToDwe5pF5RnSpEuDdLy9MfE8LnE3PlbE7E5BipQ3UjSebkgNboLHH/lNZA5qvEtvbfvQ==', 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAut9evKRuHJ/2QNfDlLwvN/S8l9hRAgPbb0u61bm4AtzaTGsLeMtScetxTWJnVvAVpMS9luhEJjt+Sbk5TNLArsgzzwARgaTKOLMT1TvWAK5EbHyI+eSrc3s7Awe1VYGwcubRFWDm16eQLv0k7iqiw+4mweHSz/wWyvBJVgwLoQ02btVtAQErCfSJCOmt0Q/oJQjj08YNRV4EKzB19+f5A+HQVAKy72dSybTzAK+3FPtTtNen/+b5wGeat7c32dhYHnGorPkPeXLtsqqUTp1su5fMfd4lElNdZaoCI7osZxWWUo17vBCZnyeXc9fk0qwD9mK6yRAxNbrY72Xx5VqIqwIDAQAB', 'http://api.auauz.net/api/aliPay/return', 'RSA2', '2088102176044281'); +COMMIT; + +-- ---------------------------- +-- Table structure for tool_email_config +-- ---------------------------- +DROP TABLE IF EXISTS `tool_email_config`; +CREATE TABLE `tool_email_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `from_user` varchar(255) DEFAULT NULL COMMENT '收件人', + `host` varchar(255) DEFAULT NULL COMMENT '邮件服务器SMTP地址', + `pass` varchar(255) DEFAULT NULL COMMENT '密码', + `port` varchar(255) DEFAULT NULL COMMENT '端口', + `user` varchar(255) DEFAULT NULL COMMENT '发件者用户名', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='邮箱配置'; + +-- ---------------------------- +-- Table structure for tool_local_storage +-- ---------------------------- +DROP TABLE IF EXISTS `tool_local_storage`; +CREATE TABLE `tool_local_storage` ( + `storage_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `real_name` varchar(255) DEFAULT NULL COMMENT '文件真实的名称', + `name` varchar(255) DEFAULT NULL COMMENT '文件名', + `suffix` varchar(255) DEFAULT NULL COMMENT '后缀', + `path` varchar(255) DEFAULT NULL COMMENT '路径', + `type` varchar(255) DEFAULT NULL COMMENT '类型', + `size` varchar(100) DEFAULT NULL COMMENT '大小', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建者', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新者', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`storage_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='本地存储'; + +-- ---------------------------- +-- Records of tool_local_storage +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for tool_qiniu_config +-- ---------------------------- +DROP TABLE IF EXISTS `tool_qiniu_config`; +CREATE TABLE `tool_qiniu_config` ( + `config_id` bigint(20) NOT NULL COMMENT 'ID', + `access_key` text DEFAULT NULL COMMENT 'accessKey', + `bucket` varchar(255) DEFAULT NULL COMMENT 'Bucket 识别符', + `host` varchar(255) NOT NULL COMMENT '外链域名', + `secret_key` text DEFAULT NULL COMMENT 'secretKey', + `type` varchar(255) DEFAULT NULL COMMENT '空间类型', + `zone` varchar(255) DEFAULT NULL COMMENT '机房', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='七牛云配置'; + +-- ---------------------------- +-- Table structure for tool_qiniu_content +-- ---------------------------- +DROP TABLE IF EXISTS `tool_qiniu_content`; +CREATE TABLE `tool_qiniu_content` ( + `content_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `bucket` varchar(255) DEFAULT NULL COMMENT 'Bucket 识别符', + `name` varchar(255) DEFAULT NULL COMMENT '文件名称', + `size` varchar(255) DEFAULT NULL COMMENT '文件大小', + `type` varchar(255) DEFAULT NULL COMMENT '文件类型:私有或公开', + `url` varchar(255) DEFAULT NULL COMMENT '文件url', + `suffix` varchar(255) DEFAULT NULL COMMENT '文件后缀', + `update_time` datetime DEFAULT NULL COMMENT '上传或同步的时间', + PRIMARY KEY (`content_id`) USING BTREE, + UNIQUE KEY `uniq_name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='七牛云文件存储'; + +-- ---------------------------- +-- Records of tool_qiniu_content +-- ---------------------------- +BEGIN; +COMMIT; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/UI source code/dns-dev-2.0/sql/tool_picture.sql b/UI source code/dns-dev-2.0/sql/tool_picture.sql new file mode 100644 index 0000000..6b36d0d --- /dev/null +++ b/UI source code/dns-dev-2.0/sql/tool_picture.sql @@ -0,0 +1,2 @@ +-- 删除免费图床表 +DROP TABLE tool_picture; \ No newline at end of file diff --git a/UI source code/dns-dev-2.0/sql/脚本如何选择.md b/UI source code/dns-dev-2.0/sql/脚本如何选择.md new file mode 100644 index 0000000..9734971 --- /dev/null +++ b/UI source code/dns-dev-2.0/sql/脚本如何选择.md @@ -0,0 +1,11 @@ +## 脚本指南 +项目根目录的 sql 文件夹内提供了本次数据库变更的脚本,脚本如何选择,以及执行的顺序如下 + +::: tip 注意 +操作数据库属于危险行为,请勿用于生产库,请事先做好备份!!! +::: + +### 初次使用 +dns.sql 为 dns 项目完整的 sql 脚本,适合于初次使用的用户 + +### 更新迭代 diff --git a/UI source code/dns_mapping_ui-master/.editorconfig b/UI source code/dns_mapping_ui-master/.editorconfig new file mode 100644 index 0000000..3454886 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.editorconfig @@ -0,0 +1,14 @@ +# https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/UI source code/dns_mapping_ui-master/.env.development b/UI source code/dns_mapping_ui-master/.env.development new file mode 100644 index 0000000..6ed6b44 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.env.development @@ -0,0 +1,8 @@ +ENV = 'development' + +# 接口地址 +VUE_APP_BASE_API = 'http://192.168.32.7:8888' +VUE_APP_WS_API = 'ws://192.168.32.7:8888' + +# 是否启用 babel-plugin-dynamic-import-node插件 +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/UI source code/dns_mapping_ui-master/.env.production b/UI source code/dns_mapping_ui-master/.env.production new file mode 100644 index 0000000..70f3cdc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.env.production @@ -0,0 +1,7 @@ +ENV = 'production' + +# 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇,Nginx 配置 +# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http +VUE_APP_BASE_API = 'http://192.168.10.175:8888' +# 如果接口是 http 形式, wss 需要改为 ws +VUE_APP_WS_API = 'ws://192.168.10.175:8888' diff --git a/UI source code/dns_mapping_ui-master/.eslintignore b/UI source code/dns_mapping_ui-master/.eslintignore new file mode 100644 index 0000000..e6529fc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.eslintignore @@ -0,0 +1,4 @@ +build/*.js +src/assets +public +dist diff --git a/UI source code/dns_mapping_ui-master/.eslintrc.js b/UI source code/dns_mapping_ui-master/.eslintrc.js new file mode 100644 index 0000000..c977505 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.eslintrc.js @@ -0,0 +1,198 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/UI source code/dns_mapping_ui-master/.gitignore b/UI source code/dns_mapping_ui-master/.gitignore new file mode 100644 index 0000000..1978bc2 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.gitignore @@ -0,0 +1,24 @@ +.DS_Store +node_modules/ +dist/ +demo/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/UI source code/dns_mapping_ui-master/.travis.yml b/UI source code/dns_mapping_ui-master/.travis.yml new file mode 100644 index 0000000..f4be7a0 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: 10 +script: npm run test +notifications: + email: false diff --git a/UI source code/dns_mapping_ui-master/LICENSE b/UI source code/dns_mapping_ui-master/LICENSE new file mode 100644 index 0000000..78a36cb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "{}" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2019 Zheng Jie + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/UI source code/dns_mapping_ui-master/README.md b/UI source code/dns_mapping_ui-master/README.md new file mode 100644 index 0000000..f835db4 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/README.md @@ -0,0 +1,69 @@ +# ELADMIN-WEB + +ELADMIN 前端源码 + +#### 项目源码 + +| | 后端源码 | 前端源码 | +|--- |--- | --- | +| github | https://github.com/elunez/eladmin | https://github.com/elunez/eladmin-web | +| 码云 | https://gitee.com/elunez/eladmin | https://gitee.com/elunez/eladmin-web | + +#### 开发文档 +[https://el-admin.vip](https://el-admin.vip) + +#### 体验地址 +[https://el-admin.vip/demo](https://el-admin.vip/demo) + +#### 前端模板 + +初始模板基于: [https://github.com/PanJiaChen/vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) + +模板文档: [https://panjiachen.github.io/vue-element-admin-site/zh/guide/](https://panjiachen.github.io/vue-element-admin-site/zh/guide/) + +#### Build Setup +``` bash +# 配置镜像加速 +https://www.ydyno.com/archives/1219.html + +# 安装依赖 +npm install + +# 启动服务 localhost:8013 +npm run dev + +# 构建生产环境 +npm run build:prod +``` + +#### 常见问题 + +1、linux 系统在安装依赖的时候会出现 node-sass 无法安装的问题 + +解决方案: +``` +1. 单独安装:npm install --unsafe-perm node-sass +2. 直接使用:npm install --unsafe-perm +``` + +2、加速node-sass安装 + +https://www.ydyno.com/archives/1219.html + +#### 特别鸣谢 + +- 感谢 [JetBrains](https://www.jetbrains.com/) 提供的非商业开源软件开发授权 + +- 感谢 [PanJiaChen](https://github.com/PanJiaChen/vue-element-admin) 大佬提供的前端模板 + +- 感谢 [Moxun](https://github.com/moxun1639) 大佬提供的前端 Curd 通用组件 + +- 感谢 [zhy6599](https://gitee.com/zhy6599) 大佬提供的后端运维管理相关功能 + +- 感谢 [j.yao.SUSE](https://github.com/everhopingandwaiting) 大佬提供的匿名接口与Redis限流等功能 + +- 感谢 [d15801543974](https://github.com/d15801543974) 大佬提供的基于注解的通用查询方式 + +#### 反馈交流 + +- QQ交流群:一群:891137268、二群:947578238、三群:659622532 \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/babel.config.js b/UI source code/dns_mapping_ui-master/babel.config.js new file mode 100644 index 0000000..804632a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/babel.config.js @@ -0,0 +1,11 @@ +const plugins = ['@vue/babel-plugin-transform-vue-jsx'] +// 生产环境移除console +if (process.env.NODE_ENV === 'production') { + plugins.push('transform-remove-console') +} +module.exports = { + plugins: plugins, + presets: [ + '@vue/app' + ] +} diff --git a/UI source code/dns_mapping_ui-master/jest.config.js b/UI source code/dns_mapping_ui-master/jest.config.js new file mode 100644 index 0000000..143cdc8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/jest.config.js @@ -0,0 +1,24 @@ +module.exports = { + moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': + 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: ['jest-serializer-vue'], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], + coverageDirectory: '/tests/unit/coverage', + // 'collectCoverage': true, + 'coverageReporters': [ + 'lcov', + 'text-summary' + ], + testURL: 'http://localhost/' +} diff --git a/UI source code/dns_mapping_ui-master/package.json b/UI source code/dns_mapping_ui-master/package.json new file mode 100644 index 0000000..2a19062 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/package.json @@ -0,0 +1,121 @@ +{ + "name": "eladmin-web", + "version": "2.6.0", + "description": "EL-ADMIN 前端源码", + "author": "Zheng Jie", + "license": "Apache-2.0", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml", + "new": "plop" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "repository": { + "type": "git", + "url": "https://github.com/elunez/eladmin-web.git" + }, + "bugs": { + "url": "https://github.com/elunez/eladmin/issues" + }, + "dependencies": { + "@riophae/vue-treeselect": "^0.4.0", + "axios": "^0.21.1", + "clipboard": "2.0.4", + "codemirror": "^5.49.2", + "connect": "3.6.6", + "core-js": "^2.6.12", + "echarts": "^4.2.1", + "echarts-gl": "^1.1.1", + "echarts-wordcloud": "^1.1.3", + "element-ui": "^2.15.6", + "file-saver": "1.3.8", + "fuse.js": "3.4.4", + "install": "^0.13.0", + "js-beautify": "^1.10.2", + "js-cookie": "2.2.0", + "jsencrypt": "^3.0.0-rc.1", + "jszip": "^3.7.1", + "less": "^3.9.0", + "less-loader": "^5.0.0", + "lodash": "^4.17.21", + "mavon-editor": "^2.9.1", + "moment": "^2.29.3", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "qs": "^6.10.1", + "screenfull": "4.2.0", + "sortablejs": "1.8.4", + "vue": "^2.6.14", + "vue-count-to": "^1.0.13", + "vue-cropper": "0.4.9", + "vue-echarts": "^5.0.0-beta.0", + "vue-highlightjs": "^1.3.3", + "vue-i18n": "^7.3.2", + "vue-image-crop-upload": "^2.5.0", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuedraggable": "2.20.0", + "vuex": "3.1.0", + "wangeditor": "^4.7.11", + "xlsx": "^0.17.4" + }, + "devDependencies": { + "@babel/parser": "^7.7.4", + "@babel/register": "7.0.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "babel-plugin-dynamic-import-node": "2.3.0", + "babel-plugin-transform-remove-console": "^6.9.4", + "chalk": "2.4.2", + "chokidar": "2.1.5", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "http-proxy-middleware": "^0.19.1", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "plop": "2.3.0", + "sass": "1.32.13", + "sass-loader": "10.2.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "tasksfile": "^5.1.1", + "vue-template-compiler": "2.6.14" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} diff --git a/UI source code/dns_mapping_ui-master/plopfile.js b/UI source code/dns_mapping_ui-master/plopfile.js new file mode 100644 index 0000000..9f3147e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/plopfile.js @@ -0,0 +1,7 @@ +const viewGenerator = require('./plop-templates/view/prompt') +const componentGenerator = require('./plop-templates/component/prompt') + +module.exports = function(plop) { + plop.setGenerator('view', viewGenerator) + plop.setGenerator('component', componentGenerator) +} diff --git a/UI source code/dns_mapping_ui-master/postcss.config.js b/UI source code/dns_mapping_ui-master/postcss.config.js new file mode 100644 index 0000000..961986e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/UI source code/dns_mapping_ui-master/public/favicon.ico b/UI source code/dns_mapping_ui-master/public/favicon.ico new file mode 100644 index 0000000..fcb6999 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/public/favicon.ico differ diff --git a/UI source code/dns_mapping_ui-master/public/index.html b/UI source code/dns_mapping_ui-master/public/index.html new file mode 100644 index 0000000..e918500 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/public/index.html @@ -0,0 +1,15 @@ + + + + + + + + + <%= webpackConfig.name %> + + +
+ + + diff --git a/UI source code/dns_mapping_ui-master/public/sjData/china.js b/UI source code/dns_mapping_ui-master/public/sjData/china.js new file mode 100644 index 0000000..eeec81f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/public/sjData/china.js @@ -0,0 +1,139 @@ +export const ChineseProvinces = [{ + name: '北京', + log_lat: [116.4551, 40.2539, 1], + value: 2, + }, + { + name: '黑龙江', + log_lat: [127.9688, 45.3686, 1], + value: 1 + }, { + name: '内蒙古', + log_lat: [110.3467, 41.4899, 1], + value: 1, + }, { + name: '吉林', + log_lat: [125.8154, 44.2584, 1], + value: 1, + }, { + name: '辽宁', + log_lat: [123.1238, 42.1216, 1], + value: 1, + }, { + name: '河北', + log_lat: [114.4995, 38.1006, 1], + value: 1, + }, { + name: '天津', + log_lat: [117.4219, 39.4189, 1], + value: 1, + }, { + name: '山西', + log_lat: [112.3352, 37.9413, 1], + value: 1, + }, { + name: '陕西', + log_lat: [109.1162, 34.2004, 1], + value: 1, + }, { + name: '甘肃', + log_lat: [103.5901, 36.3043, 1], + value: 1, + }, { + name: '宁夏', + log_lat: [106.3586, 38.1775, 1], + value: 1, + }, { + name: '青海', + log_lat: [101.4038, 36.8207, 1], + value: 1, + }, { + name: '新疆', + log_lat: [87.9236, 43.5883, 1], + value: 1, + }, { + name: '西藏', + log_lat: [91.1661, 29.9667, 1], + value: 1, + }, { + name: '四川', + log_lat: [103.9526, 30.7617, 1], + value: 1, + }, { + name: '重庆', + log_lat: [108.3866, 30.4302, 1], + value: 1, + }, { + name: '山东', + log_lat: [117.1582, 36.8701, 1], + value: 1, + }, { + name: '河南', + log_lat: [113.4668, 34.6234, 1], + value: 1, + }, { + name: '江苏', + log_lat: [118.8062, 31.9208, 1], + value: 1, + }, { + name: '安徽', + log_lat: [117.2879, 32.0581, 1], + value: 1, + }, { + name: '湖北', + log_lat: [114.3896, 30.6628, 1], + value: 1, + }, { + name: '浙江', + log_lat: [119.5313, 29.8773, 1], + value: 1, + }, { + name: '福建', + log_lat: [119.4543, 25.9222, 1], + value: 1, + }, { + name: '江西', + log_lat: [116.0046, 28.6633, 1], + value: 1, + }, { + name: '湖南', + log_lat: [113.0823, 28.2568, 1], + value: 1, + }, { + name: '贵州', + log_lat: [106.6992, 26.7682, 1], + value: 1, + }, { + name: '广东', + log_lat: [113.1244, 23.0005, 1], + value: 1, + }, { + name: '广西', + log_lat: [108.4769, 23.1152, 1], + value: 1, + }, { + name: '云南', + log_lat: [102.9199, 25.4663, 1], + value: 1, + }, { + name: '海南', + log_lat: [110.3893, 19.8516, 1], + value: 1, + }, { + name: '上海', + log_lat: [121.4648, 31.2891, 1], + value: 1, + }, { + name: '台湾', + log_lat: [121.4068, 24.9763, 1], + value: 1, + }, { + name: '澳门', + log_lat: [113.3783, 22.11, 1], + value: 1, + }, { + name: '香港', + log_lat: [114.1545, 22.15, 1], + value: 1, + }, +] \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/public/sjData/china.json b/UI source code/dns_mapping_ui-master/public/sjData/china.json new file mode 100644 index 0000000..9ecfdcb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/public/sjData/china.json @@ -0,0 +1,996 @@ +{ + "type":"FeatureCollection", + "features":[ + { + "type":"Feature", + "id":"xin_jiang", + "properties":{ + "name":"新疆", + "cp":[84.9023,41.748], + "childNum":18}, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [96.416,42.7588],[96.416,42.7148],[95.9766,42.4951],[96.0645,42.3193],[96.2402,42.2314],[95.9766,41.9238], + [95.2734,41.6162],[95.1855,41.792],[94.5703,41.4844],[94.043,41.0889],[93.8672,40.6934],[93.0762,40.6494], + [92.6367,39.6387],[92.373,39.3311],[92.373,39.1113],[92.373,39.0234],[90.1758,38.4961],[90.3516,38.2324], + [90.6152,38.3203],[90.5273,37.8369],[91.0547,37.4414],[91.3184,37.0898],[90.7031,36.7822],[90.791,36.6064], + [91.0547,36.5186],[91.0547,36.0791],[90.8789,36.0352],[90,36.2549],[89.9121,36.0791],[89.7363,36.0791], + [89.209,36.2988],[88.7695,36.3428],[88.5938,36.4746],[87.3633,36.4307],[86.2207,36.167],[86.1328,35.8594], + [85.6055,35.6836],[85.0781,35.7275],[84.1992,35.376],[83.1445,35.4199],[82.8809,35.6836],[82.4414,35.7275], + [82.002,35.332],[81.6504,35.2441],[80.4199,35.4199],[80.2441,35.2881],[80.332,35.1563],[80.2441,35.2002], + [79.8926,34.8047],[79.8047,34.4971],[79.1016,34.4531],[79.0137,34.3213],[78.2227,34.7168],[78.0469,35.2441], + [78.0469,35.5078],[77.4316,35.4639],[76.8164,35.6396],[76.5527,35.8594],[76.2012,35.8154],[75.9375,36.0352], + [76.0254,36.4746],[75.8496,36.6943],[75.498,36.7383],[75.4102,36.958],[75.0586,37.002],[74.8828,36.9141], + [74.7949,37.0459],[74.5313,37.0898],[74.5313,37.2217],[74.8828,37.2217],[75.1465,37.4414],[74.8828,37.5732], + [74.9707,37.749],[74.8828,38.4521],[74.3555,38.6719],[74.1797,38.6719],[74.0918,38.54],[73.8281,38.584], + [73.7402,38.8477],[73.8281,38.9795],[73.4766,39.375],[73.916,39.5068],[73.916,39.6826],[73.8281,39.7705], + [74.0039,40.0342],[74.8828,40.3418],[74.7949,40.5176],[75.2344,40.4297],[75.5859,40.6494],[75.7617,40.2979], + [76.377,40.3857],[76.9043,41.001],[77.6074,41.001],[78.1348,41.2207],[78.1348,41.3965],[80.1563,42.0557], + [80.2441,42.2754],[80.1563,42.627],[80.2441,42.8467],[80.5078,42.8906],[80.4199,43.0664],[80.7715,43.1982], + [80.4199,44.165],[80.4199,44.6045],[79.9805,44.8242],[79.9805,44.9561],[81.7383,45.3955],[82.0898,45.2197], + [82.5293,45.2197],[82.2656,45.6592],[83.0566,47.2412],[83.6719,47.0215],[84.7266,47.0215],[84.9023,46.8896], + [85.5176,47.0654],[85.6934,47.2852],[85.5176,48.1201],[85.7813,48.4277],[86.5723,48.5596],[86.8359,48.8232], + [86.748,48.9551],[86.8359,49.1309],[87.8027,49.1748],[87.8906,48.999],[87.7148,48.9111],[88.0664,48.7354], + [87.9785,48.6035],[88.5059,48.3838],[88.6816,48.1641],[89.1211,47.9883],[89.5605,48.0322],[89.7363,47.8564], + [90.0879,47.8564],[90.3516,47.6807],[90.5273,47.2412],[90.8789,46.9775],[91.0547,46.582],[90.8789,46.3184], + [91.0547,46.0107],[90.7031,45.7471],[90.7031,45.5273],[90.8789,45.2197],[91.582,45.0879],[93.5156,44.9561], + [94.7461,44.3408],[95.3613,44.2969],[95.3613,44.0332],[95.5371,43.9014],[95.8887,43.2422],[96.3281,42.9346], + [96.416,42.7588] + ]] + } + }, + { + "type":"Feature", + "id":"xi_zang", + "properties":{ + "name":"西藏", + "cp":[88.7695,31.6846], + "childNum":7 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [79.0137,34.3213],[79.1016,34.4531],[79.8047,34.4971],[79.8926,34.8047],[80.2441,35.2002],[80.332,35.1563], + [80.2441,35.2881],[80.4199,35.4199],[81.6504,35.2441],[82.002,35.332],[82.4414,35.7275],[82.8809,35.6836], + [83.1445,35.4199],[84.1992,35.376],[85.0781,35.7275],[85.6055,35.6836],[86.1328,35.8594],[86.2207,36.167], + [87.3633,36.4307],[88.5938,36.4746],[88.7695,36.3428],[89.209,36.2988],[89.7363,36.0791],[89.3848,36.0352], + [89.4727,35.9033],[89.7363,35.7715],[89.7363,35.4199],[89.4727,35.376],[89.4727,35.2441],[89.5605,34.8926], + [89.8242,34.8486],[89.7363,34.6729],[89.8242,34.3652],[89.6484,34.0137],[90.0879,33.4863],[90.7031,33.1348], + [91.4063,33.1348],[91.9336,32.8271],[92.1973,32.8271],[92.2852,32.7393],[92.9883,32.7393],[93.5156,32.4756], + [93.7793,32.5635],[94.1309,32.4316],[94.6582,32.6074],[95.1855,32.4316],[95.0098,32.2998],[95.1855,32.3438], + [95.2734,32.2119],[95.3613,32.168],[95.3613,31.9922],[95.4492,31.8164],[95.8008,31.6846],[95.9766,31.8164], + [96.1523,31.5967],[96.2402,31.9482],[96.5039,31.7285],[96.8555,31.6846],[96.7676,31.9922],[97.2949,32.0801], + [97.3828,32.5635],[97.7344,32.5195],[98.1738,32.3438],[98.4375,31.8604],[98.877,31.4209],[98.6133,31.2012], + [98.9648,30.7617],[99.1406,29.2676],[98.9648,29.1357],[98.9648,28.8281],[98.7891,28.8721],[98.7891,29.0039], + [98.7012,28.916],[98.6133,28.5205],[98.7891,28.3447],[98.7012,28.2129],[98.3496,28.125],[98.2617,28.3887], + [98.1738,28.125],[97.5586,28.5205],[97.2949,28.0811],[97.3828,27.9053],[97.0313,27.7295],[96.5039,28.125], + [95.7129,28.2568],[95.3613,28.125],[95.2734,27.9492],[94.2188,27.5537],[93.8672,27.0264],[93.6035,26.9385], + [92.1094,26.8506],[92.0215,27.4658],[91.582,27.5537],[91.582,27.9053],[91.4063,28.0371],[91.0547,27.8613], + [90.7031,28.0811],[89.8242,28.2129],[89.6484,28.1689],[89.1211,27.5977],[89.1211,27.334],[89.0332,27.2021], + [88.7695,27.4219],[88.8574,27.9932],[88.6816,28.125],[88.1543,27.9053],[87.8906,27.9492],[87.7148,27.8174], + [87.0996,27.8174],[86.748,28.125],[86.5723,28.125],[86.4844,27.9053],[86.1328,28.125],[86.0449,27.9053], + [85.6934,28.3447],[85.6055,28.2568],[85.166,28.3447],[85.166,28.6523],[84.9023,28.5645],[84.4629,28.7402], + [84.2871,28.8721],[84.1992,29.2236],[84.1113,29.2676],[83.584,29.1797],[83.2324,29.5752],[82.1777,30.0586], + [82.0898,30.3223],[81.3867,30.3662],[81.2109,30.0146],[81.0352,30.2344],[80.0684,30.5859],[79.7168,30.9375], + [79.0137,31.0693],[78.75,31.333],[78.8379,31.5967],[78.6621,31.8164],[78.75,31.9043],[78.4863,32.124], + [78.3984,32.5195],[78.75,32.6953],[78.9258,32.3438],[79.2773,32.5635],[79.1016,33.1787],[78.6621,33.6621], + [78.6621,34.1016],[78.9258,34.1455],[79.0137,34.3213] + ] + ] + } + }, + { + "type":"Feature", + "id":"nei_meng_gu", + "properties":{ + "name":"内蒙古", + "cp":[117.5977,44.3408], + "childNum":12 + }, + "geometry": { + "type":"Polygon", + "coordinates":[ + [ + [97.207,42.8027],[99.4922,42.583],[100.8105,42.6709],[101.7773,42.4951],[102.041,42.2314],[102.7441,42.1436], + [103.3594,41.8799],[103.8867,41.792],[104.502,41.8799],[104.502,41.6602],[105.0293,41.5723],[105.7324,41.9238], + [107.4023,42.4512],[109.4238,42.4512],[110.3906,42.7588],[111.0059,43.3301],[111.9727,43.6816],[111.9727,43.8135], + [111.4453,44.3848],[111.7969,45],[111.9727,45.0879],[113.6426,44.7363],[114.1699,44.9561],[114.5215,45.3955], + [115.6641,45.4395],[116.1914,45.7031],[116.2793,45.9668],[116.543,46.2744],[117.334,46.3623],[117.4219,46.582], + [117.7734,46.5381],[118.3008,46.7578],[118.7402,46.7139],[118.916,46.7578],[119.0918,46.6699],[119.707,46.626], + [119.9707,46.7139],[119.707,47.1973],[118.4766,47.9883],[117.8613,48.0322],[117.334,47.6807],[116.8066,47.9004], + [116.1914,47.8564],[115.9277,47.6807],[115.5762,47.9004],[115.4883,48.1641],[115.8398,48.252],[115.8398,48.5596], + [116.7188,49.834],[117.7734,49.5264],[118.5645,49.9219],[119.2676,50.0977],[119.3555,50.3174],[119.1797,50.3613], + [119.5313,50.7568],[119.5313,50.8887],[119.707,51.0645],[120.1465,51.6797],[120.6738,51.9434],[120.7617,52.1191], + [120.7617,52.251],[120.5859,52.3389],[120.6738,52.5146],[120.4102,52.6465],[120.0586,52.6025],[120.0586,52.7344], + [120.8496,53.2617],[121.4648,53.3496],[121.8164,53.042],[121.2012,52.5586],[121.6406,52.4268],[121.7285,52.2949], + [121.9922,52.2949],[122.168,52.5146],[122.6953,52.251],[122.6074,52.0752],[122.959,51.3281],[123.3105,51.2402], + [123.6621,51.3721],[124.3652,51.2842],[124.541,51.3721],[124.8926,51.3721],[125.0684,51.6357],[125.332,51.6357], + [126.0352,51.0205],[125.7715,50.7568],[125.7715,50.5371],[125.332,50.1416],[125.1563,49.834],[125.2441,49.1748], + [124.8047,49.1309],[124.4531,48.1201],[124.2773,48.5156],[122.4316,47.373],[123.0469,46.7139],[123.3984,46.8896], + [123.3984,46.9775],[123.4863,46.9775],[123.5742,46.8457],[123.5742,46.8896],[123.5742,46.6699],[123.0469,46.582], + [123.2227,46.2305],[122.7832,46.0107],[122.6953,45.7031],[122.4316,45.8789],[122.2559,45.791],[121.8164,46.0107], + [121.7285,45.7471],[121.9043,45.7031],[122.2559,45.2637],[122.0801,44.8682],[122.3438,44.2529],[123.1348,44.4727], + [123.4863,43.7256],[123.3105,43.5059],[123.6621,43.374],[123.5742,43.0225],[123.3105,42.9785],[123.1348,42.8027], + [122.7832,42.7148],[122.3438,42.8467],[122.3438,42.6709],[121.9922,42.7148],[121.7285,42.4512],[121.4648,42.4951], + [120.498,42.0996],[120.1465,41.7041],[119.8828,42.1875],[119.5313,42.3633],[119.3555,42.2754],[119.2676,41.7041], + [119.4434,41.6162],[119.2676,41.3086],[118.3887,41.3086],[118.125,41.748],[118.3008,41.792],[118.3008,42.0996], + [118.125,42.0557],[117.9492,42.2314],[118.0371,42.4072],[117.7734,42.627],[117.5098,42.583],[117.334,42.4512], + [116.8945,42.4072],[116.8066,42.0117],[116.2793,42.0117],[116.0156,41.792],[115.9277,41.9238],[115.2246,41.5723], + [114.9609,41.6162],[114.873,42.0996],[114.5215,42.1436],[114.1699,41.792],[114.2578,41.5723],[113.9063,41.4404], + [113.9941,41.2207],[113.9063,41.1328],[114.082,40.7373],[114.082,40.5176],[113.8184,40.5176],[113.5547,40.3418], + [113.2031,40.3857],[112.7637,40.166],[112.3242,40.2539],[111.9727,39.5947],[111.4453,39.6387],[111.3574,39.4189], + [111.0938,39.375],[111.0938,39.5947],[110.6543,39.2871],[110.127,39.4629],[110.2148,39.2871],[109.8633,39.2432], + [109.9512,39.1553],[108.9844,38.3203],[109.0723,38.0127],[108.8965,37.9688],[108.8086,38.0127],[108.7207,37.7051], + [108.1934,37.6172],[107.666,37.8809],[107.3145,38.1006],[106.7871,38.1885],[106.5234,38.3203],[106.9629,38.9795], + [106.7871,39.375],[106.3477,39.2871],[105.9082,38.7158],[105.8203,37.793],[104.3262,37.4414],[103.4473,37.8369], + [103.3594,38.0127],[103.5352,38.1445],[103.4473,38.3643],[104.2383,38.9795],[104.0625,39.4189],[103.3594,39.3311], + [103.0078,39.1113],[102.4805,39.2432],[101.8652,39.1113],[102.041,38.8916],[101.7773,38.6719],[101.3379,38.7598], + [101.25,39.0234],[100.9863,38.9355],[100.8105,39.4189],[100.5469,39.4189],[100.0195,39.7705],[99.4922,39.8584], + [100.1074,40.2539],[100.1953,40.6494],[99.9316,41.001],[99.2285,40.8691],[99.0527,40.6934],[98.9648,40.7813], + [98.7891,40.6055],[98.5254,40.7373],[98.6133,40.6494],[98.3496,40.5615],[98.3496,40.9131],[97.4707,41.4844], + [97.8223,41.6162],[97.8223,41.748],[97.207,42.8027] + ] + ] + } + }, + { + "type":"Feature", + "id":"qing_hai", + "properties":{ + "name":"青海", + "cp":[96.2402,35.4199], + "childNum":8 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [89.7363,36.0791],[89.9121,36.0791],[90,36.2549],[90.8789,36.0352],[91.0547,36.0791],[91.0547,36.5186], + [90.791,36.6064],[90.7031,36.7822],[91.3184,37.0898],[91.0547,37.4414],[90.5273,37.8369],[90.6152,38.3203], + [90.3516,38.2324],[90.1758,38.4961],[92.373,39.0234],[92.373,39.1113],[93.1641,39.1992],[93.1641,38.9795], + [93.6914,38.9355],[93.8672,38.7158],[94.3066,38.7598],[94.5703,38.3643],[95.0098,38.4082],[95.4492,38.2764], + [95.7129,38.3643],[96.2402,38.1006],[96.416,38.2324],[96.6797,38.1885],[96.6797,38.4521],[97.1191,38.584], + [97.0313,39.1992],[98.1738,38.8037],[98.3496,39.0234],[98.6133,38.9355],[98.7891,39.0674],[99.1406,38.9355], + [99.8438,38.3643],[100.1953,38.2764],[100.0195,38.4521],[100.1074,38.4961],[100.459,38.2764],[100.7227,38.2324], + [101.1621,37.8369],[101.5137,37.8809],[101.7773,37.6172],[101.9531,37.7051],[102.1289,37.4414],[102.5684,37.1777], + [102.4805,36.958],[102.6563,36.8262],[102.5684,36.7383],[102.832,36.3428],[103.0078,36.2549],[102.9199,36.0791], + [102.9199,35.9033],[102.6563,35.7715],[102.832,35.5957],[102.4805,35.5957],[102.3047,35.4199],[102.3926,35.2002], + [101.9531,34.8486],[101.9531,34.6289],[102.2168,34.4092],[102.1289,34.2773],[101.6895,34.1016],[100.9863,34.3652], + [100.8105,34.2773],[101.25,33.6621],[101.5137,33.7061],[101.6016,33.5303],[101.7773,33.5303],[101.6895,33.3105], + [101.7773,33.2227],[101.6016,33.1348],[101.1621,33.2227],[101.25,32.6953],[100.7227,32.6514],[100.7227,32.5195], + [100.3711,32.7393],[100.1074,32.6514],[100.1074,32.8711],[99.8438,33.0029],[99.7559,32.7393],[99.2285,32.915], + [99.2285,33.0469],[98.877,33.1787],[98.4375,34.0576],[97.8223,34.1895],[97.6465,34.1016],[97.7344,33.9258], + [97.3828,33.8818],[97.4707,33.5742],[97.7344,33.3984],[97.3828,32.8711],[97.4707,32.6953],[97.7344,32.5195], + [97.3828,32.5635],[97.2949,32.0801],[96.7676,31.9922],[96.8555,31.6846],[96.5039,31.7285],[96.2402,31.9482], + [96.1523,31.5967],[95.9766,31.8164],[95.8008,31.6846],[95.4492,31.8164],[95.3613,31.9922],[95.3613,32.168], + [95.2734,32.2119],[95.1855,32.3438],[95.0098,32.2998],[95.1855,32.4316],[94.6582,32.6074],[94.1309,32.4316], + [93.7793,32.5635],[93.5156,32.4756],[92.9883,32.7393],[92.2852,32.7393],[92.1973,32.8271],[91.9336,32.8271], + [91.4063,33.1348],[90.7031,33.1348],[90.0879,33.4863],[89.6484,34.0137],[89.8242,34.3652],[89.7363,34.6729], + [89.8242,34.8486],[89.5605,34.8926],[89.4727,35.2441],[89.4727,35.376],[89.7363,35.4199],[89.7363,35.7715], + [89.4727,35.9033],[89.3848,36.0352],[89.7363,36.0791] + ] + ] + } + }, + { + "type":"Feature", + "id":"si_chuan", + "properties":{ + "name":"四川", + "cp":[102.9199,30.1904], + "childNum":21 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [101.7773,33.5303],[101.8652,33.5742],[101.9531,33.4424],[101.8652,33.0908],[102.4805,33.4424],[102.2168,33.9258], + [102.9199,34.3213],[103.0957,34.1895],[103.1836,33.7939],[104.1504,33.6182],[104.2383,33.3984],[104.4141,33.3105], + [104.3262,33.2227],[104.4141,33.0469],[104.3262,32.8711],[104.4141,32.7393],[105.2051,32.6074],[105.3809,32.7393], + [105.3809,32.8711],[105.4688,32.915],[105.5566,32.7393],[106.084,32.8711],[106.084,32.7393],[106.3477,32.6514], + [107.0508,32.6953],[107.1387,32.4756],[107.2266,32.4316],[107.4023,32.5195],[108.0176,32.168],[108.2813,32.2559], + [108.5449,32.2119],[108.3691,32.168],[108.2813,31.9043],[108.5449,31.6846],[108.1934,31.5088],[107.9297,30.8496], + [107.4902,30.8496],[107.4023,30.7617],[107.4902,30.6299],[107.0508,30.0146],[106.7871,30.0146],[106.6113,30.3223], + [106.2598,30.1904],[105.8203,30.4541],[105.6445,30.2783],[105.5566,30.1025],[105.7324,29.8828],[105.293,29.5313], + [105.4688,29.3115],[105.7324,29.2676],[105.8203,28.96],[106.2598,28.8721],[106.3477,28.5205],[105.9961,28.7402], + [105.6445,28.4326],[105.9082,28.125],[106.1719,28.125],[106.3477,27.8174],[105.6445,27.6416],[105.5566,27.7734], + [105.293,27.7295],[105.2051,27.9932],[105.0293,28.0811],[104.8535,27.9053],[104.4141,27.9492],[104.3262,28.0371], + [104.4141,28.125],[104.4141,28.2568],[104.2383,28.4326],[104.4141,28.6084],[103.8867,28.6523],[103.7988,28.3008], + [103.4473,28.125],[103.4473,27.7734],[102.9199,27.29],[103.0078,26.3672],[102.6563,26.1914],[102.5684,26.3672], + [102.1289,26.1035],[101.8652,26.0596],[101.6016,26.2354],[101.6895,26.3672],[101.4258,26.5869],[101.4258,26.8066], + [101.4258,26.7188],[101.1621,27.0264],[101.1621,27.1582],[100.7227,27.8613],[100.3711,27.8174],[100.2832,27.7295], + [100.0195,28.125],[100.1953,28.3447],[99.668,28.8281],[99.4043,28.5205],[99.4043,28.1689],[99.2285,28.3008], + [99.1406,29.2676],[98.9648,30.7617],[98.6133,31.2012],[98.877,31.4209],[98.4375,31.8604],[98.1738,32.3438], + [97.7344,32.5195],[97.4707,32.6953],[97.3828,32.8711],[97.7344,33.3984],[97.4707,33.5742],[97.3828,33.8818], + [97.7344,33.9258],[97.6465,34.1016],[97.8223,34.1895],[98.4375,34.0576],[98.877,33.1787],[99.2285,33.0469], + [99.2285,32.915],[99.7559,32.7393],[99.8438,33.0029],[100.1074,32.8711],[100.1074,32.6514],[100.3711,32.7393], + [100.7227,32.5195],[100.7227,32.6514],[101.25,32.6953],[101.1621,33.2227],[101.6016,33.1348],[101.7773,33.2227], + [101.6895,33.3105],[101.7773,33.5303] + ] + ] + } + }, + { + "type":"Feature", + "id":"hei_long_jiang", + "properties":{ + "name":"黑龙江", + "cp":[128.1445,48.5156], + "childNum":13 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [121.4648,53.3496],[123.6621,53.5693],[124.8926,53.0859],[125.0684,53.2178],[125.5957,53.0859],[125.6836,52.9102], + [126.123,52.7783],[126.0352,52.6025],[126.2109,52.5146],[126.3867,52.2949],[126.3867,52.207],[126.5625,52.1631], + [126.4746,51.9434],[126.9141,51.3721],[126.8262,51.2842],[127.002,51.3281],[126.9141,51.1084],[127.2656,50.7568], + [127.3535,50.2734],[127.6172,50.2295],[127.5293,49.8779],[127.793,49.6143],[128.7598,49.5703],[129.1113,49.3506], + [129.4629,49.4385],[130.2539,48.8672],[130.6934,48.8672],[130.5176,48.6475],[130.8691,48.2959],[130.6934,48.1201], + [131.0449,47.6807],[132.5391,47.7246],[132.627,47.9443],[133.0664,48.1201],[133.5059,48.1201],[134.209,48.3838], + [135.0879,48.4277],[134.7363,48.252],[134.5605,47.9883],[134.7363,47.6807],[134.5605,47.4609],[134.3848,47.4609], + [134.209,47.2852],[134.209,47.1533],[133.8574,46.5381],[133.9453,46.2744],[133.5059,45.835],[133.418,45.5713], + [133.2422,45.5273],[133.0664,45.1318],[132.8906,45.0439],[131.9238,45.3516],[131.5723,45.0439],[131.0449,44.8682], + [131.3086,44.0771],[131.2207,43.7256],[131.3086,43.4619],[130.8691,43.418],[130.5176,43.6377],[130.3418,43.9893], + [129.9902,43.8574],[129.9023,44.0332],[129.8145,43.9014],[129.2871,43.8135],[129.1992,43.5938],[128.8477,43.5498], + [128.4961,44.165],[128.4082,44.4727],[128.0566,44.3408],[128.0566,44.1211],[127.7051,44.1211],[127.5293,44.6045], + [127.0898,44.6045],[127.002,44.7803],[127.0898,45],[126.9141,45.1318],[126.5625,45.2637],[126.0352,45.1758], + [125.7715,45.3076],[125.6836,45.5273],[125.0684,45.3955],[124.8926,45.5273],[124.3652,45.4395],[124.0137,45.7471], + [123.9258,46.2305],[123.2227,46.2305],[123.0469,46.582],[123.5742,46.6699],[123.5742,46.8896],[123.5742,46.8457], + [123.4863,46.9775],[123.3984,46.9775],[123.3984,46.8896],[123.0469,46.7139],[122.4316,47.373],[124.2773,48.5156], + [124.4531,48.1201],[124.8047,49.1309],[125.2441,49.1748],[125.1563,49.834],[125.332,50.1416],[125.7715,50.5371], + [125.7715,50.7568],[126.0352,51.0205],[125.332,51.6357],[125.0684,51.6357],[124.8926,51.3721],[124.541,51.3721], + [124.3652,51.2842],[123.6621,51.3721],[123.3105,51.2402],[122.959,51.3281],[122.6074,52.0752],[122.6953,52.251], + [122.168,52.5146],[121.9922,52.2949],[121.7285,52.2949],[121.6406,52.4268],[121.2012,52.5586],[121.8164,53.042], + [121.4648,53.3496] + ] + ] + } + }, + { + "type":"Feature", + "id":"gan_su", + "properties":{ + "name":"甘肃", + "cp":[95.7129,40.166], + "childNum":14 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [96.416,42.7148],[97.207,42.8027],[97.8223,41.748],[97.8223,41.6162],[97.4707,41.4844],[98.3496,40.9131], + [98.3496,40.5615],[98.6133,40.6494],[98.5254,40.7373],[98.7891,40.6055],[98.9648,40.7813],[99.0527,40.6934], + [99.2285,40.8691],[99.9316,41.001],[100.1953,40.6494],[100.1074,40.2539],[99.4922,39.8584],[100.0195,39.7705], + [100.5469,39.4189],[100.8105,39.4189],[100.9863,38.9355],[101.25,39.0234],[101.3379,38.7598],[101.7773,38.6719], + [102.041,38.8916],[101.8652,39.1113],[102.4805,39.2432],[103.0078,39.1113],[103.3594,39.3311],[104.0625,39.4189], + [104.2383,38.9795],[103.4473,38.3643],[103.5352,38.1445],[103.3594,38.0127],[103.4473,37.8369],[104.3262,37.4414], + [104.5898,37.4414],[104.5898,37.2217],[104.8535,37.2217],[105.293,36.8262],[105.2051,36.6943],[105.4688,36.123], + [105.293,35.9912],[105.3809,35.7715],[105.7324,35.7275],[105.8203,35.5518],[105.9961,35.4639],[105.9082,35.4199], + [105.9961,35.4199],[106.084,35.376],[106.2598,35.4199],[106.3477,35.2441],[106.5234,35.332],[106.4355,35.6836], + [106.6992,35.6836],[106.9629,35.8154],[106.875,36.123],[106.5234,36.2549],[106.5234,36.4746],[106.4355,36.5625], + [106.6113,36.7822],[106.6113,37.0898],[107.3145,37.0898],[107.3145,36.9141],[108.7207,36.3428],[108.6328,35.9912], + [108.5449,35.8594],[108.6328,35.5518],[108.5449,35.2881],[107.7539,35.2881],[107.7539,35.1123],[107.8418,35.0244], + [107.666,34.9365],[107.2266,34.8926],[106.9629,35.0684],[106.6113,35.0684],[106.5234,34.7607],[106.3477,34.585], + [106.6992,34.3213],[106.5234,34.2773],[106.6113,34.1455],[106.4355,33.9258],[106.5234,33.5303],[105.9961,33.6182], + [105.7324,33.3984],[105.9961,33.1787],[105.9082,33.0029],[105.4688,32.915],[105.3809,32.8711],[105.3809,32.7393], + [105.2051,32.6074],[104.4141,32.7393],[104.3262,32.8711],[104.4141,33.0469],[104.3262,33.2227],[104.4141,33.3105], + [104.2383,33.3984],[104.1504,33.6182],[103.1836,33.7939],[103.0957,34.1895],[102.9199,34.3213],[102.2168,33.9258], + [102.4805,33.4424],[101.8652,33.0908],[101.9531,33.4424],[101.8652,33.5742],[101.7773,33.5303],[101.6016,33.5303], + [101.5137,33.7061],[101.25,33.6621],[100.8105,34.2773],[100.9863,34.3652],[101.6895,34.1016],[102.1289,34.2773], + [102.2168,34.4092],[101.9531,34.6289],[101.9531,34.8486],[102.3926,35.2002],[102.3047,35.4199],[102.4805,35.5957], + [102.832,35.5957],[102.6563,35.7715],[102.9199,35.9033],[102.9199,36.0791],[103.0078,36.2549],[102.832,36.3428], + [102.5684,36.7383],[102.6563,36.8262],[102.4805,36.958],[102.5684,37.1777],[102.1289,37.4414],[101.9531,37.7051], + [101.7773,37.6172],[101.5137,37.8809],[101.1621,37.8369],[100.7227,38.2324],[100.459,38.2764],[100.1074,38.4961], + [100.0195,38.4521],[100.1953,38.2764],[99.8438,38.3643],[99.1406,38.9355],[98.7891,39.0674],[98.6133,38.9355], + [98.3496,39.0234],[98.1738,38.8037],[97.0313,39.1992],[97.1191,38.584],[96.6797,38.4521],[96.6797,38.1885], + [96.416,38.2324],[96.2402,38.1006],[95.7129,38.3643],[95.4492,38.2764],[95.0098,38.4082],[94.5703,38.3643], + [94.3066,38.7598],[93.8672,38.7158],[93.6914,38.9355],[93.1641,38.9795],[93.1641,39.1992],[92.373,39.1113], + [92.373,39.3311],[92.6367,39.6387],[93.0762,40.6494],[93.8672,40.6934],[94.043,41.0889],[94.5703,41.4844], + [95.1855,41.792],[95.2734,41.6162],[95.9766,41.9238],[96.2402,42.2314],[96.0645,42.3193],[95.9766,42.4951], + [96.416,42.7148]] + ] + } + }, + { + "type":"Feature", + "id":"yun_nan", + "properties":{ + "name":"云南", + "cp":[101.8652,25.1807], + "childNum":16 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [98.1738,28.125],[98.2617,28.3887],[98.3496,28.125],[98.7012,28.2129],[98.7891,28.3447],[98.6133,28.5205], + [98.7012,28.916],[98.7891,29.0039],[98.7891,28.8721],[98.9648,28.8281],[98.9648,29.1357],[99.1406,29.2676], + [99.2285,28.3008],[99.4043,28.1689],[99.4043,28.5205],[99.668,28.8281],[100.1953,28.3447],[100.0195,28.125], + [100.2832,27.7295],[100.3711,27.8174],[100.7227,27.8613],[101.1621,27.1582],[101.1621,27.0264],[101.4258,26.7188], + [101.4258,26.8066],[101.4258,26.5869],[101.6895,26.3672],[101.6016,26.2354],[101.8652,26.0596],[102.1289,26.1035], + [102.5684,26.3672],[102.6563,26.1914],[103.0078,26.3672],[102.9199,27.29],[103.4473,27.7734],[103.4473,28.125], + [103.7988,28.3008],[103.8867,28.6523],[104.4141,28.6084],[104.2383,28.4326],[104.4141,28.2568],[104.4141,28.125], + [104.3262,28.0371],[104.4141,27.9492],[104.8535,27.9053],[105.0293,28.0811],[105.2051,27.9932],[105.293,27.7295], + [105.2051,27.3779],[104.5898,27.334],[104.4141,27.4658],[104.1504,27.2461],[103.8867,27.4219],[103.623,27.0264], + [103.7109,26.9824],[103.7109,26.7627],[103.8867,26.543],[104.4141,26.6748],[104.6777,26.4111],[104.3262,25.708], + [104.8535,25.2246],[104.5898,25.0488],[104.6777,24.9609],[104.502,24.7412],[104.6777,24.3457],[104.7656,24.4775], + [105.0293,24.4336],[105.2051,24.082],[105.4688,24.0381],[105.5566,24.126],[105.9961,24.126],[106.1719,23.8184], + [106.1719,23.5547],[105.6445,23.4229],[105.5566,23.2031],[105.293,23.3789],[104.8535,23.1592],[104.7656,22.8516], + [104.3262,22.6758],[104.1504,22.8076],[103.9746,22.5439],[103.623,22.7637],[103.5352,22.5879],[103.3594,22.8076], + [103.0957,22.4561],[102.4805,22.7637],[102.3047,22.4121],[101.8652,22.3682],[101.7773,22.5],[101.6016,22.1924], + [101.8652,21.6211],[101.7773,21.1377],[101.6016,21.2256],[101.25,21.1816],[101.1621,21.7529],[100.6348,21.4453], + [100.1074,21.4893],[99.9316,22.0605],[99.2285,22.1484],[99.4043,22.5879],[99.3164,22.7197],[99.4922,23.0713], + [98.877,23.2031],[98.7012,23.9502],[98.877,24.126],[98.1738,24.082],[97.7344,23.8623],[97.5586,23.9063], + [97.7344,24.126],[97.6465,24.4336],[97.5586,24.4336],[97.5586,24.7412],[97.7344,24.8291],[97.8223,25.2686], + [98.1738,25.4004],[98.1738,25.6201],[98.3496,25.5762],[98.5254,25.8398],[98.7012,25.8838],[98.6133,26.0596], + [98.7012,26.1475],[98.7891,26.5869],[98.7012,27.5098],[98.5254,27.6416],[98.3496,27.5098],[98.1738,28.125] + ] + ] + } + }, + { + "type":"Feature", + "id":"guang_xi", + "properties":{ + "name":"广西", + "cp":[108.2813,23.6426], + "childNum":14 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [104.502,24.7412],[104.6777,24.6094],[105.2051,24.9609],[105.9961,24.6533],[106.1719,24.7852],[106.1719,24.9609], + [106.875,25.1807],[107.0508,25.2686],[106.9629,25.4883],[107.2266,25.6201],[107.4902,25.2246],[107.7539,25.2246], + [107.8418,25.1367],[108.1055,25.2246],[108.1934,25.4443],[108.3691,25.5322],[108.6328,25.3125],[108.6328,25.5762], + [109.0723,25.5322],[108.9844,25.752],[109.3359,25.708],[109.5117,26.0156],[109.7754,25.8838],[109.9512,26.1914], + [110.2148,25.9717],[110.5664,26.3232],[111.1816,26.3232],[111.2695,26.2354],[111.2695,25.8838],[111.4453,25.8398], + [111.0059,25.0049],[111.0938,24.9609],[111.3574,25.1367],[111.5332,24.6533],[111.709,24.7852],[112.0605,24.7412], + [111.8848,24.6533],[112.0605,24.3457],[111.8848,24.2139],[111.8848,23.9941],[111.7969,23.8184],[111.6211,23.8184], + [111.6211,23.6865],[111.3574,23.4668],[111.4453,23.0273],[111.2695,22.8076],[110.7422,22.5439],[110.7422,22.2803], + [110.6543,22.1484],[110.3027,22.1484],[110.3027,21.8848],[109.9512,21.8408],[109.8633,21.665],[109.7754,21.6211], + [109.7754,21.4014],[109.5996,21.4453],[109.1602,21.3574],[109.248,20.874],[109.0723,20.9619],[109.0723,21.5332], + [108.7207,21.5332],[108.6328,21.665],[108.2813,21.4893],[107.8418,21.6211],[107.4023,21.6211],[107.0508,21.7969], + [107.0508,21.9287],[106.6992,22.0166],[106.6113,22.4121],[106.7871,22.7637],[106.6992,22.8955],[105.9082,22.9395], + [105.5566,23.0713],[105.5566,23.2031],[105.6445,23.4229],[106.1719,23.5547],[106.1719,23.8184],[105.9961,24.126], + [105.5566,24.126],[105.4688,24.0381],[105.2051,24.082],[105.0293,24.4336],[104.7656,24.4775],[104.6777,24.3457], + [104.502,24.7412] + ] + ] + } + }, + { + "type":"Feature", + "id":"hu_nan", + "properties":{ + "name":"湖南", + "cp":[111.5332,27.3779], + "childNum":14 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [109.248,28.4766],[109.248,29.1357],[109.5117,29.6191],[109.6875,29.6191],[109.7754,29.751],[110.4785,29.6631], + [110.6543,29.751],[110.4785,30.0146],[110.8301,30.1465],[111.7969,29.9268],[112.2363,29.5313],[112.5,29.6191], + [112.6758,29.5752],[112.9395,29.7949],[113.0273,29.751],[112.9395,29.4873],[113.0273,29.4434],[113.5547,29.8389], + [113.5547,29.707],[113.7305,29.5752],[113.6426,29.3115],[113.7305,29.0918],[113.9063,29.0479],[114.1699,28.8281], + [114.082,28.5645],[114.2578,28.3447],[113.7305,27.9492],[113.6426,27.5977],[113.6426,27.3779],[113.8184,27.29], + [113.7305,27.1143],[113.9063,26.9385],[113.9063,26.6309],[114.082,26.5869],[113.9941,26.1914],[114.2578,26.1475], + [113.9941,26.0596],[113.9063,25.4443],[113.6426,25.3125],[113.2031,25.5322],[112.8516,25.3564],[113.0273,25.2246], + [113.0273,24.9609],[112.8516,24.917],[112.5879,25.1367],[112.2363,25.1807],[112.1484,24.873],[112.0605,24.7412], + [111.709,24.7852],[111.5332,24.6533],[111.3574,25.1367],[111.0938,24.9609],[111.0059,25.0049],[111.4453,25.8398], + [111.2695,25.8838],[111.2695,26.2354],[111.1816,26.3232],[110.5664,26.3232],[110.2148,25.9717],[109.9512,26.1914], + [109.7754,25.8838],[109.5117,26.0156],[109.4238,26.2793],[109.248,26.3232],[109.4238,26.5869],[109.3359,26.7188], + [109.5117,26.8066],[109.5117,27.0264],[109.3359,27.1582],[108.8965,27.0264],[108.8086,27.1143],[109.4238,27.5977], + [109.3359,27.9053],[109.3359,28.2568],[109.248,28.4766] + ] + ] + } + }, + { + "type":"Feature","id":"shan_xi_1", + "properties":{ + "name":"陕西", + "cp":[109.5996,35.6396], + "childNum":10 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [105.4688,32.915],[105.9082,33.0029],[105.9961,33.1787],[105.7324,33.3984],[105.9961,33.6182],[106.5234,33.5303], + [106.4355,33.9258],[106.6113,34.1455],[106.5234,34.2773],[106.6992,34.3213],[106.3477,34.585],[106.5234,34.7607], + [106.6113,35.0684],[106.9629,35.0684],[107.2266,34.8926],[107.666,34.9365],[107.8418,35.0244],[107.7539,35.1123], + [107.7539,35.2881],[108.5449,35.2881],[108.6328,35.5518],[108.5449,35.8594],[108.6328,35.9912],[108.7207,36.3428], + [107.3145,36.9141],[107.3145,37.0898],[107.3145,37.6172],[107.666,37.8809],[108.1934,37.6172],[108.7207,37.7051], + [108.8086,38.0127],[108.8965,37.9688],[109.0723,38.0127],[108.9844,38.3203],[109.9512,39.1553],[109.8633,39.2432], + [110.2148,39.2871],[110.127,39.4629],[110.6543,39.2871],[111.0938,39.5947],[111.0938,39.375],[111.1816,39.2432], + [110.918,38.7158],[110.8301,38.4961],[110.4785,38.1885],[110.4785,37.9688],[110.8301,37.6611],[110.3906,37.002], + [110.4785,36.123],[110.5664,35.6396],[110.2148,34.8926],[110.2148,34.6729],[110.3906,34.585],[110.4785,34.2334], + [110.6543,34.1455],[110.6543,33.8379],[111.0059,33.5303],[111.0059,33.2666],[110.7422,33.1348],[110.5664,33.2666], + [110.3027,33.1787],[109.5996,33.2666],[109.4238,33.1348],[109.7754,33.0469],[109.7754,32.915],[110.127,32.7393], + [110.127,32.6074],[109.6875,32.6074],[109.5117,32.4316],[109.5996,31.7285],[109.248,31.7285],[109.0723,31.9482], + [108.5449,32.2119],[108.2813,32.2559],[108.0176,32.168],[107.4023,32.5195],[107.2266,32.4316],[107.1387,32.4756], + [107.0508,32.6953],[106.3477,32.6514],[106.084,32.7393],[106.084,32.8711],[105.5566,32.7393],[105.4688,32.915] + ] + ] + } + }, + { + "type":"Feature", + "id":"guang_dong", + "properties":{ + "name":"广东", + "cp":[113.4668,22.8076], + "childNum":21 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [109.7754,21.4014],[109.7754,21.6211],[109.8633,21.665],[109.9512,21.8408],[110.3027,21.8848],[110.3027,22.1484], + [110.6543,22.1484],[110.7422,22.2803],[110.7422,22.5439],[111.2695,22.8076],[111.4453,23.0273],[111.3574,23.4668], + [111.6211,23.6865],[111.6211,23.8184],[111.7969,23.8184],[111.8848,23.9941],[111.8848,24.2139],[112.0605,24.3457], + [111.8848,24.6533],[112.0605,24.7412],[112.1484,24.873],[112.2363,25.1807],[112.5879,25.1367],[112.8516,24.917], + [113.0273,24.9609],[113.0273,25.2246],[112.8516,25.3564],[113.2031,25.5322],[113.6426,25.3125],[113.9063,25.4443], + [113.9941,25.2686],[114.6094,25.4004],[114.7852,25.2686],[114.6973,25.1367],[114.4336,24.9609],[114.1699,24.6973], + [114.4336,24.5215],[115.4004,24.7852],[115.8398,24.5654],[115.752,24.7852],[115.9277,24.917],[116.2793,24.7852], + [116.3672,24.873],[116.543,24.6094],[116.7188,24.6533],[116.9824,24.1699],[116.9824,23.9063],[117.1582,23.5547], + [117.334,23.2471],[116.8945,23.3789],[116.6309,23.1152],[116.543,22.8516],[115.9277,22.7197],[115.6641,22.7637], + [115.5762,22.6318],[115.0488,22.6758],[114.6094,22.3682],[114.3457,22.5439],[113.9941,22.5],[113.8184,22.1924], + [114.3457,22.1484],[114.4336,22.0166],[114.082,21.9287],[113.9941,21.7969],[113.5547,22.0166],[113.1152,21.8408], + [112.9395,21.5771],[112.4121,21.4453],[112.2363,21.5332],[111.5332,21.4893],[111.2695,21.3574],[110.7422,21.3574], + [110.6543,21.2256],[110.7422,20.918],[110.4785,20.874],[110.6543,20.2588],[110.5664,20.2588],[110.3906,20.127], + [110.0391,20.127],[109.8633,20.127],[109.8633,20.3027],[109.5996,20.918],[109.7754,21.4014],[109.7754,21.4014] + ], + [ + [113.5986,22.1649],[113.6096,22.1265],[113.5547,22.11],[113.5437,22.2034],[113.5767,22.2034],[113.5986,22.1649] + ] + ] + } + }, + { + "type":"Feature","id":"ji_lin", + "properties":{ + "name":"吉林", + "cp":[126.4746,43.5938], + "childNum":9 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [123.2227,46.2305],[123.9258,46.2305],[124.0137,45.7471],[124.3652,45.4395],[124.8926,45.5273],[125.0684,45.3955], + [125.6836,45.5273],[125.7715,45.3076],[126.0352,45.1758],[126.5625,45.2637],[126.9141,45.1318],[127.0898,45], + [127.002,44.7803],[127.0898,44.6045],[127.5293,44.6045],[127.7051,44.1211],[128.0566,44.1211],[128.0566,44.3408], + [128.4082,44.4727],[128.4961,44.165],[128.8477,43.5498],[129.1992,43.5938],[129.2871,43.8135],[129.8145,43.9014], + [129.9023,44.0332],[129.9902,43.8574],[130.3418,43.9893],[130.5176,43.6377],[130.8691,43.418],[131.3086,43.4619], + [131.3086,43.3301],[131.1328,42.9346],[130.4297,42.7148],[130.6055,42.6709],[130.6055,42.4512],[130.2539,42.7588], + [130.2539,42.8906],[130.166,42.9785],[129.9023,43.0225],[129.7266,42.4951],[129.375,42.4512],[128.9355,42.0117], + [128.0566,42.0117],[128.3203,41.5723],[128.1445,41.3525],[127.0898,41.5283],[127.1777,41.5723],[126.9141,41.792], + [126.6504,41.6602],[126.4746,41.3965],[126.123,40.957],[125.6836,40.8691],[125.5957,40.9131],[125.7715,41.2207], + [125.332,41.6602],[125.332,41.9678],[125.4199,42.0996],[125.332,42.1436],[124.8926,42.8027],[124.8926,43.0664], + [124.7168,43.0664],[124.4531,42.8467],[124.2773,43.2422],[123.8379,43.4619],[123.6621,43.374],[123.3105,43.5059], + [123.4863,43.7256],[123.1348,44.4727],[122.3438,44.2529],[122.0801,44.8682],[122.2559,45.2637],[121.9043,45.7031], + [121.7285,45.7471],[121.8164,46.0107],[122.2559,45.791],[122.4316,45.8789],[122.6953,45.7031],[122.7832,46.0107], + [123.2227,46.2305] + ] + ] + } + }, + { + "type":"Feature", + "id":"he_bei", + "properties":{ + "name":"河北", + "cp":[115.4004,37.9688], + "childNum":11 + }, + "geometry":{ + "type":"MultiPolygon", + "coordinates":[ + [ + [ + [114.5215,39.5068],[114.3457,39.8584],[113.9941,39.9902],[114.5215,40.3418],[114.3457,40.3857],[114.2578,40.6055], + [114.082,40.7373],[113.9063,41.1328],[113.9941,41.2207],[113.9063,41.4404],[114.2578,41.5723],[114.1699,41.792], + [114.5215,42.1436],[114.873,42.0996],[114.9609,41.6162],[115.2246,41.5723],[115.9277,41.9238],[116.0156,41.792], + [116.2793,42.0117],[116.8066,42.0117],[116.8945,42.4072],[117.334,42.4512],[117.5098,42.583],[117.7734,42.627], + [118.0371,42.4072],[117.9492,42.2314],[118.125,42.0557],[118.3008,42.0996],[118.3008,41.792],[118.125,41.748], + [118.3887,41.3086],[119.2676,41.3086],[118.8281,40.8252],[119.2676,40.5176],[119.5313,40.5615],[119.707,40.1221], + [119.8828,39.9463],[119.5313,39.6826],[119.4434,39.4189],[118.916,39.0674],[118.4766,38.9355],[118.125,39.0234], + [118.0371,39.1992],[118.0371,39.2432],[117.8613,39.4189],[117.9492,39.5947],[117.6855,39.5947],[117.5098,39.7705], + [117.5098,39.9902],[117.6855,39.9902],[117.6855,40.0781],[117.4219,40.21],[117.2461,40.5176],[117.4219,40.6494], + [116.9824,40.6934],[116.6309,41.0449],[116.3672,40.9131],[116.4551,40.7813],[116.1914,40.7813],[116.1035,40.6055], + [115.752,40.5615],[115.9277,40.2539],[115.4004,39.9463],[115.4883,39.6387],[115.752,39.5068],[116.1914,39.5947], + [116.3672,39.4629],[116.543,39.5947],[116.8066,39.5947],[116.8945,39.1113],[116.7188,38.9355],[116.7188,38.8037], + [117.2461,38.54],[117.5977,38.6279],[117.9492,38.3203],[117.4219,37.8369],[116.8066,37.8369],[116.4551,37.4854], + [116.2793,37.5732],[116.2793,37.3535],[116.0156,37.3535],[115.752,36.9141],[115.3125,36.5186],[115.4883,36.167], + [115.3125,36.0791],[115.1367,36.2109],[114.9609,36.0791],[114.873,36.123],[113.7305,36.3428],[113.4668,36.6504], + [113.7305,36.8701],[113.7305,37.1338],[114.1699,37.6611],[113.9941,37.7051],[113.8184,38.1445],[113.5547,38.2764], + [113.5547,38.54],[113.8184,38.8037],[113.8184,38.9355],[113.9063,39.0234],[114.3457,39.0674],[114.5215,39.5068] + ] + ], + [ + [ + [117.2461,40.0781],[117.1582,39.8145],[117.1582,39.6387],[116.8945,39.6826],[116.8945,39.8145],[116.8066,39.9902],[117.2461,40.0781] + ] + ] + ] + } + }, + { + "type":"Feature", + "id":"hu_bei", + "properties":{ + "name":"湖北", + "cp":[112.2363,31.1572], + "childNum":17 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [110.2148,31.1572],[110.127,31.377],[109.6875,31.5527],[109.7754,31.6846],[109.5996,31.7285],[109.5117,32.4316], + [109.6875,32.6074],[110.127,32.6074],[110.127,32.7393],[109.7754,32.915],[109.7754,33.0469],[109.4238,33.1348], + [109.5996,33.2666],[110.3027,33.1787],[110.5664,33.2666],[110.7422,33.1348],[111.0059,33.2666],[111.5332,32.6074], + [112.3242,32.3438],[113.2031,32.4316],[113.4668,32.2998],[113.7305,32.4316],[113.8184,31.8604],[113.9941,31.7725], + [114.1699,31.8604],[114.5215,31.7725],[114.6094,31.5527],[114.7852,31.4648],[115.1367,31.5967],[115.2246,31.4209], + [115.4004,31.4209],[115.5762,31.2012],[116.0156,31.0254],[115.752,30.6738],[116.1035,30.1904],[116.1035,29.8389], + [115.9277,29.707],[115.4883,29.7949],[114.873,29.3994],[114.2578,29.3555],[113.9063,29.0479],[113.7305,29.0918], + [113.6426,29.3115],[113.7305,29.5752],[113.5547,29.707],[113.5547,29.8389],[113.0273,29.4434],[112.9395,29.4873], + [113.0273,29.751],[112.9395,29.7949],[112.6758,29.5752],[112.5,29.6191],[112.2363,29.5313],[111.7969,29.9268], + [110.8301,30.1465],[110.4785,30.0146],[110.6543,29.751],[110.4785,29.6631],[109.7754,29.751],[109.6875,29.6191], + [109.5117,29.6191],[109.248,29.1357],[109.0723,29.3555],[108.9844,29.3115],[108.6328,29.8389],[108.457,29.7949], + [108.5449,30.2344],[108.457,30.4102],[108.6328,30.5859],[108.8086,30.498],[109.0723,30.6299],[109.1602,30.542], + [109.248,30.6299],[109.4238,30.542],[109.8633,30.8936],[110.0391,30.8057],[110.2148,31.1572] + ] + ] + } + }, + { + "type":"Feature", + "id":"gui_zhou", + "properties":{ + "name":"贵州", + "cp":[106.6113,26.9385], + "childNum":9 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [104.1504,27.2461], [104.4141,27.4658],[104.5898,27.334],[105.2051,27.3779],[105.293,27.7295],[105.5566,27.7734], + [105.6445,27.6416],[106.3477,27.8174],[106.1719,28.125],[105.9082,28.125],[105.6445,28.4326],[105.9961,28.7402], + [106.3477,28.5205],[106.5234,28.5645],[106.4355,28.7842],[106.5234,28.7842],[106.6113,28.6523],[106.6113,28.5205], + [106.6992,28.4766],[106.875,28.7842],[107.4023,28.8721],[107.4023,29.1797],[107.5781,29.2236],[107.8418,29.1357], + [107.8418,29.0039],[108.2813,29.0918],[108.3691,28.6523],[108.5449,28.6523],[108.5449,28.3887],[108.7207,28.4766], + [108.7207,28.2129],[109.0723,28.2129],[109.248,28.4766],[109.3359,28.2568],[109.3359,27.9053],[109.4238,27.5977], + [108.8086,27.1143],[108.8965,27.0264],[109.3359,27.1582],[109.5117,27.0264],[109.5117,26.8066],[109.3359,26.7188], + [109.4238,26.5869],[109.248,26.3232],[109.4238,26.2793],[109.5117,26.0156],[109.3359,25.708],[108.9844,25.752], + [109.0723,25.5322],[108.6328,25.5762],[108.6328,25.3125],[108.3691,25.5322],[108.1934,25.4443],[108.1055,25.2246], + [107.8418,25.1367],[107.7539,25.2246],[107.4902,25.2246],[107.2266,25.6201],[106.9629,25.4883],[107.0508,25.2686], + [106.875,25.1807],[106.1719,24.9609],[106.1719,24.7852],[105.9961,24.6533],[105.2051,24.9609],[104.6777,24.6094], + [104.502,24.7412],[104.6777,24.9609],[104.5898,25.0488],[104.8535,25.2246],[104.3262,25.708],[104.6777,26.4111], + [104.4141,26.6748],[103.8867,26.543],[103.7109,26.7627],[103.7109,26.9824],[103.623,27.0264],[103.8867,27.4219], + [104.1504,27.2461] + ] + ] + } + }, + { + "type":"Feature", + "id":"shan_dong", + "properties":{ + "name":"山东", + "cp":[118.7402,36.4307], + "childNum":17 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [115.4883,36.167],[115.3125,36.5186],[115.752,36.9141],[116.0156,37.3535],[116.2793,37.3535],[116.2793,37.5732], + [116.4551,37.4854],[116.8066,37.8369],[117.4219,37.8369],[117.9492,38.3203],[118.125,38.1445],[118.916,38.1445], + [119.3555,37.6611],[119.0039,37.5293],[119.0039,37.3535],[119.3555,37.1338],[119.707,37.1338],[119.8828,37.3975], + [120.498,37.8369],[120.5859,38.1445],[120.9375,38.4521],[121.0254,37.8369],[121.2012,37.6611],[121.9043,37.4854], + [122.168,37.6172],[122.2559,37.4854],[122.6074,37.4854],[122.6953,37.3535],[122.6074,36.9141],[122.4316,36.7822], + [121.8164,36.8701],[121.7285,36.6943],[121.1133,36.6064],[121.1133,36.4307],[121.377,36.2549],[120.7617,36.167], + [120.9375,35.8594],[120.6738,36.0352],[119.707,35.4639],[119.9707,34.9805],[119.3555,35.0244],[119.2676,35.1123], + [118.916,35.0244],[118.7402,34.7168],[118.4766,34.6729],[118.3887,34.4092],[118.2129,34.4092],[118.125,34.6289], + [117.9492,34.6729],[117.5977,34.4531],[117.334,34.585],[117.2461,34.4531],[116.8066,34.9365],[116.4551,34.8926], + [116.3672,34.6289],[116.1914,34.585],[115.5762,34.585],[115.4004,34.8486],[114.7852,35.0684],[115.0488,35.376], + [115.2246,35.4199],[115.4883,35.7275],[116.1035,36.0791],[115.3125,35.8154],[115.4883,36.167] + ] + ] + } + }, + { + "type":"Feature", + "id":"jiang_xi", + "properties":{"name":"江西", + "cp":[116.0156,27.29], + "childNum":11}, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [114.2578,28.3447],[114.082,28.5645],[114.1699,28.8281],[113.9063,29.0479],[114.2578,29.3555],[114.873,29.3994], + [115.4883,29.7949],[115.9277,29.707],[116.1035,29.8389],[116.2793,29.7949],[116.7188,30.0586],[116.8945,29.9268], + [116.7188,29.751],[116.7188,29.6191],[117.1582,29.707],[117.0703,29.8389],[117.1582,29.9268],[117.5098,29.6191], + [118.0371,29.5752],[118.2129,29.3994],[118.0371,29.1797],[118.0371,29.0479],[118.3887,28.7842],[118.4766,28.3447], + [118.4766,28.3008],[118.3008,28.0811],[117.7734,27.8174],[117.5098,27.9932],[116.9824,27.6416],[117.1582,27.29], + [117.0703,27.1143],[116.543,26.8066],[116.6309,26.4551],[116.3672,26.2354],[116.4551,26.1035],[116.1914,25.8838], + [116.0156,25.2686],[115.8398,25.2246],[115.9277,24.917],[115.752,24.7852],[115.8398,24.5654],[115.4004,24.7852], + [114.4336,24.5215],[114.1699,24.6973],[114.4336,24.9609],[114.6973,25.1367],[114.7852,25.2686],[114.6094,25.4004], + [113.9941,25.2686],[113.9063,25.4443],[113.9941,26.0596],[114.2578,26.1475],[113.9941,26.1914],[114.082,26.5869], + [113.9063,26.6309],[113.9063,26.9385],[113.7305,27.1143],[113.8184,27.29],[113.6426,27.3779],[113.6426,27.5977], + [113.7305,27.9492],[114.2578,28.3447] + ] + ] + } + }, + { + "type":"Feature", + "id":"he_nan", + "properties":{"name":"河南", + "cp":[113.4668,33.8818], + "childNum":17 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [110.3906,34.585],[110.8301,34.6289],[111.1816,34.8047],[111.5332,34.8486],[111.7969,35.0684],[112.0605,35.0684], + [112.0605,35.2881],[112.7637,35.2002],[113.1152,35.332],[113.6426,35.6836],[113.7305,36.3428],[114.873,36.123], + [114.9609,36.0791],[115.1367,36.2109],[115.3125,36.0791],[115.4883,36.167],[115.3125,35.8154],[116.1035,36.0791], + [115.4883,35.7275],[115.2246,35.4199],[115.0488,35.376],[114.7852,35.0684],[115.4004,34.8486],[115.5762,34.585], + [116.1914,34.585],[116.1914,34.4092],[116.543,34.2773],[116.6309,33.9258],[116.1914,33.7061],[116.0156,33.9697], + [115.6641,34.0576],[115.5762,33.9258],[115.5762,33.6621],[115.4004,33.5303],[115.3125,33.1787],[114.873,33.1348], + [114.873,33.0029],[115.1367,32.8711],[115.2246,32.6074],[115.5762,32.4316],[115.8398,32.5195],[115.9277,31.7725], + [115.4883,31.6846],[115.4004,31.4209],[115.2246,31.4209],[115.1367,31.5967],[114.7852,31.4648],[114.6094,31.5527], + [114.5215,31.7725],[114.1699,31.8604],[113.9941,31.7725],[113.8184,31.8604],[113.7305,32.4316],[113.4668,32.2998], + [113.2031,32.4316],[112.3242,32.3438],[111.5332,32.6074],[111.0059,33.2666],[111.0059,33.5303],[110.6543,33.8379], + [110.6543,34.1455],[110.4785,34.2334],[110.3906,34.585] + ] + ] + } + }, + { + "type":"Feature", + "id":"liao_ning", + "properties":{ + "name":"辽宁", + "cp":[122.3438,41.0889], + "childNum":14 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [119.2676,41.3086],[119.4434,41.6162],[119.2676,41.7041],[119.3555,42.2754],[119.5313,42.3633],[119.8828,42.1875], + [120.1465,41.7041],[120.498,42.0996],[121.4648,42.4951],[121.7285,42.4512],[121.9922,42.7148],[122.3438,42.6709], + [122.3438,42.8467],[122.7832,42.7148],[123.1348,42.8027],[123.3105,42.9785],[123.5742,43.0225],[123.6621,43.374], + [123.8379,43.4619],[124.2773,43.2422],[124.4531,42.8467],[124.7168,43.0664],[124.8926,43.0664],[124.8926,42.8027], + [125.332,42.1436],[125.4199,42.0996],[125.332,41.9678],[125.332,41.6602],[125.7715,41.2207],[125.5957,40.9131], + [125.6836,40.8691],[124.541,40.21],[124.1016,39.6826],[123.3984,39.6826],[123.1348,39.4189],[123.1348,39.0234], + [122.0801,39.0234],[121.5527,38.7158],[121.1133,38.6719],[120.9375,38.9795],[121.377,39.1992],[121.2012,39.5508], + [122.0801,40.3857],[121.9922,40.6934],[121.7285,40.8252],[121.2012,40.8252],[120.5859,40.21],[119.8828,39.9463], + [119.707,40.1221],[119.5313,40.5615],[119.2676,40.5176],[118.8281,40.8252],[119.2676,41.3086] + ] + ] + } + }, + { + "type":"Feature", + "id":"shan_xi_2", + "properties":{"name":"山西", + "cp":[112.4121,37.6611], + "childNum":11 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [110.918,38.7158],[111.1816,39.2432],[111.0938,39.375],[111.3574,39.4189],[111.4453,39.6387],[111.9727,39.5947], + [112.3242,40.2539],[112.7637,40.166],[113.2031,40.3857],[113.5547,40.3418],[113.8184,40.5176],[114.082,40.5176], + [114.082,40.7373],[114.2578,40.6055],[114.3457,40.3857],[114.5215,40.3418],[113.9941,39.9902],[114.3457,39.8584], + [114.5215,39.5068],[114.3457,39.0674],[113.9063,39.0234],[113.8184,38.9355],[113.8184,38.8037],[113.5547,38.54], + [113.5547,38.2764],[113.8184,38.1445],[113.9941,37.7051],[114.1699,37.6611],[113.7305,37.1338],[113.7305,36.8701], + [113.4668,36.6504],[113.7305,36.3428],[113.6426,35.6836],[113.1152,35.332],[112.7637,35.2002],[112.0605,35.2881], + [112.0605,35.0684],[111.7969,35.0684],[111.5332,34.8486],[111.1816,34.8047],[110.8301,34.6289],[110.3906,34.585], + [110.2148,34.6729],[110.2148,34.8926],[110.5664,35.6396],[110.4785,36.123],[110.3906,37.002],[110.8301,37.6611], + [110.4785,37.9688],[110.4785,38.1885],[110.8301,38.4961],[110.918,38.7158] + ] + ] + } + }, + { + "type":"Feature", + "id":"an_hui", + "properties":{"name":"安徽", + "cp":[117.2461,32.0361], + "childNum":17 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [116.6309,33.9258],[116.543,34.2773],[116.1914,34.4092],[116.1914,34.585],[116.3672,34.6289],[116.8945,34.4092], + [117.1582,34.0576],[117.5977,34.0137],[117.7734,33.7061],[118.125,33.75],[117.9492,33.2227],[118.0371,33.1348], + [118.2129,33.2227],[118.3008,32.7832],[118.7402,32.7393],[118.916,32.959],[119.1797,32.8271],[119.1797,32.4756], + [118.5645,32.5635],[118.6523,32.2119],[118.4766,32.168],[118.3887,31.9482],[118.916,31.5527],[118.7402,31.377], + [118.8281,31.2451],[119.3555,31.2891],[119.4434,31.1572],[119.6191,31.1133],[119.6191,31.0693],[119.4434,30.6738], + [119.2676,30.6299],[119.3555,30.4102],[118.916,30.3223],[118.916,29.9707],[118.7402,29.707],[118.2129,29.3994], + [118.0371,29.5752],[117.5098,29.6191],[117.1582,29.9268],[117.0703,29.8389],[117.1582,29.707],[116.7188,29.6191], + [116.7188,29.751],[116.8945,29.9268],[116.7188,30.0586],[116.2793,29.7949],[116.1035,29.8389],[116.1035,30.1904], + [115.752,30.6738],[116.0156,31.0254],[115.5762,31.2012],[115.4004,31.4209],[115.4883,31.6846],[115.9277,31.7725], + [115.8398,32.5195],[115.5762,32.4316],[115.2246,32.6074],[115.1367,32.8711],[114.873,33.0029],[114.873,33.1348], + [115.3125,33.1787],[115.4004,33.5303],[115.5762,33.6621],[115.5762,33.9258],[115.6641,34.0576],[116.0156,33.9697], + [116.1914,33.7061],[116.6309,33.9258] + ] + ] + } + }, + { + "type":"Feature", + "id":"fu_jian", + "properties":{ + "name":"福建", + "cp":[118.3008,25.9277], + "childNum":9 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [118.4766,28.3008],[118.8281,28.2568],[118.7402,28.0371],[118.916,27.4658],[119.2676,27.4219],[119.6191,27.6855], + [119.7949,27.29],[120.2344,27.4219],[120.4102,27.1582],[120.7617,27.0264],[120.6738,26.8945],[120.2344,26.8506], + [120.2344,26.7188],[120.4102,26.6748],[120.498,26.3672],[120.2344,26.2793],[120.4102,26.1475],[120.0586,26.1914], + [119.9707,25.9277],[119.7949,25.9277],[119.9707,25.4004],[119.7949,25.2686],[119.5313,25.1367],[119.4434,25.0049], + [119.2676,25.0928],[118.916,24.8291],[118.6523,24.5215],[118.4766,24.5215],[118.4766,24.4336],[118.2129,24.3457], + [118.2129,24.1699],[117.8613,23.9941],[117.7734,23.7744],[117.5098,23.5986],[117.1582,23.5547],[116.9824,23.9063], + [116.9824,24.1699],[116.7188,24.6533],[116.543,24.6094],[116.3672,24.873],[116.2793,24.7852],[115.9277,24.917], + [115.8398,25.2246],[116.0156,25.2686],[116.1914,25.8838],[116.4551,26.1035],[116.3672,26.2354],[116.6309,26.4551], + [116.543,26.8066],[117.0703,27.1143],[117.1582,27.29],[116.9824,27.6416],[117.5098,27.9932],[117.7734,27.8174], + [118.3008,28.0811],[118.4766,28.3008] + ] + ] + } + }, + { + "type":"Feature", + "id":"zhe_jiang", + "properties":{ + "name":"浙江", + "cp":[120.498,29.0918], + "childNum":11 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [118.2129,29.3994],[118.7402,29.707],[118.916,29.9707],[118.916,30.3223],[119.3555,30.4102],[119.2676,30.6299], + [119.4434,30.6738],[119.6191,31.0693],[119.6191,31.1133],[119.9707,31.1572],[120.498,30.8057],[120.9375,31.0254], + [121.2891,30.6738],[121.9922,30.8057],[122.6953,30.8936],[122.8711,30.7178],[122.959,30.1465],[122.6074,30.1025], + [122.6074,29.9268],[122.168,29.5313],[122.3438,28.8721],[121.9922,28.8721],[121.9922,28.4326],[121.7285,28.3447], + [121.7285,28.2129],[121.4648,28.2129],[121.5527,28.0371],[121.2891,27.9492],[121.1133,27.4219],[120.6738,27.334], + [120.6738,27.1582],[120.9375,27.0264],[120.7617,27.0264],[120.4102,27.1582],[120.2344,27.4219],[119.7949,27.29], + [119.6191,27.6855],[119.2676,27.4219],[118.916,27.4658],[118.7402,28.0371],[118.8281,28.2568],[118.4766,28.3008], + [118.4766,28.3447],[118.3887,28.7842],[118.0371,29.0479],[118.0371,29.1797],[118.2129,29.3994] + ] + ] + } + }, + { + "type":"Feature", + "id":"jiang_su", + "properties":{ + "name":"江苏", + "cp":[120.0586,32.915], + "childNum":13 + },"geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [116.3672,34.6289],[116.4551,34.8926],[116.8066,34.9365],[117.2461,34.4531],[117.334,34.585],[117.5977,34.4531], + [117.9492,34.6729],[118.125,34.6289],[118.2129,34.4092],[118.3887,34.4092],[118.4766,34.6729],[118.7402,34.7168], + [118.916,35.0244],[119.2676,35.1123],[119.3555,35.0244],[119.3555,34.8486],[119.707,34.585],[120.3223,34.3652], + [120.9375,33.0469],[121.0254,32.6514],[121.377,32.4756],[121.4648,32.168],[121.9043,31.9922],[121.9922,31.6846], + [121.9922,31.5967],[121.2012,31.8604],[121.1133,31.7285],[121.377,31.5088],[121.2012,31.4648],[120.9375,31.0254], + [120.498,30.8057],[119.9707,31.1572],[119.6191,31.1133],[119.4434,31.1572],[119.3555,31.2891],[118.8281,31.2451], + [118.7402,31.377],[118.916,31.5527],[118.3887,31.9482],[118.4766,32.168],[118.6523,32.2119],[118.5645,32.5635], + [119.1797,32.4756],[119.1797,32.8271],[118.916,32.959],[118.7402,32.7393],[118.3008,32.7832],[118.2129,33.2227], + [118.0371,33.1348],[117.9492,33.2227],[118.125,33.75],[117.7734,33.7061],[117.5977,34.0137],[117.1582,34.0576], + [116.8945,34.4092],[116.3672,34.6289] + ] + ] + } + }, + { + "type":"Feature", + "id":"chong_qing", + "properties":{ + "name":"重庆", + "cp":[107.7539,30.1904], + "childNum":40 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [108.5449,31.6846],[108.2813,31.9043],[108.3691,32.168],[108.5449,32.2119],[109.0723,31.9482],[109.248,31.7285], + [109.5996,31.7285],[109.7754,31.6846],[109.6875,31.5527],[110.127,31.377],[110.2148,31.1572],[110.0391,30.8057], + [109.8633,30.8936],[109.4238,30.542],[109.248,30.6299],[109.1602,30.542],[109.0723,30.6299],[108.8086,30.498], + [108.6328,30.5859],[108.457,30.4102],[108.5449,30.2344],[108.457,29.7949],[108.6328,29.8389],[108.9844,29.3115], + [109.0723,29.3555],[109.248,29.1357],[109.248,28.4766],[109.0723,28.2129],[108.7207,28.2129],[108.7207,28.4766], + [108.5449,28.3887],[108.5449,28.6523],[108.3691,28.6523],[108.2813,29.0918],[107.8418,29.0039],[107.8418,29.1357], + [107.5781,29.2236],[107.4023,29.1797],[107.4023,28.8721],[106.875,28.7842],[106.6992,28.4766],[106.6113,28.5205], + [106.6113,28.6523],[106.5234,28.7842],[106.4355,28.7842],[106.5234,28.5645],[106.3477,28.5205],[106.2598,28.8721], + [105.8203,28.96],[105.7324,29.2676],[105.4688,29.3115],[105.293,29.5313],[105.7324,29.8828],[105.5566,30.1025], + [105.6445,30.2783],[105.8203,30.4541],[106.2598,30.1904],[106.6113,30.3223],[106.7871,30.0146],[107.0508,30.0146], + [107.4902,30.6299],[107.4023,30.7617],[107.4902,30.8496],[107.9297,30.8496],[108.1934,31.5088],[108.5449,31.6846] + ] + ] + } + }, + { + "type":"Feature", + "id":"ning_xia", + "properties":{ + "name":"宁夏", + "cp":[105.9961,37.3096], + "childNum":5 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [104.3262,37.4414],[105.8203,37.793],[105.9082,38.7158],[106.3477,39.2871],[106.7871,39.375],[106.9629,38.9795], + [106.5234,38.3203],[106.7871,38.1885],[107.3145,38.1006],[107.666,37.8809],[107.3145,37.6172],[107.3145,37.0898], + [106.6113,37.0898],[106.6113,36.7822],[106.4355,36.5625],[106.5234,36.4746],[106.5234,36.2549],[106.875,36.123], + [106.9629,35.8154],[106.6992,35.6836],[106.4355,35.6836],[106.5234,35.332],[106.3477,35.2441],[106.2598,35.4199], + [106.084,35.376],[105.9961,35.4199],[106.084,35.4639],[105.9961,35.4639],[105.8203,35.5518],[105.7324,35.7275], + [105.3809,35.7715],[105.293,35.9912],[105.4688,36.123],[105.2051,36.6943],[105.293,36.8262],[104.8535,37.2217], + [104.5898,37.2217],[104.5898,37.4414],[104.3262,37.4414] + ] + ] + } + }, + { + "type":"Feature", + "id":"hai_nan", + "properties":{ + "name":"海南", + "cp":[109.9512,19.2041], + "childNum":18 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [108.6328,19.3799],[109.0723,19.6436],[109.248,19.9512],[109.5996,20.0391],[110.0391,20.127],[110.3906,20.127], + [110.5664,20.2588],[110.6543,20.2588],[111.0938,19.9512],[111.2695,19.9951],[110.6543,19.1602],[110.5664,18.6768], + [110.2148,18.5889],[110.0391,18.3691],[109.8633,18.3691],[109.6875,18.1055],[108.9844,18.2813],[108.6328,18.457], + [108.6328,19.3799] + ] + ] + } + }, + { + "type":"Feature", + "id":"tai_wan", + "properties":{ + "name":"台湾", + "cp":[121.0254,23.5986], + "childNum":1 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [121.9043,25.0488],[121.9922,25.0049],[121.8164,24.7412],[121.9043,24.5654],[121.6406,24.0381],[121.377,23.1152], + [121.0254,22.6758],[120.8496,22.0605],[120.7617,21.9287],[120.6738,22.3242],[120.2344,22.5879],[120.0586,23.0713], + [120.1465,23.6865],[121.0254,25.0488],[121.5527,25.3125],[121.9043,25.0488] + ] + ] + } + }, + { + "type":"Feature", + "id":"bei_jing", + "properties":{ + "name":"北京", + "cp":[116.4551,40.2539], + "childNum":19 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [117.4219,40.21],[117.334,40.1221],[117.2461,40.0781],[116.8066,39.9902],[116.8945,39.8145],[116.8945,39.6826], + [116.8066,39.5947],[116.543,39.5947],[116.3672,39.4629],[116.1914,39.5947],[115.752,39.5068],[115.4883,39.6387], + [115.4004,39.9463],[115.9277,40.2539],[115.752,40.5615],[116.1035,40.6055],[116.1914,40.7813],[116.4551,40.7813], + [116.3672,40.9131],[116.6309,41.0449],[116.9824,40.6934],[117.4219,40.6494],[117.2461,40.5176],[117.4219,40.21] + ] + ] + } + }, + { + "type":"Feature", + "id":"tian_jin", + "properties":{ + "name":"天津", + "cp":[117.4219,39.4189], + "childNum":18 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [116.8066,39.5947],[116.8945,39.6826],[117.1582,39.6387],[117.1582,39.8145],[117.2461,40.0781],[117.334,40.1221], + [117.4219,40.21],[117.6855,40.0781],[117.6855,39.9902],[117.5098,39.9902],[117.5098,39.7705],[117.6855,39.5947], + [117.9492,39.5947],[117.8613,39.4189],[118.0371,39.2432],[118.0371,39.1992],[117.8613,39.1113],[117.5977,38.6279], + [117.2461,38.54],[116.7188,38.8037],[116.7188,38.9355],[116.8945,39.1113],[116.8066,39.5947] + ] + ] + } + }, + { + "type":"Feature", + "id":"shang_hai", + "properties":{ + "name":"上海", + "cp":[121.4648,31.2891], + "childNum":19 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [[120.9375,31.0254],[121.2012,31.4648],[121.377,31.5088],[121.1133,31.7285],[121.2012,31.8604],[121.9922,31.5967], + [121.9043,31.1572],[121.9922,30.8057],[121.2891,30.6738],[120.9375,31.0254] + ] + ] + } + }, + { + "type":"Feature", + "id":"xiang_gang", + "properties":{ + "name":"香港", + "cp":[114.2578,22.3242], + "childNum":1 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [114.6094,22.4121],[114.5215,22.1484],[114.3457,22.1484],[113.9063,22.1484],[113.8184,22.1924],[113.9063,22.4121], + [114.1699,22.5439],[114.3457,22.5439],[114.4336,22.5439],[114.4336,22.4121],[114.6094,22.4121] + ] + ] + } + }, + { + "type":"Feature", + "id":"ao_men", + "properties":{ + "name":"澳门", + "cp":[113.5547,22.1484], + "childNum":1 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [113.5986,22.1649],[113.6096,22.1265],[113.5547,22.11],[113.5437,22.2034],[113.5767,22.2034],[113.5986,22.1649] + ] + ] + } + } + ] + } \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/public/sjData/word.json b/UI source code/dns_mapping_ui-master/public/sjData/word.json new file mode 100644 index 0000000..57e343d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/public/sjData/word.json @@ -0,0 +1,194 @@ +{ + "status": true, + "namemap": { + "Afghanistan": "阿富汗", + "Angola": "安哥拉", + "Albania": "阿尔巴尼亚", + "Algeria": "阿尔及利亚", + "Argentina": "阿根廷", + "Armenia": "亚美尼亚", + "Australia": "澳大利亚", + "Austria": "奥地利", + "Azerbaijan": "阿塞拜疆", + "Bahamas": "巴哈马", + "Bangladesh": "孟加拉国", + "Belgium": "比利时", + "Benin": "贝宁", + "Burkina Faso": "布基纳法索", + "Burundi": "布隆迪", + "Bulgaria": "保加利亚", + "Bosnia and Herz.": "波斯尼亚和黑塞哥维那", + "Belarus": "白俄罗斯", + "Belize": "伯利兹", + "Bermuda": "百慕大群岛", + "Bolivia": "玻利维亚", + "Brazil": "巴西", + "Brunei": "文莱", + "Bhutan": "不丹", + "Botswana": "博茨瓦纳", + "Cambodia": "柬埔寨", + "Cameroon": "喀麦隆", + "Canada": "加拿大", + "Central African Rep.": "中非共和国", + "Chad": "乍得", + "Chile": "智利", + "China": "中国", + "Colombia": "哥伦比亚", + "Congo": "刚果", + "Costa Rica": "哥斯达黎加", + "Côte d'Ivoire": "科特迪瓦", + "Croatia": "克罗地亚", + "Cuba": "古巴", + "Cyprus": "塞浦路斯", + "Czech Rep.": "捷克共和国", + "Dem. Rep. Korea": "韩国", + "Dem. Rep. Congo": "民主刚果", + "Denmark": "丹麦", + "Djibouti": "吉布提", + "Dominican Rep.": "多米尼加共和国", + "Ecuador": "厄瓜多尔", + "Egypt": "埃及", + "El Salvador": "萨尔瓦多", + "Eq. Guinea": "赤道几内亚", + "Eritrea": "厄立特里亚", + "Estonia": "爱沙尼亚", + "Ethiopia": "埃塞俄比亚", + "Falkland Is.": "福克兰群岛", + "Fiji": "斐济", + "Finland": "芬兰", + "France": "法国", + "French Guiana": "法属圭亚那", + "Fr. S. Antarctic Lands": "法属南部领地", + "Gabon": "加蓬", + "Gambia": "冈比亚", + "Germany": "德国", + "Georgia": "佐治亚州", + "Ghana": "加纳", + "Greece": "希腊", + "Greenland": "格陵兰", + "Guatemala": "危地马拉", + "Guinea": "几内亚", + "Guinea-Bissau": "几内亚比绍", + "Guyana": "圭亚那", + "Haiti": "海地", + "Heard I. and McDonald Is.": "赫德岛和麦克唐纳群岛", + "Honduras": "洪都拉斯", + "Hungary": "匈牙利", + "Iceland": "冰岛", + "India": "印度", + "Indonesia": "印度尼西亚", + "Iran": "伊朗", + "Iraq": "伊拉克", + "Ireland": "爱尔兰", + "Israel": "以色列", + "Italy": "意大利", + "Ivory Coast": "象牙海岸", + "Jamaica": "牙买加", + "Japan": "日本", + "Jordan": "乔丹", + "Kashmir": "克什米尔", + "Kazakhstan": "哈萨克斯坦", + "Kenya": "肯尼亚", + "Kosovo": "科索沃", + "Kuwait": "科威特", + "Kyrgyzstan": "吉尔吉斯斯坦", + "Laos": "老挝", + "Lao PDR": "老挝人民民主共和国", + "Latvia": "拉脱维亚", + "Lebanon": "黎巴嫩", + "Lesotho": "莱索托", + "Liberia": "利比里亚", + "Libya": "利比亚", + "Lithuania": "立陶宛", + "Luxembourg": "卢森堡", + "Madagascar": "马达加斯加", + "Macedonia": "马其顿", + "Malawi": "马拉维", + "Malaysia": "马来西亚", + "Mali": "马里", + "Mauritania": "毛里塔尼亚", + "Mexico": "墨西哥", + "Moldova": "摩尔多瓦", + "Mongolia": "蒙古", + "Montenegro": "黑山", + "Morocco": "摩洛哥", + "Mozambique": "莫桑比克", + "Myanmar": "缅甸", + "Namibia": "纳米比亚", + "Netherlands": "荷兰", + "New Caledonia": "新喀里多尼亚", + "New Zealand": "新西兰", + "Nepal": "尼泊尔", + "Nicaragua": "尼加拉瓜", + "Niger": "尼日尔", + "Nigeria": "尼日利亚", + "Korea": "朝鲜", + "Northern Cyprus": "北塞浦路斯", + "Norway": "挪威", + "Oman": "阿曼", + "Pakistan": "巴基斯坦", + "Panama": "巴拿马", + "Papua New Guinea": "巴布亚新几内亚", + "Paraguay": "巴拉圭", + "Peru": "秘鲁", + "Republic of the Congo": "刚果共和国", + "Philippines": "菲律宾", + "Poland": "波兰", + "Portugal": "葡萄牙", + "Puerto Rico": "波多黎各", + "Qatar": "卡塔尔", + "Republic of Seychelles": "塞舌尔共和国", + "Romania": "罗马尼亚", + "Russia": "俄罗斯", + "Rwanda": "卢旺达", + "Samoa": "萨摩亚", + "Saudi Arabia": "沙特阿拉伯", + "Senegal": "塞内加尔", + "Serbia": "塞尔维亚", + "Sierra Leone": "塞拉利昂", + "Slovakia": "斯洛伐克", + "Slovenia": "斯洛文尼亚", + "Solomon Is.": "所罗门群岛", + "Somaliland": "索马里兰", + "Somalia": "索马里", + "South Africa": "南非", + "S. Geo. and S. Sandw. Is.": "南乔治亚和南桑德威奇群岛", + "S. Sudan": "南苏丹", + "Spain": "西班牙", + "Sri Lanka": "斯里兰卡", + "Sudan": "苏丹", + "Suriname": "苏里南", + "Swaziland": "斯威士兰", + "Sweden": "瑞典", + "Switzerland": "瑞士", + "Syria": "叙利亚", + "Tajikistan": "塔吉克斯坦", + "Tanzania": "坦桑尼亚", + "Thailand": "泰国", + "The Kingdom of Tonga": "汤加王国", + "Timor-Leste": "东帝汶", + "Togo": "多哥", + "Trinidad and Tobago": "特立尼达和多巴哥", + "Tunisia": "突尼斯", + "Turkey": "土耳其", + "Turkmenistan": "土库曼斯坦", + "Uganda": "乌干达", + "Ukraine": "乌克兰", + "United Arab Emirates": "阿拉伯联合酋长国", + "United Kingdom": "大不列颠联合王国", + "United Republic of Tanzania": "坦桑尼亚联合共和国", + "United States": "美国", + "United States of America": "美利坚合众国", + "Uruguay": "乌拉圭", + "Uzbekistan": "乌兹别克斯坦", + "Vanuatu": "瓦努阿图", + "Venezuela": "委内瑞拉", + "Vietnam": "越南", + "West Bank": "西岸", + "W. Sahara": "西撒哈拉", + "Yemen": "也门", + "Zambia": "赞比亚", + "Zimbabwe": "津巴布韦" + }, + "dataArr": [] + } \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/App.vue b/UI source code/dns_mapping_ui-master/src/App.vue new file mode 100644 index 0000000..ec9032c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/api/data.js b/UI source code/dns_mapping_ui-master/src/api/data.js new file mode 100644 index 0000000..d975d75 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/data.js @@ -0,0 +1,17 @@ +import request from '@/utils/request' +import qs from 'qs' + +export function initData(url, params) { + return request({ + url: url + '?' + qs.stringify(params, { indices: false }), + method: 'get' + }) +} + +export function download(url, params) { + return request({ + url: url + '?' + qs.stringify(params, { indices: false }), + method: 'get', + responseType: 'blob' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/generator/genConfig.js b/UI source code/dns_mapping_ui-master/src/api/generator/genConfig.js new file mode 100644 index 0000000..e15b200 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/generator/genConfig.js @@ -0,0 +1,16 @@ +import request from '@/utils/request' + +export function get(tableName) { + return request({ + url: 'api/genConfig/' + tableName, + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/genConfig', + data, + method: 'put' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/generator/generator.js b/UI source code/dns_mapping_ui-master/src/api/generator/generator.js new file mode 100644 index 0000000..0c49718 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/generator/generator.js @@ -0,0 +1,33 @@ +import request from '@/utils/request' + +export function getAllTable() { + return request({ + url: 'api/generator/tables/all', + method: 'get' + }) +} + +export function generator(tableName, type) { + return request({ + url: 'api/generator/' + tableName + '/' + type, + method: 'post', + responseType: type === 2 ? 'blob' : '' + }) +} + +export function save(data) { + return request({ + url: 'api/generator', + data, + method: 'put' + }) +} + +export function sync(tables) { + return request({ + url: 'api/generator/sync', + method: 'post', + data: tables + }) +} + diff --git a/UI source code/dns_mapping_ui-master/src/api/login.js b/UI source code/dns_mapping_ui-master/src/api/login.js new file mode 100644 index 0000000..bdafcbc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/login.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + +export function login(username, password, code, uuid) { + return request({ + url: 'auth/login', + method: 'post', + data: { + username, + password, + code, + uuid + } + }) +} + +export function getInfo() { + return request({ + url: 'auth/info', + method: 'get' + }) +} + +export function getCodeImg() { + return request({ + url: 'auth/code', + method: 'get' + }) +} + +export function logout() { + return request({ + url: 'auth/logout', + method: 'delete' + }) +} + diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/app.js b/UI source code/dns_mapping_ui-master/src/api/mnt/app.js new file mode 100644 index 0000000..2a27054 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/app.js @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/app', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/app', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/app', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/connect.js b/UI source code/dns_mapping_ui-master/src/api/mnt/connect.js new file mode 100644 index 0000000..1bbe90b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/connect.js @@ -0,0 +1,17 @@ +import request from '@/utils/request' + +export function testDbConnect(data) { + return request({ + url: 'api/database/testConnect', + method: 'post', + data + }) +} + +export function testServerConnect(data) { + return request({ + url: 'api/serverDeploy/testConnect', + method: 'post', + data + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/database.js b/UI source code/dns_mapping_ui-master/src/api/mnt/database.js new file mode 100644 index 0000000..91797fb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/database.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/database', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/database', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/database', + method: 'put', + data + }) +} + +export function testDbConnection(data) { + return request({ + url: 'api/database/testConnect', + method: 'post', + data + }) +} + +export default { add, edit, del, testDbConnection } diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/deploy.js b/UI source code/dns_mapping_ui-master/src/api/mnt/deploy.js new file mode 100644 index 0000000..c1475ea --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/deploy.js @@ -0,0 +1,77 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/deploy', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/deploy', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/deploy', + method: 'put', + data + }) +} + +export function getApps() { + return request({ + url: 'api/app', + method: 'get' + }) +} + +export function getServers() { + return request({ + url: 'api/serverDeploy', + method: 'get' + }) +} + +/** + * 启动服务 + * @param data 选中行 + */ +export function startServer(data) { + return request({ + url: 'api/deploy/startServer', + method: 'post', + data + }) +} + +/** + * 停止服务 + * @param data 选中行 + */ +export function stopServer(data) { + return request({ + url: 'api/deploy/stopServer', + method: 'post', + data + }) +} + +/** + * 停止服务 + * @param data 选中行 + */ +export function serverStatus(data) { + return request({ + url: 'api/deploy/serverStatus', + method: 'post', + data + }) +} + +export default { add, edit, del, stopServer, serverStatus, startServer, getServers, getApps } diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/deployHistory.js b/UI source code/dns_mapping_ui-master/src/api/mnt/deployHistory.js new file mode 100644 index 0000000..30335e4 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/deployHistory.js @@ -0,0 +1,21 @@ +import request from '@/utils/request' + +export function del(ids) { + return request({ + url: 'api/deployHistory', + method: 'delete', + data: ids + }) +} + +/** + * 版本回退 + * @param data 选中行 + */ +export function reducte(data) { + return request({ + url: 'api/deploy/serverReduction', + method: 'post', + data + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/mnt/serverDeploy.js b/UI source code/dns_mapping_ui-master/src/api/mnt/serverDeploy.js new file mode 100644 index 0000000..e796114 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/mnt/serverDeploy.js @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/serverDeploy', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/serverDeploy', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/serverDeploy', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/monitor/log.js b/UI source code/dns_mapping_ui-master/src/api/monitor/log.js new file mode 100644 index 0000000..13f0d39 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/monitor/log.js @@ -0,0 +1,22 @@ +import request from '@/utils/request' + +export function getErrDetail(id) { + return request({ + url: 'api/logs/error/' + id, + method: 'get' + }) +} + +export function delAllError() { + return request({ + url: 'api/logs/del/error', + method: 'delete' + }) +} + +export function delAllInfo() { + return request({ + url: 'api/logs/del/info', + method: 'delete' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/monitor/online.js b/UI source code/dns_mapping_ui-master/src/api/monitor/online.js new file mode 100644 index 0000000..057275b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/monitor/online.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function del(keys) { + return request({ + url: 'auth/online', + method: 'delete', + data: keys + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/search.js b/UI source code/dns_mapping_ui-master/src/api/search.js new file mode 100644 index 0000000..aafc4ac --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/search.js @@ -0,0 +1,25 @@ +import request from '@/utils/request' + +export function getsearchList(params) { + return request({ + url: '/dns', + method: 'get', + params + }) +} + +export function getleftList(params) { + return request({ + url: '/dns/dataCount', + method: 'get', + params + }) +} + +export function getmapList(params) { + return request({ + url: '/dns/mapData', + method: 'get', + params + }) +} \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/api/system/code.js b/UI source code/dns_mapping_ui-master/src/api/system/code.js new file mode 100644 index 0000000..0d2e4c2 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/code.js @@ -0,0 +1,15 @@ +import request from '@/utils/request' + +export function resetEmail(data) { + return request({ + url: 'api/code/resetEmail?email=' + data, + method: 'post' + }) +} + +export function updatePass(pass) { + return request({ + url: 'api/users/updatePass/' + pass, + method: 'get' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/system/dept.js b/UI source code/dns_mapping_ui-master/src/api/system/dept.js new file mode 100644 index 0000000..ed4f944 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/dept.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +export function getDepts(params) { + return request({ + url: 'api/dept', + method: 'get', + params + }) +} + +export function getDeptSuperior(ids) { + const data = ids.length || ids.length === 0 ? ids : Array.of(ids) + return request({ + url: 'api/dept/superior', + method: 'post', + data + }) +} + +export function add(data) { + return request({ + url: 'api/dept', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/dept', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/dept', + method: 'put', + data + }) +} + +export default { add, edit, del, getDepts, getDeptSuperior } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/dict.js b/UI source code/dns_mapping_ui-master/src/api/system/dict.js new file mode 100644 index 0000000..99170f7 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/dict.js @@ -0,0 +1,34 @@ +import request from '@/utils/request' + +export function getDicts() { + return request({ + url: 'api/dict/all', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/dict', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/dict/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/dict', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/dictDetail.js b/UI source code/dns_mapping_ui-master/src/api/system/dictDetail.js new file mode 100644 index 0000000..e8dc512 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/dictDetail.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +export function get(dictName) { + const params = { + dictName, + page: 0, + size: 9999 + } + return request({ + url: 'api/dictDetail', + method: 'get', + params + }) +} + +export function getDictMap(dictName) { + const params = { + dictName, + page: 0, + size: 9999 + } + return request({ + url: 'api/dictDetail/map', + method: 'get', + params + }) +} + +export function add(data) { + return request({ + url: 'api/dictDetail', + method: 'post', + data + }) +} + +export function del(id) { + return request({ + url: 'api/dictDetail/' + id, + method: 'delete' + }) +} + +export function edit(data) { + return request({ + url: 'api/dictDetail', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/job.js b/UI source code/dns_mapping_ui-master/src/api/system/job.js new file mode 100644 index 0000000..a00630e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/job.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +export function getAllJob() { + const params = { + page: 0, + size: 9999, + enabled: true + } + return request({ + url: 'api/job', + method: 'get', + params + }) +} + +export function add(data) { + return request({ + url: 'api/job', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/job', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/job', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/menu.js b/UI source code/dns_mapping_ui-master/src/api/system/menu.js new file mode 100644 index 0000000..282dd8d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/menu.js @@ -0,0 +1,65 @@ +import request from '@/utils/request' + +export function getMenusTree(pid) { + return request({ + url: 'api/menus/lazy?pid=' + pid, + method: 'get' + }) +} + +export function getMenus(params) { + return request({ + url: 'api/menus', + method: 'get', + params + }) +} + +export function getMenuSuperior(ids) { + const data = Array.isArray(ids) || ids.length === 0 ? ids : Array.of(ids) + return request({ + url: 'api/menus/superior', + method: 'post', + data + }) +} + +export function getChild(id) { + return request({ + url: 'api/menus/child?id=' + id, + method: 'get' + }) +} + +export function buildMenus() { + return request({ + url: 'api/menus/build', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/menus', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/menus', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/menus', + method: 'put', + data + }) +} + +export default { add, edit, del, getMenusTree, getMenuSuperior, getMenus, getChild } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/role.js b/UI source code/dns_mapping_ui-master/src/api/system/role.js new file mode 100644 index 0000000..1f7bc1e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/role.js @@ -0,0 +1,57 @@ +import request from '@/utils/request' + +// 获取所有的Role +export function getAll() { + return request({ + url: 'api/roles/all', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/roles', + method: 'post', + data + }) +} + +export function get(id) { + return request({ + url: 'api/roles/' + id, + method: 'get' + }) +} + +export function getLevel() { + return request({ + url: 'api/roles/level', + method: 'get' + }) +} + +export function del(ids) { + return request({ + url: 'api/roles', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/roles', + method: 'put', + data + }) +} + +export function editMenu(data) { + return request({ + url: 'api/roles/menu', + method: 'put', + data + }) +} + +export default { add, edit, del, get, editMenu, getLevel } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/timing.js b/UI source code/dns_mapping_ui-master/src/api/system/timing.js new file mode 100644 index 0000000..613e15f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/timing.js @@ -0,0 +1,41 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/jobs', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/jobs', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/jobs', + method: 'put', + data + }) +} + +export function updateIsPause(id) { + return request({ + url: 'api/jobs/' + id, + method: 'put' + }) +} + +export function execution(id) { + return request({ + url: 'api/jobs/exec/' + id, + method: 'put' + }) +} + +export default { del, updateIsPause, execution, add, edit } diff --git a/UI source code/dns_mapping_ui-master/src/api/system/user.js b/UI source code/dns_mapping_ui-master/src/api/system/user.js new file mode 100644 index 0000000..6cd91a5 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/system/user.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' +import { encrypt } from '@/utils/rsaEncrypt' + +export function add(data) { + return request({ + url: 'api/users', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/users', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/users', + method: 'put', + data + }) +} + +export function editUser(data) { + return request({ + url: 'api/users/center', + method: 'put', + data + }) +} + +export function updatePass(user) { + const data = { + oldPass: encrypt(user.oldPass), + newPass: encrypt(user.newPass) + } + return request({ + url: 'api/users/updatePass/', + method: 'post', + data + }) +} + +export function updateEmail(form) { + const data = { + password: encrypt(form.pass), + email: form.email + } + return request({ + url: 'api/users/updateEmail/' + form.code, + method: 'post', + data + }) +} + +export default { add, edit, del } + diff --git a/UI source code/dns_mapping_ui-master/src/api/tools/alipay.js b/UI source code/dns_mapping_ui-master/src/api/tools/alipay.js new file mode 100644 index 0000000..54090f5 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/tools/alipay.js @@ -0,0 +1,25 @@ +import request from '@/utils/request' + +export function get() { + return request({ + url: 'api/aliPay', + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/aliPay', + data, + method: 'put' + }) +} + +// 支付 +export function toAliPay(url, data) { + return request({ + url: 'api/' + url, + data, + method: 'post' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/tools/email.js b/UI source code/dns_mapping_ui-master/src/api/tools/email.js new file mode 100644 index 0000000..af030cb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/tools/email.js @@ -0,0 +1,24 @@ +import request from '@/utils/request' + +export function get() { + return request({ + url: 'api/email', + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/email', + data, + method: 'put' + }) +} + +export function send(data) { + return request({ + url: 'api/email', + data, + method: 'post' + }) +} diff --git a/UI source code/dns_mapping_ui-master/src/api/tools/localStorage.js b/UI source code/dns_mapping_ui-master/src/api/tools/localStorage.js new file mode 100644 index 0000000..63ebe2b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/tools/localStorage.js @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/localStorage', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/localStorage/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/localStorage', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/UI source code/dns_mapping_ui-master/src/api/tools/qiniu.js b/UI source code/dns_mapping_ui-master/src/api/tools/qiniu.js new file mode 100644 index 0000000..6d56771 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/api/tools/qiniu.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +export function get() { + return request({ + url: 'api/qiNiuContent/config', + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/qiNiuContent/config', + data, + method: 'put' + }) +} + +export function download(id) { + return request({ + url: 'api/qiNiuContent/download/' + id, + method: 'get' + }) +} + +export function sync() { + return request({ + url: 'api/qiNiuContent/synchronize', + method: 'post' + }) +} + +export function del(ids) { + return request({ + url: 'api/qiNiuContent', + method: 'delete', + data: ids + }) +} + +export default { del, download, sync } diff --git a/UI source code/dns_mapping_ui-master/src/assets/401_images/401.gif b/UI source code/dns_mapping_ui-master/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/401_images/401.gif differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/404_images/404.png b/UI source code/dns_mapping_ui-master/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/404_images/404.png differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/404_images/404_cloud.png b/UI source code/dns_mapping_ui-master/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/404_images/404_cloud.png differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/index.js b/UI source code/dns_mapping_ui-master/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/Steve-Jobs.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/Steve-Jobs.svg new file mode 100644 index 0000000..53843e2 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/Steve-Jobs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/alipay.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/alipay.svg new file mode 100644 index 0000000..9138981 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/alipay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/anq.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/anq.svg new file mode 100644 index 0000000..a466608 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/anq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/app.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/app.svg new file mode 100644 index 0000000..0796da3 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/backup.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/backup.svg new file mode 100644 index 0000000..a3272a4 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/backup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/blog.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/blog.svg new file mode 100644 index 0000000..a990eba --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/blog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chain.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chain.svg new file mode 100644 index 0000000..ed3317f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chart.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/codeConsole.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/codeConsole.svg new file mode 100644 index 0000000..672ec6e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/codeConsole.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dashboard.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/database.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/database.svg new file mode 100644 index 0000000..7fbad9b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/database.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/date.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..0540e99 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/deploy.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/deploy.svg new file mode 100644 index 0000000..f4a1c56 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/deploy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dept.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dept.svg new file mode 100644 index 0000000..894e4bf --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dept.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dev.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dev.svg new file mode 100644 index 0000000..ed4d23c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/develop.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/develop.svg new file mode 100644 index 0000000..e189223 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/develop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dictionary.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dictionary.svg new file mode 100644 index 0000000..6e83c43 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/dictionary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/doc.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/doc.svg new file mode 100644 index 0000000..9160de8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/doc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/download.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..0243c6a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/edit.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/education.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/email.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..f1cf3ae --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/error.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/error.svg new file mode 100644 index 0000000..fd935da --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/exit-fullscreen.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fullscreen.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fwb.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fwb.svg new file mode 100644 index 0000000..59933fc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/fwb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/github.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..8145e95 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/gonggao.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/gonggao.svg new file mode 100644 index 0000000..22aed08 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/gonggao.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/icon.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82fbdd9 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/image.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/image.svg new file mode 100644 index 0000000..16d572f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/index.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/index.svg new file mode 100644 index 0000000..fdb3826 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/index.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/international.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/ipvisits.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/ipvisits.svg new file mode 100644 index 0000000..4ca473d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/ipvisits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/java.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/java.svg new file mode 100644 index 0000000..e2effbb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/java.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/link.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/list.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/lock.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..0f842ea --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/log.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..4fefe74 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/login.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/login.svg new file mode 100644 index 0000000..cc5a854 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/markdown.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/markdown.svg new file mode 100644 index 0000000..7cd6747 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/markdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/menu.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/menu.svg new file mode 100644 index 0000000..e4360a0 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/message.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/mnt.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/mnt.svg new file mode 100644 index 0000000..936ce29 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/mnt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/money.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/monitor.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..339370a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/monitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/nested.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/password.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..4ab451f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/people.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/peoples.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..2c91161 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/permission.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/permission.svg new file mode 100644 index 0000000..c4c7409 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/permission.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/phone.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..da339f9 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/qiniu.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/qiniu.svg new file mode 100644 index 0000000..c2f9f8b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/qiniu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/redis.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..bef111b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/role.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/role.svg new file mode 100644 index 0000000..76cb18f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/role.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/search.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/server.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..db6dcdf --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/shopping.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/size.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/skill.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/source.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/source.svg new file mode 100644 index 0000000..1c3a038 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/source.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sqlMonitor.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sqlMonitor.svg new file mode 100644 index 0000000..950a430 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sqlMonitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/swagger.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..ded7de8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sys-tools.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sys-tools.svg new file mode 100644 index 0000000..8f9055e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/sys-tools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..9333c60 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system.svg @@ -0,0 +1 @@ + diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system1.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system1.svg new file mode 100644 index 0000000..37b0a0a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/system1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tab.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/theme.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/timing.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/timing.svg new file mode 100644 index 0000000..f8fdc6d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/timing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tools.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tools.svg new file mode 100644 index 0000000..aba1a40 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree-table.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/unlock.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/unlock.svg new file mode 100644 index 0000000..1219e41 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/unlock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..09d7a81 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user1.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user1.svg new file mode 100644 index 0000000..14ca51e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/user1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/validCode.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..a1feb74 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/visits.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/visits.svg new file mode 100644 index 0000000..8425662 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/visits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/web.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/web.svg new file mode 100644 index 0000000..9c57415 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/web.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/wechat.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/weixin.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/weixin.svg new file mode 100644 index 0000000..8dbcfa5 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/weixin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svg/zujian.svg b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/zujian.svg new file mode 100644 index 0000000..2aba32f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svg/zujian.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/assets/icons/svgo.yml b/UI source code/dns_mapping_ui-master/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/UI source code/dns_mapping_ui-master/src/assets/images/avatar.png b/UI source code/dns_mapping_ui-master/src/assets/images/avatar.png new file mode 100644 index 0000000..997732a Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/images/avatar.png differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/images/background.jpeg b/UI source code/dns_mapping_ui-master/src/assets/images/background.jpeg new file mode 100644 index 0000000..bae295e Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/images/background.jpeg differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/images/logo.png b/UI source code/dns_mapping_ui-master/src/assets/images/logo.png new file mode 100644 index 0000000..f757710 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/images/logo.png differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/images/newlogo.png b/UI source code/dns_mapping_ui-master/src/assets/images/newlogo.png new file mode 100644 index 0000000..97ef198 Binary files /dev/null and b/UI source code/dns_mapping_ui-master/src/assets/images/newlogo.png differ diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/btn.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/btn.scss new file mode 100644 index 0000000..8f47f2c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import 'variables'; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue) +} + +.light-blue-btn { + @include colorBtn($light-blue) +} + +.red-btn { + @include colorBtn($red) +} + +.pink-btn { + @include colorBtn($pink) +} + +.green-btn { + @include colorBtn($green) +} + +.tiffany-btn { + @include colorBtn($tiffany) +} + +.yellow-btn { + @include colorBtn($yellow) +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/eladmin.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/eladmin.scss new file mode 100644 index 0000000..e1e0195 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/eladmin.scss @@ -0,0 +1,117 @@ +.head-container { + padding-bottom: 10px; + .filter-item { + display: inline-block; + vertical-align: middle; + margin: 0 3px 10px 0; + input { + height: 30.5px; + line-height: 30.5px; + } + } + .el-form-item-label { + margin: 0 3px 9px 0; + display: inline-block; + text-align: right; + vertical-align: middle; + font-size: 14px; + color: #606266; + line-height: 30.5px; + padding: 0 7px 0 7px; + } + .el-button+.el-button { + margin-left: 0 !important; + } + .el-select__caret.el-input__icon.el-icon-arrow-up{ + line-height: 30.5px; + } + .date-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + height: 30.5px !important; + width: 230px !important; + } +} +.el-avatar { + display: inline-block; + text-align: center; + background: #ccc; + color: #fff; + white-space: nowrap; + position: relative; + overflow: hidden; + vertical-align: middle; + width: 32px; + height: 32px; + line-height: 32px; + border-radius: 16px; +} + +.logo-con{ + height: 60px; + padding: 13px 0 0; + img{ + height: 32px; + width: 135px; + display: block; + //margin: 0 auto; + } +} + +#el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #fff; + font-family: Arial, serif; + font-size: 12px; + letter-spacing: 1px; +} + +#el-main-footer { + background: none repeat scroll 0 0 white; + border-top: 1px solid #e7eaec; + overflow: hidden; + padding: 10px 6px 0 6px; + height: 33px; + font-size: 0.7rem !important; + color: #7a8b9a; + letter-spacing: 0.8px; + font-family: Arial, sans-serif !important; + position: fixed; + bottom: 0; + z-index: 99; + width: 100%; +} +.eladmin-upload { + border: 1px dashed #c0ccda; + border-radius: 5px; + height: 45px; + line-height: 45px; + width: 368px; +} +.my-blockquote{ + margin: 0 0 10px; + padding: 15px; + line-height: 22px; + border-left: 5px solid #00437B; + border-radius: 0 2px 2px 0; + background-color: #f2f2f2; +} +.my-code{ + position: relative; + padding: 15px; + line-height: 20px; + border-left: 5px solid #ddd; + color: #333; + font-family: Courier New, serif; + font-size: 12px +} + +.el-tabs{ + margin-bottom: 25px; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/element-ui.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..8f7881c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/element-ui.scss @@ -0,0 +1,79 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0; + } + } +} + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/element-variables.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..a4f8c4a --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/element-variables.scss @@ -0,0 +1,31 @@ +/** +* I think element-ui's default theme color is too light for long-term use. +* So I modified the default color and you can modify it to your liking. +**/ + +/* theme color */ +$--color-primary: #1890ff; +$--color-success: #13ce66; +$--color-warning: #FFBA00; +$--color-danger: #ff4949; +// $--color-info: #1E1E1E; + +$--button-font-weight: 400; + +// $--color-text-regular: #1f2d3d; + +$--border-color-light: #dfe4ed; +$--border-color-lighter: #e6ebf5; + +$--table-border:1px solid#dfe6ec; + +/* icon font path, required */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "../../../node_modules/element-ui/packages/theme-chalk/src/index"; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + theme: $--color-primary; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/index.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/index.scss new file mode 100644 index 0000000..7add05b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/index.scss @@ -0,0 +1,182 @@ +@import 'variables'; +@import 'mixin'; +@import 'transition'; +@import 'element-ui'; +@import 'sidebar'; +@import 'btn'; +@import 'eladmin'; + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0 !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container全局样式 +.app-container { + padding: 20px 20px 45px 20px; +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +.pagination-container { + margin-top: 30px; +} + +.text-center { + text-align: center +} + +// .sub-navbar { +// height: 50px; +// line-height: 50px; +// position: relative; +// width: 100%; +// text-align: right; +// padding-right: 20px; +// transition: 600ms ease position; +// background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + +// .subtitle { +// font-size: 20px; +// color: #fff; +// } + +// &.draft { +// background: #d0d0d0; +// } + +// &.deleted { +// background: #d0d0d0; +// } +// } + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +//refine vue-multiselect plugin +.multiselect { + line-height: 16px; +} + +.multiselect--active { + z-index: 1000 !important; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/mixin.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } + + @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/sidebar.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..d99315e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/sidebar.scss @@ -0,0 +1,197 @@ +// #app { +// height: 100vh; +// .main-container { +// min-height: 100%; +// transition: margin-left .28s; +// margin-left: $sideBarWidth; +// position: relative; +// } + +// .sidebar-container { +// transition: width 0.28s; +// width: $sideBarWidth !important; +// background-color: $menuBg; +// height: 100%; +// position: fixed; +// font-size: 0; +// top: 0; +// bottom: 0; +// left: 0; +// z-index: 1001; +// overflow: hidden; + +// // reset element-ui css +// .horizontal-collapse-transition { +// transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; +// } + +// .scrollbar-wrapper { +// overflow-x: hidden !important; +// // width: 80% !important; +// // margin-left: -20px; +// } + +// .el-scrollbar__bar.is-vertical { +// right: 0; +// } + +// .el-scrollbar { +// height: 100%; +// width: 80%; +// } + +// &.has-logo { +// .el-scrollbar { +// height: calc(100% - 50px); +// } +// } + +// .is-horizontal { +// display: none; +// } + +// a { +// display: inline-block; +// width: 100%; +// overflow: hidden; +// } + +// .svg-icon { +// margin-right: 16px; +// } + +// .el-menu { +// border: none; +// height: 100%; +// width: 100% !important; +// } + +// // menu hover +// .submenu-title-noDropdown, +// .el-submenu__title { +// &:hover { +// background-color: $menuHover !important; +// } +// } + +// .is-active>.el-submenu__title { +// color: $subMenuActiveText !important; +// font-size: 30px !important; +// } + +// & .nest-menu .el-submenu>.el-submenu__title, +// & .el-submenu .el-menu-item { +// min-width: $sideBarWidth !important; +// background-color: $subMenuBg !important; +// font-size: 30px !important; +// &:hover { +// background-color: $subMenuHover !important; +// } +// } +// } + +// .hideSidebar { +// .sidebar-container { +// width:0px !important; +// } + +// .main-container { +// margin-left:0; +// } + +// .submenu-title-noDropdown { +// padding: 0 !important; +// position: relative; + +// .el-tooltip { +// padding: 0 !important; + +// .svg-icon { +// margin-left: 20px; +// } +// } +// } +// .el-menu--collapse { +// .el-submenu { +// &>.el-submenu__title { +// &>span { +// font-size: 30px !important; +// height: 0; +// width: 0; +// overflow: hidden; +// visibility: hidden; +// display: inline-block; +// } +// } +// } +// } +// } + +// .el-menu--collapse .el-menu .el-submenu { +// min-width: $sideBarWidth !important; +// } + +// // mobile responsive +// .mobile { +// .main-container { +// margin-left: 0; +// } + +// .sidebar-container { +// transition: transform .28s; +// width: $sideBarWidth !important; +// } + +// &.hideSidebar { +// .sidebar-container { +// pointer-events: none; +// transition-duration: 0.3s; +// transform: translate3d(-$sideBarWidth, 0, 0); +// } +// } +// } + +// .withoutAnimation { + +// .main-container, +// .sidebar-container { +// transition: none; +// } +// } +// } + +// // when menu collapsed +// .el-menu--vertical { +// &>.el-menu { +// .svg-icon { +// margin-right: 16px; +// } +// } + +// .nest-menu .el-submenu>.el-submenu__title, +// .el-menu-item { +// &:hover { +// // you can use $subMenuHover +// background-color: $menuHover !important; +// } +// } + +// // the scroll bar appears when the subMenu is too long +// >.el-menu--popup { +// max-height: 100vh; +// overflow-y: auto; + +// &::-webkit-scrollbar-track-piece { +// background: #d3dce6; +// } + +// &::-webkit-scrollbar { +// width: 6px; +// } + +// &::-webkit-scrollbar-thumb { +// background: #99a9bf; +// border-radius: 20px; +// } +// } +// } diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/transition.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/transition.scss new file mode 100644 index 0000000..4cb27cc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/transition.scss @@ -0,0 +1,48 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/UI source code/dns_mapping_ui-master/src/assets/styles/variables.scss b/UI source code/dns_mapping_ui-master/src/assets/styles/variables.scss new file mode 100644 index 0000000..ba0cd3f --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/assets/styles/variables.scss @@ -0,0 +1,35 @@ +// base color +$blue:#324157; +$light-blue:#3A71A8; +$red:#C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow:#FEC171; +$panGreen: #30B08F; + +// sidebar +$menuText:#bfcbd9; +$menuActiveText:#fff; +$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 + +$menuBg:#4608ad; +$menuHover:#263445; + +$subMenuBg:#1f2d3d; +$subMenuHover:#001528; + +$sideBarWidth: 0px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuText: $menuText; + menuActiveText: $menuActiveText; + subMenuActiveText: $subMenuActiveText; + menuBg: $menuBg; + menuHover: $menuHover; + subMenuBg: $subMenuBg; + subMenuHover: $subMenuHover; + sideBarWidth: $sideBarWidth; +} diff --git a/UI source code/dns_mapping_ui-master/src/components/Breadcrumb/index.vue b/UI source code/dns_mapping_ui-master/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..204ea59 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Breadcrumb/index.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Crud/CRUD.operation.vue b/UI source code/dns_mapping_ui-master/src/components/Crud/CRUD.operation.vue new file mode 100644 index 0000000..33d2077 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Crud/CRUD.operation.vue @@ -0,0 +1,268 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Crud/Pagination.vue b/UI source code/dns_mapping_ui-master/src/components/Crud/Pagination.vue new file mode 100644 index 0000000..d4482fb --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Crud/Pagination.vue @@ -0,0 +1,18 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Crud/RR.operation.vue b/UI source code/dns_mapping_ui-master/src/components/Crud/RR.operation.vue new file mode 100644 index 0000000..df2c138 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Crud/RR.operation.vue @@ -0,0 +1,20 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Crud/UD.operation.vue b/UI source code/dns_mapping_ui-master/src/components/Crud/UD.operation.vue new file mode 100644 index 0000000..c60abd7 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Crud/UD.operation.vue @@ -0,0 +1,71 @@ + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Crud/crud.js b/UI source code/dns_mapping_ui-master/src/components/Crud/crud.js new file mode 100644 index 0000000..ae36765 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Crud/crud.js @@ -0,0 +1,863 @@ +import { initData, download } from '@/api/data' +import { parseTime, downloadFile } from '@/utils/index' +import Vue from 'vue' + +/** + * CRUD配置 + * @author moxun + * @param {*} options
+ * @return crud instance. + * @example + * 要使用多crud时,请在关联crud的组件处使用crud-tag进行标记,如: + */ +function CRUD(options) { + const defaultOptions = { + tag: 'default', + // id字段名 + idField: 'id', + // 标题 + title: '', + // 请求数据的url + url: '', + // 表格数据 + data: [], + // 选择项 + selections: [], + // 待查询的对象 + query: {}, + // 查询数据的参数 + params: {}, + // Form 表单 + form: {}, + // 重置表单 + defaultForm: () => {}, + // 排序规则,默认 id 降序, 支持多字段排序 ['id,desc', 'createTime,asc'] + sort: ['id,desc'], + // 等待时间 + time: 50, + // CRUD Method + crudMethod: { + add: (form) => {}, + del: (id) => {}, + edit: (form) => {}, + get: (id) => {} + }, + // 主页操作栏显示哪些按钮 + optShow: { + add: true, + edit: true, + del: true, + download: true, + reset: true + }, + // 自定义一些扩展属性 + props: {}, + // 在主页准备 + queryOnPresenterCreated: true, + // 调试开关 + debug: false + } + options = mergeOptions(defaultOptions, options) + const data = { + ...options, + // 记录数据状态 + dataStatus: {}, + status: { + add: CRUD.STATUS.NORMAL, + edit: CRUD.STATUS.NORMAL, + // 添加或编辑状态 + get cu() { + if (this.add === CRUD.STATUS.NORMAL && this.edit === CRUD.STATUS.NORMAL) { + return CRUD.STATUS.NORMAL + } else if (this.add === CRUD.STATUS.PREPARED || this.edit === CRUD.STATUS.PREPARED) { + return CRUD.STATUS.PREPARED + } else if (this.add === CRUD.STATUS.PROCESSING || this.edit === CRUD.STATUS.PROCESSING) { + return CRUD.STATUS.PROCESSING + } + throw new Error('wrong crud\'s cu status') + }, + // 标题 + get title() { + return this.add > CRUD.STATUS.NORMAL ? `新增${crud.title}` : this.edit > CRUD.STATUS.NORMAL ? `编辑${crud.title}` : crud.title + } + }, + msg: { + submit: '提交成功', + add: '新增成功', + edit: '编辑成功', + del: '删除成功' + }, + page: { + // 页码 + page: 0, + // 每页数据条数 + size: 10, + // 总数据条数 + total: 0 + }, + // 整体loading + loading: false, + // 导出的 Loading + downloadLoading: false, + // 删除的 Loading + delAllLoading: false + } + const methods = { + /** + * 通用的提示 + */ + submitSuccessNotify() { + crud.notify(crud.msg.submit, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + addSuccessNotify() { + crud.notify(crud.msg.add, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + editSuccessNotify() { + crud.notify(crud.msg.edit, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + delSuccessNotify() { + crud.notify(crud.msg.del, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + // 搜索 + toQuery() { + crud.page.page = 1 + crud.refresh() + }, + // 刷新 + refresh() { + if (!callVmHook(crud, CRUD.HOOK.beforeRefresh)) { + return + } + return new Promise((resolve, reject) => { + crud.loading = true + // 请求数据 + initData(crud.url, crud.getQueryParams()).then(data => { + const table = crud.getTable() + if (table && table.lazy) { // 懒加载子节点数据,清掉已加载的数据 + table.store.states.treeData = {} + table.store.states.lazyTreeNodeMap = {} + } + crud.page.total = data.totalElements + crud.data = data.content + crud.resetDataStatus() + // time 毫秒后显示表格 + setTimeout(() => { + crud.loading = false + callVmHook(crud, CRUD.HOOK.afterRefresh) + }, crud.time) + resolve(data) + }).catch(err => { + crud.loading = false + reject(err) + }) + }) + }, + /** + * 启动添加 + */ + toAdd() { + crud.resetForm() + if (!(callVmHook(crud, CRUD.HOOK.beforeToAdd, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) { + return + } + crud.status.add = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterToAdd, crud.form) + callVmHook(crud, CRUD.HOOK.afterToCU, crud.form) + }, + /** + * 启动编辑 + * @param {*} data 数据项 + */ + toEdit(data) { + crud.resetForm(JSON.parse(JSON.stringify(data))) + if (!(callVmHook(crud, CRUD.HOOK.beforeToEdit, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) { + return + } + crud.status.edit = CRUD.STATUS.PREPARED + crud.getDataStatus(crud.getDataId(data)).edit = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterToEdit, crud.form) + callVmHook(crud, CRUD.HOOK.afterToCU, crud.form) + }, + /** + * 启动删除 + * @param {*} data 数据项 + */ + toDelete(data) { + crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.PREPARED + }, + /** + * 取消删除 + * @param {*} data 数据项 + */ + cancelDelete(data) { + if (!callVmHook(crud, CRUD.HOOK.beforeDeleteCancel, data)) { + return + } + crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.NORMAL + callVmHook(crud, CRUD.HOOK.afterDeleteCancel, data) + }, + /** + * 取消新增/编辑 + */ + cancelCU() { + const addStatus = crud.status.add + const editStatus = crud.status.edit + if (addStatus === CRUD.STATUS.PREPARED) { + if (!callVmHook(crud, CRUD.HOOK.beforeAddCancel, crud.form)) { + return + } + crud.status.add = CRUD.STATUS.NORMAL + } + if (editStatus === CRUD.STATUS.PREPARED) { + if (!callVmHook(crud, CRUD.HOOK.beforeEditCancel, crud.form)) { + return + } + crud.status.edit = CRUD.STATUS.NORMAL + crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL + } + crud.resetForm() + if (addStatus === CRUD.STATUS.PREPARED) { + callVmHook(crud, CRUD.HOOK.afterAddCancel, crud.form) + } + if (editStatus === CRUD.STATUS.PREPARED) { + callVmHook(crud, CRUD.HOOK.afterEditCancel, crud.form) + } + // 清除表单验证 + if (crud.findVM('form').$refs['form']) { + crud.findVM('form').$refs['form'].clearValidate() + } + }, + /** + * 提交新增/编辑 + */ + submitCU() { + if (!callVmHook(crud, CRUD.HOOK.beforeValidateCU)) { + return + } + crud.findVM('form').$refs['form'].validate(valid => { + if (!valid) { + return + } + if (!callVmHook(crud, CRUD.HOOK.afterValidateCU)) { + return + } + if (crud.status.add === CRUD.STATUS.PREPARED) { + crud.doAdd() + } else if (crud.status.edit === CRUD.STATUS.PREPARED) { + crud.doEdit() + } + }) + }, + /** + * 执行添加 + */ + doAdd() { + if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) { + return + } + crud.status.add = CRUD.STATUS.PROCESSING + crud.crudMethod.add(crud.form).then(() => { + crud.status.add = CRUD.STATUS.NORMAL + crud.resetForm() + crud.addSuccessNotify() + callVmHook(crud, CRUD.HOOK.afterSubmit) + crud.toQuery() + }).catch(() => { + crud.status.add = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterAddError) + }) + }, + /** + * 执行编辑 + */ + doEdit() { + if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) { + return + } + crud.status.edit = CRUD.STATUS.PROCESSING + crud.crudMethod.edit(crud.form).then(() => { + crud.status.edit = CRUD.STATUS.NORMAL + crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL + crud.editSuccessNotify() + crud.resetForm() + callVmHook(crud, CRUD.HOOK.afterSubmit) + crud.refresh() + }).catch(() => { + crud.status.edit = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterEditError) + }) + }, + /** + * 执行删除 + * @param {*} data 数据项 + */ + doDelete(data) { + let delAll = false + let dataStatus + const ids = [] + if (data instanceof Array) { + delAll = true + data.forEach(val => { + ids.push(this.getDataId(val)) + }) + } else { + ids.push(this.getDataId(data)) + dataStatus = crud.getDataStatus(this.getDataId(data)) + } + if (!callVmHook(crud, CRUD.HOOK.beforeDelete, data)) { + return + } + if (!delAll) { + dataStatus.delete = CRUD.STATUS.PROCESSING + } + return crud.crudMethod.del(ids).then(() => { + if (delAll) { + crud.delAllLoading = false + } else dataStatus.delete = CRUD.STATUS.PREPARED + crud.dleChangePage(1) + crud.delSuccessNotify() + callVmHook(crud, CRUD.HOOK.afterDelete, data) + crud.refresh() + }).catch(() => { + if (delAll) { + crud.delAllLoading = false + } else dataStatus.delete = CRUD.STATUS.PREPARED + }) + }, + /** + * 通用导出 + */ + doExport() { + crud.downloadLoading = true + download(crud.url + '/download', crud.getQueryParams()).then(result => { + downloadFile(result, crud.title + '数据', 'xlsx') + crud.downloadLoading = false + }).catch(() => { + crud.downloadLoading = false + }) + }, + /** + * 获取查询参数 + */ + getQueryParams: function() { + // 清除参数无值的情况 + Object.keys(crud.query).length !== 0 && Object.keys(crud.query).forEach(item => { + if (crud.query[item] === null || crud.query[item] === '') crud.query[item] = undefined + }) + Object.keys(crud.params).length !== 0 && Object.keys(crud.params).forEach(item => { + if (crud.params[item] === null || crud.params[item] === '') crud.params[item] = undefined + }) + return { + page: crud.page.page - 1, + size: crud.page.size, + sort: crud.sort, + ...crud.query, + ...crud.params + } + }, + // 当前页改变 + pageChangeHandler(e) { + crud.page.page = e + crud.refresh() + }, + // 每页条数改变 + sizeChangeHandler(e) { + crud.page.size = e + crud.page.page = 1 + crud.refresh() + }, + // 预防删除第二页最后一条数据时,或者多选删除第二页的数据时,页码错误导致请求无数据 + dleChangePage(size) { + if (crud.data.length === size && crud.page.page !== 1) { + crud.page.page -= 1 + } + }, + // 选择改变 + selectionChangeHandler(val) { + crud.selections = val + }, + /** + * 重置查询参数 + * @param {Boolean} toQuery 重置后进行查询操作 + */ + resetQuery(toQuery = true) { + const defaultQuery = JSON.parse(JSON.stringify(crud.defaultQuery)) + const query = crud.query + Object.keys(query).forEach(key => { + query[key] = defaultQuery[key] + }) + // 重置参数 + this.params = {} + if (toQuery) { + crud.toQuery() + } + }, + /** + * 重置表单 + * @param {Array} data 数据 + */ + resetForm(data) { + const form = data || (typeof crud.defaultForm === 'object' ? JSON.parse(JSON.stringify(crud.defaultForm)) : crud.defaultForm.apply(crud.findVM('form'))) + const crudFrom = crud.form + for (const key in form) { + if (crudFrom.hasOwnProperty(key)) { + crudFrom[key] = form[key] + } else { + Vue.set(crudFrom, key, form[key]) + } + } + // add by ghl 2020-10-04 页面重复添加信息时,下拉框的校验会存在,需要找工取消 + if (crud.findVM('form').$refs['form']) { + crud.findVM('form').$refs['form'].clearValidate() + } + }, + /** + * 重置数据状态 + */ + resetDataStatus() { + const dataStatus = {} + function resetStatus(datas) { + datas.forEach(e => { + dataStatus[crud.getDataId(e)] = { + delete: 0, + edit: 0 + } + if (e.children) { + resetStatus(e.children) + } + }) + } + resetStatus(crud.data) + crud.dataStatus = dataStatus + }, + /** + * 获取数据状态 + * @param {Number | String} id 数据项id + */ + getDataStatus(id) { + return crud.dataStatus[id] + }, + /** + * 用于树形表格多选, 选中所有 + * @param selection + */ + selectAllChange(selection) { + // 如果选中的数目与请求到的数目相同就选中子节点,否则就清空选中 + if (selection && selection.length === crud.data.length) { + selection.forEach(val => { + crud.selectChange(selection, val) + }) + } else { + crud.getTable().clearSelection() + } + }, + /** + * 用于树形表格多选,单选的封装 + * @param selection + * @param row + */ + selectChange(selection, row) { + // 如果selection中存在row代表是选中,否则是取消选中 + if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) { + if (row.children) { + row.children.forEach(val => { + crud.getTable().toggleRowSelection(val, true) + selection.push(val) + if (val.children) { + crud.selectChange(selection, val) + } + }) + } + } else { + crud.toggleRowSelection(selection, row) + } + }, + /** + * 切换选中状态 + * @param selection + * @param data + */ + toggleRowSelection(selection, data) { + if (data.children) { + data.children.forEach(val => { + crud.getTable().toggleRowSelection(val, false) + if (val.children) { + crud.toggleRowSelection(selection, val) + } + }) + } + }, + findVM(type) { + return crud.vms.find(vm => vm && vm.type === type).vm + }, + notify(title, type = CRUD.NOTIFICATION_TYPE.INFO) { + crud.vms[0].vm.$notify({ + title, + type, + duration: 2500 + }) + }, + updateProp(name, value) { + Vue.set(crud.props, name, value) + }, + getDataId(data) { + return data[this.idField] + }, + getTable() { + return this.findVM('presenter').$refs.table + }, + attchTable() { + const table = this.getTable() + this.updateProp('table', table) + const that = this + table.$on('expand-change', (row, expanded) => { + if (!expanded) { + return + } + const lazyTreeNodeMap = table.store.states.lazyTreeNodeMap + row.children = lazyTreeNodeMap[crud.getDataId(row)] + if (row.children) { + row.children.forEach(ele => { + const id = crud.getDataId(ele) + if (that.dataStatus[id] === undefined) { + that.dataStatus[id] = { + delete: 0, + edit: 0 + } + } + }) + } + }) + } + } + const crud = Object.assign({}, data) + // 可观测化 + Vue.observable(crud) + // 附加方法 + Object.assign(crud, methods) + // 记录初始默认的查询参数,后续重置查询时使用 + Object.assign(crud, { + defaultQuery: JSON.parse(JSON.stringify(data.query)), + // 预留4位存储:组件 主页、头部、分页、表单,调试查看也方便找 + vms: Array(4), + /** + * 注册组件实例 + * @param {String} type 类型 + * @param {*} vm 组件实例 + * @param {Number} index 该参数内部使用 + */ + registerVM(type, vm, index = -1) { + const vmObj = { + type, + vm: vm + } + if (index < 0) { + this.vms.push(vmObj) + return + } + if (index < 4) { // 内置预留vm数 + this.vms[index] = vmObj + return + } + this.vms.length = Math.max(this.vms.length, index) + this.vms.splice(index, 1, vmObj) + }, + /** + * 取消注册组件实例 + * @param {*} vm 组件实例 + */ + unregisterVM(type, vm) { + for (let i = this.vms.length - 1; i >= 0; i--) { + if (this.vms[i] === undefined) { + continue + } + if (this.vms[i].type === type && this.vms[i].vm === vm) { + if (i < 4) { // 内置预留vm数 + this.vms[i] = undefined + } else { + this.vms.splice(i, 1) + } + break + } + } + } + }) + // 冻结处理,需要扩展数据的话,使用crud.updateProp(name, value),以crud.props.name形式访问,这个是响应式的,可以做数据绑定 + Object.freeze(crud) + return crud +} + +// hook VM +function callVmHook(crud, hook) { + if (crud.debug) { + console.log('callVmHook: ' + hook) + } + const tagHook = crud.tag ? hook + '$' + crud.tag : null + let ret = true + const nargs = [crud] + for (let i = 2; i < arguments.length; ++i) { + nargs.push(arguments[i]) + } + // 有些组件扮演了多个角色,调用钩子时,需要去重 + const vmSet = new Set() + crud.vms.forEach(vm => vm && vmSet.add(vm.vm)) + vmSet.forEach(vm => { + if (vm[hook]) { + ret = vm[hook].apply(vm, nargs) !== false && ret + } + if (tagHook && vm[tagHook]) { + ret = vm[tagHook].apply(vm, nargs) !== false && ret + } + }) + return ret +} + +function mergeOptions(src, opts) { + const optsRet = { + ...src + } + for (const key in src) { + if (opts.hasOwnProperty(key)) { + optsRet[key] = opts[key] + } + } + return optsRet +} + +/** + * 查找crud + * @param {*} vm + * @param {string} tag + */ +function lookupCrud(vm, tag) { + tag = tag || vm.$attrs['crud-tag'] || 'default' + // function lookupCrud(vm, tag) { + if (vm.$crud) { + const ret = vm.$crud[tag] + if (ret) { + return ret + } + } + return vm.$parent ? lookupCrud(vm.$parent, tag) : undefined +} + +/** + * crud主页 + */ +function presenter(crud) { + if (crud) { + console.warn('[CRUD warn]: ' + 'please use $options.cruds() { return CRUD(...) or [CRUD(...), ...] }') + } + return { + data() { + // 在data中返回crud,是为了将crud与当前实例关联,组件观测crud相关属性变化 + return { + crud: this.crud + } + }, + beforeCreate() { + this.$crud = this.$crud || {} + let cruds = this.$options.cruds instanceof Function ? this.$options.cruds() : crud + if (!(cruds instanceof Array)) { + cruds = [cruds] + } + cruds.forEach(ele => { + if (this.$crud[ele.tag]) { + console.error('[CRUD error]: ' + 'crud with tag [' + ele.tag + ' is already exist') + } + this.$crud[ele.tag] = ele + ele.registerVM('presenter', this, 0) + }) + this.crud = this.$crud['defalut'] || cruds[0] + }, + methods: { + parseTime + }, + created() { + for (const k in this.$crud) { + if (this.$crud[k].queryOnPresenterCreated) { + this.$crud[k].toQuery() + } + } + }, + destroyed() { + for (const k in this.$crud) { + this.$crud[k].unregisterVM('presenter', this) + } + }, + mounted() { + // 如果table未实例化(例如使用了v-if),请稍后在适当时机crud.attchTable刷新table信息 + if (this.$refs.table !== undefined) { + this.crud.attchTable() + } + } + } +} + +/** + * 头部 + */ +function header() { + return { + data() { + return { + crud: this.crud, + query: this.crud.query + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('header', this, 1) + }, + destroyed() { + this.crud.unregisterVM('header', this) + } + } +} + +/** + * 分页 + */ +function pagination() { + return { + data() { + return { + crud: this.crud, + page: this.crud.page + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('pagination', this, 2) + }, + destroyed() { + this.crud.unregisterVM('pagination', this) + } + } +} + +/** + * 表单 + */ +function form(defaultForm) { + return { + data() { + return { + crud: this.crud, + form: this.crud.form + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('form', this, 3) + }, + created() { + this.crud.defaultForm = defaultForm + this.crud.resetForm() + }, + destroyed() { + this.crud.unregisterVM('form', this) + } + } +} + +/** + * crud + */ +function crud(options = {}) { + const defaultOptions = { + type: undefined + } + options = mergeOptions(defaultOptions, options) + return { + data() { + return { + crud: this.crud + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM(options.type, this) + }, + destroyed() { + this.crud.unregisterVM(options.type, this) + } + } +} + +/** + * CRUD钩子 + */ +CRUD.HOOK = { + /** 刷新 - 之前 */ + beforeRefresh: 'beforeCrudRefresh', + /** 刷新 - 之后 */ + afterRefresh: 'afterCrudRefresh', + /** 删除 - 之前 */ + beforeDelete: 'beforeCrudDelete', + /** 删除 - 之后 */ + afterDelete: 'afterCrudDelete', + /** 删除取消 - 之前 */ + beforeDeleteCancel: 'beforeCrudDeleteCancel', + /** 删除取消 - 之后 */ + afterDeleteCancel: 'afterCrudDeleteCancel', + /** 新建 - 之前 */ + beforeToAdd: 'beforeCrudToAdd', + /** 新建 - 之后 */ + afterToAdd: 'afterCrudToAdd', + /** 编辑 - 之前 */ + beforeToEdit: 'beforeCrudToEdit', + /** 编辑 - 之后 */ + afterToEdit: 'afterCrudToEdit', + /** 开始 "新建/编辑" - 之前 */ + beforeToCU: 'beforeCrudToCU', + /** 开始 "新建/编辑" - 之后 */ + afterToCU: 'afterCrudToCU', + /** "新建/编辑" 验证 - 之前 */ + beforeValidateCU: 'beforeCrudValidateCU', + /** "新建/编辑" 验证 - 之后 */ + afterValidateCU: 'afterCrudValidateCU', + /** 添加取消 - 之前 */ + beforeAddCancel: 'beforeCrudAddCancel', + /** 添加取消 - 之后 */ + afterAddCancel: 'afterCrudAddCancel', + /** 编辑取消 - 之前 */ + beforeEditCancel: 'beforeCrudEditCancel', + /** 编辑取消 - 之后 */ + afterEditCancel: 'afterCrudEditCancel', + /** 提交 - 之前 */ + beforeSubmit: 'beforeCrudSubmitCU', + /** 提交 - 之后 */ + afterSubmit: 'afterCrudSubmitCU', + afterAddError: 'afterCrudAddError', + afterEditError: 'afterCrudEditError' +} + +/** + * CRUD状态 + */ +CRUD.STATUS = { + NORMAL: 0, + PREPARED: 1, + PROCESSING: 2 +} + +/** + * CRUD通知类型 + */ +CRUD.NOTIFICATION_TYPE = { + SUCCESS: 'success', + WARNING: 'warning', + INFO: 'info', + ERROR: 'error' +} + +export default CRUD + +export { + presenter, + header, + form, + pagination, + crud +} diff --git a/UI source code/dns_mapping_ui-master/src/components/DateRangePicker/index.vue b/UI source code/dns_mapping_ui-master/src/components/DateRangePicker/index.vue new file mode 100644 index 0000000..eef79bd --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/DateRangePicker/index.vue @@ -0,0 +1,45 @@ + diff --git a/UI source code/dns_mapping_ui-master/src/components/Dict/Dict.js b/UI source code/dns_mapping_ui-master/src/components/Dict/Dict.js new file mode 100644 index 0000000..48554de --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Dict/Dict.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import { get as getDictDetail } from '@/api/system/dictDetail' + +export default class Dict { + constructor(dict) { + this.dict = dict + } + + async init(names, completeCallback) { + if (names === undefined || name === null) { + throw new Error('need Dict names') + } + const ps = [] + names.forEach(n => { + Vue.set(this.dict.dict, n, {}) + Vue.set(this.dict.label, n, {}) + Vue.set(this.dict, n, []) + ps.push(getDictDetail(n).then(data => { + this.dict[n].splice(0, 0, ...data.content) + data.content.forEach(d => { + Vue.set(this.dict.dict[n], d.value, d) + Vue.set(this.dict.label[n], d.value, d.label) + }) + })) + }) + await Promise.all(ps) + completeCallback() + } +} diff --git a/UI source code/dns_mapping_ui-master/src/components/Dict/index.js b/UI source code/dns_mapping_ui-master/src/components/Dict/index.js new file mode 100644 index 0000000..0952f43 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Dict/index.js @@ -0,0 +1,29 @@ +import Dict from './Dict' + +const install = function(Vue) { + Vue.mixin({ + data() { + if (this.$options.dicts instanceof Array) { + const dict = { + dict: {}, + label: {} + } + return { + dict + } + } + return {} + }, + created() { + if (this.$options.dicts instanceof Array) { + new Dict(this.dict).init(this.$options.dicts, () => { + this.$nextTick(() => { + this.$emit('dictReady') + }) + }) + } + } + }) +} + +export default { install } diff --git a/UI source code/dns_mapping_ui-master/src/components/Doc/index.vue b/UI source code/dns_mapping_ui-master/src/components/Doc/index.vue new file mode 100644 index 0000000..47c5e8d --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Doc/index.vue @@ -0,0 +1,16 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/BarChart.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/BarChart.vue new file mode 100644 index 0000000..fa265ef --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/BarChart.vue @@ -0,0 +1,106 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Category.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Category.vue new file mode 100644 index 0000000..5859114 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Category.vue @@ -0,0 +1,438 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Egressdns.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Egressdns.vue new file mode 100644 index 0000000..a7ec7a7 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Egressdns.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Forwarder.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Forwarder.vue new file mode 100644 index 0000000..b660498 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Forwarder.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Fwdrdns.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Fwdrdns.vue new file mode 100644 index 0000000..0be12ba --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Fwdrdns.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Nonstandard.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Nonstandard.vue new file mode 100644 index 0000000..7e5cc9b --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Nonstandard.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Openrdns.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Openrdns.vue new file mode 100644 index 0000000..20a42cf --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53Openrdns.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53sj.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53sj.vue new file mode 100644 index 0000000..06ff958 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53sj.vue @@ -0,0 +1,166 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53zg.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53zg.vue new file mode 100644 index 0000000..3ab40d6 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Do53zg.vue @@ -0,0 +1,145 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohsj.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohsj.vue new file mode 100644 index 0000000..03510a5 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohsj.vue @@ -0,0 +1,163 @@ + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohzg.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohzg.vue new file mode 100644 index 0000000..812b58e --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Dohzg.vue @@ -0,0 +1,145 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Funnel.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Funnel.vue new file mode 100644 index 0000000..380b373 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Funnel.vue @@ -0,0 +1,120 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/PieChart.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/PieChart.vue new file mode 100644 index 0000000..ff1bc52 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/PieChart.vue @@ -0,0 +1,84 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Echarts/Time.vue b/UI source code/dns_mapping_ui-master/src/components/Echarts/Time.vue new file mode 100644 index 0000000..4ab9c55 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Echarts/Time.vue @@ -0,0 +1,104 @@ + + + + \ No newline at end of file diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/FilteredSearch.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/FilteredSearch.vue new file mode 100644 index 0000000..afe1155 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/FilteredSearch.vue @@ -0,0 +1,518 @@ + + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/RecentSearch.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/RecentSearch.vue new file mode 100644 index 0000000..a6338b3 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/RecentSearch.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/SearchItem.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/SearchItem.vue new file mode 100644 index 0000000..1cdf097 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/SearchItem.vue @@ -0,0 +1,343 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/TrimInput.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/TrimInput.vue new file mode 100644 index 0000000..f126f2c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/TrimInput.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VAutoInput.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VAutoInput.vue new file mode 100644 index 0000000..049f200 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VAutoInput.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VInput.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VInput.vue new file mode 100644 index 0000000..31cd2a5 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VInput.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VPicker.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VPicker.vue new file mode 100644 index 0000000..497280c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VPicker.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VSelect.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VSelect.vue new file mode 100644 index 0000000..5572a6c --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VSelect.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VTimerange.vue b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VTimerange.vue new file mode 100644 index 0000000..ca891c6 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/VTimerange.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/cursorPosition.js b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/cursorPosition.js new file mode 100644 index 0000000..ffe12fd --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/cursorPosition.js @@ -0,0 +1,14 @@ +/* 不能导入导出 global 是不支持document的 */ + +export default function getTxt1CursorPosition(dom,document){ + var oTxt1 =dom + var cursurPosition=-1; + if(oTxt1.selectionStart || oTxt1.selectionStart===0){//非IE浏览器 + cursurPosition= oTxt1.selectionStart; + }else{//IE + var range = document.selection.createRange(); + range.moveStart("character",-oTxt1.value.length); + cursurPosition=range.text.length; + } + return cursurPosition +} diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/historyApi.js b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/historyApi.js new file mode 100644 index 0000000..8b5a305 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/historyApi.js @@ -0,0 +1,86 @@ +import remove from 'lodash/remove' +import Moment from 'moment' +/* 配置文件 */ +import vue from '@/main.js' +import isEqual from 'lodash/isEqual' + +//时间的历史纪录 +class searchHistory { + constructor(key = 'searchHistory', maxLength = 10) { + this.key = key + this.maxLength = maxLength + if (!this.getHistory()) { + localStorage.setItem(this.key, '{}'); + } + } + + getSaveKey() { + //暂时 不这么写 + //获取 页面对应的关键字 , 因为页签的问题, 一个页面 可能出现两个搜索框的问题 .... + var route = vue.$route.path; + return route + } + + getHistory() { + var historyList = JSON.parse(localStorage.getItem(this.key)) + return historyList + } + + getPageHistory(saveKey) { //获取当前页的搜索数据... + var route = saveKey || vue.$route.path; + var historyMap = JSON.parse(localStorage.getItem(this.key)) || {} + return historyMap[route] || [] + } + + setHistory(val) { + localStorage.setItem(this.key, JSON.stringify(val)); + } + + addItem(item, saveKey) { + // var route = vue.$route.name + var route = saveKey || vue.$route.path; //fullPath path name(使用name最好,就是需要改 ) + var historyMap = JSON.parse(localStorage.getItem(this.key)) || {}; + if (!historyMap[route]) { + historyMap[route] = [] + } + + //删除 重复的搜索历史记录 + var itemObj = {} + item.forEach((obj) => { + itemObj[obj.name] = obj.value + }); + historyMap[route] = historyMap[route].filter((historyList, index) => { + var historyItemObj = {}; + historyList.forEach((item) => { + historyItemObj[item.name] = item.value + }); + return !isEqual(itemObj, historyItemObj); + }); + + + // historyMap[route].push(item); + historyMap[route].unshift(item); + + if (historyMap[route].length > this.maxLength) { + historyMap[route].pop() + } + var info = JSON.stringify(historyMap) + localStorage.setItem(this.key, info); + } + + clearPageHistory(saveKey) { + //清除当前 页的搜索数据... + var route = saveKey || vue.$route.path; //fullPath path name(使用name最好,就是需要改 ) + var historyMap = JSON.parse(localStorage.getItem(this.key) || '{}'); + historyMap[route] = [] + var info = JSON.stringify(historyMap) + localStorage.setItem(this.key, info); + } + + clear() { + localStorage.setItem(this.key, '{}'); + } +} + +var history = new searchHistory(); +export default history diff --git a/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/keyboard.js b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/keyboard.js new file mode 100644 index 0000000..9f3ee00 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/FilteredSearch/components/keyboard.js @@ -0,0 +1,31 @@ +export function fireKeyEvent(el, evtType, keyCode) { + var evtObj; + if (document.createEvent) { + if (window.KeyEvent) {//firefox 浏览器下模拟事件 + evtObj = document.createEvent('KeyEvents'); + evtObj.initKeyEvent(evtType, true, true, window, true, false, false, false, keyCode, 0); + } else {//chrome 浏览器下模拟事件 + evtObj = document.createEvent('UIEvents'); + evtObj.initUIEvent(evtType, true, true, window, 1); + + delete evtObj.keyCode; + if (typeof evtObj.keyCode === "undefined") {//为了模拟keycode + Object.defineProperty(evtObj, "keyCode", { value: keyCode }); + } else { + evtObj.key = String.fromCharCode(keyCode); + } + + if (typeof evtObj.ctrlKey === 'undefined') {//为了模拟ctrl键 + Object.defineProperty(evtObj, "ctrlKey", { value: true }); + } else { + evtObj.ctrlKey = true; + } + } + el.dispatchEvent(evtObj); + + } else if (document.createEventObject) {//IE 浏览器下模拟事件 + evtObj = document.createEventObject(); + evtObj.keyCode = keyCode + el.fireEvent('on' + evtType, evtObj); + } +} diff --git a/UI source code/dns_mapping_ui-master/src/components/GithubCorner/index.vue b/UI source code/dns_mapping_ui-master/src/components/GithubCorner/index.vue new file mode 100644 index 0000000..bc79cbf --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/GithubCorner/index.vue @@ -0,0 +1,54 @@ + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/Hamburger/index.vue b/UI source code/dns_mapping_ui-master/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/HeaderSearch/index.vue b/UI source code/dns_mapping_ui-master/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..c713efc --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/HeaderSearch/index.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/IconSelect/index.vue b/UI source code/dns_mapping_ui-master/src/components/IconSelect/index.vue new file mode 100644 index 0000000..b0ec9fa --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/IconSelect/index.vue @@ -0,0 +1,68 @@ + + + + + + diff --git a/UI source code/dns_mapping_ui-master/src/components/IconSelect/requireIcons.js b/UI source code/dns_mapping_ui-master/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/IconSelect/requireIcons.js @@ -0,0 +1,11 @@ + +const req = require.context('../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const icons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default icons diff --git a/UI source code/dns_mapping_ui-master/src/components/Iframe/index.vue b/UI source code/dns_mapping_ui-master/src/components/Iframe/index.vue new file mode 100644 index 0000000..9f395a3 --- /dev/null +++ b/UI source code/dns_mapping_ui-master/src/components/Iframe/index.vue @@ -0,0 +1,30 @@ +