parent
c11542acd1
commit
d2099524ac
@ -0,0 +1,9 @@
|
|||||||
|
### IDEA ###
|
||||||
|
.idea/*
|
||||||
|
.vscode
|
||||||
|
*.iml
|
||||||
|
*/target/*
|
||||||
|
*/*.iml
|
||||||
|
/.gradle/
|
||||||
|
/application.pid
|
||||||
|
upload/*
|
||||||
@ -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-2023 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.
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>eladmin</artifactId>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<properties>
|
||||||
|
<hutool.version>5.8.20</hutool.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<artifactId>eladmin-common</artifactId>
|
||||||
|
<name>公共模块</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!--工具包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -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 me.zhengjie.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jacky
|
||||||
|
* 用于标记匿名访问方法
|
||||||
|
*/
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface AnonymousAccess {
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.annotation;
|
||||||
|
|
||||||
|
import me.zhengjie.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;
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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 me.zhengjie.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 {};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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 me.zhengjie.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.
|
||||||
|
* <p>
|
||||||
|
* 支持匿名访问 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 {};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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 me.zhengjie.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 {};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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 me.zhengjie.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 {};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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 me.zhengjie.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 {};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.aspect;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import me.zhengjie.annotation.Limit;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
import me.zhengjie.utils.RequestHolder;
|
||||||
|
import me.zhengjie.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<Object,Object> redisTemplate;
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class);
|
||||||
|
|
||||||
|
public LimitAspect(RedisTemplate<Object,Object> redisTemplate) {
|
||||||
|
this.redisTemplate = redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pointcut("@annotation(me.zhengjie.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<Object> keys = ImmutableList.of(StringUtils.join(limit.prefix(), "_", key, "_", request.getRequestURI().replace("/","_")));
|
||||||
|
|
||||||
|
String luaScript = buildLuaScript();
|
||||||
|
RedisScript<Number> 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;";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.aspect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限流枚举
|
||||||
|
* @author /
|
||||||
|
*/
|
||||||
|
public enum LimitType {
|
||||||
|
// 默认
|
||||||
|
CUSTOMER,
|
||||||
|
// by ip addr
|
||||||
|
IP
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package me.zhengjie.base;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019年10月24日20:48:53
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.base;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
public interface BaseMapper<D, E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO转Entity
|
||||||
|
* @param dto /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
E toEntity(D dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity转DTO
|
||||||
|
* @param entity /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
D toDto(E entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO集合转Entity集合
|
||||||
|
* @param dtoList /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
List <E> toEntity(List<D> dtoList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity集合转DTO集合
|
||||||
|
* @param entityList /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
List <D> toDto(List<E> entityList);
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.config;
|
||||||
|
|
||||||
|
import me.zhengjie.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
*/
|
||||||
|
@Service(value = "el")
|
||||||
|
public class AuthorityConfig {
|
||||||
|
|
||||||
|
public Boolean check(String ...permissions){
|
||||||
|
// 获取当前用户的所有权限
|
||||||
|
List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
|
||||||
|
// 判断当前用户的所有权限是否包含接口上定义的权限
|
||||||
|
return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhengjie.utils.ElConstant;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
*/
|
||||||
|
@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(ElConstant.WIN)) {
|
||||||
|
return windows;
|
||||||
|
} else if(os.toLowerCase().startsWith(ElConstant.MAC)){
|
||||||
|
return mac;
|
||||||
|
}
|
||||||
|
return linux;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ElPath{
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
private String avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description
|
||||||
|
* @date 2020-05-18
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
public class RsaProperties {
|
||||||
|
|
||||||
|
public static String privateKey;
|
||||||
|
|
||||||
|
@Value("${rsa.private_key}")
|
||||||
|
public void setPrivateKey(String privateKey) {
|
||||||
|
RsaProperties.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一关于错误配置信息 异常
|
||||||
|
*
|
||||||
|
* @author: liaojinlong
|
||||||
|
* @date: 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. <p>Note that the detail message associated with
|
||||||
|
* {@code cause} is <i>not</i> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.exception;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
* 统一异常处理
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.exception;
|
||||||
|
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.exception;
|
||||||
|
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.exception.handler;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
class ApiError {
|
||||||
|
|
||||||
|
private Integer status = 400;
|
||||||
|
private Long timestamp;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private ApiError() {
|
||||||
|
timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.exception.handler;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
import me.zhengjie.exception.EntityExistException;
|
||||||
|
import me.zhengjie.exception.EntityNotFoundException;
|
||||||
|
import me.zhengjie.utils.ThrowableUtil;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.validation.ObjectError;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import static org.springframework.http.HttpStatus.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有不可知的异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Throwable.class)
|
||||||
|
public ResponseEntity<ApiError> handleException(Throwable e){
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return buildResponseEntity(ApiError.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BadCredentialsException
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BadCredentialsException.class)
|
||||||
|
public ResponseEntity<ApiError> badCredentialsException(BadCredentialsException e){
|
||||||
|
// 打印堆栈信息
|
||||||
|
String message = "坏的凭证".equals(e.getMessage()) ? "用户名或密码不正确" : e.getMessage();
|
||||||
|
log.error(message);
|
||||||
|
return buildResponseEntity(ApiError.error(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理自定义异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = BadRequestException.class)
|
||||||
|
public ResponseEntity<ApiError> badRequestException(BadRequestException e) {
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 EntityExist
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = EntityExistException.class)
|
||||||
|
public ResponseEntity<ApiError> entityExistException(EntityExistException e) {
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return buildResponseEntity(ApiError.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 EntityNotFound
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = EntityNotFoundException.class)
|
||||||
|
public ResponseEntity<ApiError> entityNotFoundException(EntityNotFoundException e) {
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return buildResponseEntity(ApiError.error(NOT_FOUND.value(),e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有接口数据验证异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public ResponseEntity<ApiError> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
|
||||||
|
String message = objectError.getDefaultMessage();
|
||||||
|
if (objectError instanceof FieldError) {
|
||||||
|
message = ((FieldError) objectError).getField() + ": " + message;
|
||||||
|
}
|
||||||
|
return buildResponseEntity(ApiError.error(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一返回
|
||||||
|
*/
|
||||||
|
private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) {
|
||||||
|
return new ResponseEntity<>(apiError, HttpStatus.valueOf(apiError.getStatus()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaojinlong
|
||||||
|
* @date: 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:";
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常用静态常量
|
||||||
|
*
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-12-26
|
||||||
|
*/
|
||||||
|
public class ElConstant {
|
||||||
|
/**
|
||||||
|
* win 系统
|
||||||
|
*/
|
||||||
|
public static final String WIN = "win";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac 系统
|
||||||
|
*/
|
||||||
|
public static final String MAC = "mac";
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package me.zhengjie.utils;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
|
public class PageResult<T> {
|
||||||
|
|
||||||
|
private final List<T> content;
|
||||||
|
|
||||||
|
private final long totalElements;
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
public class RequestHolder {
|
||||||
|
|
||||||
|
public static HttpServletRequest getHttpServletRequest() {
|
||||||
|
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
import me.zhengjie.utils.enums.DataScopeEnum;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录的用户
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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();
|
||||||
|
// 将 Java 对象转换为 JSONObject 对象
|
||||||
|
JSONObject jsonObject = (JSONObject) JSON.toJSON(userDetails);
|
||||||
|
return jsonObject.getJSONObject("user").getLong("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户的数据权限
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static List<Long> getCurrentUserDataScope(){
|
||||||
|
UserDetails userDetails = getCurrentUser();
|
||||||
|
// 将 Java 对象转换为 JSONObject 对象
|
||||||
|
JSONObject jsonObject = (JSONObject) JSON.toJSON(userDetails);
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONArray("dataScopes");
|
||||||
|
return JSON.parseArray(jsonArray.toJSONString(), Long.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据权限级别
|
||||||
|
* @return 级别
|
||||||
|
*/
|
||||||
|
public static String getDataScopeType() {
|
||||||
|
List<Long> dataScopes = getCurrentUserDataScope();
|
||||||
|
if(dataScopes.size() != 0){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return DataScopeEnum.ALL.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常工具 2019-01-06
|
||||||
|
* @author Zheng Jie
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证工具
|
||||||
|
*
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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 Validator.isEmail(email);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 验证码业务场景
|
||||||
|
* </p>
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 验证码业务场景对应的 Redis 中的 key
|
||||||
|
* </p>
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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;
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 数据权限枚举
|
||||||
|
* </p>
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description
|
||||||
|
* @date 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package me.zhengjie.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class DateUtilsTest {
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
long l = System.currentTimeMillis() / 1000;
|
||||||
|
LocalDateTime localDateTime = DateUtil.fromTimeStamp(l);
|
||||||
|
System.out.print(DateUtil.localDateTimeFormatyMdHms(localDateTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
System.out.println(DateUtil.localDateTimeFormatyMdHms(now));
|
||||||
|
Date date = DateUtil.toDate(now);
|
||||||
|
LocalDateTime localDateTime = DateUtil.toLocalDateTime(date);
|
||||||
|
System.out.println(DateUtil.localDateTimeFormatyMdHms(localDateTime));
|
||||||
|
LocalDateTime localDateTime1 = DateUtil.fromTimeStamp(date.getTime() / 1000);
|
||||||
|
System.out.println(DateUtil.localDateTimeFormatyMdHms(localDateTime1));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package me.zhengjie.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static me.zhengjie.utils.EncryptUtils.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class EncryptUtilsTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称加密
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDesEncrypt() {
|
||||||
|
try {
|
||||||
|
assertEquals("7772841DC6099402", desEncrypt("123456"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称解密
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDesDecrypt() {
|
||||||
|
try {
|
||||||
|
assertEquals("123456", desDecrypt("7772841DC6099402"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package me.zhengjie.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
|
||||||
|
import static me.zhengjie.utils.FileUtil.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class FileUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToFile() {
|
||||||
|
long retval = toFile(new MockMultipartFile("foo", (byte[]) null)).getTotalSpace();
|
||||||
|
assertEquals(500695072768L, retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetExtensionName() {
|
||||||
|
assertEquals("foo", getExtensionName("foo"));
|
||||||
|
assertEquals("exe", getExtensionName("bar.exe"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetFileNameNoEx() {
|
||||||
|
assertEquals("foo", getFileNameNoEx("foo"));
|
||||||
|
assertEquals("bar", getFileNameNoEx("bar.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSize() {
|
||||||
|
assertEquals("1000B ", getSize(1000));
|
||||||
|
assertEquals("1.00KB ", getSize(1024));
|
||||||
|
assertEquals("1.00MB ", getSize(1048576));
|
||||||
|
assertEquals("1.00GB ", getSize(1073741824));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package me.zhengjie.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static me.zhengjie.utils.StringUtils.getIp;
|
||||||
|
import static me.zhengjie.utils.StringUtils.getWeekDay;
|
||||||
|
import static me.zhengjie.utils.StringUtils.toCamelCase;
|
||||||
|
import static me.zhengjie.utils.StringUtils.toCapitalizeCamelCase;
|
||||||
|
import static me.zhengjie.utils.StringUtils.toUnderScoreCase;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
public class StringUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToCamelCase() {
|
||||||
|
assertNull(toCamelCase(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToCapitalizeCamelCase() {
|
||||||
|
assertNull(StringUtils.toCapitalizeCamelCase(null));
|
||||||
|
assertEquals("HelloWorld", toCapitalizeCamelCase("hello_world"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToUnderScoreCase() {
|
||||||
|
assertNull(StringUtils.toUnderScoreCase(null));
|
||||||
|
assertEquals("hello_world", toUnderScoreCase("helloWorld"));
|
||||||
|
assertEquals("\u0000\u0000", toUnderScoreCase("\u0000\u0000"));
|
||||||
|
assertEquals("\u0000_a", toUnderScoreCase("\u0000A"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetWeekDay() {
|
||||||
|
SimpleDateFormat simpleDateformat = new SimpleDateFormat("E");
|
||||||
|
assertEquals(simpleDateformat.format(new Date()), getWeekDay());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetIP() {
|
||||||
|
assertEquals("127.0.0.1", getIp(new MockHttpServletRequest()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>eladmin</artifactId>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>eladmin-generator</artifactId>
|
||||||
|
<name>代码生成模块</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<configuration.version>1.10</configuration.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<artifactId>eladmin-common</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--模板引擎-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/commons-configuration/commons-configuration -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-configuration</groupId>
|
||||||
|
<artifactId>commons-configuration</artifactId>
|
||||||
|
<version>${configuration.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -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 me.zhengjie.domain;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成配置
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-03
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Entity
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Table(name = "code_gen_config")
|
||||||
|
public class GenConfig implements Serializable {
|
||||||
|
|
||||||
|
public GenConfig(String tableName) {
|
||||||
|
this.tableName = tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "config_id")
|
||||||
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@ApiModelProperty(value = "表名")
|
||||||
|
private String tableName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "接口名称")
|
||||||
|
private String apiAlias;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@ApiModelProperty(value = "包路径")
|
||||||
|
private String pack;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@ApiModelProperty(value = "模块名")
|
||||||
|
private String moduleName;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@ApiModelProperty(value = "前端文件路径")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "前端文件路径")
|
||||||
|
private String apiPath;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "作者")
|
||||||
|
private String author;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "表前缀")
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否覆盖")
|
||||||
|
private Boolean cover = false;
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.domain.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表的数据信息
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TableInfo {
|
||||||
|
|
||||||
|
/** 表名称 */
|
||||||
|
private Object tableName;
|
||||||
|
|
||||||
|
/** 创建日期 */
|
||||||
|
private Object createTime;
|
||||||
|
|
||||||
|
/** 数据库引擎 */
|
||||||
|
private Object engine;
|
||||||
|
|
||||||
|
/** 编码集 */
|
||||||
|
private Object coding;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private Object remark;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.repository;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.ColumnInfo;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-14
|
||||||
|
*/
|
||||||
|
public interface ColumnInfoRepository extends JpaRepository<ColumnInfo,Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询表信息
|
||||||
|
* @param tableName 表格名
|
||||||
|
* @return 表信息
|
||||||
|
*/
|
||||||
|
List<ColumnInfo> findByTableNameOrderByIdAsc(String tableName);
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.repository;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-14
|
||||||
|
*/
|
||||||
|
public interface GenConfigRepository extends JpaRepository<GenConfig,Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询表配置
|
||||||
|
* @param tableName 表名
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
GenConfig findByTableName(String tableName);
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.rest;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
import me.zhengjie.service.GenConfigService;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-14
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/genConfig")
|
||||||
|
@Api(tags = "系统:代码生成器配置管理")
|
||||||
|
public class GenConfigController {
|
||||||
|
|
||||||
|
private final GenConfigService genConfigService;
|
||||||
|
|
||||||
|
@ApiOperation("查询")
|
||||||
|
@GetMapping(value = "/{tableName}")
|
||||||
|
public ResponseEntity<GenConfig> queryGenConfig(@PathVariable String tableName){
|
||||||
|
return new ResponseEntity<>(genConfigService.find(tableName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@ApiOperation("修改")
|
||||||
|
public ResponseEntity<Object> updateGenConfig(@Validated @RequestBody GenConfig genConfig){
|
||||||
|
return new ResponseEntity<>(genConfigService.update(genConfig.getTableName(), genConfig),HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.rest;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.domain.ColumnInfo;
|
||||||
|
import me.zhengjie.domain.vo.TableInfo;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
import me.zhengjie.service.GenConfigService;
|
||||||
|
import me.zhengjie.service.GeneratorService;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
import me.zhengjie.utils.PageUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-02
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/generator")
|
||||||
|
@Api(tags = "系统:代码生成管理")
|
||||||
|
public class GeneratorController {
|
||||||
|
|
||||||
|
private final GeneratorService generatorService;
|
||||||
|
private final GenConfigService genConfigService;
|
||||||
|
|
||||||
|
@Value("${generator.enabled}")
|
||||||
|
private Boolean generatorEnabled;
|
||||||
|
|
||||||
|
@ApiOperation("查询数据库数据")
|
||||||
|
@GetMapping(value = "/tables/all")
|
||||||
|
public ResponseEntity<Object> queryAllTables(){
|
||||||
|
return new ResponseEntity<>(generatorService.getTables(), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("查询数据库数据")
|
||||||
|
@GetMapping(value = "/tables")
|
||||||
|
public ResponseEntity<PageResult<TableInfo>> queryTables(@RequestParam(defaultValue = "") String name,
|
||||||
|
@RequestParam(defaultValue = "0")Integer page,
|
||||||
|
@RequestParam(defaultValue = "10")Integer size){
|
||||||
|
int[] startEnd = PageUtil.transToStartEnd(page, size);
|
||||||
|
return new ResponseEntity<>(generatorService.getTables(name,startEnd), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("查询字段数据")
|
||||||
|
@GetMapping(value = "/columns")
|
||||||
|
public ResponseEntity<PageResult<ColumnInfo>> queryColumns(@RequestParam String tableName){
|
||||||
|
List<ColumnInfo> columnInfos = generatorService.getColumns(tableName);
|
||||||
|
return new ResponseEntity<>(PageUtil.toPage(columnInfos,columnInfos.size()), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("保存字段数据")
|
||||||
|
@PutMapping
|
||||||
|
public ResponseEntity<HttpStatus> saveColumn(@RequestBody List<ColumnInfo> columnInfos){
|
||||||
|
generatorService.save(columnInfos);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("同步字段数据")
|
||||||
|
@PostMapping(value = "sync")
|
||||||
|
public ResponseEntity<HttpStatus> syncColumn(@RequestBody List<String> tables){
|
||||||
|
for (String table : tables) {
|
||||||
|
generatorService.sync(generatorService.getColumns(table), generatorService.query(table));
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("生成代码")
|
||||||
|
@PostMapping(value = "/{tableName}/{type}")
|
||||||
|
public ResponseEntity<Object> generatorCode(@PathVariable String tableName, @PathVariable Integer type, HttpServletRequest request, HttpServletResponse response){
|
||||||
|
if(!generatorEnabled && type == 0){
|
||||||
|
throw new BadRequestException("此环境不允许生成代码,请选择预览或者下载查看!");
|
||||||
|
}
|
||||||
|
switch (type){
|
||||||
|
// 生成代码
|
||||||
|
case 0: generatorService.generator(genConfigService.find(tableName), generatorService.getColumns(tableName));
|
||||||
|
break;
|
||||||
|
// 预览
|
||||||
|
case 1: return generatorService.preview(genConfigService.find(tableName), generatorService.getColumns(tableName));
|
||||||
|
// 打包
|
||||||
|
case 2: generatorService.download(genConfigService.find(tableName), generatorService.getColumns(tableName), request, response);
|
||||||
|
break;
|
||||||
|
default: throw new BadRequestException("没有这个选项");
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-14
|
||||||
|
*/
|
||||||
|
public interface GenConfigService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询表配置
|
||||||
|
* @param tableName 表名
|
||||||
|
* @return 表配置
|
||||||
|
*/
|
||||||
|
GenConfig find(String tableName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新表配置
|
||||||
|
* @param tableName 表名
|
||||||
|
* @param genConfig 表配置
|
||||||
|
* @return 表配置
|
||||||
|
*/
|
||||||
|
GenConfig update(String tableName, GenConfig genConfig);
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
import me.zhengjie.domain.ColumnInfo;
|
||||||
|
import me.zhengjie.domain.vo.TableInfo;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-02
|
||||||
|
*/
|
||||||
|
public interface GeneratorService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据库元数据
|
||||||
|
* @param name 表名
|
||||||
|
* @param startEnd 分页参数
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
PageResult<TableInfo> getTables(String name, int[] startEnd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到数据表的元数据
|
||||||
|
* @param name 表名
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
List<ColumnInfo> getColumns(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步表数据
|
||||||
|
* @param columnInfos /
|
||||||
|
* @param columnInfoList /
|
||||||
|
*/
|
||||||
|
void sync(List<ColumnInfo> columnInfos, List<ColumnInfo> columnInfoList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保持数据
|
||||||
|
* @param columnInfos /
|
||||||
|
*/
|
||||||
|
void save(List<ColumnInfo> columnInfos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有table
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
Object getTables();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成
|
||||||
|
* @param genConfig 配置信息
|
||||||
|
* @param columns 字段信息
|
||||||
|
*/
|
||||||
|
void generator(GenConfig genConfig, List<ColumnInfo> columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览
|
||||||
|
* @param genConfig 配置信息
|
||||||
|
* @param columns 字段信息
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
ResponseEntity<Object> preview(GenConfig genConfig, List<ColumnInfo> columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打包下载
|
||||||
|
* @param genConfig 配置信息
|
||||||
|
* @param columns 字段信息
|
||||||
|
* @param request /
|
||||||
|
* @param response /
|
||||||
|
*/
|
||||||
|
void download(GenConfig genConfig, List<ColumnInfo> columns, HttpServletRequest request, HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据库的表字段数据数据
|
||||||
|
* @param table /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
List<ColumnInfo> query(String table);
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.service.impl;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
import me.zhengjie.repository.GenConfigRepository;
|
||||||
|
import me.zhengjie.service.GenConfigService;
|
||||||
|
import me.zhengjie.utils.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-14
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GenConfigServiceImpl implements GenConfigService {
|
||||||
|
|
||||||
|
private final GenConfigRepository genConfigRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GenConfig find(String tableName) {
|
||||||
|
GenConfig genConfig = genConfigRepository.findByTableName(tableName);
|
||||||
|
if(genConfig == null){
|
||||||
|
return new GenConfig(tableName);
|
||||||
|
}
|
||||||
|
return genConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GenConfig update(String tableName, GenConfig genConfig) {
|
||||||
|
String separator = File.separator;
|
||||||
|
String[] paths;
|
||||||
|
String symbol = "\\";
|
||||||
|
if (symbol.equals(separator)) {
|
||||||
|
paths = genConfig.getPath().split("\\\\");
|
||||||
|
} else {
|
||||||
|
paths = genConfig.getPath().split(File.separator);
|
||||||
|
}
|
||||||
|
StringBuilder api = new StringBuilder();
|
||||||
|
for (String path : paths) {
|
||||||
|
api.append(path);
|
||||||
|
api.append(separator);
|
||||||
|
if ("src".equals(path)) {
|
||||||
|
api.append("api");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genConfig.setApiPath(api.toString());
|
||||||
|
return genConfigRepository.save(genConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.domain.GenConfig;
|
||||||
|
import me.zhengjie.domain.ColumnInfo;
|
||||||
|
import me.zhengjie.domain.vo.TableInfo;
|
||||||
|
import me.zhengjie.exception.BadRequestException;
|
||||||
|
import me.zhengjie.repository.ColumnInfoRepository;
|
||||||
|
import me.zhengjie.service.GeneratorService;
|
||||||
|
import me.zhengjie.utils.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-02
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GeneratorServiceImpl implements GeneratorService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GeneratorServiceImpl.class);
|
||||||
|
@PersistenceContext
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
|
private final ColumnInfoRepository columnInfoRepository;
|
||||||
|
|
||||||
|
private final String CONFIG_MESSAGE = "请先配置生成器";
|
||||||
|
@Override
|
||||||
|
public Object getTables() {
|
||||||
|
// 使用预编译防止sql注入
|
||||||
|
String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " +
|
||||||
|
"where table_schema = (select database()) " +
|
||||||
|
"order by create_time desc";
|
||||||
|
Query query = em.createNativeQuery(sql);
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<TableInfo> getTables(String name, int[] startEnd) {
|
||||||
|
// 使用预编译防止sql注入
|
||||||
|
String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " +
|
||||||
|
"where table_schema = (select database()) " +
|
||||||
|
"and table_name like :table order by create_time desc";
|
||||||
|
Query query = em.createNativeQuery(sql);
|
||||||
|
query.setFirstResult(startEnd[0]);
|
||||||
|
query.setMaxResults(startEnd[1] - startEnd[0]);
|
||||||
|
query.setParameter("table", StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%");
|
||||||
|
List result = query.getResultList();
|
||||||
|
List<TableInfo> tableInfos = new ArrayList<>();
|
||||||
|
for (Object obj : result) {
|
||||||
|
Object[] arr = (Object[]) obj;
|
||||||
|
tableInfos.add(new TableInfo(arr[0], arr[1], arr[2], arr[3], ObjectUtil.isNotEmpty(arr[4]) ? arr[4] : "-"));
|
||||||
|
}
|
||||||
|
String countSql = "select count(1) from information_schema.tables " +
|
||||||
|
"where table_schema = (select database()) and table_name like :table";
|
||||||
|
Query queryCount = em.createNativeQuery(countSql);
|
||||||
|
queryCount.setParameter("table", StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%");
|
||||||
|
BigInteger totalElements = (BigInteger) queryCount.getSingleResult();
|
||||||
|
return PageUtil.toPage(tableInfos, totalElements.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ColumnInfo> getColumns(String tableName) {
|
||||||
|
List<ColumnInfo> columnInfos = columnInfoRepository.findByTableNameOrderByIdAsc(tableName);
|
||||||
|
if (CollectionUtil.isNotEmpty(columnInfos)) {
|
||||||
|
return columnInfos;
|
||||||
|
} else {
|
||||||
|
columnInfos = query(tableName);
|
||||||
|
return columnInfoRepository.saveAll(columnInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ColumnInfo> query(String tableName) {
|
||||||
|
// 使用预编译防止sql注入
|
||||||
|
String sql = "select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns " +
|
||||||
|
"where table_name = ? and table_schema = (select database()) order by ordinal_position";
|
||||||
|
Query query = em.createNativeQuery(sql);
|
||||||
|
query.setParameter(1, tableName);
|
||||||
|
List result = query.getResultList();
|
||||||
|
List<ColumnInfo> columnInfos = new ArrayList<>();
|
||||||
|
for (Object obj : result) {
|
||||||
|
Object[] arr = (Object[]) obj;
|
||||||
|
columnInfos.add(
|
||||||
|
new ColumnInfo(
|
||||||
|
tableName,
|
||||||
|
arr[0].toString(),
|
||||||
|
"NO".equals(arr[1]),
|
||||||
|
arr[2].toString(),
|
||||||
|
ObjectUtil.isNotNull(arr[3]) ? arr[3].toString() : null,
|
||||||
|
ObjectUtil.isNotNull(arr[4]) ? arr[4].toString() : null,
|
||||||
|
ObjectUtil.isNotNull(arr[5]) ? arr[5].toString() : null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return columnInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sync(List<ColumnInfo> columnInfos, List<ColumnInfo> columnInfoList) {
|
||||||
|
// 第一种情况,数据库类字段改变或者新增字段
|
||||||
|
for (ColumnInfo columnInfo : columnInfoList) {
|
||||||
|
// 根据字段名称查找
|
||||||
|
List<ColumnInfo> columns = columnInfos.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList());
|
||||||
|
// 如果能找到,就修改部分可能被字段
|
||||||
|
if (CollectionUtil.isNotEmpty(columns)) {
|
||||||
|
ColumnInfo column = columns.get(0);
|
||||||
|
column.setColumnType(columnInfo.getColumnType());
|
||||||
|
column.setExtra(columnInfo.getExtra());
|
||||||
|
column.setKeyType(columnInfo.getKeyType());
|
||||||
|
if (StringUtils.isBlank(column.getRemark())) {
|
||||||
|
column.setRemark(columnInfo.getRemark());
|
||||||
|
}
|
||||||
|
columnInfoRepository.save(column);
|
||||||
|
} else {
|
||||||
|
// 如果找不到,则保存新字段信息
|
||||||
|
columnInfoRepository.save(columnInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 第二种情况,数据库字段删除了
|
||||||
|
for (ColumnInfo columnInfo : columnInfos) {
|
||||||
|
// 根据字段名称查找
|
||||||
|
List<ColumnInfo> columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList());
|
||||||
|
// 如果找不到,就代表字段被删除了,则需要删除该字段
|
||||||
|
if (CollectionUtil.isEmpty(columns)) {
|
||||||
|
columnInfoRepository.delete(columnInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(List<ColumnInfo> columnInfos) {
|
||||||
|
columnInfoRepository.saveAll(columnInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generator(GenConfig genConfig, List<ColumnInfo> columns) {
|
||||||
|
if (genConfig.getId() == null) {
|
||||||
|
throw new BadRequestException(CONFIG_MESSAGE);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
GenUtil.generatorCode(columns, genConfig);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
throw new BadRequestException("生成失败,请手动处理已生成的文件");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<Object> preview(GenConfig genConfig, List<ColumnInfo> columns) {
|
||||||
|
if (genConfig.getId() == null) {
|
||||||
|
throw new BadRequestException(CONFIG_MESSAGE);
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> genList = GenUtil.preview(columns, genConfig);
|
||||||
|
return new ResponseEntity<>(genList, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(GenConfig genConfig, List<ColumnInfo> columns, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
if (genConfig.getId() == null) {
|
||||||
|
throw new BadRequestException(CONFIG_MESSAGE);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
File file = new File(GenUtil.download(columns, genConfig));
|
||||||
|
String zipPath = file.getPath() + ".zip";
|
||||||
|
ZipUtil.zip(file.getPath(), zipPath);
|
||||||
|
FileUtil.downloadFile(request, response, new File(zipPath), true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new BadRequestException("打包失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.configuration.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql字段转java
|
||||||
|
*
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-01-03
|
||||||
|
*/
|
||||||
|
public class ColUtil {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ColUtil.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换mysql数据类型为java数据类型
|
||||||
|
*
|
||||||
|
* @param type 数据库字段类型
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
static String cloToJava(String type) {
|
||||||
|
Configuration config = getConfig();
|
||||||
|
assert config != null;
|
||||||
|
return config.getString(type, "unknowType");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取配置信息
|
||||||
|
*/
|
||||||
|
public static PropertiesConfiguration getConfig() {
|
||||||
|
try {
|
||||||
|
return new PropertiesConfiguration("generator.properties");
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
# Database type to Java type
|
||||||
|
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
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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 ${package}.rest;
|
||||||
|
|
||||||
|
import me.zhengjie.annotation.Log;
|
||||||
|
import ${package}.domain.${className};
|
||||||
|
import ${package}.service.${className}Service;
|
||||||
|
import ${package}.service.dto.${className}QueryCriteria;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
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 io.swagger.annotations.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
import ${package}.service.dto.${className}Dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Api(tags = "${apiAlias}管理")
|
||||||
|
@RequestMapping("/api/${changeClassName}")
|
||||||
|
public class ${className}Controller {
|
||||||
|
|
||||||
|
private final ${className}Service ${changeClassName}Service;
|
||||||
|
|
||||||
|
@Log("导出数据")
|
||||||
|
@ApiOperation("导出数据")
|
||||||
|
@GetMapping(value = "/download")
|
||||||
|
@PreAuthorize("@el.check('${changeClassName}:list')")
|
||||||
|
public void export${className}(HttpServletResponse response, ${className}QueryCriteria criteria) throws IOException {
|
||||||
|
${changeClassName}Service.download(${changeClassName}Service.queryAll(criteria), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@Log("查询${apiAlias}")
|
||||||
|
@ApiOperation("查询${apiAlias}")
|
||||||
|
@PreAuthorize("@el.check('${changeClassName}:list')")
|
||||||
|
public ResponseEntity<PageResult<${className}Dto>> query${className}(${className}QueryCriteria criteria, Pageable pageable){
|
||||||
|
return new ResponseEntity<>(${changeClassName}Service.queryAll(criteria,pageable),HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Log("新增${apiAlias}")
|
||||||
|
@ApiOperation("新增${apiAlias}")
|
||||||
|
@PreAuthorize("@el.check('${changeClassName}:add')")
|
||||||
|
public ResponseEntity<Object> create${className}(@Validated @RequestBody ${className} resources){
|
||||||
|
${changeClassName}Service.create(resources);
|
||||||
|
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Log("修改${apiAlias}")
|
||||||
|
@ApiOperation("修改${apiAlias}")
|
||||||
|
@PreAuthorize("@el.check('${changeClassName}:edit')")
|
||||||
|
public ResponseEntity<Object> update${className}(@Validated @RequestBody ${className} resources){
|
||||||
|
${changeClassName}Service.update(resources);
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Log("删除${apiAlias}")
|
||||||
|
@ApiOperation("删除${apiAlias}")
|
||||||
|
@PreAuthorize("@el.check('${changeClassName}:del')")
|
||||||
|
public ResponseEntity<Object> delete${className}(@RequestBody ${pkColumnType}[] ids) {
|
||||||
|
${changeClassName}Service.deleteAll(ids);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 ${package}.service.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
<#if hasTimestamp>
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
</#if>
|
||||||
|
<#if hasBigDecimal>
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
</#if>
|
||||||
|
import java.io.Serializable;
|
||||||
|
<#if !auto && pkColumnType = 'Long'>
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import com.alibaba.fastjson.serializer.ToStringSerializer;
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description /
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class ${className}Dto implements Serializable {
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
|
||||||
|
<#if column.remark != ''>
|
||||||
|
/** ${column.remark} */
|
||||||
|
</#if>
|
||||||
|
<#if column.columnKey = 'PRI'>
|
||||||
|
<#if !auto && pkColumnType = 'Long'>
|
||||||
|
/** 防止精度丢失 */
|
||||||
|
@JSONField(serializeUsing = ToStringSerializer.class)
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
@ -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 ${package}.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
|
import javax.persistence.*;
|
||||||
|
<#if isNotNullColumns??>
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
</#if>
|
||||||
|
<#if hasDateAnnotation>
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import org.hibernate.annotations.*;
|
||||||
|
</#if>
|
||||||
|
<#if hasTimestamp>
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
</#if>
|
||||||
|
<#if hasBigDecimal>
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
</#if>
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description /
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@Table(name="${tableName}")
|
||||||
|
public class ${className} implements Serializable {
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
|
||||||
|
<#if column.columnKey = 'PRI'>
|
||||||
|
@Id
|
||||||
|
<#if auto>
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
@Column(name = "`${column.columnName}`"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.istNotNull && column.columnKey != 'PRI'>,nullable = false</#if>)
|
||||||
|
<#if column.istNotNull && column.columnKey != 'PRI'>
|
||||||
|
<#if column.columnType = 'String'>
|
||||||
|
@NotBlank
|
||||||
|
<#else>
|
||||||
|
@NotNull
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#if (column.dateAnnotation)?? && column.dateAnnotation != ''>
|
||||||
|
<#if column.dateAnnotation = 'CreationTimestamp'>
|
||||||
|
@CreationTimestamp
|
||||||
|
<#else>
|
||||||
|
@UpdateTimestamp
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
<#if column.remark != ''>
|
||||||
|
@ApiModelProperty(value = "${column.remark}")
|
||||||
|
<#else>
|
||||||
|
@ApiModelProperty(value = "${column.changeColumnName}")
|
||||||
|
</#if>
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
public void copy(${className} source){
|
||||||
|
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 ${package}.service.mapstruct;
|
||||||
|
|
||||||
|
import me.zhengjie.base.BaseMapper;
|
||||||
|
import ${package}.domain.${className};
|
||||||
|
import ${package}.service.dto.${className}Dto;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface ${className}Mapper extends BaseMapper<${className}Dto, ${className}> {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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 ${package}.service.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
<#if queryHasTimestamp>
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
</#if>
|
||||||
|
<#if queryHasBigDecimal>
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
</#if>
|
||||||
|
<#if betweens??>
|
||||||
|
import java.util.List;
|
||||||
|
</#if>
|
||||||
|
<#if queryColumns??>
|
||||||
|
import me.zhengjie.annotation.Query;
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class ${className}QueryCriteria{
|
||||||
|
<#if queryColumns??>
|
||||||
|
<#list queryColumns as column>
|
||||||
|
|
||||||
|
<#if column.queryType = '='>
|
||||||
|
/** 精确 */
|
||||||
|
@Query
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
<#if column.queryType = 'Like'>
|
||||||
|
/** 模糊 */
|
||||||
|
@Query(type = Query.Type.INNER_LIKE)
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
<#if column.queryType = '!='>
|
||||||
|
/** 不等于 */
|
||||||
|
@Query(type = Query.Type.NOT_EQUAL)
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
<#if column.queryType = 'NotNull'>
|
||||||
|
/** 不为空 */
|
||||||
|
@Query(type = Query.Type.NOT_NULL)
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
<#if column.queryType = '>='>
|
||||||
|
/** 大于等于 */
|
||||||
|
@Query(type = Query.Type.GREATER_THAN)
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
<#if column.queryType = '<='>
|
||||||
|
/** 小于等于 */
|
||||||
|
@Query(type = Query.Type.LESS_THAN)
|
||||||
|
private ${column.columnType} ${column.changeColumnName};
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<#if betweens??>
|
||||||
|
<#list betweens as column>
|
||||||
|
/** BETWEEN */
|
||||||
|
@Query(type = Query.Type.BETWEEN)
|
||||||
|
private List<${column.columnType}> ${column.changeColumnName};
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
@ -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 ${package}.repository;
|
||||||
|
|
||||||
|
import ${package}.domain.${className};
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
public interface ${className}Repository extends JpaRepository<${className}, ${pkColumnType}>, JpaSpecificationExecutor<${className}> {
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
<#if column.columnKey = 'UNI'>
|
||||||
|
/**
|
||||||
|
* 根据 ${column.capitalColumnName} 查询
|
||||||
|
* @param ${column.columnName} /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
${className} findBy${column.capitalColumnName}(${column.columnType} ${column.columnName});
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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 ${package}.service;
|
||||||
|
|
||||||
|
import ${package}.domain.${className};
|
||||||
|
import ${package}.service.dto.${className}Dto;
|
||||||
|
import ${package}.service.dto.${className}QueryCriteria;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.List;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description 服务接口
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
public interface ${className}Service {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据分页
|
||||||
|
* @param criteria 条件
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @return Map<String,Object>
|
||||||
|
*/
|
||||||
|
PageResult<${className}Dto> queryAll(${className}QueryCriteria criteria, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有数据不分页
|
||||||
|
* @param criteria 条件参数
|
||||||
|
* @return List<${className}Dto>
|
||||||
|
*/
|
||||||
|
List<${className}Dto> queryAll(${className}QueryCriteria criteria);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询
|
||||||
|
* @param ${pkChangeColName} ID
|
||||||
|
* @return ${className}Dto
|
||||||
|
*/
|
||||||
|
${className}Dto findById(${pkColumnType} ${pkChangeColName});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建
|
||||||
|
* @param resources /
|
||||||
|
*/
|
||||||
|
void create(${className} resources);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
* @param resources /
|
||||||
|
*/
|
||||||
|
void update(${className} resources);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多选删除
|
||||||
|
* @param ids /
|
||||||
|
*/
|
||||||
|
void deleteAll(${pkColumnType}[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出数据
|
||||||
|
* @param all 待导出的数据
|
||||||
|
* @param response /
|
||||||
|
* @throws IOException /
|
||||||
|
*/
|
||||||
|
void download(List<${className}Dto> all, HttpServletResponse response) throws IOException;
|
||||||
|
}
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* 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 ${package}.service.impl;
|
||||||
|
|
||||||
|
import ${package}.domain.${className};
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
<#if column.columnKey = 'UNI'>
|
||||||
|
<#if column_index = 1>
|
||||||
|
import me.zhengjie.exception.EntityExistException;
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
import me.zhengjie.utils.ValidationUtil;
|
||||||
|
import me.zhengjie.utils.FileUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import ${package}.repository.${className}Repository;
|
||||||
|
import ${package}.service.${className}Service;
|
||||||
|
import ${package}.service.dto.${className}Dto;
|
||||||
|
import ${package}.service.dto.${className}QueryCriteria;
|
||||||
|
import ${package}.service.mapstruct.${className}Mapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
<#if !auto && pkColumnType = 'Long'>
|
||||||
|
import cn.hutool.core.lang.Snowflake;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
</#if>
|
||||||
|
<#if !auto && pkColumnType = 'String'>
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
</#if>
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import me.zhengjie.utils.PageUtil;
|
||||||
|
import me.zhengjie.utils.QueryHelp;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @website https://eladmin.vip
|
||||||
|
* @description 服务实现
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${date}
|
||||||
|
**/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ${className}ServiceImpl implements ${className}Service {
|
||||||
|
|
||||||
|
private final ${className}Repository ${changeClassName}Repository;
|
||||||
|
private final ${className}Mapper ${changeClassName}Mapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<${className}Dto> queryAll(${className}QueryCriteria criteria, Pageable pageable){
|
||||||
|
Page<${className}> page = ${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
||||||
|
return PageUtil.toPage(page.map(${changeClassName}Mapper::toDto));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<${className}Dto> queryAll(${className}QueryCriteria criteria){
|
||||||
|
return ${changeClassName}Mapper.toDto(${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public ${className}Dto findById(${pkColumnType} ${pkChangeColName}) {
|
||||||
|
${className} ${changeClassName} = ${changeClassName}Repository.findById(${pkChangeColName}).orElseGet(${className}::new);
|
||||||
|
ValidationUtil.isNull(${changeClassName}.get${pkCapitalColName}(),"${className}","${pkChangeColName}",${pkChangeColName});
|
||||||
|
return ${changeClassName}Mapper.toDto(${changeClassName});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void create(${className} resources) {
|
||||||
|
<#if !auto && pkColumnType = 'Long'>
|
||||||
|
Snowflake snowflake = IdUtil.createSnowflake(1, 1);
|
||||||
|
resources.set${pkCapitalColName}(snowflake.nextId());
|
||||||
|
</#if>
|
||||||
|
<#if !auto && pkColumnType = 'String'>
|
||||||
|
resources.set${pkCapitalColName}(IdUtil.simpleUUID());
|
||||||
|
</#if>
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
<#if column.columnKey = 'UNI'>
|
||||||
|
if(${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()) != null){
|
||||||
|
throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
${changeClassName}Repository.save(resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void update(${className} resources) {
|
||||||
|
${className} ${changeClassName} = ${changeClassName}Repository.findById(resources.get${pkCapitalColName}()).orElseGet(${className}::new);
|
||||||
|
ValidationUtil.isNull( ${changeClassName}.get${pkCapitalColName}(),"${className}","id",resources.get${pkCapitalColName}());
|
||||||
|
<#if columns??>
|
||||||
|
<#list columns as column>
|
||||||
|
<#if column.columnKey = 'UNI'>
|
||||||
|
<#if column_index = 1>
|
||||||
|
${className} ${changeClassName}1 = null;
|
||||||
|
</#if>
|
||||||
|
${changeClassName}1 = ${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}());
|
||||||
|
if(${changeClassName}1 != null && !${changeClassName}1.get${pkCapitalColName}().equals(${changeClassName}.get${pkCapitalColName}())){
|
||||||
|
throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
${changeClassName}.copy(resources);
|
||||||
|
${changeClassName}Repository.save(${changeClassName});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAll(${pkColumnType}[] ids) {
|
||||||
|
for (${pkColumnType} ${pkChangeColName} : ids) {
|
||||||
|
${changeClassName}Repository.deleteById(${pkChangeColName});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(List<${className}Dto> all, HttpServletResponse response) throws IOException {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
for (${className}Dto ${changeClassName} : all) {
|
||||||
|
Map<String,Object> map = new LinkedHashMap<>();
|
||||||
|
<#list columns as column>
|
||||||
|
<#if column.columnKey != 'PRI'>
|
||||||
|
<#if column.remark != ''>
|
||||||
|
map.put("${column.remark}", ${changeClassName}.get${column.capitalColumnName}());
|
||||||
|
<#else>
|
||||||
|
map.put(" ${column.changeColumnName}", ${changeClassName}.get${column.capitalColumnName}());
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
FileUtil.downloadExcel(list, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function add(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/${changeClassName}',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids) {
|
||||||
|
return request({
|
||||||
|
url: 'api/${changeClassName}/',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function edit(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/${changeClassName}',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { add, edit, del }
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>eladmin</artifactId>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>eladmin-logging</artifactId>
|
||||||
|
<name>日志模块</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<artifactId>eladmin-common</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -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 me.zhengjie.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Log {
|
||||||
|
String value() default "";
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.aspect;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
import me.zhengjie.service.SysLogService;
|
||||||
|
import me.zhengjie.utils.RequestHolder;
|
||||||
|
import me.zhengjie.utils.SecurityUtils;
|
||||||
|
import me.zhengjie.utils.StringUtils;
|
||||||
|
import me.zhengjie.utils.ThrowableUtil;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Aspect
|
||||||
|
@Slf4j
|
||||||
|
public class LogAspect {
|
||||||
|
|
||||||
|
private final SysLogService sysLogService;
|
||||||
|
|
||||||
|
ThreadLocal<Long> currentTime = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public LogAspect(SysLogService sysLogService) {
|
||||||
|
this.sysLogService = sysLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置切入点
|
||||||
|
*/
|
||||||
|
@Pointcut("@annotation(me.zhengjie.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();
|
||||||
|
SysLog sysLog = new SysLog("INFO",System.currentTimeMillis() - currentTime.get());
|
||||||
|
currentTime.remove();
|
||||||
|
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||||
|
sysLogService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request),joinPoint, sysLog);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置异常通知
|
||||||
|
*
|
||||||
|
* @param joinPoint join point for advice
|
||||||
|
* @param e exception
|
||||||
|
*/
|
||||||
|
@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
|
||||||
|
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
|
||||||
|
SysLog sysLog = new SysLog("ERROR",System.currentTimeMillis() - currentTime.get());
|
||||||
|
currentTime.remove();
|
||||||
|
sysLog.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes());
|
||||||
|
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||||
|
sysLogService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, sysLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
try {
|
||||||
|
return SecurityUtils.getCurrentUsername();
|
||||||
|
}catch (Exception e){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table(name = "sys_log")
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SysLog 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 SysLog(String logType, Long time) {
|
||||||
|
this.logType = logType;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.repository;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface LogRepository extends JpaRepository<SysLog,Long>, JpaSpecificationExecutor<SysLog> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据日志类型删除信息
|
||||||
|
* @param logType 日志类型
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Query(value = "delete from sys_log where log_type = ?1", nativeQuery = true)
|
||||||
|
void deleteByLogType(String logType);
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.rest;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.annotation.Log;
|
||||||
|
import me.zhengjie.service.SysLogService;
|
||||||
|
import me.zhengjie.service.dto.SysLogQueryCriteria;
|
||||||
|
import me.zhengjie.service.dto.SysLogSmallDto;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
import me.zhengjie.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.web.bind.annotation.*;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/logs")
|
||||||
|
@Api(tags = "系统:日志管理")
|
||||||
|
public class SysLogController {
|
||||||
|
|
||||||
|
private final SysLogService sysLogService;
|
||||||
|
|
||||||
|
@Log("导出数据")
|
||||||
|
@ApiOperation("导出数据")
|
||||||
|
@GetMapping(value = "/download")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public void exportLog(HttpServletResponse response, SysLogQueryCriteria criteria) throws IOException {
|
||||||
|
criteria.setLogType("INFO");
|
||||||
|
sysLogService.download(sysLogService.queryAll(criteria), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log("导出错误数据")
|
||||||
|
@ApiOperation("导出错误数据")
|
||||||
|
@GetMapping(value = "/error/download")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public void exportErrorLog(HttpServletResponse response, SysLogQueryCriteria criteria) throws IOException {
|
||||||
|
criteria.setLogType("ERROR");
|
||||||
|
sysLogService.download(sysLogService.queryAll(criteria), response);
|
||||||
|
}
|
||||||
|
@GetMapping
|
||||||
|
@ApiOperation("日志查询")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public ResponseEntity<Object> queryLog(SysLogQueryCriteria criteria, Pageable pageable){
|
||||||
|
criteria.setLogType("INFO");
|
||||||
|
return new ResponseEntity<>(sysLogService.queryAll(criteria,pageable), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/user")
|
||||||
|
@ApiOperation("用户日志查询")
|
||||||
|
public ResponseEntity<PageResult<SysLogSmallDto>> queryUserLog(SysLogQueryCriteria criteria, Pageable pageable){
|
||||||
|
criteria.setLogType("INFO");
|
||||||
|
criteria.setUsername(SecurityUtils.getCurrentUsername());
|
||||||
|
return new ResponseEntity<>(sysLogService.queryAllByUser(criteria,pageable), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/error")
|
||||||
|
@ApiOperation("错误日志查询")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public ResponseEntity<Object> queryErrorLog(SysLogQueryCriteria criteria, Pageable pageable){
|
||||||
|
criteria.setLogType("ERROR");
|
||||||
|
return new ResponseEntity<>(sysLogService.queryAll(criteria,pageable), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/error/{id}")
|
||||||
|
@ApiOperation("日志异常详情查询")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public ResponseEntity<Object> queryErrorLogDetail(@PathVariable Long id){
|
||||||
|
return new ResponseEntity<>(sysLogService.findByErrDetail(id), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
@DeleteMapping(value = "/del/error")
|
||||||
|
@Log("删除所有ERROR日志")
|
||||||
|
@ApiOperation("删除所有ERROR日志")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public ResponseEntity<Object> delAllErrorLog(){
|
||||||
|
sysLogService.delAllByError();
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping(value = "/del/info")
|
||||||
|
@Log("删除所有INFO日志")
|
||||||
|
@ApiOperation("删除所有INFO日志")
|
||||||
|
@PreAuthorize("@el.check()")
|
||||||
|
public ResponseEntity<Object> delAllInfoLog(){
|
||||||
|
sysLogService.delAllByInfo();
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service;
|
||||||
|
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
import me.zhengjie.service.dto.SysLogQueryCriteria;
|
||||||
|
import me.zhengjie.service.dto.SysLogSmallDto;
|
||||||
|
import me.zhengjie.utils.PageResult;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
public interface SysLogService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param criteria 查询条件
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
Object queryAll(SysLogQueryCriteria criteria, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询全部数据
|
||||||
|
* @param criteria 查询条件
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
List<SysLog> queryAll(SysLogQueryCriteria criteria);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户日志
|
||||||
|
* @param criteria 查询条件
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @return -
|
||||||
|
*/
|
||||||
|
PageResult<SysLogSmallDto> queryAllByUser(SysLogQueryCriteria criteria, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存日志数据
|
||||||
|
* @param username 用户
|
||||||
|
* @param browser 浏览器
|
||||||
|
* @param ip 请求IP
|
||||||
|
* @param joinPoint /
|
||||||
|
* @param sysLog 日志实体
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, SysLog sysLog);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询异常详情
|
||||||
|
* @param id 日志ID
|
||||||
|
* @return Object
|
||||||
|
*/
|
||||||
|
Object findByErrDetail(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出日志
|
||||||
|
* @param sysLogs 待导出的数据
|
||||||
|
* @param response /
|
||||||
|
* @throws IOException /
|
||||||
|
*/
|
||||||
|
void download(List<SysLog> sysLogs, HttpServletResponse response) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除所有错误日志
|
||||||
|
*/
|
||||||
|
void delAllByError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除所有INFO日志
|
||||||
|
*/
|
||||||
|
void delAllByInfo();
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-5-22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysLogErrorDto 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;
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhengjie.annotation.Query;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志查询类
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-6-4 09:23:07
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysLogQueryCriteria {
|
||||||
|
|
||||||
|
@Query(blurry = "username,description,address,requestIp,method,params")
|
||||||
|
private String blurry;
|
||||||
|
|
||||||
|
@Query
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Query
|
||||||
|
private String logType;
|
||||||
|
|
||||||
|
@Query(type = Query.Type.BETWEEN)
|
||||||
|
private List<Timestamp> createTime;
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-5-22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysLogSmallDto implements Serializable {
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String requestIp;
|
||||||
|
|
||||||
|
private Long time;
|
||||||
|
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
private String browser;
|
||||||
|
|
||||||
|
private Timestamp createTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
import me.zhengjie.repository.LogRepository;
|
||||||
|
import me.zhengjie.service.SysLogService;
|
||||||
|
import me.zhengjie.service.dto.SysLogQueryCriteria;
|
||||||
|
import me.zhengjie.service.dto.SysLogSmallDto;
|
||||||
|
import me.zhengjie.service.mapstruct.LogErrorMapper;
|
||||||
|
import me.zhengjie.service.mapstruct.LogSmallMapper;
|
||||||
|
import me.zhengjie.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.jdbc.core.JdbcTemplate;
|
||||||
|
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 org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SysLogServiceImpl implements SysLogService {
|
||||||
|
|
||||||
|
// @Resource
|
||||||
|
// private JdbcTemplate jdbcTemplateSecond;
|
||||||
|
|
||||||
|
private final LogRepository logRepository;
|
||||||
|
private final LogErrorMapper logErrorMapper;
|
||||||
|
private final LogSmallMapper logSmallMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object queryAll(SysLogQueryCriteria criteria, Pageable pageable) {
|
||||||
|
Page<SysLog> 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 PageUtil.toPage(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SysLog> queryAll(SysLogQueryCriteria criteria) {
|
||||||
|
return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<SysLogSmallDto> queryAllByUser(SysLogQueryCriteria criteria, Pageable pageable) {
|
||||||
|
Page<SysLog> 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, SysLog sysLog) {
|
||||||
|
if (sysLog == null) {
|
||||||
|
throw new IllegalArgumentException("Log 不能为 null!");
|
||||||
|
}
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class);
|
||||||
|
|
||||||
|
// 方法路径
|
||||||
|
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||||
|
|
||||||
|
// 描述
|
||||||
|
sysLog.setDescription(aopLog.value());
|
||||||
|
|
||||||
|
sysLog.setRequestIp(ip);
|
||||||
|
sysLog.setAddress(StringUtils.getCityInfo(sysLog.getRequestIp()));
|
||||||
|
sysLog.setMethod(methodName);
|
||||||
|
sysLog.setUsername(username);
|
||||||
|
sysLog.setParams(getParameter(method, joinPoint.getArgs()));
|
||||||
|
// 记录登录用户,隐藏密码信息
|
||||||
|
if (signature.getName().equals("login") && StringUtils.isNotEmpty(sysLog.getParams())) {
|
||||||
|
JSONObject obj = JSON.parseObject(sysLog.getParams());
|
||||||
|
sysLog.setUsername(obj.getString("username"));
|
||||||
|
sysLog.setParams(JSON.toJSONString(Dict.create().set("username", sysLog.getUsername())));
|
||||||
|
}
|
||||||
|
sysLog.setBrowser(browser);
|
||||||
|
logRepository.save(sysLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据方法和传入的参数获取请求参数
|
||||||
|
*/
|
||||||
|
private String getParameter(Method method, Object[] args) {
|
||||||
|
List<Object> argList = new ArrayList<>();
|
||||||
|
Parameter[] parameters = method.getParameters();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
// 过滤掉不能序列化的类型: MultiPartFile
|
||||||
|
if (args[i] instanceof MultipartFile) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 将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<String, Object> map = new HashMap<>(2);
|
||||||
|
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 ? JSON.toJSONString(argList.get(0)) : JSON.toJSONString(argList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object findByErrDetail(Long id) {
|
||||||
|
SysLog sysLog = logRepository.findById(id).orElseGet(SysLog::new);
|
||||||
|
ValidationUtil.isNull(sysLog.getId(), "Log", "id", id);
|
||||||
|
byte[] details = sysLog.getExceptionDetail();
|
||||||
|
return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(List<SysLog> sysLogs, HttpServletResponse response) throws IOException {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
for (SysLog sysLog : sysLogs) {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
map.put("用户名", sysLog.getUsername());
|
||||||
|
map.put("IP", sysLog.getRequestIp());
|
||||||
|
map.put("IP来源", sysLog.getAddress());
|
||||||
|
map.put("描述", sysLog.getDescription());
|
||||||
|
map.put("浏览器", sysLog.getBrowser());
|
||||||
|
map.put("请求耗时/毫秒", sysLog.getTime());
|
||||||
|
map.put("异常详情", new String(
|
||||||
|
ObjectUtil.isNotNull(sysLog.getExceptionDetail()) ? sysLog.getExceptionDetail() : "".getBytes()));
|
||||||
|
map.put("创建日期", sysLog.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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service.mapstruct;
|
||||||
|
|
||||||
|
import me.zhengjie.base.BaseMapper;
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
import me.zhengjie.service.dto.SysLogErrorDto;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-5-22
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface LogErrorMapper extends BaseMapper<SysLogErrorDto, SysLog> {
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.service.mapstruct;
|
||||||
|
|
||||||
|
import me.zhengjie.base.BaseMapper;
|
||||||
|
import me.zhengjie.domain.SysLog;
|
||||||
|
import me.zhengjie.service.dto.SysLogSmallDto;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2019-5-22
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface LogSmallMapper extends BaseMapper<SysLogSmallDto, SysLog> {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>eladmin</artifactId>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>eladmin-system</artifactId>
|
||||||
|
<name>核心模块</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jjwt.version>0.11.5</jjwt.version>
|
||||||
|
<!-- oshi监控需要指定jna版本, 问题详见 https://github.com/oshi/oshi/issues/1040 -->
|
||||||
|
<jna.version>5.8.0</jna.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- 代码生成模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<artifactId>eladmin-generator</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<artifactId>eladmin-common</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- tools 模块包含了 common 和 logging 模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.zhengjie</groupId>
|
||||||
|
<artifactId>eladmin-tools</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring boot websocket -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- jwt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- quartz -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.quartz-scheduler</groupId>
|
||||||
|
<artifactId>quartz</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- linux的管理 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.ethz.ganymed</groupId>
|
||||||
|
<artifactId>ganymed-ssh2</artifactId>
|
||||||
|
<version>build210</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jcraft</groupId>
|
||||||
|
<artifactId>jsch</artifactId>
|
||||||
|
<version>0.1.55</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 获取系统信息 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.oshi</groupId>
|
||||||
|
<artifactId>oshi-core</artifactId>
|
||||||
|
<version>6.1.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- 打包 -->
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<!-- 跳过单元测试 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skipTests>true</skipTests>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -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 me.zhengjie.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
|
||||||
|
*
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 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.addAllowedOriginPattern("*");
|
||||||
|
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<HttpMessageConverter<?>> converters) {
|
||||||
|
// 使用 fastjson 序列化,会导致 @JsonIgnore 失效,可以使用 @JSONField(serialize = false) 替换
|
||||||
|
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
|
||||||
|
List<MediaType> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2023 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 me.zhengjie.config;
|
||||||
|
|
||||||
|
import org.apache.catalina.connector.Connector;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bearBoy80
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
public class RelaxedQueryCharsConnectorCustomizer implements TomcatConnectorCustomizer {
|
||||||
|
@Override
|
||||||
|
public void customize(Connector connector) {
|
||||||
|
connector.setProperty("relaxedQueryChars", "[]{}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 me.zhengjie.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ZhangHouYing
|
||||||
|
* @date 2019-08-24 15:44
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WebSocketConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServerEndpointExporter serverEndpointExporter() {
|
||||||
|
return new ServerEndpointExporter();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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 me.zhengjie.config.thread;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池配置属性类
|
||||||
|
* @author https://juejin.im/entry/5abb8f6951882555677e9da2
|
||||||
|
* @date 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue