update version to 2.0

更新版本到2.0
使用最新springboot 2.1.3 RELEASE版本及其他库升级到最新版本
大量重构了代码,减少一些第三方依赖。
This commit is contained in:
czx
2019-04-22 22:12:11 +08:00
parent 3f75db2be3
commit 0eb7c1ec06
344 changed files with 3325 additions and 9725 deletions

674
LICENSE
View File

@@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/]
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {fullname}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see [http://www.gnu.org/licenses/].
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
x_springboot Copyright (C) 2017 suke czx
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
[http://www.gnu.org/licenses/].
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
[http://www.gnu.org/philosophy/why-not-lgpl.html].

207
README.md
View File

@@ -1,180 +1,123 @@
**目前版本更新到V2.0**
**项目说明** **项目说明**
- X-SpringBoot 是一个轻量级的Java快速开发平台基于各大开源项目组合而来用于快速构建中小型API、RESTful API项目该项目已经有过多个真实项目的实践稳定、简单、快速使我们摆脱那些重复劳动。 - X-SpringBoot 是一个轻量级的Java快速开发平台基于各大开源项目组合而来用于快速构建中小型API、RESTful API项目该项目已经有过多个真实项目的实践稳定、简单、快速使我们摆脱那些重复劳动。
- 本项目已大量重构,精简了大量代码减少第三方依赖,最干净的脚手架。
- 专为X-SpringBoot 量身定制《接口》代码生成工具https://github.com/yzcheng90/x_springboot-inteface-generatorper - 引入了lombok 大量简化了代码
- 引入了MyBatis Plus 大量简化了SQL
- 专为X-SpringBoot 量身定制《后台管理》代码生成工具https://github.com/yzcheng90/x_springboot-generator - 引入hutool 工具包 规范工具类
- 引入minio 分布式文件系统
- 专为X-SpringBoot 量身定制《安卓快速开发框架》https://github.com/yzcheng90/x-android - 前后端完全脱离,前端代码可单独部署
- 支持密码和手机号 获取token
- 专为x-android 量身定制代码生成工具 https://github.com/yzcheng90/x-android-generator (生成出来可能包名有问题。改改也能用 - 账号密码admin/admin
<br>
**版本信息**
- 核心框架Spring Boot 2.1.3
- 安全框架Apache Shiro 1.4
- 视图框架Spring MVC 5.1
- 持久层框架MyBatis Plus 3.1.0
- 日志管理SLF4J 1.7、Log4j
- 页面交互Vue2.x
**环境**
- jdk 1.8
- mysql 5.7
- redis
- nginx
**具有如下特点**
- 友好的代码结构及注释,便于阅读及二次开发
- 实现前后端分离通过token进行数据交互前端再也不用关注后端技术
- 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求
- 页面交互使用Vue2.x极大的提高了开发效率
- 统一异常处理
- 使用Druid Spring Boot Starter 集成Druid数据库连接池与监控
- 完善的代码生成机制可在线生成entity、xml、dao、service、html、js、sql代码减少70%以上的开发任务
- 引入quartz定时任务可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能
- 引入API模板根据token作为登录令牌极大的方便了APP接口开发
- 引入快速API代码生成,减少90%以上的开发任务复杂逻辑只须要修改mapper.xml一个模块只须几分钟
- 引入接口数据加密传输
- 引入Hibernate Validator校验框架轻松实现后端校验
- 引入云存储服务,已支持:七牛云、阿里云、腾讯云等
- 引入swagger文档支持方便编写API接口文档
- 引入路由机制,刷新页面会停留在当前页
<br>
**项目结构** **项目结构**
``` ```
X-SpringBoot X-SpringBoot
├─doc 项目SQL语句 ├─doc 项目SQL语句
├─authentication 权限认证
├─common 公共模块 ├─common 公共模块
│ ├─annotation 自定义注解
│ ├─aspect 系统日志 │ ├─aspect 系统日志
│ ├─base base包
│ ├─exception 异常处理 │ ├─exception 异常处理
│ ├─utils 一些工具类
│ ├─validator 后台校验 │ ├─validator 后台校验
│ └─xss XSS过滤 │ └─xss XSS过滤
├─config 配置信息 ├─config 配置信息
├─interceptor token拦截器
├─modules 功能模块 ├─modules 功能模块
│ ├─app API接口模块(APP调用) │ ├─app API接口模块(APP调用)
│ ├─job 定时任务模块
│ ├─oss 文件服务模块 │ ├─oss 文件服务模块
│ └─sys 权限模块 │ └─sys 权限模块
├─Application 项目启动类 ├─Application 项目启动类
├─Swagger2 swagger2类
├──resources ├──resources
│ ├─mapper SQL对应的XML文件 │ ├─mapper SQL对应的XML文件
│ ├─static 第三方库、插件等静态资源
│ └─views 项目静态页面
```
<br>
**技术选型:**
- 核心框架Spring Boot 1.5
- 安全框架Apache Shiro 1.3
- 视图框架Spring MVC 4.3
- 持久层框架MyBatis 3.3
- 定时器Quartz 2.3
- 数据库连接池Druid 1.0
- 日志管理SLF4J 1.7、Log4j
- 页面交互Vue2.x
<br>
![image](https://github.com/yzcheng90/X-SpringBoot/blob/master/pic/AppBaseResult_img.png)
<br>
<h3>统一接口请求和返回工具类 <a href="https://github.com/yzcheng90/X-SpringBoot/blob/master/src/main/java/com/suke/czx/common/utils/AppBaseResult.java">AppBaseResult.java</a></h3>
<br>
<h3>数据返回加解密工具类 <a href="https://github.com/yzcheng90/X-SpringBoot/blob/master/src/main/java/com/suke/czx/common/utils/CDESCrypt.java">CDESCrypt.java</a></h3>
---
> 接口controller类示例
>
```javascript
@ApiOperation(value="列表", notes="列表") //swagger2的接口显示
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/list")
public AppBaseResult list(@RequestBody AppBaseResult appBaseResult)throws Exception{ //使用AppBaseResult类接口转过来的封装参数
logger.info("AppUpdateController 列表",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class); //解密后反序列化为MAP
//查询列表数据
Query query = new Query(params);
query.isPaging(true); //开启拦截器分页不需要多写一条SQL去查询条数
List<HashMap<String,Object>> appUpdateList = appUpdateService.queryList(query);
PageUtils pageUtil = new PageUtils(appUpdateList, query.getTotle(), query.getLimit(), query.getPage());
return AppBaseResult.success().setEncryptData(pageUtil); //数据加密返回
}
``` ```
--- **部署**
>接口数据『未加密』返回 - 后台部署
> ```
```javascript 1、 $git clong https://github.com/yzcheng90/X-SpringBoot.git
{ 2 、IDEA 打开项目引入依赖
"code": 200,
"message": "请求成功",
"data": "[{\"id\":\"20171130104836867615\",\"name\":\"吕经理\",\"phone\":\"13888888888\",\"car\":\"湘A12345\",\"address\":\"A栋\",\"tplanarrivaltime\":\"2017-11-30 10:45:46\",\"sintervieweename\":\"张小曼\",\"iintervieweephone\":\"15625448521\",\"tcreatetime\":\"2017-11-30 10:48:36\",\"suserid\":\"test01\",\"susername\":\"章涛宁\",\"svisitorintend\":\"\",\"tplanleavetime\":\"2017-12-21 09:49:09\",\"saccessibleid\":\"20171221949935675\",\"tentertime\":\"2017-12-21 09:49:09\"}]",
"version": "1.0",
"mobile": ""
}
3、 创建数据库x_springboot数据库编码为UTF-8执行doc/db.sql文件初始化数据
4、 IDEA运行Application.java则可启动项目 http://localhost:8080
```
- 前台部署
```
1、 打开nginx 目录 /conf/nginx.conf
2、 在server中修改 root 和 index
...
server {
....
#静态页面目录
root E:\github\X-SpringBoot\x-springboot-ui;
#默认首页
index login.html;
....
location ^~// {
proxy_pass http://127.0.0.1:8080; #这里为后台服务地址
}
}
...
3、启动nginx 访问 localhost
```
**常见问题**
1、启动报错
``` ```
--- 是因为依赖没有引入 maven --> reimport 重新引入
>接口数据『加密』返回
>
```javascript
{
"code": 200,
"message": "请求成功",
"data": "BJ5EH8YbByGQ8ZyxAB8WEWUlj1rpZbvOSVzScAPyKk5B8WMw8NhjfrZeLROzgsM/ag2RJr33B9ZfS5xEJd5ORHig/NLmIAt2LcElMuUA1FwIPn3BOJu4CAohwtZEX4rSYRGSVv5LEpyXJNTqlZ/R5OeDTyTYdE9aAD1D3++LmspFq7Us8r33+6rc6PkTqnHGBI6rSCL1yugP0mdMIRPgrguMknbE9TloDPP1AuncomTYiRs4jfwv6kRVk9uWbSgFjjGFChGwtyHnVrSttxRNi0o9YS51NwoL2ZK8/0kNlnHxHImwWLq2394sOf9Jy4X0XcUdjuJalSPyRMxyHhglWmFwMYnIEc3dOYdB/snMc0ESXdXvzyxlpT/IwB5T4QdcmBmQIsMyEIr2ZKDR6fO/KUH+QvQJT2oSYNz+0gr4IqgBYzhIOPmE/f0tzhI/fHyMNOoH+2WRxL4gYgi3nzYZBudK8Hb0U/ddGc8gasreTWnW2Z3BrO2T9uK+0LWdR9Uq/6QccqlPmUJlMdRuaVyKcPz65LQn/f9qlASnKNbkVK+LmJi/JeP5lkBdK089l9vRX3y5YRWwuGrfJcc9VjvSp89vNhTAFtnEN9ChqG2iuiJgUhsEZtFluDoeycC8eBoncFpWXK4cnD2BZZIJPowEOs37u8HvHPOjaeqkctU1OVA=",
"version": "1.0",
"mobile": ""
}
``` ```
2、验证码失败
--- ```
>系统示例图 是因为redis 没有启动
```
![image](https://github.com/yzcheng90/X-SpringBoot/blob/master/pic/20180108172123_1.png) 3、数据库连接不上mysql 5.7
![image](https://github.com/yzcheng90/X-SpringBoot/blob/master/pic/20180108172123_2.png)
![image](https://github.com/yzcheng90/X-SpringBoot/blob/master/pic/20180108172123_3.png)
*** 常见问题 ***
1、 数据库连接不上mysql 5.7
``` ```
1) 看看application.yml 配置文件中 spring.profiles.active: dev 1) 看看application.yml 配置文件中 spring.profiles.active: dev
当前配置的是dev ,就修改application-dev.yml 中的数据库连接IP用户密码 当前配置的是dev ,就修改application-dev.yml 中的数据库连接IP用户密码
2) 如果改完了还是不行看看你mysql版本8.0以上 须要修改pom.xml中的 mysql-connector-java 的版本 2) 如果改完了还是不行看看你mysql版本8.0以上 须要修改pom.xml中的 mysql-connector-java 的版本
```
2、 加解密问题
```
1) Demo中 Contorller请求响应参数类 AppBaseResult 是对请求和响应的参数进行加密处理,
如果不须要可以在该类中的 decryptData 、decryptData、setEncryptData 这三个方法中加解密的地方注释
2Demo中的加解密算法目前只有java 版本没有其他语言版 可以自行替换其他多语言算法
3如果须要用到swagger API 须要把 1)中的三个方法中加解密的地方注释。swagger API 中参数传值。
第一层为json格式 参数须要传成json然后toString 放到 data 字段中
如下:
{
"code": 200,
"message": "请求成功",
"data": "{\"id\":\"20171130104836867615\",\"name\":\"吕经理\"}",
"version": "1.0",
"mobile": ""
}
``` ```
**本地部署** **最后**
- 下载源码
- 创建数据库x_springboot数据库编码为UTF-8
- 执行doc/db.sql文件初始化数据
- 修改application-test.yml更新MySQL账号和密码
- Eclipse、IDEA运行Application.java则可启动项目
- 项目访问路径http://localhost:8080/x_springboot
- 账号密码admin/admin
- Swagger路径http://localhost:8080/x_springboot/swagger/index.html
- 交流QQ群17470566 - 交流QQ群17470566
- 本人QQ913624256 - 本人QQ913624256
- 如果喜欢记得star fork 谢谢您的关注 x_springboot会持续维护 - 如果喜欢记得star fork 谢谢您的关注 x_springboot会持续维护

View File

@@ -1,32 +1,260 @@
-- 菜单 /*
Navicat MySQL Data Transfer
Source Server : 192.168.0.201
Source Server Version : 50718
Source Host : 192.168.0.201:3306
Source Database : x_springboot
Target Server Type : MYSQL
Target Server Version : 50718
File Encoding : 65001
Date: 2019-04-22 16:36:27
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for sys_config
-- ----------------------------
DROP TABLE IF EXISTS `sys_config`;
CREATE TABLE `sys_config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`config_key` varchar(50) DEFAULT NULL COMMENT 'key',
`config_value` varchar(2000) DEFAULT NULL COMMENT 'value',
`config_status` tinyint(4) DEFAULT '1' COMMENT '状态 0隐藏 1显示',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`config_key`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='系统配置信息表';
-- ----------------------------
-- Records of sys_config
-- ----------------------------
INSERT INTO `sys_config` VALUES ('1', 'CLOUD_STORAGE_CONFIG_KEY', '{\"type\":1,\"qiniuDomain\":\"http://oss.sukeintel.com.qiniudns.com\",\"qiniuPrefix\":\"upload\",\"qiniuAccessKey\":\"fRCR9phC7SE-V9ZHzYUSjVqB9pKPkgq2soRcSIid\",\"qiniuSecretKey\":\"HvlNtDjrYLhokEGn-idybYVpjM6fKxpW271gd7y1\",\"qiniuBucketName\":\"sukeintel\",\"aliyunDomain\":\"\",\"aliyunPrefix\":\"\",\"aliyunEndPoint\":\"\",\"aliyunAccessKeyId\":\"\",\"aliyunAccessKeySecret\":\"\",\"aliyunBucketName\":\"\",\"qcloudDomain\":\"\",\"qcloudPrefix\":\"\",\"qcloudSecretId\":\"\",\"qcloudSecretKey\":\"\",\"qcloudBucketName\":\"\"}', '0', '云存储配置信息');
INSERT INTO `sys_config` VALUES ('2', 'test', 'test', '1', '测试');
-- ----------------------------
-- Table structure for sys_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL COMMENT '用户名',
`operation` varchar(50) DEFAULT NULL COMMENT '用户操作',
`method` varchar(200) DEFAULT NULL COMMENT '请求方法',
`params` varchar(5000) DEFAULT NULL COMMENT '请求参数',
`time` bigint(20) NOT NULL COMMENT '执行时长(毫秒)',
`ip` varchar(64) DEFAULT NULL COMMENT 'IP地址',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COMMENT='系统日志';
-- ----------------------------
-- Records of sys_log
-- ----------------------------
INSERT INTO `sys_log` VALUES ('1', 'admin', '修改定时任务', 'com.suke.czx.modules.job.controller.ScheduleJobController.update()', '{\"jobId\":1,\"beanName\":\"testTask\",\"methodName\":\"test\",\"params\":\"test\",\"cronExpression\":\"0 0/30 * * * ?\",\"status\":0,\"remark\":\"有参数测试\",\"createTime\":\"Dec 1, 2016 11:16:46 PM\"}', '78', '0:0:0:0:0:0:0:1', '2018-01-08 17:22:23');
INSERT INTO `sys_log` VALUES ('2', 'sk', '用户登录', 'com.suke.czx.modules.sys.controller.SysLoginController.login()', '\"sk\"', '1713', '0:0:0:0:0:0:0:1', '2019-04-18 13:59:11');
INSERT INTO `sys_log` VALUES ('3', 'sk', '用户登录', 'com.suke.czx.modules.sys.controller.SysLoginController.login()', '\"sk\"', '11', '0:0:0:0:0:0:0:1', '2019-04-18 13:59:43');
INSERT INTO `sys_log` VALUES ('4', 'admin', '保存配置', 'com.suke.czx.modules.sys.controller.SysConfigController.save()', '{\"id\":2,\"configKey\":\"test\",\"configValue\":\"test\",\"remark\":\"测试\"}', '65', '0:0:0:0:0:0:0:1', '2019-04-18 15:07:25');
INSERT INTO `sys_log` VALUES ('5', 'admin', '保存菜单', 'com.suke.czx.modules.sys.controller.SysMenuController.save()', '{\"menuId\":31,\"parentId\":0,\"parentName\":\"一级菜单\",\"name\":\"测试\",\"type\":0,\"orderNum\":0}', '8', '0:0:0:0:0:0:0:1', '2019-04-18 15:23:03');
INSERT INTO `sys_log` VALUES ('6', 'admin', '删除菜单', 'com.suke.czx.modules.sys.controller.SysMenuController.delete()', '31', '7', '0:0:0:0:0:0:0:1', '2019-04-18 15:24:26');
INSERT INTO `sys_log` VALUES ('7', 'admin', '删除角色', 'com.suke.czx.modules.sys.controller.SysRoleController.delete()', '[5]', '9', '0:0:0:0:0:0:0:1', '2019-04-18 16:00:11');
INSERT INTO `sys_log` VALUES ('8', 'admin', '保存角色', 'com.suke.czx.modules.sys.controller.SysRoleController.save()', '{\"roleId\":6,\"roleName\":\"测试2\",\"remark\":\"测试2\",\"createUserId\":1,\"menuIdList\":[1,3,19,20,21,22],\"createTime\":\"Apr 18, 2019 4:02:00 PM\"}', '76', '0:0:0:0:0:0:0:1', '2019-04-18 16:02:01');
INSERT INTO `sys_log` VALUES ('9', 'admin', '删除角色', 'com.suke.czx.modules.sys.controller.SysRoleController.delete()', '[6]', '5', '0:0:0:0:0:0:0:1', '2019-04-18 16:02:09');
INSERT INTO `sys_log` VALUES ('10', 'admin', '删除用户', 'com.suke.czx.modules.sys.controller.SysUserController.delete()', '[7]', '8', '0:0:0:0:0:0:0:1', '2019-04-18 16:04:59');
INSERT INTO `sys_log` VALUES ('11', 'admin', '保存用户', 'com.suke.czx.modules.sys.controller.SysUserController.save()', '{\"userId\":8,\"username\":\"sk\",\"password\":\"f84d76f5e13503d2ef9580eb8472615c395ea2010ac582035d86a4bd7d9ac73c\",\"salt\":\"v4rnaIJ4zl29yGhXdjOO\",\"email\":\"sk@sk.com\",\"mobile\":\"12345678963\",\"status\":1,\"createUserId\":1,\"createTime\":\"Apr 18, 2019 4:08:20 PM\",\"roleIdList\":[]}', '66', '0:0:0:0:0:0:0:1', '2019-04-18 16:08:21');
INSERT INTO `sys_log` VALUES ('12', 'admin', '删除用户', 'com.suke.czx.modules.sys.controller.SysUserController.delete()', '[8]', '9', '0:0:0:0:0:0:0:1', '2019-04-18 16:08:25');
INSERT INTO `sys_log` VALUES ('13', 'admin', '保存角色', 'com.suke.czx.modules.sys.controller.SysRoleController.save()', '{\"roleId\":7,\"roleName\":\"1\",\"remark\":\"1\",\"createUserId\":1,\"menuIdList\":[1,2,15,16,17,18],\"createTime\":\"Apr 18, 2019 4:09:08 PM\"}', '23', '0:0:0:0:0:0:0:1', '2019-04-18 16:09:08');
INSERT INTO `sys_log` VALUES ('14', 'admin', '保存角色', 'com.suke.czx.modules.sys.controller.SysRoleController.save()', '{\"roleId\":8,\"roleName\":\"2\",\"remark\":\"2\",\"createUserId\":1,\"menuIdList\":[1,2,15,16,17,18],\"createTime\":\"Apr 18, 2019 4:09:15 PM\"}', '9', '0:0:0:0:0:0:0:1', '2019-04-18 16:09:15');
INSERT INTO `sys_log` VALUES ('15', 'admin', '保存角色', 'com.suke.czx.modules.sys.controller.SysRoleController.save()', '{\"roleId\":9,\"roleName\":\"3\",\"remark\":\"3\",\"createUserId\":1,\"menuIdList\":[1,6,7,8,9,10,11,12,13,14],\"createTime\":\"Apr 18, 2019 4:09:22 PM\"}', '8', '0:0:0:0:0:0:0:1', '2019-04-18 16:09:23');
INSERT INTO `sys_log` VALUES ('16', 'admin', '删除角色', 'com.suke.czx.modules.sys.controller.SysRoleController.delete()', '[7,8,9]', '5', '0:0:0:0:0:0:0:1', '2019-04-18 16:09:29');
INSERT INTO `sys_log` VALUES ('17', 'admin', '保存用户', 'com.suke.czx.modules.sys.controller.SysUserController.save()', '{\"userId\":2,\"username\":\"sk\",\"password\":\"cc523ea48e608b07a8ddc08aa774e07a0dc176bebe86bf528bb79775ea73a26b\",\"salt\":\"rKn3NKzdWEyuIqGaoyiZ\",\"email\":\"sk@sk.com\",\"mobile\":\"18365412365\",\"status\":1,\"createUserId\":1,\"createTime\":\"Apr 22, 2019 11:32:18 AM\",\"roleIdList\":[]}', '76', '0:0:0:0:0:0:0:1', '2019-04-22 11:32:18');
INSERT INTO `sys_log` VALUES ('18', 'admin', '删除用户', 'com.suke.czx.modules.sys.controller.SysUserController.delete()', '[2]', '8', '0:0:0:0:0:0:0:1', '2019-04-22 11:32:23');
-- ----------------------------
-- Table structure for sys_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` ( CREATE TABLE `sys_menu` (
`menu_id` bigint NOT NULL AUTO_INCREMENT, `menu_id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint COMMENT '父菜单ID一级菜单为0', `parent_id` bigint(20) DEFAULT NULL COMMENT '父菜单ID一级菜单为0',
`name` varchar(50) COMMENT '菜单名称', `name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
`url` varchar(200) COMMENT '菜单URL', `url` varchar(200) DEFAULT NULL COMMENT '菜单URL',
`perms` varchar(500) COMMENT '授权(多个用逗号分隔user:list,user:create)', `perms` varchar(500) DEFAULT NULL COMMENT '授权(多个用逗号分隔user:list,user:create)',
`type` int COMMENT '类型 0目录 1菜单 2按钮', `type` int(11) DEFAULT NULL COMMENT '类型 0目录 1菜单 2按钮',
`icon` varchar(50) COMMENT '菜单图标', `icon` varchar(50) DEFAULT NULL COMMENT '菜单图标',
`order_num` int COMMENT '排序', `order_num` int(11) DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`menu_id`) PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单管理'; ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COMMENT='菜单管理';
-- 系统用户 -- ----------------------------
-- Records of sys_menu
-- ----------------------------
INSERT INTO `sys_menu` VALUES ('1', '0', '系统管理', null, null, '0', 'fa fa-cog', '0');
INSERT INTO `sys_menu` VALUES ('2', '1', '管理员列表', 'modules/sys/user.html', null, '1', 'fa fa-user', '1');
INSERT INTO `sys_menu` VALUES ('3', '1', '角色管理', 'modules/sys/role.html', null, '1', 'fa fa-user-secret', '2');
INSERT INTO `sys_menu` VALUES ('4', '1', '菜单管理', 'modules/sys/menu.html', null, '1', 'fa fa-th-list', '3');
INSERT INTO `sys_menu` VALUES ('15', '2', '查看', null, 'sys:user:list,sys:user:info', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('16', '2', '新增', null, 'sys:user:save,sys:role:select', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('17', '2', '修改', null, 'sys:user:update,sys:role:select', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('18', '2', '删除', null, 'sys:user:delete', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('19', '3', '查看', null, 'sys:role:list,sys:role:info', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('20', '3', '新增', null, 'sys:role:save,sys:menu:list', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('21', '3', '修改', null, 'sys:role:update,sys:menu:list', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('22', '3', '删除', null, 'sys:role:delete', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('23', '4', '查看', null, 'sys:menu:list,sys:menu:info', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('24', '4', '新增', null, 'sys:menu:save,sys:menu:select', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('25', '4', '修改', null, 'sys:menu:update,sys:menu:select', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('26', '4', '删除', null, 'sys:menu:delete', '2', null, '0');
INSERT INTO `sys_menu` VALUES ('27', '1', '参数管理', 'modules/sys/config.html', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', '1', 'fa fa-sun-o', '6');
INSERT INTO `sys_menu` VALUES ('29', '1', '系统日志', 'modules/sys/log.html', 'sys:log:list', '1', 'fa fa-file-text-o', '7');
INSERT INTO `sys_menu` VALUES ('30', '1', '文件上传', 'modules/oss/oss.html', 'sys:oss:all', '1', 'fa fa-file-image-o', '6');
INSERT INTO `sys_menu` VALUES ('31', '0', 'Swagger', null, null, '0', 'fa fa-cog', '0');
INSERT INTO `sys_menu` VALUES ('32', '31', '在线API', 'swagger/index.html', null, '1', 'fa fa-file-text-o', '1');
-- ----------------------------
-- Table structure for sys_oss
-- ----------------------------
DROP TABLE IF EXISTS `sys_oss`;
CREATE TABLE `sys_oss` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(200) DEFAULT NULL COMMENT 'URL地址',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='文件上传';
-- ----------------------------
-- Records of sys_oss
-- ----------------------------
INSERT INTO `sys_oss` VALUES ('1', 'http://oss.sukeintel.com.qiniudns.com/upload/20190401/1964f6d819b54852a7a87d855f240827.png', '2019-04-01 09:50:31');
INSERT INTO `sys_oss` VALUES ('2', 'http://oss.sukeintel.com/upload/20190401/35d86809a5564d1c82ec95f5ea33b0aa.png', '2019-04-01 11:01:18');
INSERT INTO `sys_oss` VALUES ('3', 'http://oss.sukeintel.com/upload/20190401/e0a49d8bd0ee4f66affc526c01e4fc11.png', '2019-04-01 11:03:05');
INSERT INTO `sys_oss` VALUES ('4', 'http://oss.sukeintel.com/upload/20190401/229117ef71a34d69b113f072f00f2b84.png', '2019-04-01 11:18:18');
INSERT INTO `sys_oss` VALUES ('5', 'http://oss.sukeintel.com/upload/20190401/4669fb66bea94dc48c75d9b0fbdcc1df.png', '2019-04-01 11:51:56');
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`role_id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_name` varchar(100) DEFAULT NULL COMMENT '角色名称',
`remark` varchar(100) DEFAULT NULL COMMENT '备注',
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建者ID',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='角色';
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('4', '管理员', '管理员', '1', '2019-04-18 10:12:05');
-- ----------------------------
-- Table structure for sys_role_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_menu`;
CREATE TABLE `sys_role_menu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) DEFAULT NULL COMMENT '角色ID',
`menu_id` bigint(20) DEFAULT NULL COMMENT '菜单ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 COMMENT='角色与菜单对应关系';
-- ----------------------------
-- Records of sys_role_menu
-- ----------------------------
INSERT INTO `sys_role_menu` VALUES ('1', '4', '1');
INSERT INTO `sys_role_menu` VALUES ('2', '4', '2');
INSERT INTO `sys_role_menu` VALUES ('3', '4', '15');
INSERT INTO `sys_role_menu` VALUES ('4', '4', '16');
INSERT INTO `sys_role_menu` VALUES ('10', '4', '21');
INSERT INTO `sys_role_menu` VALUES ('11', '4', '22');
INSERT INTO `sys_role_menu` VALUES ('12', '5', '1');
INSERT INTO `sys_role_menu` VALUES ('13', '5', '3');
INSERT INTO `sys_role_menu` VALUES ('14', '5', '19');
INSERT INTO `sys_role_menu` VALUES ('15', '5', '20');
INSERT INTO `sys_role_menu` VALUES ('16', '5', '21');
INSERT INTO `sys_role_menu` VALUES ('17', '5', '22');
INSERT INTO `sys_role_menu` VALUES ('18', '5', '4');
INSERT INTO `sys_role_menu` VALUES ('19', '5', '23');
INSERT INTO `sys_role_menu` VALUES ('20', '5', '24');
INSERT INTO `sys_role_menu` VALUES ('21', '5', '25');
INSERT INTO `sys_role_menu` VALUES ('22', '5', '26');
INSERT INTO `sys_role_menu` VALUES ('23', '6', '1');
INSERT INTO `sys_role_menu` VALUES ('24', '6', '3');
INSERT INTO `sys_role_menu` VALUES ('25', '6', '19');
INSERT INTO `sys_role_menu` VALUES ('26', '6', '20');
INSERT INTO `sys_role_menu` VALUES ('27', '6', '21');
INSERT INTO `sys_role_menu` VALUES ('28', '6', '22');
INSERT INTO `sys_role_menu` VALUES ('29', '7', '1');
INSERT INTO `sys_role_menu` VALUES ('30', '7', '2');
INSERT INTO `sys_role_menu` VALUES ('31', '7', '15');
INSERT INTO `sys_role_menu` VALUES ('32', '7', '16');
INSERT INTO `sys_role_menu` VALUES ('33', '7', '17');
INSERT INTO `sys_role_menu` VALUES ('34', '7', '18');
INSERT INTO `sys_role_menu` VALUES ('35', '8', '1');
INSERT INTO `sys_role_menu` VALUES ('36', '8', '2');
INSERT INTO `sys_role_menu` VALUES ('37', '8', '15');
INSERT INTO `sys_role_menu` VALUES ('38', '8', '16');
INSERT INTO `sys_role_menu` VALUES ('39', '8', '17');
INSERT INTO `sys_role_menu` VALUES ('40', '8', '18');
INSERT INTO `sys_role_menu` VALUES ('41', '9', '1');
INSERT INTO `sys_role_menu` VALUES ('42', '9', '6');
INSERT INTO `sys_role_menu` VALUES ('43', '9', '7');
INSERT INTO `sys_role_menu` VALUES ('44', '9', '8');
INSERT INTO `sys_role_menu` VALUES ('45', '9', '9');
INSERT INTO `sys_role_menu` VALUES ('46', '9', '10');
INSERT INTO `sys_role_menu` VALUES ('47', '9', '11');
INSERT INTO `sys_role_menu` VALUES ('48', '9', '12');
INSERT INTO `sys_role_menu` VALUES ('49', '9', '13');
INSERT INTO `sys_role_menu` VALUES ('50', '9', '14');
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` ( CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名', `username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) COMMENT '密码', `password` varchar(100) DEFAULT NULL COMMENT '密码',
`salt` varchar(20) COMMENT '', `salt` varchar(20) DEFAULT NULL COMMENT '',
`email` varchar(100) COMMENT '邮箱', `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(100) COMMENT '手机号', `mobile` varchar(100) DEFAULT NULL COMMENT '手机号',
`status` tinyint COMMENT '状态 0禁用 1正常', `status` tinyint(4) DEFAULT NULL COMMENT '状态 0禁用 1正常',
`create_user_id` bigint(20) COMMENT '创建者ID', `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建者ID',
`create_time` datetime COMMENT '创建时间', `create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`), PRIMARY KEY (`user_id`),
UNIQUE INDEX (`username`) UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统用户'; ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='系统用户';
-- 系统用户Token -- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'yzcheng90@qq.com', '13612345678', '1', '1', '2016-11-11 11:11:11');
-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
`role_id` bigint(20) DEFAULT NULL COMMENT '角色ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户与角色对应关系';
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('1', '7', '5');
-- ----------------------------
-- Table structure for sys_user_token
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_token`;
CREATE TABLE `sys_user_token` ( CREATE TABLE `sys_user_token` (
`user_id` bigint(20) NOT NULL, `user_id` bigint(20) NOT NULL,
`token` varchar(100) NOT NULL COMMENT 'token', `token` varchar(100) NOT NULL COMMENT 'token',
@@ -36,336 +264,8 @@ CREATE TABLE `sys_user_token` (
UNIQUE KEY `token` (`token`) UNIQUE KEY `token` (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统用户Token'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统用户Token';
-- 角色 -- ----------------------------
CREATE TABLE `sys_role` ( -- Records of sys_user_token
`role_id` bigint NOT NULL AUTO_INCREMENT, -- ----------------------------
`role_name` varchar(100) COMMENT '角色名称', INSERT INTO `sys_user_token` VALUES ('1', '152a9c69193ed60261c6feec3cce02e0', '2019-04-23 04:34:07', '2019-04-22 16:34:07');
`remark` varchar(100) COMMENT '备注', INSERT INTO `sys_user_token` VALUES ('7', 'cc3c74959d0eaacce1a3c3410ccc105b', '2019-04-19 02:55:21', '2019-04-18 14:55:21');
`create_user_id` bigint(20) COMMENT '创建者ID',
`create_time` datetime COMMENT '创建时间',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';
-- 用户与角色对应关系
CREATE TABLE `sys_user_role` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint COMMENT '用户ID',
`role_id` bigint COMMENT '角色ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户与角色对应关系';
-- 角色与菜单对应关系
CREATE TABLE `sys_role_menu` (
`id` bigint NOT NULL AUTO_INCREMENT,
`role_id` bigint COMMENT '角色ID',
`menu_id` bigint COMMENT '菜单ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色与菜单对应关系';
-- 系统配置信息
CREATE TABLE `sys_config` (
`id` bigint NOT NULL AUTO_INCREMENT,
`key` varchar(50) COMMENT 'key',
`value` varchar(2000) COMMENT 'value',
`status` tinyint DEFAULT 1 COMMENT '状态 0隐藏 1显示',
`remark` varchar(500) COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE INDEX (`key`)
) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8 COMMENT='系统配置信息表';
-- 系统日志
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) COMMENT '用户名',
`operation` varchar(50) COMMENT '用户操作',
`method` varchar(200) COMMENT '请求方法',
`params` varchar(5000) COMMENT '请求参数',
`time` bigint NOT NULL COMMENT '执行时长(毫秒)',
`ip` varchar(64) COMMENT 'IP地址',
`create_date` datetime COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8 COMMENT='系统日志';
-- 初始数据
INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `create_user_id`, `create_time`) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'yzcheng90@qq.com', '13888888888', '1', '1', '2018-1-18 11:11:11');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('1', '0', '系统管理', NULL, NULL, '0', 'fa fa-cog', '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('2', '1', '管理员列表', 'modules/sys/user.html', NULL, '1', 'fa fa-user', '1');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('3', '1', '角色管理', 'modules/sys/role.html', NULL, '1', 'fa fa-user-secret', '2');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('4', '1', '菜单管理', 'modules/sys/menu.html', NULL, '1', 'fa fa-th-list', '3');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('5', '1', 'SQL监控', 'druid/sql.html', NULL, '1', 'fa fa-bug', '4');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('15', '2', '查看', NULL, 'sys:user:list,sys:user:info', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('16', '2', '新增', NULL, 'sys:user:save,sys:role:select', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('17', '2', '修改', NULL, 'sys:user:update,sys:role:select', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('18', '2', '删除', NULL, 'sys:user:delete', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('19', '3', '查看', NULL, 'sys:role:list,sys:role:info', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('20', '3', '新增', NULL, 'sys:role:save,sys:menu:list', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('21', '3', '修改', NULL, 'sys:role:update,sys:menu:list', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('22', '3', '删除', NULL, 'sys:role:delete', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('23', '4', '查看', NULL, 'sys:menu:list,sys:menu:info', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('24', '4', '新增', NULL, 'sys:menu:save,sys:menu:select', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('25', '4', '修改', NULL, 'sys:menu:update,sys:menu:select', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('26', '4', '删除', NULL, 'sys:menu:delete', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('27', '1', '参数管理', 'modules/sys/config.html', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', '1', 'fa fa-sun-o', '6');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('29', '1', '系统日志', 'modules/sys/log.html', 'sys:log:list', '1', 'fa fa-file-text-o', '7');
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 云存储服务相关SQL如果不使用该功能则不用执行下面SQL -------------------------------------------------------------------------------------------------------------
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 文件上传
CREATE TABLE `sys_oss` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(200) COMMENT 'URL地址',
`create_date` datetime COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8 COMMENT='文件上传';
INSERT INTO `sys_config` (`key`, `value`, `status`, `remark`) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{\"aliyunAccessKeyId\":\"\",\"aliyunAccessKeySecret\":\"\",\"aliyunBucketName\":\"\",\"aliyunDomain\":\"\",\"aliyunEndPoint\":\"\",\"aliyunPrefix\":\"\",\"qcloudBucketName\":\"\",\"qcloudDomain\":\"\",\"qcloudPrefix\":\"\",\"qcloudSecretId\":\"\",\"qcloudSecretKey\":\"\",\"qiniuAccessKey\":\"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ\",\"qiniuBucketName\":\"ios-app\",\"qiniuDomain\":\"http://7xqbwh.dl1.z0.glb.clouddn.com\",\"qiniuPrefix\":\"upload\",\"qiniuSecretKey\":\"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV\",\"type\":1}', '0', '云存储配置信息');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('30', '1', '文件上传', 'modules/oss/oss.html', 'sys:oss:all', '1', 'fa fa-file-image-o', '6');
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- APP接口相关SQL如果不使用该功能则不用执行下面SQL -------------------------------------------------------------------------------------------------------------
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 用户表
CREATE TABLE `tb_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`mobile` varchar(20) NOT NULL COMMENT '手机号',
`password` varchar(64) COMMENT '密码',
`create_time` datetime COMMENT '创建时间',
PRIMARY KEY (`user_id`),
UNIQUE INDEX (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';
-- 账号13612345678 密码admin
INSERT INTO `tb_user` (`username`, `mobile`, `password`, `create_time`) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41');
-- APP版本更新表
CREATE TABLE `tb_app_update` (
`appid` varchar(50) DEFAULT NULL COMMENT 'APPID ',
`update_content` varchar(500) DEFAULT NULL COMMENT '更新内容',
`version_code` int(20) DEFAULT NULL COMMENT '版本码',
`version_name` varchar(50) DEFAULT NULL COMMENT '版本号',
`url` varchar(255) DEFAULT NULL COMMENT 'URL地址',
`app_file_name` varchar(255) DEFAULT NULL COMMENT '文件名',
`md5` varchar(255) DEFAULT NULL COMMENT 'MD5值',
`size` varchar(50) DEFAULT NULL COMMENT '文件大小',
`is_force` varchar(50) DEFAULT NULL COMMENT '是否强制安装',
`is_ignorable` varchar(50) DEFAULT NULL COMMENT '是否可忽略该版本',
`is_silent` varchar(50) DEFAULT NULL COMMENT '是否静默下载:有新版本时不提示直接下载',
`upload_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '上传时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='APP版本管理';
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 定时任务相关表结构如果不使用该功能则不用执行下面SQL -------------------------------------------------------------------------------------------------------------
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 初始化菜单数据
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('6', '1', '定时任务', 'modules/job/schedule.html', NULL, '1', 'fa fa-tasks', '5');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('7', '6', '查看', NULL, 'sys:schedule:list,sys:schedule:info', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('8', '6', '新增', NULL, 'sys:schedule:save', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('9', '6', '修改', NULL, 'sys:schedule:update', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('10', '6', '删除', NULL, 'sys:schedule:delete', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('11', '6', '暂停', NULL, 'sys:schedule:pause', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('12', '6', '恢复', NULL, 'sys:schedule:resume', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('13', '6', '立即执行', NULL, 'sys:schedule:run', '2', NULL, '0');
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES ('14', '6', '日志列表', NULL, 'sys:schedule:log', '2', NULL, '0');
-- 定时任务
CREATE TABLE `schedule_job` (
`job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务id',
`bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
`method_name` varchar(100) DEFAULT NULL COMMENT '方法名',
`params` varchar(2000) DEFAULT NULL COMMENT '参数',
`cron_expression` varchar(100) DEFAULT NULL COMMENT 'cron表达式',
`status` tinyint(4) DEFAULT NULL COMMENT '任务状态 0正常 1暂停',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务';
-- 定时任务日志
CREATE TABLE `schedule_job_log` (
`log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志id',
`job_id` bigint(20) NOT NULL COMMENT '任务id',
`bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
`method_name` varchar(100) DEFAULT NULL COMMENT '方法名',
`params` varchar(2000) DEFAULT NULL COMMENT '参数',
`status` tinyint(4) NOT NULL COMMENT '任务状态 0成功 1失败',
`error` varchar(2000) DEFAULT NULL COMMENT '失败信息',
`times` int(11) NOT NULL COMMENT '耗时(单位:毫秒)',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`log_id`),
KEY `job_id` (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务日志';
INSERT INTO `schedule_job` (`bean_name`, `method_name`, `params`, `cron_expression`, `status`, `remark`, `create_time`) VALUES ('testTask', 'test1', 'test', '0 0/30 * * * ?', '0', '有参数测试', '2016-12-01 23:16:46');
INSERT INTO `schedule_job` (`bean_name`, `method_name`, `params`, `cron_expression`, `status`, `remark`, `create_time`) VALUES ('testTask', 'test2', NULL, '0 0/30 * * * ?', '1', '无参数测试', '2016-12-03 14:55:56');
-- quartz自带表结构
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

BIN
pic/20190419153826.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
pic/20190422163331.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
pic/20190422163826.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,214 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>x_springboot</groupId>
<artifactId>x_springboot</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<description>war包对应的pom打war包执行【mvn clean package -f pom-war.xml】</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
<mysql.version>5.1.38</mysql.version>
<druid.version>1.1.3</druid.version>
<quartz.version>2.3.0</quartz.version>
<commons.lang.version>2.6</commons.lang.version>
<commons.fileupload.version>1.3.1</commons.fileupload.version>
<commons.io.version>2.5</commons.io.version>
<commons.codec.version>1.10</commons.codec.version>
<commons.configuration.version>1.10</commons.configuration.version>
<shiro.version>1.3.2</shiro.version>
<jwt.version>0.7.0</jwt.version>
<kaptcha.version>0.0.9</kaptcha.version>
<qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
<aliyun.oss.version>2.5.0</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons.codec.version}</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>${commons.configuration.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>${qcloud.cos.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>${artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

182
pom.xml
View File

@@ -2,54 +2,42 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <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"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>x_springboot</groupId> <groupId>x-springboot</groupId>
<artifactId>x_springboot</artifactId> <artifactId>x-springboot</artifactId>
<version>1.0.0</version> <version>2.0.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>x_springboot</description> <description>x-springboot</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version> <version>2.1.3.RELEASE</version>
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version> <mybatis-plus.version>3.1.0</mybatis-plus.version>
<mysql.version>5.1.38</mysql.version> <mysql.version>8.0.15</mysql.version>
<druid.version>1.1.3</druid.version>
<quartz.version>2.3.0</quartz.version> <minio.version>6.0.2</minio.version>
<commons.lang.version>2.6</commons.lang.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version> <swagger.version>2.9.2</swagger.version>
<commons.io.version>2.5</commons.io.version>
<commons.codec.version>1.10</commons.codec.version> <shiro.version>1.4.0</shiro.version>
<commons.configuration.version>1.10</commons.configuration.version>
<shiro.version>1.3.2</shiro.version>
<jwt.version>0.7.0</jwt.version>
<kaptcha.version>0.0.9</kaptcha.version> <kaptcha.version>0.0.9</kaptcha.version>
<qiniu.version>[7.2.0, 7.2.99]</qiniu.version> <qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
<aliyun.oss.version>2.5.0</aliyun.oss.version> <aliyun.oss.version>2.5.0</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version> <qcloud.cos.version>4.4</qcloud.cos.version>
<!--wagon plugin 配置--> <hutool.version>4.4.5</hutool.version>
<service-path>/work/x_springboot</service-path> <commons.fileupload.version>1.3.1</commons.fileupload.version>
<pack-name>${artifactId}-${version}.jar</pack-name> <commons.io.version>2.5</commons.io.version>
<remote-addr>192.168.1.10:22</remote-addr>
<remote-username>root</remote-username>
<remote-passwd>123456</remote-passwd>
<!--webmagic 配置-->
<us.codecraft.version>0.7.3</us.codecraft.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
@@ -58,10 +46,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
@@ -76,37 +60,27 @@
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!--mybatis plus extension,包含了mybatis plus core-->
<dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-plus-extension</artifactId>
<version>${mybatis.spring.boot.version}</version> <version>${mybatis-plus.version}</version>
</dependency> </dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--mysql-->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version> <version>${mysql.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId> <!--commons 相关-->
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
</dependency>
<dependency> <dependency>
<groupId>commons-fileupload</groupId> <groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId> <artifactId>commons-fileupload</artifactId>
@@ -117,16 +91,26 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>${commons.io.version}</version> <version>${commons.io.version}</version>
</dependency> </dependency>
<!-- 监控端点-->
<dependency> <dependency>
<groupId>commons-codec</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>commons-codec</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
<version>${commons.codec.version}</version>
</dependency> </dependency>
<!--minio文件系统-->
<dependency> <dependency>
<groupId>commons-configuration</groupId> <groupId>io.minio</groupId>
<artifactId>commons-configuration</artifactId> <artifactId>minio</artifactId>
<version>${commons.configuration.version}</version> <version>${minio.version}</version>
</dependency> </dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.shiro</groupId> <groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId> <artifactId>shiro-core</artifactId>
@@ -137,16 +121,13 @@
<artifactId>shiro-spring</artifactId> <artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version> <version>${shiro.version}</version>
</dependency> </dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.github.axet</groupId> <groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version> <version>${kaptcha.version}</version>
</dependency> </dependency>
<!--oss 相关-->
<dependency> <dependency>
<groupId>com.qiniu</groupId> <groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId> <artifactId>qiniu-java-sdk</artifactId>
@@ -169,45 +150,28 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--swagger 依赖-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version> <version>${swagger.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version> <version>${swagger.version}</version>
</dependency>
<!--webmagic !!!-->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>${us.codecraft.version}</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>${us.codecraft.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>${artifactId}</finalName> <finalName>${artifactId}</finalName>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@@ -216,34 +180,6 @@
<fork>true</fork> <fork>true</fork>
</configuration> </configuration>
</plugin> </plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<fromFile>target/${pack-name}</fromFile>
<url><![CDATA[scp://${remote-username}:${remote-passwd}@${remote-addr}${service-path}]]></url>
<commands>
<!-- Kill Old Process -->
<command>pkill -f ${pack-name}</command>
<command>rm -f ${service-path}/x_springboot.log</command>
<!-- Restart jar packagewrite result into x_springboot.log -->
<command><![CDATA[nohup java -jar ${service-path}/${pack-name} --spring.profiles.active=test > ${service-path}/x-springboot.log 2>&1 & ]]></command>
<command><![CDATA[netstat -nptl]]></command>
<command><![CDATA[ps -ef | grep java | grep -v grep]]></command>
</commands>
<!-- 运行命令 mvn clean package wagon:upload-single wagon:sshexec-->
<displayCommandOutputs>true</displayCommandOutputs>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>com.spotify</groupId> <groupId>com.spotify</groupId>

View File

@@ -1,23 +1,17 @@
package com.suke.czx; package com.suke.czx;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Slf4j
@EnableSwagger2 @EnableSwagger2
@EnableTransactionManagement
@SpringBootApplication @SpringBootApplication
public class Application extends SpringBootServletInitializer { public class Application {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(Application.class, args); SpringApplication.run(Application.class, args);
} log.info("==================X-SpringBoot启动成功================");
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
} }
} }

View File

@@ -1,4 +1,4 @@
package com.suke.czx.modules.sys.oauth2; package com.suke.czx.authentication;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.suke.czx.common.utils.R; import com.suke.czx.common.utils.R;
@@ -37,7 +37,12 @@ public class OAuth2Filter extends AuthenticatingFilter {
@Override @Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
return false; if (request instanceof HttpServletRequest) {
if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
return true;
}
}
return super.isAccessAllowed(request, response, mappedValue);
} }
@Override @Override

View File

@@ -1,7 +1,7 @@
package com.suke.czx.modules.sys.oauth2; package com.suke.czx.authentication;
import com.suke.czx.modules.sys.entity.SysUserEntity; import com.suke.czx.modules.sys.entity.SysUser;
import com.suke.czx.modules.sys.entity.SysUserTokenEntity; import com.suke.czx.modules.sys.entity.SysUserToken;
import com.suke.czx.modules.sys.service.ShiroService; import com.suke.czx.modules.sys.service.ShiroService;
import org.apache.shiro.authc.*; import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.AuthorizationInfo;
@@ -35,7 +35,7 @@ public class OAuth2Realm extends AuthorizingRealm {
*/ */
@Override @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal(); SysUser user = (SysUser)principals.getPrimaryPrincipal();
Long userId = user.getUserId(); Long userId = user.getUserId();
//用户权限列表 //用户权限列表
@@ -54,14 +54,14 @@ public class OAuth2Realm extends AuthorizingRealm {
String accessToken = (String) token.getPrincipal(); String accessToken = (String) token.getPrincipal();
//根据accessToken查询用户信息 //根据accessToken查询用户信息
SysUserTokenEntity tokenEntity = shiroService.queryByToken(accessToken); SysUserToken tokenEntity = shiroService.queryByToken(accessToken);
//token失效 //token失效
if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){ if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
throw new IncorrectCredentialsException("token失效请重新登录"); throw new IncorrectCredentialsException("token失效请重新登录");
} }
//查询用户信息 //查询用户信息
SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId()); SysUser user = shiroService.queryUser(tokenEntity.getUserId());
//账号锁定 //账号锁定
if(user.getStatus() == 0){ if(user.getStatus() == 0){
throw new LockedAccountException("账号已被锁定,请联系管理员"); throw new LockedAccountException("账号已被锁定,请联系管理员");

View File

@@ -1,4 +1,4 @@
package com.suke.czx.modules.sys.oauth2; package com.suke.czx.authentication;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;

View File

@@ -1,4 +1,4 @@
package com.suke.czx.modules.sys.oauth2; package com.suke.czx.authentication;
import com.suke.czx.common.exception.RRException; import com.suke.czx.common.exception.RRException;

View File

@@ -1,4 +1,4 @@
package com.suke.czx.modules.app.annotation; package com.suke.czx.common.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@@ -1,4 +1,4 @@
package com.suke.czx.modules.app.annotation; package com.suke.czx.common.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@@ -1,40 +0,0 @@
package com.suke.czx.common.aspect;
import com.suke.czx.common.exception.RRException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Redis切面处理类
*
* @author czx
* @email object_czx@163.com
* @date 2017-07-17 23:30
*/
@Aspect
@Configuration
public class RedisAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
//是否开启redis缓存 true开启 false关闭
@Value("${spring.redis.open: false}")
private boolean open;
@Around("execution(* com.suke.czx.common.utils.RedisUtils.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = null;
if(open){
try{
result = point.proceed();
}catch (Exception e){
logger.error("redis error", e);
throw new RRException("Redis服务异常");
}
}
return result;
}
}

View File

@@ -1,11 +1,10 @@
package com.suke.czx.common.aspect; package com.suke.czx.common.aspect;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.suke.czx.common.annotation.SysLog;
import com.suke.czx.common.utils.HttpContextUtils; import com.suke.czx.common.utils.HttpContextUtils;
import com.suke.czx.common.utils.IPUtils; import com.suke.czx.common.utils.IPUtils;
import com.suke.czx.modules.sys.entity.SysLogEntity; import com.suke.czx.modules.sys.entity.SysLog;
import com.suke.czx.modules.sys.entity.SysUserEntity; import com.suke.czx.modules.sys.entity.SysUser;
import com.suke.czx.modules.sys.service.SysLogService; import com.suke.czx.modules.sys.service.SysLogService;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
@@ -57,8 +56,8 @@ public class SysLogAspect {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod(); Method method = signature.getMethod();
SysLogEntity sysLog = new SysLogEntity(); SysLog sysLog = new SysLog();
SysLog syslog = method.getAnnotation(SysLog.class); com.suke.czx.common.annotation.SysLog syslog = method.getAnnotation(com.suke.czx.common.annotation.SysLog.class);
if(syslog != null){ if(syslog != null){
//注解上的描述 //注解上的描述
sysLog.setOperation(syslog.value()); sysLog.setOperation(syslog.value());
@@ -84,7 +83,7 @@ public class SysLogAspect {
sysLog.setIp(IPUtils.getIpAddr(request)); sysLog.setIp(IPUtils.getIpAddr(request));
//用户名 //用户名
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername(); String username = ((SysUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
sysLog.setUsername(username); sysLog.setUsername(username);
sysLog.setTime(time); sysLog.setTime(time);

View File

@@ -0,0 +1,31 @@
package com.suke.czx.common.base;
import com.suke.czx.common.utils.MPPageConvert;
import com.suke.czx.modules.sys.entity.SysUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Controller公共组件
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月9日 下午9:42:26
*/
public abstract class AbstractController {
@Autowired
protected MPPageConvert mpPageConvert;
protected SysUser getUser() {
return (SysUser) SecurityUtils.getSubject().getPrincipal();
}
protected Long getUserId() {
return getUser().getUserId();
}
}

View File

@@ -1,6 +1,6 @@
package com.suke.czx.common.exception; package com.suke.czx.common.exception;
import com.suke.czx.common.utils.AppBaseResult; import com.suke.czx.common.utils.R;
import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -16,35 +16,32 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
* @date 2016年10月27日 下午10:16:19 * @date 2016年10月27日 下午10:16:19
*/ */
@RestControllerAdvice @RestControllerAdvice
public class RRExceptionHandler extends AppBaseResult { public class RRExceptionHandler extends R {
private Logger logger = LoggerFactory.getLogger(getClass()); private Logger logger = LoggerFactory.getLogger(getClass());
/** /**
* 自定义异常 * 自定义异常
*/ */
@ExceptionHandler(RRException.class) @ExceptionHandler(RRException.class)
public AppBaseResult handleRRException(RRException e){ public R handleRRException(RRException e){
AppBaseResult appBaseResult = new AppBaseResult(); return R.error(e.getCode(),e.getMessage());
appBaseResult.setCode(e.getCode());
appBaseResult.setMessage(e.getMessage());
return appBaseResult;
} }
@ExceptionHandler(DuplicateKeyException.class) @ExceptionHandler(DuplicateKeyException.class)
public AppBaseResult handleDuplicateKeyException(DuplicateKeyException e){ public R handleDuplicateKeyException(DuplicateKeyException e){
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return AppBaseResult.error("数据库中已存在该记录"); return R.error("数据库中已存在该记录");
} }
@ExceptionHandler(AuthorizationException.class) @ExceptionHandler(AuthorizationException.class)
public AppBaseResult handleAuthorizationException(AuthorizationException e){ public R handleAuthorizationException(AuthorizationException e){
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return AppBaseResult.error("没有权限,请联系管理员授权"); return R.error("没有权限,请联系管理员授权");
} }
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public AppBaseResult handleException(Exception e){ public R handleException(Exception e){
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return AppBaseResult.error(); return R.error();
} }
} }

View File

@@ -1,154 +0,0 @@
package com.suke.czx.common.utils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.http.HttpStatus;
import java.io.Serializable;
import java.util.HashMap;
/**
* @category app返回类
* @author czx
* 2017-04-25
*/
public class AppBaseResult<T> implements Serializable {
private int code = 500;
private String message = "";
private String data = "";
private String version = "1.0";
private String mobile = "";
public final static int ERROR = 401;
public final static int SUCCESS = 200;
public final static int FAIL = 500;
public final static int TOKENFAIL = 1000;
public final static String KEY = "czx12345";
public static AppBaseResult success(String msg){
AppBaseResult appBaseResult = new AppBaseResult();
appBaseResult.setCode(SUCCESS);
appBaseResult.setMessage(msg);
return appBaseResult;
}
public static AppBaseResult success(){
AppBaseResult appBaseResult = new AppBaseResult();
appBaseResult.setCode(SUCCESS);
appBaseResult.setMessage("请求成功");
return appBaseResult;
}
public static AppBaseResult error(String msg){
AppBaseResult appBaseResult = new AppBaseResult();
appBaseResult.setCode(FAIL);
appBaseResult.setMessage(msg);
return appBaseResult;
}
public static AppBaseResult error(int code,String msg){
AppBaseResult appBaseResult = new AppBaseResult();
appBaseResult.setCode(code);
appBaseResult.setMessage(msg);
return appBaseResult;
}
public static AppBaseResult error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public int getCode() {
return code;
}
public AppBaseResult setCode(int status) {
this.code = status;
return this;
}
public String getMessage() {
return message;
}
public AppBaseResult setMessage(String message) {
this.message = message;
return this;
}
public String getData() {
return this.data;
}
public void setData(String data) {
this.data = data;
}
public HashMap<String,Object> decryptData(String data) {
String mData = null;
if(!Tools.isEmpty(data)){
try {
mData = CDESCrypt.decryptString(data, KEY);
//mData=data;
} catch (Exception e) {
e.printStackTrace();
}
}
return new Gson().fromJson(mData,new TypeToken<HashMap<String,Object>>() {}.getType());
}
public String decryptData() {
String mData = null;
if(!Tools.isEmpty(this.data)){
try {
mData = CDESCrypt.decryptString(this.data, KEY);
//mData=this.data;
} catch (Exception e) {
e.printStackTrace();
}
}
return mData;
}
public AppBaseResult setEncryptData(T t) {
String mData = new Gson().toJson(t);
try {
if(!Tools.isEmpty(mData)){
this.data = CDESCrypt.encryptString(mData, KEY);
//this.data=mData;
}else{
this.data = mData;
}
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
public String getVersion() {
return version;
}
public AppBaseResult setVersion(String version) {
this.version = version;
return this;
}
public String getMobile() {
return mobile;
}
public AppBaseResult setMobile(String mobile) {
this.mobile = mobile;
return this;
}
@Override
public String toString() {
return "{" +
"code='" + code + '\'' +
", message='" + message + '\'' +
", data='" + data + '\'' +
", version='" + version + '\'' +
", mobile='" + mobile + '\'' +
'}';
}
}

View File

@@ -1,84 +0,0 @@
package com.suke.czx.common.utils;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class CDESCrypt {
public CDESCrypt() {
}
public static String encryptString(String message,String key) throws Exception {
return new String(Base64.encodeBase64(encrypt(message, key)));
}
public static String encryptAsHexString(String message,String key) throws Exception {
return toHexString(encrypt(message, key));
}
public static byte[] encrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(1, secretKey, iv);
byte[] bytes = message.getBytes("UTF-8");
return cipher.doFinal(bytes);
}
public static String decryptString(String message,String key) throws Exception {
byte[] bytes = Base64.decodeBase64(message.getBytes("UTF-8"));
return decrypt(bytes, key);
}
public static String decryptAsHexString(String message,String key) throws Exception {
byte[] bytes = convertHexString(message);
return decrypt(bytes, key);
}
public static String decrypt(byte[] bytes, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(2, secretKey, iv);
byte[] retBytes = cipher.doFinal(bytes);
return new String(retBytes);
}
public static byte[] convertHexString(String ss) {
byte[] digest = new byte[ss.length() / 2];
for(int i = 0; i < digest.length; ++i) {
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte)byteValue;
}
return digest;
}
public static String toHexString(byte[] b) {
StringBuffer hexString = new StringBuffer();
for(int i = 0; i < b.length; ++i) {
String plainText = Integer.toHexString(255 & b[i]);
if(plainText.length() < 2) {
plainText = "0" + plainText;
}
hexString.append(plainText);
}
return hexString.toString();
}
}

View File

@@ -1,240 +0,0 @@
package com.suke.czx.common.utils;
import net.sf.json.JSONObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
/**
* Http请求类
*
* @author M
*/
public class CHttpRequest
{
public static JSONObject httpRequest(String requestUrl, String requestMethod) throws Exception
{
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
HttpURLConnection httpUrlConn = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try
{
URL url = new URL(requestUrl);
// http协议传输
httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestMethod(requestMethod); // 设置请求方式GET/POST
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 将返回的输入流转换成字符串
inputStream = httpUrlConn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null)
buffer.append(str);
jsonObject = JSONObject.fromObject(buffer.toString());
}
finally
{
if(bufferedReader != null) bufferedReader.close();
if(inputStreamReader != null) inputStreamReader.close();
// 释放资源
if(inputStream != null) inputStream.close();
if(httpUrlConn != null) httpUrlConn.disconnect();
}
return jsonObject;
}
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param)
{
String result = "";
BufferedReader in = null;
try
{
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet())
{
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
result += line;
}
}
catch (Exception e)
{
System.out.println("发送GET请求出现异常" + e);
e.printStackTrace();
}
finally
{
try
{
if (in != null)
{
in.close();
}
}
catch (Exception e2)
{
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param add_url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static Object sendPost(String add_url, String param)
{
try
{
URL url = new URL(add_url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
connection.connect();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(param.getBytes("utf-8"));
out.flush();
out.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
String lines;
StringBuffer sbf = new StringBuffer();
while ((lines = reader.readLine()) != null)
{
lines = new String(lines.getBytes());
sbf.append(lines);
}
reader.close();
// 断开连接
connection.disconnect();
return sbf;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* 向指定 URL 发送get方法的请求获取图片
*
* @param url
* 发送请求的 URL
* @param saveAdress
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
* @throws Exception
*/
public static String getPicture(String url,String saveAdress) throws Exception{
String result="ok";
try {
URL urlget = new URL(url);
//打开链接
HttpURLConnection conn = (HttpURLConnection)urlget.openConnection();
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(inStream);
//new一个文件对象用来保存图片
File imageFile = new File(saveAdress);
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流
outStream.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据中间参数代表从哪个位置开始读len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
}

View File

@@ -8,9 +8,15 @@ package com.suke.czx.common.utils;
* @date 2016年11月15日 下午1:23:52 * @date 2016年11月15日 下午1:23:52
*/ */
public class Constant { public class Constant {
public static final String NUMBER_CODE_KEY = "x_springboot:number:code:";
public static final String MOBILE_CODE_KEY = "x_springboot:mobile:code:";
/** 超级管理员ID */ /** 超级管理员ID */
public static final int SUPER_ADMIN = 1; public static final int SUPER_ADMIN = 1;
public static final int CODE_SIZE = 4;
/** /**
* 菜单类型 * 菜单类型
* *
@@ -86,7 +92,11 @@ public class Constant {
/** /**
* 腾讯云 * 腾讯云
*/ */
QCLOUD(3); QCLOUD(3),
/**
* minio
*/
MINIO(4);
private int value; private int value;

View File

@@ -1,125 +0,0 @@
package com.suke.czx.common.utils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* 日期处理
*
* @author czx
* @email object_czx@163.com
* @date 2017年12月21日 下午12:53:33
*/
public class DateUtils {
/** 时间格式(yyyy-MM-dd) */
public final static String DATE_PATTERN = "yyyy-MM-dd";
public final static String DATE_PATTERN_C = "yyyy年MM月dd日";
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static String format(Date date) {
return format(date, DATE_PATTERN);
}
public static String format(Date date, String pattern) {
if(date != null){
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
/**
* 判断两个时间是否正常
* @param start 开始时间
* @param end 结束时间
* @return 1:正常 2结束时间大于开始时间 3两个时间一样
*/
public static int compareDate(String start, String end) {
DateFormat df = new SimpleDateFormat(DATE_TIME_PATTERN);
try {
Date dt1 = df.parse(start);
Date dt2 = df.parse(end);
if (dt1.getTime() > dt2.getTime()) {
return 1;
} else if (dt1.getTime() < dt2.getTime()) {
return -1;
} else {
return 0;
}
} catch (Exception exception) {
exception.printStackTrace();
}
return 0;
}
public static Date getNextDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
date = calendar.getTime();
return date;
}
public static Date getNextMinute(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MINUTE,60);
date = calendar.getTime();
return date;
}
public static String getDateUUID(){
Calendar Cld = Calendar.getInstance();
int YY = Cld.get(Calendar.YEAR) ;
int MM = Cld.get(Calendar.MONTH)+1;
int DD = Cld.get(Calendar.DATE);
int HH = Cld.get(Calendar.HOUR_OF_DAY);
int mm = Cld.get(Calendar.MINUTE);
int SS = Cld.get(Calendar.SECOND);
int MI = Cld.get(Calendar.MILLISECOND);
int number = (int)(Math.random()*999);
return YY + "" + MM + "" + DD + "" + HH + "" + mm + "" + SS + "" + MI + "" + number;
}
public static String stringToDate(String str){
SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy K:m:s a", Locale.ENGLISH);
Date d2 = null;
try {
d2 = sdf.parse(str);
} catch (ParseException e) {
e.printStackTrace();
return "";
}
return format(d2,DATE_TIME_PATTERN);
}
public static Date timeToDate(Long time){
SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_PATTERN);
String d = format.format(time);
try {
Date date=format.parse(d);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
public static Date strToDate(String str){
SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_PATTERN);
try {
String d = format.format(DateFormat.getDateInstance().parse(str));
Date date=format.parse(d);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -1,6 +1,6 @@
package com.suke.czx.common.utils; package com.suke.czx.common.utils;
import com.alibaba.druid.util.StringUtils; import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -26,19 +26,19 @@ public class IPUtils {
String ip = null; String ip = null;
try { try {
ip = request.getHeader("x-forwarded-for"); ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP"); ip = request.getHeader("Proxy-Client-IP");
} }
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP"); ip = request.getHeader("WL-Proxy-Client-IP");
} }
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP"); ip = request.getHeader("HTTP_CLIENT_IP");
} }
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR"); ip = request.getHeader("HTTP_X_FORWARDED_FOR");
} }
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr(); ip = request.getRemoteAddr();
} }
} catch (Exception e) { } catch (Exception e) {

View File

@@ -1,35 +0,0 @@
package com.suke.czx.common.utils;
import java.security.MessageDigest;
public class MD5 {
public static String md5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
str = buf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
public static void main(String[] args) {
System.out.println(md5("31119@qq.com"+"123456"));
System.out.println(md5("123456"));
}
}

View File

@@ -0,0 +1,55 @@
package com.suke.czx.common.utils;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @Author czx
* @Description //TODO Page 数据转换
* @Date 17:13 2019/4/18
**/
@Component
public class MPPageConvert {
/**
* @Author czx
* @Description //TODO 前台传过来的参数转换为MyBatis Plus的Page
* @Date 17:14 2019/4/18
* @Param [param]
* @return com.baomidou.mybatisplus.core.metadata.IPage<T>
**/
public <T> IPage<T> pageParamConvert(Map<String, Object> param){
int currPage = 1;
int limit = 10;
if(MapUtil.getInt(param,"page") != null){
currPage = MapUtil.getInt(param,"page");
}
if(MapUtil.getInt(param,"limit") != null){
limit = MapUtil.getInt(param,"limit");
}
IPage<T> page = new Page<>(currPage,limit);
return page;
}
/**
* @Author czx
* @Description //TODO 将MyBatis Plus 的Page 转换为前台能用的Page
* @Date 17:14 2019/4/18
* @Param [page]
* @return java.util.HashMap
**/
public HashMap pageValueConvert(IPage<?> page){
HashMap<Object,Object> pageData = new HashMap<>();
pageData.put("list",page.getRecords());
pageData.put("totalCount",page.getTotal());
pageData.put("pageSize",page.getSize());
pageData.put("currPage",page.getCurrent());
pageData.put("totalPage",page.getPages());
return pageData;
}
}

View File

@@ -1,81 +0,0 @@
package com.suke.czx.common.utils;
import java.io.Serializable;
import java.util.List;
/**
* 分页工具类
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月4日 下午12:59:00
*/
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
//总记录数
private int totalCount;
//每页记录数
private int pageSize;
//总页数
private int totalPage;
//当前页数
private int currPage;
//列表数据
private List<?> list;
/**
* 分页
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrPage() {
return currPage;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}

View File

@@ -1,62 +0,0 @@
package com.suke.czx.common.utils;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 查询参数
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-14 23:15
*/
public class Query extends LinkedHashMap<String, Object> {
private static final long serialVersionUID = 1L;
//当前页码
private int page;
//每页条数
private int limit;
//总条数
private int totle;
public Query(Map<String, Object> params){
this.putAll(params);
//分页参数
this.page = Integer.parseInt(params.get("page").toString());
this.limit = Integer.parseInt(params.get("limit").toString());
this.put("offset", (page - 1) * limit);
this.put("page", page);
this.put("limit", limit);
}
public void isPaging(boolean bool){
if(bool){
this.put("paging",this);
}
}
public int getTotle() {
return totle;
}
public void setTotle(int totle) {
this.totle = totle;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}

View File

@@ -1,15 +0,0 @@
package com.suke.czx.common.utils;
/**
* Redis所有Keys
*
* @author czx
* @email object_czx@163.com
* @date 2017-07-18 19:51
*/
public class RedisKeys {
public static String getSysConfigKey(String key){
return "sys:config:" + key;
}
}

View File

@@ -1,93 +0,0 @@
package com.suke.czx.common.utils;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*
* @author czx
* @email object_czx@163.com
* @date 2017-07-17 21:12
*/
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ValueOperations<String, String> valueOperations;
@Autowired
private HashOperations<String, String, Object> hashOperations;
@Autowired
private ListOperations<String, Object> listOperations;
@Autowired
private SetOperations<String, Object> setOperations;
@Autowired
private ZSetOperations<String, Object> zSetOperations;
/** 默认过期时长,单位:秒 */
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/** 不设置过期时长 */
public final static long NOT_EXPIRE = -1;
private final static Gson gson = new Gson();
public void set(String key, Object value, long expire){
valueOperations.set(key, toJson(value));
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
public void set(String key, Object value){
set(key, value, DEFAULT_EXPIRE);
}
public <T> T get(String key, Class<T> clazz, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
public <T> T get(String key, Class<T> clazz) {
return get(key, clazz, NOT_EXPIRE);
}
public String get(String key, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
}
public String get(String key) {
return get(key, NOT_EXPIRE);
}
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* Object转成JSON数据
*/
private String toJson(Object object){
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String){
return String.valueOf(object);
}
return gson.toJson(object);
}
/**
* JSON数据转成Object
*/
private <T> T fromJson(String json, Class<T> clazz){
return gson.fromJson(json, clazz);
}
}

View File

@@ -1,10 +1,10 @@
package com.suke.czx.common.utils; package com.suke.czx.common.utils;
import com.suke.czx.common.exception.RRException; import com.suke.czx.modules.sys.entity.SysUser;
import com.suke.czx.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session; import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;
/** /**
* Shiro工具类 * Shiro工具类
@@ -13,43 +13,34 @@ import org.apache.shiro.subject.Subject;
* @email object_czx@163.com * @email object_czx@163.com
* @date 2016年11月12日 上午9:49:19 * @date 2016年11月12日 上午9:49:19
*/ */
@Component
public class ShiroUtils { public class ShiroUtils {
public static Session getSession() { public Session getSession() {
return SecurityUtils.getSubject().getSession(); return SecurityUtils.getSubject().getSession();
} }
public static Subject getSubject() { public Subject getSubject() {
return SecurityUtils.getSubject(); return SecurityUtils.getSubject();
} }
public static SysUserEntity getUserEntity() { public SysUser getUserEntity() {
return (SysUserEntity)SecurityUtils.getSubject().getPrincipal(); return (SysUser)SecurityUtils.getSubject().getPrincipal();
} }
public static Long getUserId() { public Long getUserId() {
return getUserEntity().getUserId(); return getUserEntity().getUserId();
} }
public static void setSessionAttribute(Object key, Object value) { public void setSessionAttribute(Object key, Object value) {
getSession().setAttribute(key, value); getSession().setAttribute(key, value);
} }
public static Object getSessionAttribute(Object key) { public Object getSessionAttribute(Object key) {
return getSession().getAttribute(key); return getSession().getAttribute(key);
} }
public static boolean isLogin() { public boolean isLogin() {
return SecurityUtils.getSubject().getPrincipal() != null; return SecurityUtils.getSubject().getPrincipal() != null;
} }
public static String getKaptcha(String key) {
Object kaptcha = getSessionAttribute(key);
if(kaptcha == null){
throw new RRException("验证码已失效");
}
getSession().removeAttribute(key);
return kaptcha.toString();
}
} }

View File

@@ -1,293 +0,0 @@
package com.suke.czx.common.utils;
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tools {
/**
* 随机生成六位数验证码
*
* @return
*/
public static int getRandomNum() {
Random r = new Random();
return r.nextInt(900000) + 100000;// (Math.random()*(999999-100000)+100000)
}
/**
* 检测字符串是否不为空(null,"","null")
*
* @param s
* @return 不为空则返回true否则返回false
*/
public static boolean notEmpty(String s) {
return s != null && !"".equals(s) && !"null".equals(s);
}
/**
* 检测字符串是否为空(null,"","null")
*
* @param s
* @return 为空则返回true不否则返回false
*/
public static boolean isEmpty(String s) {
return s == null || "".equals(s) || "null".equals(s);
}
/**
* 字符串转换为字符串数组
*
* @param str
* 字符串
* @param splitRegex
* 分隔符
* @return
*/
public static String[] str2StrArray(String str, String splitRegex) {
if (isEmpty(str)) {
return null;
}
return str.split(splitRegex);
}
/**
* 用默认的分隔符(,)将字符串转换为字符串数组
*
* @param str
* 字符串
* @return
*/
public static String[] str2StrArray(String str) {
return str2StrArray(str, ",\\s*");
}
/**
* 按照yyyy-MM-dd HH:mm:ss的格式日期转字符串
*
* @param date
* @return yyyy-MM-dd HH:mm:ss
*/
public static String date2Str(Date date) {
return date2Str(date, "yyyy-MM-dd HH:mm:ss");
}
/**
* 按照yyyy-MM-dd HH:mm:ss的格式字符串转日期
*
* @param date
* @return
*/
public static Date str2Date(String date) {
if (notEmpty(date)) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return new Date();
} else {
return null;
}
}
/**
* 按照参数format的格式日期转字符串
*
* @param date
* @param format
* @return
*/
public static String date2Str(Date date, String format) {
if (date != null) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
} else {
return "";
}
}
/**
* 把时间根据时、分、秒转换为时间段
*
* @param StrDate
*/
public static String getTimes(String StrDate) {
String resultTimes = "";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now;
try {
now = new Date();
Date date = df.parse(StrDate);
long times = now.getTime() - date.getTime();
long day = times / (24 * 60 * 60 * 1000);
long hour = (times / (60 * 60 * 1000) - day * 24);
long min = ((times / (60 * 1000)) - day * 24 * 60 - hour * 60);
long sec = (times / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
StringBuffer sb = new StringBuffer();
// sb.append("发表于:");
if (hour > 0) {
sb.append(hour + "小时前");
} else if (min > 0) {
sb.append(min + "分钟前");
} else {
sb.append(sec + "秒前");
}
resultTimes = sb.toString();
} catch (ParseException e) {
e.printStackTrace();
}
return resultTimes;
}
/**
* 写txt里的单行内容
*
* 文件路径
* @param content
* 写入的内容
*/
public static void writeFile(String fileP, String content) {
String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")) + "../../"; // 项目路径
filePath = (filePath.trim() + fileP.trim()).substring(6).trim();
if (filePath.indexOf(":") != 1) {
filePath = File.separator + filePath;
}
try {
OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
BufferedWriter writer = new BufferedWriter(write);
writer.write(content);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 验证邮箱
*
* @param email
* @return
*/
public static boolean checkEmail(String email) {
boolean flag = false;
try {
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
Pattern regex = Pattern.compile(check);
Matcher matcher = regex.matcher(email);
flag = matcher.matches();
} catch (Exception e) {
flag = false;
}
return flag;
}
/**
* 验证手机号码
*
* @return
*/
public static boolean checkMobileNumber(String mobileNumber) {
boolean flag = false;
try {
Pattern regex = Pattern
.compile("^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8})|(0\\d{2}-\\d{8})|(0\\d{3}-\\d{7})$");
Matcher matcher = regex.matcher(mobileNumber);
flag = matcher.matches();
} catch (Exception e) {
flag = false;
}
return flag;
}
/**
* 读取txt里的单行内容
*
* 文件路径
*/
public static String readTxtFile(String fileP) {
try {
String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")) + "../../"; // 项目路径
filePath = filePath.replaceAll("file:/", "");
filePath = filePath.replaceAll("%20", " ");
filePath = filePath.trim() + fileP.trim();
if (filePath.indexOf(":") != 1) {
filePath = File.separator + filePath;
}
String encoding = "utf-8";
File file = new File(filePath);
if (file.isFile() && file.exists()) { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding); // 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
return lineTxt;
}
read.close();
} else {
System.out.println("找不到指定的文件,查看此路径是否正确:" + filePath);
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
}
return "";
}
public static String appMd5(File file) {
MessageDigest digest = null;
FileInputStream fis = null;
byte[] buffer = new byte[1024];
try {
if (!file.isFile()) {
return "";
}
digest = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
while (true) {
int len;
if ((len = fis.read(buffer, 0, 1024)) == -1) {
fis.close();
break;
}
digest.update(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
BigInteger var5 = new BigInteger(1, digest.digest());
return String.format("%1$032x", new Object[]{var5});
}
public static void main(String[] args) {
//;
//System.out.println("---------------"+DigestUtils.sha256Hex("123456"));
try {
System.out.println("---------------"+CDESCrypt.encryptString("123456", "suke1728"));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -1,33 +0,0 @@
package com.suke.czx.common.utils;
import java.util.Calendar;
/**
* Created by czx on 2017/9/19.
*/
public class UUIDS {
public static String getDateUUID(){
Calendar Cld = Calendar.getInstance();
int YY = Cld.get(Calendar.YEAR) ;
int MM = Cld.get(Calendar.MONTH)+1;
int DD = Cld.get(Calendar.DATE);
int HH = Cld.get(Calendar.HOUR_OF_DAY);
int mm = Cld.get(Calendar.MINUTE);
int SS = Cld.get(Calendar.SECOND);
int MI = Cld.get(Calendar.MILLISECOND);
int number = (int)(Math.random()*999);
return YY + "" + MM + "" + DD + "" + HH + "" + mm + "" + SS + "" + MI + "" + number;
}
public static String getDateTime(){
Calendar Cld = Calendar.getInstance();
int YY = Cld.get(Calendar.YEAR) ;
int MM = Cld.get(Calendar.MONTH)+1;
int DD = Cld.get(Calendar.DATE);
int HH = Cld.get(Calendar.HOUR_OF_DAY);
int mm = Cld.get(Calendar.MINUTE);
int SS = Cld.get(Calendar.SECOND);
return YY + "" + MM + "" + DD + "" + HH + "" + mm + "" + SS;
}
}

View File

@@ -1,10 +0,0 @@
package com.suke.czx.common.validator.group;
/**
* 新增数据 Group
* @author czx
* @email object_czx@163.com
* @date 2017-03-16 0:04
*/
public interface AddGroup {
}

View File

@@ -1,10 +0,0 @@
package com.suke.czx.common.validator.group;
/**
* 阿里云
* @author czx
* @email object_czx@163.com
* @date 2017-03-28 13:51
*/
public interface AliyunGroup {
}

View File

@@ -1,14 +0,0 @@
package com.suke.czx.common.validator.group;
import javax.validation.GroupSequence;
/**
* 定义校验顺序如果AddGroup组失败则UpdateGroup组不会再校验
* @author czx
* @email object_czx@163.com
* @date 2017-03-15 23:15
*/
@GroupSequence({AddGroup.class, UpdateGroup.class})
public interface Group {
}

View File

@@ -1,10 +0,0 @@
package com.suke.czx.common.validator.group;
/**
* 腾讯云
* @author czx
* @email object_czx@163.com
* @date 2017-03-28 13:51
*/
public interface QcloudGroup {
}

View File

@@ -1,10 +0,0 @@
package com.suke.czx.common.validator.group;
/**
* 七牛
* @author czx
* @email object_czx@163.com
* @date 2017-03-28 13:51
*/
public interface QiniuGroup {
}

View File

@@ -1,12 +0,0 @@
package com.suke.czx.common.validator.group;
/**
* 更新数据 Group
* @author czx
* @email object_czx@163.com
* @date 2017-03-15 21:21
*/
public interface UpdateGroup {
}

View File

@@ -1,6 +1,7 @@
package com.suke.czx.config; package com.suke.czx.config;
import com.suke.czx.common.xss.XssFilter; import com.suke.czx.common.xss.XssFilter;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -40,4 +41,5 @@ public class FilterConfig {
registration.setOrder(Integer.MAX_VALUE); registration.setOrder(Integer.MAX_VALUE);
return registration; return registration;
} }
} }

View File

@@ -0,0 +1,21 @@
package com.suke.czx.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@MapperScan(value = "com.suke.czx.modules.*.mapper")
public class MyBatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}

View File

@@ -1,57 +0,0 @@
package com.suke.czx.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis配置
*
* @author czx
* @email object_czx@163.com
* @date 2017-07-70 19:22
*/
@Configuration
public class RedisConfig {
@Autowired
private RedisConnectionFactory factory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}

View File

@@ -0,0 +1,33 @@
package com.suke.czx.config;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* RedisTemplate 配置
*/
@EnableCaching
@Configuration
@ConditionalOnBean(RedisConnectionFactory.class)
@AllArgsConstructor
public class RedisTemplateConfig {
private final RedisConnectionFactory redisConnectionFactory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}

View File

@@ -1,7 +1,7 @@
package com.suke.czx.config; package com.suke.czx.config;
import com.suke.czx.modules.sys.oauth2.OAuth2Filter; import com.suke.czx.authentication.OAuth2Filter;
import com.suke.czx.modules.sys.oauth2.OAuth2Realm; import com.suke.czx.authentication.OAuth2Realm;
import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.LifecycleBeanPostProcessor;
@@ -50,25 +50,23 @@ public class ShiroConfig {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager); shiroFilter.setSecurityManager(securityManager);
shiroFilter.setLoginUrl("/sys/unauthorized");
shiroFilter.setUnauthorizedUrl("/sys/unauthorized");
//oauth过滤 //oauth过滤
Map<String, Filter> filters = new HashMap<>(); Map<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new OAuth2Filter()); filters.put("oauth2", new OAuth2Filter());
shiroFilter.setFilters(filters); shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>(); Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/webjars/**", "anon"); filterMap.put("/actuator/**", "anon");
filterMap.put("/druid/**", "anon"); filterMap.put("/app/**", "anon"); //APP 模块开放 后面通过拦截器管理
filterMap.put("/app/**", "anon"); filterMap.put("/sys/login", "anon"); //用户密码登录
filterMap.put("/sys/login", "anon"); filterMap.put("/sys/unauthorized", "anon"); //未认证
filterMap.put("/**/*.css", "anon"); filterMap.put("/sys/code/**", "anon"); //验证码
filterMap.put("/**/*.js", "anon"); filterMap.put("/mobile/code/**", "anon"); //短信验证码
filterMap.put("/**/*.html", "anon"); filterMap.put("/mobile/login/**", "anon"); //手机短信登录
filterMap.put("/v2/**", "anon"); filterMap.put("/v2/**", "anon");
filterMap.put("/fonts/**", "anon");
filterMap.put("/plugins/**", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/favicon.ico", "anon");
filterMap.put("/captcha.jpg", "anon");
filterMap.put("/", "anon"); filterMap.put("/", "anon");
filterMap.put("/**", "oauth2"); filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap); shiroFilter.setFilterChainDefinitionMap(filterMap);

View File

@@ -1,29 +1,36 @@
package com.suke.czx.modules.app.config; package com.suke.czx.config;
import com.suke.czx.modules.app.interceptor.AuthorizationInterceptor; import com.suke.czx.interceptor.AuthorizationInterceptor;
import com.suke.czx.modules.app.resolver.LoginUserHandlerMethodArgumentResolver; import com.suke.czx.interceptor.LoginUserHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List; import java.util.List;
/** /**
* MVC配置 * MVC配置
*
* @author czx * @author czx
* @email object_czx@163.com * @email object_czx@163.com
* @date 2017-04-20 22:30 * @date 2019-04-18 22:30
*/ */
@Configuration @Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter { public class WebMvcConfig implements WebMvcConfigurer {
@Autowired @Autowired
private AuthorizationInterceptor authorizationInterceptor; private AuthorizationInterceptor authorizationInterceptor;
@Autowired @Autowired
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver; private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
/**
* @Author czx
* @Description //TODO 因为在shiro中放开了对/app 下的鉴权所有这里加了一个拦截器针对/app
* @Date 14:45 2019/4/19
* @Param [registry]
* @return void
**/
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/app/**"); registry.addInterceptor(authorizationInterceptor).addPathPatterns("/app/**");
@@ -33,4 +40,17 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter {
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserHandlerMethodArgumentResolver); argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
} }
/**
* 跨域支持
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600 * 24);
}
} }

View File

@@ -1,14 +0,0 @@
package com.suke.czx.datasources;
/**
* 增加多数据源,在此配置
*
* @author czx
* @email object_czx@163.com
* @date 2017/8/18 23:46
*/
public interface DataSourceNames {
String FIRST = "first";
String SECOND = "second";
}

View File

@@ -1,13 +0,0 @@
package com.suke.czx.datasources;
import com.suke.czx.modules.user.entity.UserEntity;
/**
* Created by czx on 2018/3/15.
*/
public interface DataSourceTestInterface {
UserEntity queryObject(Long userId);
UserEntity queryObject2(Long userId);
}

View File

@@ -1,31 +0,0 @@
package com.suke.czx.datasources;
import com.suke.czx.datasources.annotation.DataSource;
import com.suke.czx.modules.user.entity.UserEntity;
import com.suke.czx.modules.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 测试
* @author czx
* @email object_czx@163.com
* @date 2017/9/16 23:10
*/
@Service
public class DataSourceTestService implements DataSourceTestInterface{
@Autowired
private UserService userService;
@Override
public UserEntity queryObject(Long userId){
return userService.queryObject(userId);
}
@DataSource(name = DataSourceNames.SECOND)
@Override
public UserEntity queryObject2(Long userId){
return userService.queryObject(userId);
}
}

View File

@@ -1,41 +0,0 @@
package com.suke.czx.datasources;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 动态数据源
* @author czx
* @email object_czx@163.com
* @date 2017/8/19 1:03
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(new HashMap<>(targetDataSources));
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}

View File

@@ -1,42 +0,0 @@
package com.suke.czx.datasources;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 配置多数据源
* @author czx
* @email object_czx@163.com
* @date 2017/8/19 0:41
*/
@Configuration
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.first")
public DataSource firstDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.second")
public DataSource secondDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
Map<String, DataSource> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
return new DynamicDataSource(firstDataSource, targetDataSources);
}
}

View File

@@ -1,16 +0,0 @@
package com.suke.czx.datasources.annotation;
import java.lang.annotation.*;
/**
* 多数据源注解
* @author czx
* @email object_czx@163.com
* @date 2017/9/16 22:16
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String name() default "";
}

View File

@@ -1,109 +0,0 @@
package com.suke.czx.datasources.aspect;
import com.suke.czx.datasources.DataSourceNames;
import com.suke.czx.datasources.DynamicDataSource;
import com.suke.czx.datasources.annotation.DataSource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 多数据源,切面处理类
* @author czx
* @email object_czx@163.com
* @date 2017/9/16 22:20
*/
@Aspect
@Component
public class DataSourceAspect implements Ordered {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.suke.czx.datasources.annotation.DataSource)")
public void dataSourcePointCut() {
}
/* @Before("dataSourcePointCut()")
public void around(JoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource ds = method.getAnnotation(DataSource.class);
if(ds == null){
DynamicDataSource.setDataSource(DataSourceNames.FIRST);
logger.debug("set datasource is " + DataSourceNames.FIRST);
}else {
DynamicDataSource.setDataSource(ds.name());
logger.debug("set datasource is " + ds.name());
}
}*/
/**
* 拦截目标方法,获取由@DataSource指定的数据源标识设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
@Before("dataSourcePointCut()")
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}
/**
* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSource.setDataSource(source.name());
logger.debug("set datasource is " + source.name());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null) {
if (m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSource.setDataSource(source.name());
logger.debug("set datasource is " + source.name());
}
} else {
DynamicDataSource.setDataSource(DataSourceNames.FIRST);
logger.debug("set datasource is " + DataSourceNames.FIRST);
}
} catch (Exception e) {
logger.debug(clazz + ":" + e.getMessage());
}
}
@After("dataSourcePointCut()")
public void after(){
DynamicDataSource.clearDataSource();
}
@Override
public int getOrder() {
return 1;
}
}

View File

@@ -1,10 +1,10 @@
package com.suke.czx.modules.app.interceptor; package com.suke.czx.interceptor;
import io.jsonwebtoken.Claims; import com.suke.czx.common.annotation.AuthIgnore;
import com.suke.czx.modules.sys.entity.SysUserToken;
import com.suke.czx.modules.sys.service.ShiroService;
import com.suke.czx.common.exception.RRException; import com.suke.czx.common.exception.RRException;
import com.suke.czx.modules.app.utils.JwtUtils;
import com.suke.czx.modules.app.annotation.Login;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@@ -23,42 +23,46 @@ import javax.servlet.http.HttpServletResponse;
*/ */
@Component @Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter { public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Autowired @Autowired
private JwtUtils jwtUtils; private ShiroService shiroService;
public static final String USER_KEY = "userId"; public static final String USER_KEY = "userId";
public static final String TOKEN = "token";
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Login annotation; AuthIgnore annotation;
if(handler instanceof HandlerMethod) { if(handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class); annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
}else{ }else{
return true; return true;
} }
if(annotation == null){ if(annotation != null){
return true; return true;
} }
//获取用户凭证 //获取用户凭证
String token = request.getHeader(jwtUtils.getHeader()); String token = request.getHeader(TOKEN);
if(StringUtils.isBlank(token)){ if(StringUtils.isBlank(token)){
token = request.getParameter(jwtUtils.getHeader()); token = request.getParameter(TOKEN);
} }
//凭证为空 //凭证为空
if(StringUtils.isBlank(token)){ if(StringUtils.isBlank(token)){
throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value()); throw new RRException(TOKEN + "不能为空", HttpStatus.UNAUTHORIZED.value());
} }
Claims claims = jwtUtils.getClaimByToken(token); //根据accessToken查询用户信息
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){ SysUserToken tokenEntity = shiroService.queryByToken(token);
throw new RRException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value()); //token失效
if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
throw new RRException("token:" + token + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
} }
//设置userId到request里后续根据userId获取用户信息 //设置userId到request里后续根据userId获取用户信息
request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject())); request.setAttribute(USER_KEY, tokenEntity.getUserId());
return true; return true;
} }

View File

@@ -1,9 +1,8 @@
package com.suke.czx.modules.app.resolver; package com.suke.czx.interceptor;
import com.suke.czx.modules.app.annotation.LoginUser; import com.suke.czx.common.annotation.LoginUser;
import com.suke.czx.modules.app.interceptor.AuthorizationInterceptor; import com.suke.czx.modules.sys.entity.SysUser;
import com.suke.czx.modules.user.entity.UserEntity; import com.suke.czx.modules.sys.service.SysUserService;
import com.suke.czx.modules.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -22,11 +21,11 @@ import org.springframework.web.method.support.ModelAndViewContainer;
@Component @Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired @Autowired
private UserService userService; private SysUserService sysUserService;
@Override @Override
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class); return parameter.getParameterType().isAssignableFrom(SysUser.class) && parameter.hasParameterAnnotation(LoginUser.class);
} }
@Override @Override
@@ -38,7 +37,7 @@ public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgu
} }
//获取用户信息 //获取用户信息
UserEntity user = userService.queryObject((Long)object); SysUser user = sysUserService.getById((Long)object);
return user; return user;
} }

View File

@@ -1,15 +0,0 @@
package com.suke.czx.modules.app.annotation;
import java.lang.annotation.*;
/**
* app登录效验
* @author czx
* @email object_czx@163.com
* @date 2017/9/23 14:30
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Login {
}

View File

@@ -1,15 +0,0 @@
package com.suke.czx.modules.app.annotation;
import java.lang.annotation.*;
/**
* app版本校验
* @author czx
* @email object_czx@163.com
* @date 2017/9/23 14:30
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface VersionCheck {
}

View File

@@ -1,67 +0,0 @@
package com.suke.czx.modules.app.controller;
import com.google.gson.Gson;
import com.suke.czx.common.exception.RRException;
import com.suke.czx.common.utils.AppBaseResult;
import com.suke.czx.common.validator.Assert;
import com.suke.czx.modules.app.service.user.AppUserService;
import com.suke.czx.modules.app.utils.JwtUtils;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* APP登录授权
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-23 15:31
*/
@RestController
@RequestMapping("/app")
public class ApiLoginController {
private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
@Resource(name = "appUserService")
private AppUserService appUserService;
@Autowired
private JwtUtils jwtUtils;
@ApiOperation(value = "用户登录", notes = "用户登录后返回token和用户信息", response = String.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 401, message = "token失效"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@PostMapping("login")
public AppBaseResult login(@RequestBody AppBaseResult appBaseResult) throws Exception {
logger.info("用户登录",appBaseResult.decryptData());
HashMap<String,Object> pd = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
Assert.isNull(pd.get("mobile"), "手机号不能为空");
Assert.isNull(pd.get("password"), "密码不能为空");
if (!Assert.checkCellphone(pd.get("mobile").toString())){
throw new RRException("请输入正确的手机号");
}
//用户登录
HashMap<String,Object> user = appUserService.queryByMobile(pd);
//生成token
String token = jwtUtils.generateToken(user.get("user_id"));
user.put("token", token);
user.put("expire", jwtUtils.getExpire());
return AppBaseResult.success().setEncryptData(user);
}
}

View File

@@ -1,39 +0,0 @@
package com.suke.czx.modules.app.controller;
import com.google.gson.Gson;
import com.suke.czx.common.utils.AppBaseResult;
import com.suke.czx.common.validator.Assert;
import com.suke.czx.modules.app.service.user.AppUserService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
/**
* 注册
* @author czx
* @email object_czx@163.com
* @date 2017-03-26 17:27
*/
@RestController
@RequestMapping("/app")
public class ApiRegisterController {
@Resource(name = "appUserService")
private AppUserService appUserService;
/**
* 注册
*/
@PostMapping("register")
public AppBaseResult register(@RequestBody AppBaseResult appBaseResult) throws Exception {
HashMap<String,Object> pd = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
Assert.isNull(pd.get("mobile"), "手机号不能为空");
Assert.isNull(pd.get("password"), "密码不能为空");
appUserService.save(pd);
return AppBaseResult.success();
}
}

View File

@@ -1,50 +0,0 @@
package com.suke.czx.modules.app.controller;
import com.suke.czx.common.utils.R;
import com.suke.czx.modules.app.annotation.AuthIgnore;
import com.suke.czx.modules.app.annotation.Login;
import com.suke.czx.modules.app.annotation.LoginUser;
import com.suke.czx.modules.user.entity.UserEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* APP测试接口
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-23 15:47
*/
@RestController
@RequestMapping("/app")
public class ApiTestController {
/**
* 获取用户信息
*/
@Login
@GetMapping("userInfo")
public R userInfo(@LoginUser UserEntity user){
return R.ok().put("user", user);
}
/**
* 获取用户ID
*/
@Login
@GetMapping("userId")
public R userInfo(@RequestAttribute("userId") Integer userId){
return R.ok().put("userId", userId);
}
/**
* 忽略Token验证测试
*/
@AuthIgnore
@GetMapping("notToken")
public R notToken(){
return R.ok().put("msg", "无需token也能访问。。。");
}
}

View File

@@ -0,0 +1,38 @@
package com.suke.czx.modules.app.controller;
import com.suke.czx.common.annotation.AuthIgnore;
import com.suke.czx.common.annotation.LoginUser;
import com.suke.czx.common.base.AbstractController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/app")
public class TestController extends AbstractController {
/**
* @Author czx
* @Description //TODO 需要token
* @Date 14:42 2019/4/19
* @Param [userId]
* @return java.lang.String
**/
@RequestMapping(value = "/getUserId")
public String getUserId(@LoginUser String userId){
return "userId:" + userId;
}
/**
* @Author czx
* @Description //TODO 不需要token
* @Date 14:43 2019/4/19
* @Param []
* @return java.lang.String
**/
@AuthIgnore
@RequestMapping(value = "/hello")
public String hello(){
return "--------------------hello";
}
}

View File

@@ -1,107 +0,0 @@
package com.suke.czx.modules.app.controller.appUpdate;
import java.util.HashMap;
import com.google.gson.Gson;
import com.suke.czx.common.utils.*;
import java.util.List;
import org.slf4j.LoggerFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestBody;
import com.suke.czx.modules.app.service.appUpdate.AppUpdateService;
import javax.annotation.Resource;
/**
* APP版本管理
*
* @author czx
* @email object_czx@163.com
* @date 2018-01-05 15:28:57
*/
@Api(value = "API - AppUpdateController ", description = "APP版本管理")
@RestController
@RequestMapping("/app")
public class AppUpdateController {
private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
@Resource(name = "appUpdateService")
private AppUpdateService appUpdateService;
/**
* 列表
*/
@ApiOperation(value="列表", notes="列表")
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/list")
public AppBaseResult list(@RequestBody AppBaseResult appBaseResult)throws Exception{
logger.info("AppUpdateController 列表",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
//查询列表数据
Query query = new Query(params);
query.isPaging(true);
List<HashMap<String,Object>> appUpdateList = appUpdateService.queryList(query);
PageUtils pageUtil = new PageUtils(appUpdateList, query.getTotle(), query.getLimit(), query.getPage());
return AppBaseResult.success().setEncryptData(pageUtil);
}
/**
* 信息
*/
@ApiOperation(value="信息", notes="信息")
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/info")
public AppBaseResult info(@RequestBody AppBaseResult appBaseResult)throws Exception{
logger.info("AppUpdateController 信息",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
HashMap<String,Object> data = appUpdateService.queryObject(params);
return AppBaseResult.success().setEncryptData(data);
}
/**
* 保存
*/
@ApiOperation(value="保存", notes="保存")
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/save")
public AppBaseResult save(@RequestBody AppBaseResult appBaseResult)throws Exception{
logger.info("AppUpdateController 保存",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
appUpdateService.saveInfo(params);
return AppBaseResult.success();
}
/**
* 修改
*/
@ApiOperation(value="修改", notes="修改")
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/update")
public AppBaseResult update(@RequestBody AppBaseResult appBaseResult)throws Exception{
logger.info("AppUpdateController 修改",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
appUpdateService.updateInfo(params);
return AppBaseResult.success();
}
/**
* 删除
*/
@ApiOperation(value="删除", notes="删除")
@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", required = true,dataType = "string", paramType = "query", defaultValue = "")})
@PostMapping("/appUpdate/delete")
public AppBaseResult delete(@RequestBody AppBaseResult appBaseResult)throws Exception{
logger.info("AppUpdateController 修改",appBaseResult.decryptData());
HashMap<String,Object> params = new Gson().fromJson(appBaseResult.decryptData(),HashMap.class);
appUpdateService.deleteInfo(params);
return AppBaseResult.success();
}
}

View File

@@ -1,100 +0,0 @@
package com.suke.czx.modules.app.dao;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.List;
/**
* DAO
* @author czx
* @email yzcheng90@qq.com
* @date 2017-12-21 10:40:37
*/
@Repository("daoSupport")
public class DaoSupport {
@Autowired
private SqlSession sqlSession;
/**
* 保存对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object save(String str, Object obj) throws Exception {
return sqlSession.insert(str, obj);
}
/**
* 批量更新
* @param str
* @return
* @throws Exception
*/
public Object batchSave(String str, List objs )throws Exception{
return sqlSession.insert(str, objs);
}
/**
* 修改对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object update(String str, Object obj) throws Exception {
return sqlSession.update(str, obj);
}
/**
* 批量更新
* @param str
* @return
* @throws Exception
*/
public Object batchDelete(String str, List objs )throws Exception{
return sqlSession.delete(str, objs);
}
/**
* 删除对象
* @param str
* @return
* @throws Exception
*/
public Object delete(String str, Object obj) throws Exception {
return sqlSession.delete(str, obj);
}
/**
* 查找对象
* @param str
* @return
* @throws Exception
*/
public HashMap<String,Object> findForObject(String str, Object obj) throws Exception {
return sqlSession.selectOne(str, obj);
}
/**
* 查找对象
* @param str
* @return
* @throws Exception
*/
public List<HashMap<String,Object>> findForList(String str, Object obj) throws Exception {
return sqlSession.selectList(str, obj);
}
public Object findForMap(String str, Object obj, String key, String value) throws Exception {
return sqlSession.selectMap(str, obj, key);
}
}

View File

@@ -1,135 +0,0 @@
package com.suke.czx.modules.app.interceptor;
import com.suke.czx.common.utils.Query;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.MappedStatement.Builder;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
/**
* 分页用拦截器
* Created by czx on 2017/11/15.
*/
@Intercepts({@Signature(type=Executor.class,method="query",args={ MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })})
public class PageInterceptor implements Interceptor{
public Object intercept(Invocation invocation) throws Throwable {
//当前环境 MappedStatementBoundSql及sql取得
MappedStatement mappedStatement=(MappedStatement)invocation.getArgs()[0];
Object parameter = invocation.getArgs()[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String originalSql = boundSql.getSql().trim();
Object parameterObject = boundSql.getParameterObject();
Query queryPage = searchPageWithXpath(parameterObject,".","paging");
if(queryPage!=null ){
//Page对象存在的场合开始分页处理
String countSql = getCountSql(originalSql);
Connection connection=mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection() ;
PreparedStatement countStmt = connection.prepareStatement(countSql);
BoundSql countBS = copyFromBoundSql(mappedStatement, boundSql, countSql);
DefaultParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBS);
parameterHandler.setParameters(countStmt);
ResultSet rs = countStmt.executeQuery();
int totpage=0;
if (rs.next()) {
totpage = rs.getInt(1);
}
rs.close();
countStmt.close();
connection.close();
queryPage.setTotle(totpage);
//对原始Sql追加limit
int offset = (int)queryPage.get("offset");
StringBuffer sb = new StringBuffer();
sb.append(originalSql).append(" limit ").append(offset).append(",").append(queryPage.getLimit());
BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, sb.toString());
MappedStatement newMs = copyFromMappedStatement(mappedStatement,new BoundSqlSqlSource(newBoundSql));
invocation.getArgs()[0]= newMs;
}
return invocation.proceed();
}
private Query searchPageWithXpath(Object o,String... xpaths) {
if (o instanceof Query) {
Query query = (Query) o;
for(String xpath : xpaths){
if(query.containsKey(xpath)){
return query;
}
}
}
return null;
}
/**
* 复制MappedStatement对象
*/
private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {
Builder builder = new Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());
builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
//builder.key(ms.getK());
builder.timeout(ms.getTimeout());
builder.parameterMap(ms.getParameterMap());
builder.resultMaps(ms.getResultMaps());
builder.resultSetType(ms.getResultSetType());
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());
return builder.build();
}
/**
* 复制BoundSql对象
*/
private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) {
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(),sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
for (ParameterMapping mapping : boundSql.getParameterMappings()) {
String prop = mapping.getProperty();
if (boundSql.hasAdditionalParameter(prop)) {
newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
}
}
return newBoundSql;
}
/**
* 根据原Sql语句获取对应的查询总记录数的Sql语句
*/
private String getCountSql(String sql) {
return "SELECT COUNT(*) FROM (" + sql + ") aliasForPage";
}
public class BoundSqlSqlSource implements SqlSource {
BoundSql boundSql;
public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}
public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}
public Object plugin(Object arg0) {
return Plugin.wrap(arg0, this);
}
public void setProperties(Properties arg0) {
}
}

View File

@@ -1,74 +0,0 @@
package com.suke.czx.modules.app.service;
import com.suke.czx.modules.app.dao.DaoSupport;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
/**
* Created by czx on 2017/12/21.
*/
public class ServiceSupport {
@Resource(name = "daoSupport")
private DaoSupport dao;
/**
* 保存对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object insert(String str, Object obj) throws Exception{
return dao.save(str,obj);
}
/**
* 修改对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object update(String str, Object obj) throws Exception{
return dao.update(str,obj);
}
/**
* 删除对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object delete(String str, Object obj) throws Exception{
return dao.delete(str,obj);
}
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public HashMap<String,Object> findForObject(String str, Object obj) throws Exception{
return dao.findForObject(str,obj);
}
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public List<HashMap<String,Object>> findForList(String str, Object obj) throws Exception{
return dao.findForList(str,obj);
}
}

View File

@@ -1,47 +0,0 @@
package com.suke.czx.modules.app.service.appUpdate;
import com.suke.czx.modules.app.service.ServiceSupport;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
/**
* APP版本管理
*
* @author czx
* @email object_czx@163.com
* @date 2018-01-05 15:28:57
*/
@Service("appUpdateService")
public class AppUpdateService extends ServiceSupport{
public HashMap<String,Object> queryObject(HashMap<String,Object> param) throws Exception{
return findForObject("appUpdate.AppUpdateDao.queryObject",param);
}
public List<HashMap<String,Object>> queryList(HashMap<String,Object> param) throws Exception{
return findForList("appUpdate.AppUpdateDao.queryList",param);
}
public void saveInfo(HashMap<String,Object> param) throws Exception{
insert("appUpdate.AppUpdateDao.save",param);
}
public void updateInfo(HashMap<String,Object> param) throws Exception{
update("appUpdate.AppUpdateDao.update",param);
}
public void deleteInfo(HashMap<String,Object> param) throws Exception{
delete("appUpdate.AppUpdateDao.delete",param);
}
public void deleteBatch(HashMap<String,Object> param) throws Exception{
delete("appUpdate.AppUpdateDao.deleteBatch",param);
}
}

View File

@@ -1,49 +0,0 @@
package com.suke.czx.modules.app.service.user;
import com.suke.czx.common.exception.RRException;
import com.suke.czx.common.validator.Assert;
import com.suke.czx.modules.app.service.ServiceSupport;
import com.suke.czx.modules.user.entity.UserEntity;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
/**
* Created by czx on 2018/1/5.
*/
@Service("appUserService")
public class AppUserService extends ServiceSupport {
/**
* 根据手机号查询用户
* @return
* @throws Exception
*/
public HashMap<String,Object> queryByMobile(HashMap<String,Object> param) throws Exception {
String mobile = param.get("mobile").toString();
String password = param.get("password").toString();
HashMap<String,Object> user = findForObject("api.AppUserDao.queryByMobile", mobile);
Assert.isNull(user, "用户不存在");
//密码错误
String userpassword = DigestUtils.sha256Hex(password);
if(!user.get("password").equals(userpassword)){
throw new RRException("密码错误");
}
return user;
}
/**
* 注册用户
* @throws Exception
*/
public void save(HashMap<String,Object> param) throws Exception {
String password = param.get("password").toString();
param.put("password",DigestUtils.sha256Hex(password));
param.put("createTime",new Date());
insert("api.AppUserDao.save",param);
}
}

View File

@@ -1,88 +0,0 @@
package com.suke.czx.modules.app.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* jwt工具类
* @author czx
* @email object_czx@163.com
* @date 2017/9/21 22:21
*/
@ConfigurationProperties(prefix = "jwtconfig.jwt")
@Component
public class JwtUtils {
private Logger logger = LoggerFactory.getLogger(getClass());
private String secret;
private long expire;
private String header;
/**
* 生成jwt token
*/
public String generateToken(Object userId) {
Date nowDate = new Date();
//过期时间
Date expireDate = new Date(nowDate.getTime() + expire * 1000);
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setSubject(userId.toString())
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
logger.debug("validate is token error ", e);
return null;
}
}
/**
* token是否过期
* @return true过期
*/
public boolean isTokenExpired(Date expiration) {
return expiration.before(new Date());
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public long getExpire() {
return expire;
}
public void setExpire(long expire) {
this.expire = expire;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
}

View File

@@ -1,55 +0,0 @@
package com.suke.czx.modules.job.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.util.Properties;
/**
* 定时任务配置
*
* @author czx
* @email object_czx@163.com
* @date 2017-04-20 23:38
*/
@Configuration
public class ScheduleConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
//quartz参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
//线程池配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
//JobStore配置
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
//集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
factory.setQuartzProperties(prop);
factory.setSchedulerName("RenrenScheduler");
//延时启动
factory.setStartupDelay(30);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
//可选QuartzScheduler 启动时更新己存在的Job这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
//设置自动启动默认为true
factory.setAutoStartup(true);
return factory;
}
}

View File

@@ -1,133 +0,0 @@
package com.suke.czx.modules.job.controller;
import com.suke.czx.common.annotation.SysLog;
import com.suke.czx.common.utils.PageUtils;
import com.suke.czx.common.utils.Query;
import com.suke.czx.common.utils.R;
import com.suke.czx.common.validator.ValidatorUtils;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import com.suke.czx.modules.job.service.ScheduleJobService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 定时任务
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月28日 下午2:16:40
*/
@RestController
@RequestMapping("/sys/schedule")
public class ScheduleJobController {
@Autowired
private ScheduleJobService scheduleJobService;
/**
* 定时任务列表
*/
@RequestMapping("/list")
@RequiresPermissions("sys:schedule:list")
public R list(@RequestParam Map<String, Object> params){
//查询列表数据
Query query = new Query(params);
List<ScheduleJobEntity> jobList = scheduleJobService.queryList(query);
int total = scheduleJobService.queryTotal(query);
PageUtils pageUtil = new PageUtils(jobList, total, query.getLimit(), query.getPage());
return R.ok().put("page", pageUtil);
}
/**
* 定时任务信息
*/
@RequestMapping("/info/{jobId}")
@RequiresPermissions("sys:schedule:info")
public R info(@PathVariable("jobId") Long jobId){
ScheduleJobEntity schedule = scheduleJobService.queryObject(jobId);
return R.ok().put("schedule", schedule);
}
/**
* 保存定时任务
*/
@SysLog("保存定时任务")
@RequestMapping("/save")
@RequiresPermissions("sys:schedule:save")
public R save(@RequestBody ScheduleJobEntity scheduleJob){
ValidatorUtils.validateEntity(scheduleJob);
scheduleJobService.save(scheduleJob);
return R.ok();
}
/**
* 修改定时任务
*/
@SysLog("修改定时任务")
@RequestMapping("/update")
@RequiresPermissions("sys:schedule:update")
public R update(@RequestBody ScheduleJobEntity scheduleJob){
ValidatorUtils.validateEntity(scheduleJob);
scheduleJobService.update(scheduleJob);
return R.ok();
}
/**
* 删除定时任务
*/
@SysLog("删除定时任务")
@RequestMapping("/delete")
@RequiresPermissions("sys:schedule:delete")
public R delete(@RequestBody Long[] jobIds){
scheduleJobService.deleteBatch(jobIds);
return R.ok();
}
/**
* 立即执行任务
*/
@SysLog("立即执行任务")
@RequestMapping("/run")
@RequiresPermissions("sys:schedule:run")
public R run(@RequestBody Long[] jobIds){
scheduleJobService.run(jobIds);
return R.ok();
}
/**
* 暂停定时任务
*/
@SysLog("暂停定时任务")
@RequestMapping("/pause")
@RequiresPermissions("sys:schedule:pause")
public R pause(@RequestBody Long[] jobIds){
scheduleJobService.pause(jobIds);
return R.ok();
}
/**
* 恢复定时任务
*/
@SysLog("恢复定时任务")
@RequestMapping("/resume")
@RequiresPermissions("sys:schedule:resume")
public R resume(@RequestBody Long[] jobIds){
scheduleJobService.resume(jobIds);
return R.ok();
}
}

View File

@@ -1,56 +0,0 @@
package com.suke.czx.modules.job.controller;
import com.suke.czx.common.utils.PageUtils;
import com.suke.czx.modules.job.entity.ScheduleJobLogEntity;
import com.suke.czx.modules.job.service.ScheduleJobLogService;
import com.suke.czx.common.utils.Query;
import com.suke.czx.common.utils.R;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* 定时任务日志
*
* @author czx
* @email object_czx@163.com
* @date 2016年12月1日 下午10:39:52
*/
@RestController
@RequestMapping("/sys/scheduleLog")
public class ScheduleJobLogController {
@Autowired
private ScheduleJobLogService scheduleJobLogService;
/**
* 定时任务日志列表
*/
@RequestMapping("/list")
@RequiresPermissions("sys:schedule:log")
public R list(@RequestParam Map<String, Object> params){
//查询列表数据
Query query = new Query(params);
List<ScheduleJobLogEntity> jobList = scheduleJobLogService.queryList(query);
int total = scheduleJobLogService.queryTotal(query);
PageUtils pageUtil = new PageUtils(jobList, total, query.getLimit(), query.getPage());
return R.ok().put("page", pageUtil);
}
/**
* 定时任务日志信息
*/
@RequestMapping("/info/{logId}")
public R info(@PathVariable("logId") Long logId){
ScheduleJobLogEntity log = scheduleJobLogService.queryObject(logId);
return R.ok().put("log", log);
}
}

View File

@@ -1,23 +0,0 @@
package com.suke.czx.modules.job.dao;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import com.suke.czx.modules.sys.dao.BaseDao;
import org.apache.ibatis.annotations.Mapper;
import java.util.Map;
/**
* 定时任务
*
* @author czx
* @email object_czx@163.com
* @date 2016年12月1日 下午10:29:57
*/
@Mapper
public interface ScheduleJobDao extends BaseDao<ScheduleJobEntity> {
/**
* 批量更新状态
*/
int updateBatch(Map<String, Object> map);
}

View File

@@ -1,17 +0,0 @@
package com.suke.czx.modules.job.dao;
import com.suke.czx.modules.job.entity.ScheduleJobLogEntity;
import com.suke.czx.modules.sys.dao.BaseDao;
import org.apache.ibatis.annotations.Mapper;
/**
* 定时任务日志
*
* @author czx
* @email object_czx@163.com
* @date 2016年12月1日 下午10:30:02
*/
@Mapper
public interface ScheduleJobLogDao extends BaseDao<ScheduleJobLogEntity> {
}

View File

@@ -1,161 +0,0 @@
package com.suke.czx.modules.job.entity;
import org.hibernate.validator.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
/**
* 定时器
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月28日 下午12:54:44
*/
public class ScheduleJobEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 任务调度参数key
*/
public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
/**
* 任务id
*/
private Long jobId;
/**
* spring bean名称
*/
@NotBlank(message="bean名称不能为空")
private String beanName;
/**
* 方法名
*/
@NotBlank(message="方法名称不能为空")
private String methodName;
/**
* 参数
*/
private String params;
/**
* cron表达式
*/
@NotBlank(message="cron表达式不能为空")
private String cronExpression;
/**
* 任务状态 0正常 1暂停
*/
private Integer status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private Date createTime;
/**
* 设置任务id
* @param jobId 任务id
*/
public void setJobId(Long jobId) {
this.jobId = jobId;
}
/**
* 获取任务id
* @return Long
*/
public Long getJobId() {
return jobId;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
/**
* 设置:任务状态
* @param status 任务状态
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* 获取:任务状态
* @return String
*/
public Integer getStatus() {
return status;
}
/**
* 设置cron表达式
* @param cronExpression cron表达式
*/
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
/**
* 获取cron表达式
* @return String
*/
public String getCronExpression() {
return cronExpression;
}
/**
* 设置:创建时间
* @param createTime 创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取:创建时间
* @return Date
*/
public Date getCreateTime() {
return createTime;
}
}

View File

@@ -1,133 +0,0 @@
package com.suke.czx.modules.job.entity;
import java.io.Serializable;
import java.util.Date;
/**
* 定时执行日志
*
* @author czx
* @email object_czx@163.com
* @date 2016年12月1日 下午10:26:18
*/
public class ScheduleJobLogEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 日志id
*/
private Long logId;
/**
* 任务id
*/
private Long jobId;
/**
* spring bean名称
*/
private String beanName;
/**
* 方法名
*/
private String methodName;
/**
* 参数
*/
private String params;
/**
* 任务状态 0成功 1失败
*/
private Integer status;
/**
* 失败信息
*/
private String error;
/**
* 耗时(单位:毫秒)
*/
private Integer times;
/**
* 创建时间
*/
private Date createTime;
public Long getLogId() {
return logId;
}
public void setLogId(Long logId) {
this.logId = logId;
}
public Long getJobId() {
return jobId;
}
public void setJobId(Long jobId) {
this.jobId = jobId;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public Integer getTimes() {
return times;
}
public void setTimes(Integer times) {
this.times = times;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@@ -1,37 +0,0 @@
package com.suke.czx.modules.job.service;
import com.suke.czx.modules.job.entity.ScheduleJobLogEntity;
import java.util.List;
import java.util.Map;
/**
* 定时任务日志
*
* @author czx
* @email object_czx@163.com
* @date 2016年12月1日 下午10:34:48
*/
public interface ScheduleJobLogService {
/**
* 根据ID查询定时任务日志
*/
ScheduleJobLogEntity queryObject(Long jobId);
/**
* 查询定时任务日志列表
*/
List<ScheduleJobLogEntity> queryList(Map<String, Object> map);
/**
* 查询总数
*/
int queryTotal(Map<String, Object> map);
/**
* 保存定时任务日志
*/
void save(ScheduleJobLogEntity log);
}

View File

@@ -1,66 +0,0 @@
package com.suke.czx.modules.job.service;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import java.util.List;
import java.util.Map;
/**
* 定时任务
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月28日 上午9:55:32
*/
public interface ScheduleJobService {
/**
* 根据ID查询定时任务
*/
ScheduleJobEntity queryObject(Long jobId);
/**
* 查询定时任务列表
*/
List<ScheduleJobEntity> queryList(Map<String, Object> map);
/**
* 查询总数
*/
int queryTotal(Map<String, Object> map);
/**
* 保存定时任务
*/
void save(ScheduleJobEntity scheduleJob);
/**
* 更新定时任务
*/
void update(ScheduleJobEntity scheduleJob);
/**
* 批量删除定时任务
*/
void deleteBatch(Long[] jobIds);
/**
* 批量更新定时任务状态
*/
int updateBatch(Long[] jobIds, int status);
/**
* 立即执行
*/
void run(Long[] jobIds);
/**
* 暂停运行
*/
void pause(Long[] jobIds);
/**
* 恢复运行
*/
void resume(Long[] jobIds);
}

View File

@@ -1,38 +0,0 @@
package com.suke.czx.modules.job.service.impl;
import com.suke.czx.modules.job.dao.ScheduleJobLogDao;
import com.suke.czx.modules.job.entity.ScheduleJobLogEntity;
import com.suke.czx.modules.job.service.ScheduleJobLogService;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("scheduleJobLogService")
public class ScheduleJobLogServiceImpl implements ScheduleJobLogService {
@Autowired
private ScheduleJobLogDao scheduleJobLogDao;
@Override
public ScheduleJobLogEntity queryObject(Long jobId) {
return scheduleJobLogDao.queryObject(jobId);
}
@Override
public List<ScheduleJobLogEntity> queryList(Map<String, Object> map) {
return scheduleJobLogDao.queryList(map);
}
@Override
public int queryTotal(Map<String, Object> map) {
return scheduleJobLogDao.queryTotal(map);
}
@Override
public void save(ScheduleJobLogEntity log) {
scheduleJobLogDao.save(log);
}
}

View File

@@ -1,126 +0,0 @@
package com.suke.czx.modules.job.service.impl;
import com.suke.czx.common.utils.Constant;
import com.suke.czx.modules.job.dao.ScheduleJobDao;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import com.suke.czx.modules.job.service.ScheduleJobService;
import com.suke.czx.modules.job.utils.ScheduleUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {
@Autowired
private Scheduler scheduler;
@Autowired
private ScheduleJobDao schedulerJobDao;
/**
* 项目启动时,初始化定时器
*/
@PostConstruct
public void init(){
List<ScheduleJobEntity> scheduleJobList = schedulerJobDao.queryList(new HashMap<>());
for(ScheduleJobEntity scheduleJob : scheduleJobList){
CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
//如果不存在,则创建
if(cronTrigger == null) {
ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
}else {
ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
}
}
}
@Override
public ScheduleJobEntity queryObject(Long jobId) {
return schedulerJobDao.queryObject(jobId);
}
@Override
public List<ScheduleJobEntity> queryList(Map<String, Object> map) {
return schedulerJobDao.queryList(map);
}
@Override
public int queryTotal(Map<String, Object> map) {
return schedulerJobDao.queryTotal(map);
}
@Override
@Transactional
public void save(ScheduleJobEntity scheduleJob) {
scheduleJob.setCreateTime(new Date());
scheduleJob.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
schedulerJobDao.save(scheduleJob);
ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
}
@Override
@Transactional
public void update(ScheduleJobEntity scheduleJob) {
ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
schedulerJobDao.update(scheduleJob);
}
@Override
@Transactional
public void deleteBatch(Long[] jobIds) {
for(Long jobId : jobIds){
ScheduleUtils.deleteScheduleJob(scheduler, jobId);
}
//删除数据
schedulerJobDao.deleteBatch(jobIds);
}
@Override
public int updateBatch(Long[] jobIds, int status){
Map<String, Object> map = new HashMap<>();
map.put("list", jobIds);
map.put("status", status);
return schedulerJobDao.updateBatch(map);
}
@Override
@Transactional
public void run(Long[] jobIds) {
for(Long jobId : jobIds){
ScheduleUtils.run(scheduler, queryObject(jobId));
}
}
@Override
@Transactional
public void pause(Long[] jobIds) {
for(Long jobId : jobIds){
ScheduleUtils.pauseJob(scheduler, jobId);
}
updateBatch(jobIds, Constant.ScheduleStatus.PAUSE.getValue());
}
@Override
@Transactional
public void resume(Long[] jobIds) {
for(Long jobId : jobIds){
ScheduleUtils.resumeJob(scheduler, jobId);
}
updateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue());
}
}

View File

@@ -1,47 +0,0 @@
package com.suke.czx.modules.job.task;
import com.suke.czx.modules.sys.entity.SysUserEntity;
import com.suke.czx.modules.sys.service.SysUserService;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 测试定时任务(演示Demo可删除)
*
* testTask为spring bean的名称
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月30日 下午1:34:24
*/
@Component("testTask")
public class TestTask {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private SysUserService sysUserService;
//定时任务只能接受一个参数如果有多个参数使用json数据即可
public void test(String params){
logger.info("我是带参数的test方法正在被执行参数为" + params);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
SysUserEntity user = sysUserService.queryObject(1L);
System.out.println(ToStringBuilder.reflectionToString(user));
}
public void test2(){
logger.info("我是不带参数的test2方法正在被执行");
}
}

View File

@@ -1,81 +0,0 @@
package com.suke.czx.modules.job.utils;
import com.google.gson.Gson;
import com.suke.czx.common.utils.SpringContextUtils;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import com.suke.czx.modules.job.entity.ScheduleJobLogEntity;
import com.suke.czx.modules.job.service.ScheduleJobLogService;
import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 定时任务
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月30日 下午12:44:21
*/
public class ScheduleJob extends QuartzJobBean {
private Logger logger = LoggerFactory.getLogger(getClass());
private ExecutorService service = Executors.newSingleThreadExecutor();
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
String jsonJob = context.getMergedJobDataMap().getString(ScheduleJobEntity.JOB_PARAM_KEY);
ScheduleJobEntity scheduleJob = new Gson().fromJson(jsonJob, ScheduleJobEntity.class);
//获取scheduleJobLogService
ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService) SpringContextUtils.getBean("scheduleJobLogService");
//数据库保存执行记录
ScheduleJobLogEntity log = new ScheduleJobLogEntity();
log.setJobId(scheduleJob.getJobId());
log.setBeanName(scheduleJob.getBeanName());
log.setMethodName(scheduleJob.getMethodName());
log.setParams(scheduleJob.getParams());
log.setCreateTime(new Date());
//任务开始时间
long startTime = System.currentTimeMillis();
try {
//执行任务
logger.info("任务准备执行任务ID" + scheduleJob.getJobId());
ScheduleRunnable task = new ScheduleRunnable(scheduleJob.getBeanName(),
scheduleJob.getMethodName(), scheduleJob.getParams());
Future<?> future = service.submit(task);
future.get();
//任务执行总时长
long times = System.currentTimeMillis() - startTime;
log.setTimes((int)times);
//任务状态 0成功 1失败
log.setStatus(0);
logger.info("任务执行完毕任务ID" + scheduleJob.getJobId() + " 总共耗时:" + times + "毫秒");
} catch (Exception e) {
logger.error("任务执行失败任务ID" + scheduleJob.getJobId(), e);
//任务执行总时长
long times = System.currentTimeMillis() - startTime;
log.setTimes((int)times);
//任务状态 0成功 1失败
log.setStatus(1);
log.setError(StringUtils.substring(e.toString(), 0, 2000));
}finally {
scheduleJobLogService.save(log);
}
}
}

View File

@@ -1,47 +0,0 @@
package com.suke.czx.modules.job.utils;
import com.suke.czx.common.utils.SpringContextUtils;
import com.suke.czx.common.exception.RRException;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
/**
* 执行定时任务
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月30日 下午12:49:33
*/
public class ScheduleRunnable implements Runnable {
private Object target;
private Method method;
private String params;
public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException {
this.target = SpringContextUtils.getBean(beanName);
this.params = params;
if(StringUtils.isNotBlank(params)){
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
}else{
this.method = target.getClass().getDeclaredMethod(methodName);
}
}
@Override
public void run() {
try {
ReflectionUtils.makeAccessible(method);
if(StringUtils.isNotBlank(params)){
method.invoke(target, params);
}else{
method.invoke(target);
}
}catch (Exception e) {
throw new RRException("执行定时任务失败", e);
}
}
}

View File

@@ -1,152 +0,0 @@
package com.suke.czx.modules.job.utils;
import com.google.gson.Gson;
import com.suke.czx.common.exception.RRException;
import com.suke.czx.modules.job.entity.ScheduleJobEntity;
import com.suke.czx.common.utils.Constant.ScheduleStatus;
import org.quartz.*;
/**
* 定时任务工具类
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月30日 下午12:44:59
*/
public class ScheduleUtils {
private final static String JOB_NAME = "TASK_";
/**
* 获取触发器key
*/
private static TriggerKey getTriggerKey(Long jobId) {
return TriggerKey.triggerKey(JOB_NAME + jobId);
}
/**
* 获取jobKey
*/
private static JobKey getJobKey(Long jobId) {
return JobKey.jobKey(JOB_NAME + jobId);
}
/**
* 获取表达式触发器
*/
public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
try {
return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
} catch (SchedulerException e) {
throw new RRException("getCronTrigger异常请检查qrtz开头的表是否有脏数据", e);
}
}
/**
* 创建定时任务
*/
public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
try {
//构建job
JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getJobId())).build();
//构建cron
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
.withMisfireHandlingInstructionDoNothing();
//根据cron构建一个CronTrigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getJobId())).
withSchedule(scheduleBuilder).build();
//放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, new Gson().toJson(scheduleJob));
scheduler.scheduleJob(jobDetail, trigger);
//暂停任务
if(scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()){
pauseJob(scheduler, scheduleJob.getJobId());
}
} catch (SchedulerException e) {
throw new RRException("创建定时任务失败", e);
}
}
/**
* 更新定时任务
*/
public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
try {
TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId());
//表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
.withMisfireHandlingInstructionDoNothing();
CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId());
//按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//参数
trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, new Gson().toJson(scheduleJob));
scheduler.rescheduleJob(triggerKey, trigger);
//暂停任务
if(scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()){
pauseJob(scheduler, scheduleJob.getJobId());
}
} catch (SchedulerException e) {
throw new RRException("更新定时任务失败", e);
}
}
/**
* 立即执行任务
*/
public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
try {
//参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, new Gson().toJson(scheduleJob));
scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap);
} catch (SchedulerException e) {
throw new RRException("立即执行定时任务失败", e);
}
}
/**
* 暂停任务
*/
public static void pauseJob(Scheduler scheduler, Long jobId) {
try {
scheduler.pauseJob(getJobKey(jobId));
} catch (SchedulerException e) {
throw new RRException("暂停定时任务失败", e);
}
}
/**
* 恢复任务
*/
public static void resumeJob(Scheduler scheduler, Long jobId) {
try {
scheduler.resumeJob(getJobKey(jobId));
} catch (SchedulerException e) {
throw new RRException("暂停定时任务失败", e);
}
}
/**
* 删除定时任务
*/
public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
try {
scheduler.deleteJob(getJobKey(jobId));
} catch (SchedulerException e) {
throw new RRException("删除定时任务失败", e);
}
}
}

View File

@@ -1,12 +1,10 @@
package com.suke.czx.modules.oss.cloud; package com.suke.czx.modules.oss.cloud;
import com.suke.czx.common.validator.group.AliyunGroup; import lombok.Data;
import com.suke.czx.common.validator.group.QiniuGroup;
import com.suke.czx.common.validator.group.QcloudGroup;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.URL; import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@@ -16,219 +14,84 @@ import java.io.Serializable;
* @email object_czx@163.com * @email object_czx@163.com
* @date 2017-03-25 16:12 * @date 2017-03-25 16:12
*/ */
@Data
public class CloudStorageConfig implements Serializable { public class CloudStorageConfig implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
//类型 1七牛 2阿里云 3腾讯云 //类型 1七牛 2阿里云 3腾讯云 4minio
@Range(min=1, max=3, message = "类型错误") @Range(min=1, max=4, message = "类型错误")
private Integer type; private Integer type;
//七牛绑定的域名 //七牛绑定的域名
@NotBlank(message="七牛绑定的域名不能为空", groups = QiniuGroup.class) @NotBlank(message="七牛绑定的域名不能为空")
@URL(message = "七牛绑定的域名格式不正确", groups = QiniuGroup.class) @URL(message = "七牛绑定的域名格式不正确")
private String qiniuDomain; private String qiniuDomain;
//七牛路径前缀 //七牛路径前缀
private String qiniuPrefix; private String qiniuPrefix;
//七牛ACCESS_KEY //七牛ACCESS_KEY
@NotBlank(message="七牛AccessKey不能为空", groups = QiniuGroup.class) @NotBlank(message="七牛AccessKey不能为空")
private String qiniuAccessKey; private String qiniuAccessKey;
//七牛SECRET_KEY //七牛SECRET_KEY
@NotBlank(message="七牛SecretKey不能为空", groups = QiniuGroup.class) @NotBlank(message="七牛SecretKey不能为空")
private String qiniuSecretKey; private String qiniuSecretKey;
//七牛存储空间名 //七牛存储空间名
@NotBlank(message="七牛空间名不能为空", groups = QiniuGroup.class) @NotBlank(message="七牛空间名不能为空")
private String qiniuBucketName; private String qiniuBucketName;
//阿里云绑定的域名 //阿里云绑定的域名
@NotBlank(message="阿里云绑定的域名不能为空", groups = AliyunGroup.class) @NotBlank(message="阿里云绑定的域名不能为空")
@URL(message = "阿里云绑定的域名格式不正确", groups = AliyunGroup.class) @URL(message = "阿里云绑定的域名格式不正确")
private String aliyunDomain; private String aliyunDomain;
//阿里云路径前缀 //阿里云路径前缀
private String aliyunPrefix; private String aliyunPrefix;
//阿里云EndPoint //阿里云EndPoint
@NotBlank(message="阿里云EndPoint不能为空", groups = AliyunGroup.class) @NotBlank(message="阿里云EndPoint不能为空")
private String aliyunEndPoint; private String aliyunEndPoint;
//阿里云AccessKeyId //阿里云AccessKeyId
@NotBlank(message="阿里云AccessKeyId不能为空", groups = AliyunGroup.class) @NotBlank(message="阿里云AccessKeyId不能为空")
private String aliyunAccessKeyId; private String aliyunAccessKeyId;
//阿里云AccessKeySecret //阿里云AccessKeySecret
@NotBlank(message="阿里云AccessKeySecret不能为空", groups = AliyunGroup.class) @NotBlank(message="阿里云AccessKeySecret不能为空")
private String aliyunAccessKeySecret; private String aliyunAccessKeySecret;
//阿里云BucketName //阿里云BucketName
@NotBlank(message="阿里云BucketName不能为空", groups = AliyunGroup.class) @NotBlank(message="阿里云BucketName不能为空")
private String aliyunBucketName; private String aliyunBucketName;
//腾讯云绑定的域名 //腾讯云绑定的域名
@NotBlank(message="腾讯云绑定的域名不能为空", groups = QcloudGroup.class) @NotBlank(message="腾讯云绑定的域名不能为空")
@URL(message = "腾讯云绑定的域名格式不正确", groups = QcloudGroup.class) @URL(message = "腾讯云绑定的域名格式不正确")
private String qcloudDomain; private String qcloudDomain;
//腾讯云路径前缀 //腾讯云路径前缀
private String qcloudPrefix; private String qcloudPrefix;
//腾讯云AppId //腾讯云AppId
@NotNull(message="腾讯云AppId不能为空", groups = QcloudGroup.class) @NotNull(message="腾讯云AppId不能为空")
private Integer qcloudAppId; private Integer qcloudAppId;
//腾讯云SecretId //腾讯云SecretId
@NotBlank(message="腾讯云SecretId不能为空", groups = QcloudGroup.class) @NotBlank(message="腾讯云SecretId不能为空")
private String qcloudSecretId; private String qcloudSecretId;
//腾讯云SecretKey //腾讯云SecretKey
@NotBlank(message="腾讯云SecretKey不能为空", groups = QcloudGroup.class) @NotBlank(message="腾讯云SecretKey不能为空")
private String qcloudSecretKey; private String qcloudSecretKey;
//腾讯云BucketName //腾讯云BucketName
@NotBlank(message="腾讯云BucketName不能为空", groups = QcloudGroup.class) @NotBlank(message="腾讯云BucketName不能为空")
private String qcloudBucketName; private String qcloudBucketName;
//腾讯云COS所属地区 //腾讯云COS所属地区
@NotBlank(message="所属地区不能为空", groups = QcloudGroup.class) @NotBlank(message="所属地区不能为空")
private String qcloudRegion; private String qcloudRegion;
public Integer getType() {
return type;
}
public void setType(Integer type) { //minio
this.type = type; @NotBlank(message="minio服务器地址")
} @URL(message = "minio服务器地址格式不正确")
private String minioUrl;
//access-key (用户名)
@NotNull(message="minio-accessKey不能为空")
private String minioAccessKey;
//secret-key (密码)
@NotNull(message="minio-secretKey不能为空")
private String minioSecretKey;
//bucketName (桶)
@NotNull(message="minio-bucketName不能为空")
private String minioBucketName;
public String getQiniuDomain() {
return qiniuDomain;
}
public void setQiniuDomain(String qiniuDomain) {
this.qiniuDomain = qiniuDomain;
}
public String getQiniuAccessKey() {
return qiniuAccessKey;
}
public void setQiniuAccessKey(String qiniuAccessKey) {
this.qiniuAccessKey = qiniuAccessKey;
}
public String getQiniuSecretKey() {
return qiniuSecretKey;
}
public void setQiniuSecretKey(String qiniuSecretKey) {
this.qiniuSecretKey = qiniuSecretKey;
}
public String getQiniuBucketName() {
return qiniuBucketName;
}
public void setQiniuBucketName(String qiniuBucketName) {
this.qiniuBucketName = qiniuBucketName;
}
public String getQiniuPrefix() {
return qiniuPrefix;
}
public void setQiniuPrefix(String qiniuPrefix) {
this.qiniuPrefix = qiniuPrefix;
}
public String getAliyunDomain() {
return aliyunDomain;
}
public void setAliyunDomain(String aliyunDomain) {
this.aliyunDomain = aliyunDomain;
}
public String getAliyunPrefix() {
return aliyunPrefix;
}
public void setAliyunPrefix(String aliyunPrefix) {
this.aliyunPrefix = aliyunPrefix;
}
public String getAliyunEndPoint() {
return aliyunEndPoint;
}
public void setAliyunEndPoint(String aliyunEndPoint) {
this.aliyunEndPoint = aliyunEndPoint;
}
public String getAliyunAccessKeyId() {
return aliyunAccessKeyId;
}
public void setAliyunAccessKeyId(String aliyunAccessKeyId) {
this.aliyunAccessKeyId = aliyunAccessKeyId;
}
public String getAliyunAccessKeySecret() {
return aliyunAccessKeySecret;
}
public void setAliyunAccessKeySecret(String aliyunAccessKeySecret) {
this.aliyunAccessKeySecret = aliyunAccessKeySecret;
}
public String getAliyunBucketName() {
return aliyunBucketName;
}
public void setAliyunBucketName(String aliyunBucketName) {
this.aliyunBucketName = aliyunBucketName;
}
public String getQcloudDomain() {
return qcloudDomain;
}
public void setQcloudDomain(String qcloudDomain) {
this.qcloudDomain = qcloudDomain;
}
public String getQcloudPrefix() {
return qcloudPrefix;
}
public void setQcloudPrefix(String qcloudPrefix) {
this.qcloudPrefix = qcloudPrefix;
}
public Integer getQcloudAppId() {
return qcloudAppId;
}
public void setQcloudAppId(Integer qcloudAppId) {
this.qcloudAppId = qcloudAppId;
}
public String getQcloudSecretId() {
return qcloudSecretId;
}
public void setQcloudSecretId(String qcloudSecretId) {
this.qcloudSecretId = qcloudSecretId;
}
public String getQcloudSecretKey() {
return qcloudSecretKey;
}
public void setQcloudSecretKey(String qcloudSecretKey) {
this.qcloudSecretKey = qcloudSecretKey;
}
public String getQcloudBucketName() {
return qcloudBucketName;
}
public void setQcloudBucketName(String qcloudBucketName) {
this.qcloudBucketName = qcloudBucketName;
}
public String getQcloudRegion() {
return qcloudRegion;
}
public void setQcloudRegion(String qcloudRegion) {
this.qcloudRegion = qcloudRegion;
}
} }

View File

@@ -1,10 +1,8 @@
package com.suke.czx.modules.oss.cloud; package com.suke.czx.modules.oss.cloud;
import com.suke.czx.common.utils.DateUtils; import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -17,6 +15,13 @@ public abstract class CloudStorageService {
/** 云存储配置信息 */ /** 云存储配置信息 */
CloudStorageConfig config; CloudStorageConfig config;
public String newFileName(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
public String newFileName(String suffix){
return UUID.randomUUID().toString().replaceAll("-", "") + "." + suffix;
}
/** /**
* 文件路径 * 文件路径
* @param prefix 前缀 * @param prefix 前缀
@@ -24,10 +29,9 @@ public abstract class CloudStorageService {
* @return 返回上传路径 * @return 返回上传路径
*/ */
public String getPath(String prefix, String suffix) { public String getPath(String prefix, String suffix) {
//生成uuid
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//文件路径 //文件路径
String path = DateUtils.format(new Date(), "yyyyMMdd") + "/" + uuid; String path = DateUtil.today() + "/" + newFileName();
if(StringUtils.isNotBlank(prefix)){ if(StringUtils.isNotBlank(prefix)){
path = prefix + "/" + path; path = prefix + "/" + path;

View File

@@ -0,0 +1,62 @@
package com.suke.czx.modules.oss.cloud;
import com.suke.czx.common.exception.RRException;
import io.minio.MinioClient;
import lombok.SneakyThrows;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* @Author czx
* @Description //TODO minio 文件存储 具体其他操作看官网 https://docs.min.io/
**/
public class MinioCloudStorageService extends CloudStorageService{
private MinioClient client;
/**
* 外链过期时间,有两种方法
* 1、可以通过命令设置共享域为 public 就可以永久外链了
* 2、可以通过代码层返回文件流
*/
private Integer expires = 7 * 3600;
public MinioCloudStorageService(CloudStorageConfig config){
this.config = config;
//初始化
init();
}
@SneakyThrows
private void init(){
client = new MinioClient(config.getMinioUrl(), config.getMinioAccessKey(), config.getMinioSecretKey());
}
@Override
public String upload(byte[] data, String path) {
return upload(new ByteArrayInputStream(data),path);
}
@Override
public String uploadSuffix(byte[] data, String suffix) {
return upload(data,newFileName(suffix));
}
@SneakyThrows
@Override
public String upload(InputStream inputStream, String path) {
try {
client.putObject(config.getMinioBucketName(), path, inputStream, inputStream.available(), "application/octet-stream");
} catch (Exception e) {
throw new RRException("上传文件失败", e);
}
return client.presignedGetObject(config.getMinioBucketName(), path, expires);
}
@Override
public String uploadSuffix(InputStream inputStream, String suffix) {
return upload(inputStream,newFileName(suffix));
}
}

View File

@@ -28,8 +28,9 @@ public final class OSSFactory {
return new AliyunCloudStorageService(config); return new AliyunCloudStorageService(config);
}else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){ }else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){
return new QcloudCloudStorageService(config); return new QcloudCloudStorageService(config);
}else if(config.getType() == Constant.CloudService.MINIO.getValue()){
return new MinioCloudStorageService(config);
} }
return null; return null;
} }

View File

@@ -1,31 +1,30 @@
package com.suke.czx.modules.oss.controller; package com.suke.czx.modules.oss.controller;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.suke.czx.common.base.AbstractController;
import com.suke.czx.common.exception.RRException; import com.suke.czx.common.exception.RRException;
import com.suke.czx.common.utils.*; import com.suke.czx.common.utils.ConfigConstant;
import com.suke.czx.common.validator.group.AliyunGroup; import com.suke.czx.common.utils.Constant;
import com.suke.czx.common.utils.*; import com.suke.czx.common.utils.R;
import com.suke.czx.common.validator.ValidatorUtils; import com.suke.czx.common.validator.ValidatorUtils;
import com.suke.czx.common.validator.group.QcloudGroup;
import com.suke.czx.common.validator.group.QiniuGroup;
import com.suke.czx.modules.oss.cloud.CloudStorageConfig; import com.suke.czx.modules.oss.cloud.CloudStorageConfig;
import com.suke.czx.modules.oss.cloud.OSSFactory; import com.suke.czx.modules.oss.cloud.OSSFactory;
import com.suke.czx.modules.oss.entity.SysOssEntity; import com.suke.czx.modules.oss.entity.SysOss;
import com.suke.czx.modules.oss.service.SysOssService; import com.suke.czx.modules.oss.service.SysOssService;
import com.suke.czx.modules.sys.service.SysConfigService; import com.suke.czx.modules.sys.service.SysConfigService;
import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* 文件上传 * 文件上传
* *
@@ -35,11 +34,11 @@ import java.util.Map;
*/ */
@RestController @RestController
@RequestMapping("sys/oss") @RequestMapping("sys/oss")
public class SysOssController { @AllArgsConstructor
@Autowired public class SysOssController extends AbstractController {
private SysOssService sysOssService;
@Autowired private final SysOssService sysOssService;
private SysConfigService sysConfigService; private final SysConfigService sysConfigService;
private final static String KEY = ConfigConstant.CLOUD_STORAGE_CONFIG_KEY; private final static String KEY = ConfigConstant.CLOUD_STORAGE_CONFIG_KEY;
@@ -50,13 +49,15 @@ public class SysOssController {
@RequiresPermissions("sys:oss:all") @RequiresPermissions("sys:oss:all")
public R list(@RequestParam Map<String, Object> params){ public R list(@RequestParam Map<String, Object> params){
//查询列表数据 //查询列表数据
Query query = new Query(params); QueryWrapper<SysOss> queryWrapper = new QueryWrapper<>();
List<SysOssEntity> sysOssList = sysOssService.queryList(query); if(MapUtil.getStr(params,"key") != null){
int total = sysOssService.queryTotal(query); queryWrapper
.like("remark",MapUtil.getStr(params,"key"));
}
IPage<SysOss> sysConfigList = sysOssService.page(mpPageConvert.<SysOss>pageParamConvert(params),queryWrapper);
PageUtils pageUtil = new PageUtils(sysOssList, total, query.getLimit(), query.getPage()); return R.ok().put("page", mpPageConvert.pageValueConvert(sysConfigList));
return R.ok().put("page", pageUtil);
} }
@@ -80,21 +81,7 @@ public class SysOssController {
public R saveConfig(@RequestBody CloudStorageConfig config){ public R saveConfig(@RequestBody CloudStorageConfig config){
//校验类型 //校验类型
ValidatorUtils.validateEntity(config); ValidatorUtils.validateEntity(config);
if(config.getType() == Constant.CloudService.QINIU.getValue()){
//校验七牛数据
ValidatorUtils.validateEntity(config, QiniuGroup.class);
}else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){
//校验阿里云数据
ValidatorUtils.validateEntity(config, AliyunGroup.class);
}else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){
//校验腾讯云数据
ValidatorUtils.validateEntity(config, QcloudGroup.class);
}
sysConfigService.updateValueByKey(KEY, new Gson().toJson(config)); sysConfigService.updateValueByKey(KEY, new Gson().toJson(config));
return R.ok(); return R.ok();
} }
@@ -114,7 +101,7 @@ public class SysOssController {
String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix); String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);
//保存文件信息 //保存文件信息
SysOssEntity ossEntity = new SysOssEntity(); SysOss ossEntity = new SysOss();
ossEntity.setUrl(url); ossEntity.setUrl(url);
ossEntity.setCreateDate(new Date()); ossEntity.setCreateDate(new Date());
sysOssService.save(ossEntity); sysOssService.save(ossEntity);
@@ -129,8 +116,7 @@ public class SysOssController {
@RequestMapping("/delete") @RequestMapping("/delete")
@RequiresPermissions("sys:oss:all") @RequiresPermissions("sys:oss:all")
public R delete(@RequestBody Long[] ids){ public R delete(@RequestBody Long[] ids){
sysOssService.deleteBatch(ids); sysOssService.removeById(ids);
return R.ok(); return R.ok();
} }

View File

@@ -1,17 +0,0 @@
package com.suke.czx.modules.oss.dao;
import com.suke.czx.modules.oss.entity.SysOssEntity;
import com.suke.czx.modules.sys.dao.BaseDao;
import org.apache.ibatis.annotations.Mapper;
/**
* 文件上传
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-25 12:13:26
*/
@Mapper
public interface SysOssDao extends BaseDao<SysOssEntity> {
}

View File

@@ -0,0 +1,29 @@
package com.suke.czx.modules.oss.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* 文件上传
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-25 12:13:26
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysOss extends Model<SysOss> implements Serializable {
private static final long serialVersionUID = 1L;
//
private Long id;
//URL地址
private String url;
//创建时间
private Date createDate;
}

View File

@@ -1,61 +0,0 @@
package com.suke.czx.modules.oss.entity;
import java.io.Serializable;
import java.util.Date;
/**
* 文件上传
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-25 12:13:26
*/
public class SysOssEntity implements Serializable {
private static final long serialVersionUID = 1L;
//
private Long id;
//URL地址
private String url;
//创建时间
private Date createDate;
/**
* 设置:
*/
public void setId(Long id) {
this.id = id;
}
/**
* 获取:
*/
public Long getId() {
return id;
}
/**
* 设置URL地址
*/
public void setUrl(String url) {
this.url = url;
}
/**
* 获取URL地址
*/
public String getUrl() {
return url;
}
/**
* 设置:创建时间
*/
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
/**
* 获取:创建时间
*/
public Date getCreateDate() {
return createDate;
}
}

View File

@@ -0,0 +1,15 @@
package com.suke.czx.modules.oss.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suke.czx.modules.oss.entity.SysOss;
/**
* 文件上传
*
* @author czx
* @email object_czx@163.com
* @date 2017-03-25 12:13:26
*/
public interface SysOssMapper extends BaseMapper<SysOss> {
}

View File

@@ -1,9 +1,7 @@
package com.suke.czx.modules.oss.service; package com.suke.czx.modules.oss.service;
import com.suke.czx.modules.oss.entity.SysOssEntity; import com.baomidou.mybatisplus.extension.service.IService;
import com.suke.czx.modules.oss.entity.SysOss;
import java.util.List;
import java.util.Map;
/** /**
* 文件上传 * 文件上传
@@ -12,19 +10,7 @@ import java.util.Map;
* @email object_czx@163.com * @email object_czx@163.com
* @date 2017-03-25 12:13:26 * @date 2017-03-25 12:13:26
*/ */
public interface SysOssService { public interface SysOssService extends IService<SysOss> {
SysOssEntity queryObject(Long id);
List<SysOssEntity> queryList(Map<String, Object> map);
int queryTotal(Map<String, Object> map);
void save(SysOssEntity sysOss);
void update(SysOssEntity sysOss);
void delete(Long id);
void deleteBatch(Long[] ids);
} }

View File

@@ -1,55 +1,17 @@
package com.suke.czx.modules.oss.service.impl; package com.suke.czx.modules.oss.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suke.czx.modules.oss.mapper.SysOssMapper;
import com.suke.czx.modules.oss.entity.SysOss;
import com.suke.czx.modules.oss.service.SysOssService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.suke.czx.modules.oss.dao.SysOssDao;
import com.suke.czx.modules.oss.entity.SysOssEntity;
import com.suke.czx.modules.oss.service.SysOssService;
@Service
@AllArgsConstructor
public class SysOssServiceImpl extends ServiceImpl<SysOssMapper,SysOss> implements SysOssService {
@Service("sysOssService")
public class SysOssServiceImpl implements SysOssService {
@Autowired
private SysOssDao sysOssDao;
@Override
public SysOssEntity queryObject(Long id){
return sysOssDao.queryObject(id);
}
@Override
public List<SysOssEntity> queryList(Map<String, Object> map){
return sysOssDao.queryList(map);
}
@Override
public int queryTotal(Map<String, Object> map){
return sysOssDao.queryTotal(map);
}
@Override
public void save(SysOssEntity sysOss){
sysOssDao.save(sysOss);
}
@Override
public void update(SysOssEntity sysOss){
sysOssDao.update(sysOss);
}
@Override
public void delete(Long id){
sysOssDao.delete(id);
}
@Override
public void deleteBatch(Long[] ids){
sysOssDao.deleteBatch(ids);
}
} }

View File

@@ -1,25 +0,0 @@
package com.suke.czx.modules.sys.controller;
import com.suke.czx.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Controller公共组件
*
* @author czx
* @email object_czx@163.com
* @date 2016年11月9日 下午9:42:26
*/
public abstract class AbstractController {
protected Logger logger = LoggerFactory.getLogger(getClass());
protected SysUserEntity getUser() {
return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
}
protected Long getUserId() {
return getUser().getUserId();
}
}

View File

@@ -1,17 +1,20 @@
package com.suke.czx.modules.sys.controller; package com.suke.czx.modules.sys.controller;
import com.suke.czx.common.utils.PageUtils; import cn.hutool.core.map.MapUtil;
import com.suke.czx.common.utils.Query; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.suke.czx.common.annotation.SysLog;
import com.suke.czx.common.base.AbstractController;
import com.suke.czx.common.utils.R; import com.suke.czx.common.utils.R;
import com.suke.czx.common.validator.ValidatorUtils; import com.suke.czx.common.validator.ValidatorUtils;
import com.suke.czx.modules.sys.entity.SysConfigEntity; import com.suke.czx.modules.sys.entity.SysConfig;
import com.suke.czx.common.annotation.SysLog;
import com.suke.czx.modules.sys.service.SysConfigService; import com.suke.czx.modules.sys.service.SysConfigService;
import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.io.Serializable;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
/** /**
@@ -19,13 +22,13 @@ import java.util.Map;
* *
* @author czx * @author czx
* @email object_czx@163.com * @email object_czx@163.com
* @date 2016年12月4日 下午6:55:53 * @date 2019年4月18日 下午6:55:53
*/ */
@RestController @RestController
@RequestMapping("/sys/config") @RequestMapping("/sys/config")
@AllArgsConstructor
public class SysConfigController extends AbstractController { public class SysConfigController extends AbstractController {
@Autowired private final SysConfigService sysConfigService;
private SysConfigService sysConfigService;
/** /**
* 所有配置列表 * 所有配置列表
@@ -34,13 +37,14 @@ public class SysConfigController extends AbstractController {
@RequiresPermissions("sys:config:list") @RequiresPermissions("sys:config:list")
public R list(@RequestParam Map<String, Object> params){ public R list(@RequestParam Map<String, Object> params){
//查询列表数据 //查询列表数据
Query query = new Query(params); QueryWrapper<SysConfig> queryWrapper = new QueryWrapper<>();
List<SysConfigEntity> configList = sysConfigService.queryList(query); if(MapUtil.getStr(params,"key") != null){
int total = sysConfigService.queryTotal(query); queryWrapper
.like("remark",MapUtil.getStr(params,"key"));
}
IPage<SysConfig> sysConfigList = sysConfigService.page(mpPageConvert.<SysConfig>pageParamConvert(params),queryWrapper);
PageUtils pageUtil = new PageUtils(configList, total, query.getLimit(), query.getPage()); return R.ok().put("page", mpPageConvert.pageValueConvert(sysConfigList));
return R.ok().put("page", pageUtil);
} }
@@ -50,7 +54,7 @@ public class SysConfigController extends AbstractController {
@RequestMapping("/info/{id}") @RequestMapping("/info/{id}")
@RequiresPermissions("sys:config:info") @RequiresPermissions("sys:config:info")
public R info(@PathVariable("id") Long id){ public R info(@PathVariable("id") Long id){
SysConfigEntity config = sysConfigService.queryObject(id); SysConfig config = sysConfigService.getById(id);
return R.ok().put("config", config); return R.ok().put("config", config);
} }
@@ -61,7 +65,7 @@ public class SysConfigController extends AbstractController {
@SysLog("保存配置") @SysLog("保存配置")
@RequestMapping("/save") @RequestMapping("/save")
@RequiresPermissions("sys:config:save") @RequiresPermissions("sys:config:save")
public R save(@RequestBody SysConfigEntity config){ public R save(@RequestBody SysConfig config){
ValidatorUtils.validateEntity(config); ValidatorUtils.validateEntity(config);
sysConfigService.save(config); sysConfigService.save(config);
@@ -75,10 +79,10 @@ public class SysConfigController extends AbstractController {
@SysLog("修改配置") @SysLog("修改配置")
@RequestMapping("/update") @RequestMapping("/update")
@RequiresPermissions("sys:config:update") @RequiresPermissions("sys:config:update")
public R update(@RequestBody SysConfigEntity config){ public R update(@RequestBody SysConfig config){
ValidatorUtils.validateEntity(config); ValidatorUtils.validateEntity(config);
sysConfigService.update(config); sysConfigService.updateById(config);
return R.ok(); return R.ok();
} }
@@ -90,8 +94,7 @@ public class SysConfigController extends AbstractController {
@RequestMapping("/delete") @RequestMapping("/delete")
@RequiresPermissions("sys:config:delete") @RequiresPermissions("sys:config:delete")
public R delete(@RequestBody Long[] ids){ public R delete(@RequestBody Long[] ids){
sysConfigService.deleteBatch(ids); sysConfigService.removeById((Serializable)Arrays.asList(ids));
return R.ok(); return R.ok();
} }

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