4
.gitignore
vendored
4
.gitignore
vendored
@@ -31,3 +31,7 @@ build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Custom ###
|
||||
/application-config.yml
|
||||
data
|
||||
|
||||
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM eclipse-temurin:17-jdk-alpine
|
||||
LABEL authors="FatttSnake"
|
||||
|
||||
VOLUME /data
|
||||
|
||||
ARG EXTRACTED=target/extracted
|
||||
COPY ${EXTRACTED}/dependencies/ /
|
||||
COPY ${EXTRACTED}/spring-boot-loader/ /
|
||||
COPY ${EXTRACTED}/snapshot-dependencies/ /
|
||||
RUN true
|
||||
COPY ${EXTRACTED}/application/ /
|
||||
|
||||
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher", "--spring.config.additional-location=file:data/"]
|
||||
674
LICENSE
Normal file
674
LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://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> <name of author>
|
||||
|
||||
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 <https://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:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
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
|
||||
<https://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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
77
README.md
Normal file
77
README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
<div align="center">
|
||||
<h1>
|
||||
<img alt="Logo" src="doc/logo.svg" width="128">
|
||||
<br>
|
||||
<span>API of Oxygen Toolbox</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div align="center">
|
||||
<a href="https://ci.fatweb.top/job/Oxygen%20Toolbox%20API/">
|
||||
<img alt="Build" src="https://ci.fatweb.top/job/Oxygen%20Toolbox%20API/badge/icon">
|
||||
</a>
|
||||
<a href="https://github.com/FatttSnake/oxygen-api/releases/latest">
|
||||
<img alt="Release" src="https://img.shields.io/github/v/release/FatttSnake/oxygen-api">
|
||||
</a>
|
||||
<a href="LICENSE">
|
||||
<img alt="LICENSE" src="https://img.shields.io/github/license/FatttSnake/oxygen-api">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
# Overview ([ZH](README_zh.md), EN)
|
||||
|
||||
This project is the backend API of Oxygen Toolbox. Provides tool store, tool management, authentication, user management and other functions.
|
||||
|
||||
# Requires
|
||||
|
||||
- Java 17+
|
||||
- MySQL
|
||||
- Redis
|
||||
|
||||
# Related projects
|
||||
|
||||
[Web UI of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-ui)
|
||||
|
||||
[Desktop Client of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-desktop)
|
||||
|
||||
[Android Client of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-android)
|
||||
|
||||
# Quick Start
|
||||
|
||||
1. First run, generate configuration file template
|
||||
|
||||
```shell
|
||||
java -jar oxygen-api.jar
|
||||
```
|
||||
|
||||
2. Copy the `application-config.example.yml` file in the `data` directory to the running directory and rename it to `application-config.yml`
|
||||
|
||||
```shell
|
||||
cp ./data/application-config.example.yml application-config.yml
|
||||
```
|
||||
|
||||
3. Edit the content of the configuration file `application-config.yml`
|
||||
|
||||
|
||||
4. Run again
|
||||
|
||||
```shell
|
||||
java -jar oxygen-api.jar
|
||||
```
|
||||
|
||||
# Security
|
||||
|
||||
Integration with Spring Security and add other filter for jwt token process. The secret key is stored in `application-config.yml`.
|
||||
|
||||
# Database
|
||||
|
||||
Two databases, MySQL + SQLite, are used. MySQL is used to store key data, and SQLite is used to store logs and other data that require a large amount of reading and writing.
|
||||
|
||||
# Q&A
|
||||
|
||||
> **Q: What is the default administrator account and password?**
|
||||
>
|
||||
> A: If configured in `application-config.yml` before initializing the database, use the specified account and password. If not configured, a random password will be generated by default. See the console output for details.
|
||||
|
||||
> **Q: Do I need to initialize the database?**
|
||||
>
|
||||
> A: This project uses `Flyway` to automatically initialize the database without manually defining the data table structure. To ensure data security, please back up the database before upgrading.
|
||||
77
README_zh.md
Normal file
77
README_zh.md
Normal file
@@ -0,0 +1,77 @@
|
||||
<div align="center">
|
||||
<h1>
|
||||
<img alt="Logo" src="doc/logo.svg" width="128">
|
||||
<br>
|
||||
<span>API of Oxygen Toolbox</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div align="center">
|
||||
<a href="https://ci.fatweb.top/job/Oxygen%20Toolbox%20API/">
|
||||
<img alt="Build" src="https://ci.fatweb.top/job/Oxygen%20Toolbox%20API/badge/icon">
|
||||
</a>
|
||||
<a href="https://github.com/FatttSnake/oxygen-api/releases/latest">
|
||||
<img alt="Release" src="https://img.shields.io/github/v/release/FatttSnake/oxygen-api">
|
||||
</a>
|
||||
<a href="LICENSE">
|
||||
<img alt="LICENSE" src="https://img.shields.io/github/license/FatttSnake/oxygen-api">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
# 概述 (ZH, [EN](README.md))
|
||||
|
||||
本项目为 Oxygen Toolbox 的后端 API。提供工具商店、工具管理、认证鉴权、用户管理等功能。
|
||||
|
||||
# 环境要求
|
||||
|
||||
- Java 17+
|
||||
- MySQL
|
||||
- Redis
|
||||
|
||||
# 关联项目
|
||||
|
||||
[Web UI of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-ui)
|
||||
|
||||
[Desktop Client of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-desktop)
|
||||
|
||||
[Android Client of Oxygen Toolbox](https://github.com/FatttSnake/oxygen-android)
|
||||
|
||||
# 快速开始
|
||||
|
||||
1. 初次运行,生成配置文件模板
|
||||
|
||||
```shell
|
||||
java -jar oxygen-api.jar
|
||||
```
|
||||
|
||||
2. 将 `data` 目录下的 `application-config.example.yml` 文件复制到运行目录下,并重命名为 `application-config.yml`
|
||||
|
||||
```shell
|
||||
cp ./data/application-config.example.yml application-config.yml
|
||||
```
|
||||
|
||||
3. 编辑配置文件 `application-config.yml` 内容
|
||||
|
||||
|
||||
4. 再次运行
|
||||
|
||||
```shell
|
||||
java -jar oxygen-api.jar
|
||||
```
|
||||
|
||||
# 安全
|
||||
|
||||
集成 Spring Security 并采用 jwt 令牌, 密钥存储在 `application-config.yml` 中。
|
||||
|
||||
# 数据库
|
||||
|
||||
采用 MySQL + SQLite 双数据库,MySQL 用于存放关键数据,SQLite 用于存放日志等需要大量读写的数据。
|
||||
|
||||
# Q&A
|
||||
|
||||
> **Q: 默认管理员账号和密码是什么?**
|
||||
>
|
||||
> A: 初始化数据库前配置在 `application-config.yml` 中,则使用所指定账号密码。未配置则默认生成随机密码,详见控制台输出。
|
||||
|
||||
> **Q: 是否需要初始化数据库?**
|
||||
>
|
||||
> A: 本项目采用 `Flyway` 自动初始化数据库,无需手动定义数据表结构。为保证数据安全,升级时请先备份数据库。
|
||||
19
build-docker.sh
Normal file
19
build-docker.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
JAR_NAME=`ls target | grep oxygen-api- | grep -vE "original|asc|pom|javadoc"`
|
||||
JAR_VERSION=${JAR_NAME%.*}
|
||||
JAR_VERSION=${JAR_VERSION#*-}
|
||||
JAR_VERSION=${JAR_VERSION#*-}
|
||||
BUILD_TIME=$(date "+%Y%m%d%H%M%S")
|
||||
|
||||
echo ${BUILD_TIME} > .build_time
|
||||
|
||||
mkdir target/extracted
|
||||
java -Djarmode=layertools -jar target/${JAR_NAME} extract --destination target/extracted
|
||||
|
||||
if [[ "${JAR_VERSION}" =~ ^.*SNAPSHOT$ ]]
|
||||
then
|
||||
docker build -t ${DOCKER_HUB_URL}/oxygen-api:snapshot-latest -t ${DOCKER_HUB_URL}/oxygen-api:${JAR_VERSION} -t ${DOCKER_HUB_URL}/oxygen-api:${JAR_VERSION}-${BUILD_TIME} .
|
||||
else
|
||||
docker build -t ${DOCKER_HUB_URL}/oxygen-api:latest -t ${DOCKER_HUB_URL}/oxygen-api:${JAR_VERSION} -t ${DOCKER_HUB_URL}/oxygen-api:${JAR_VERSION}-${BUILD_TIME} .
|
||||
fi
|
||||
2073
doc/database.drawio
Normal file
2073
doc/database.drawio
Normal file
File diff suppressed because it is too large
Load Diff
1
doc/logo.svg
Normal file
1
doc/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.9 KiB |
520
doc/permission.drawio
Normal file
520
doc/permission.drawio
Normal file
@@ -0,0 +1,520 @@
|
||||
<mxfile host="Electron" modified="2024-04-09T07:13:23.570Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.18 Chrome/120.0.6099.199 Electron/28.1.2 Safari/537.36" etag="3V7vMcZBLGFwQN8DHP6f" version="22.1.18" type="device">
|
||||
<diagram name="第 1 页" id="R2cIEvIs15c5_Cru6pMt">
|
||||
<mxGraphModel dx="19748" dy="12892" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-4" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-1" target="SDpw32q9kxCI3RyRmRBe-3" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-6" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-1" target="SDpw32q9kxCI3RyRmRBe-3" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-9" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-7" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-11" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-10" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-14" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-13" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-16" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-15" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-18" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-17" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-1" value="系统<br style="font-size: 12px;">1000000" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;flipH=0;flipV=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-15571" y="-7904" width="114" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-23" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-22" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-80" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.25;entryY=0;entryDx=0;entryDy=0;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="JPuPo5tm-n4Eqjx5owfL-21">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-3" value="系统管理<br style="font-size: 12px;">1990000<br>/system" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-15344" y="-7904" width="114" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-25" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-24" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-30" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-29" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-33" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-34" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-35" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-37" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-36" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-7" value="用户管理<br style="font-size: 12px;">1010000<br>^/system/user$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14329" y="-9774" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-46" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-38" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-47" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-39" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-48" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-40" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-49" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-41" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-10" value="角色管理<br style="font-size: 12px;">1020000<br>^/system/role$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14329" y="-9149.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-50" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-42" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-51" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-43" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-52" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-44" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-53" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-45" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-13" value="用户组管理<br style="font-size: 12px;">1030000<br>^/system/group$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14329" y="-8384" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-57" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-15" target="SDpw32q9kxCI3RyRmRBe-56" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-15" value="日志管理<br style="font-size: 12px;">1520000<br>^/system/log$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14329" y="-7734" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-59" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-17" target="SDpw32q9kxCI3RyRmRBe-58" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-61" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-17" target="SDpw32q9kxCI3RyRmRBe-60" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-17" value="系统设置<br style="font-size: 12px;">1530000<br>^/system/settings$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14327.5" y="-7350" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-55" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-22" target="SDpw32q9kxCI3RyRmRBe-54" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-22" value="权限管理<br style="font-size: 12px;">1040000<br>^/system/power$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14329" y="-8073" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-63" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-62" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-78" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-69" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-79" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-71" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-24" value="查询<br style="font-size: 12px;">1010100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9979" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-80" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-29" target="SDpw32q9kxCI3RyRmRBe-72" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-29" value="增加<br style="font-size: 12px;">1010200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9818" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-81" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-32" target="SDpw32q9kxCI3RyRmRBe-73" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-82" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-32" target="SDpw32q9kxCI3RyRmRBe-74" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-32" value="修改<br>1010300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9706" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-83" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-36" target="SDpw32q9kxCI3RyRmRBe-75" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-84" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-36" target="SDpw32q9kxCI3RyRmRBe-77" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-36" value="删除<br>1010400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9557" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-94" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-86" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-95" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-87" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-96" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-88" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-38" value="查询<br style="font-size: 12px;">1020100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9366" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-97" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-39" target="SDpw32q9kxCI3RyRmRBe-89" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-39" value="增加<br style="font-size: 12px;">1020200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9184" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-98" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-40" target="SDpw32q9kxCI3RyRmRBe-90" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-99" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-40" target="SDpw32q9kxCI3RyRmRBe-91" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-40" value="修改<br>1020300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-9052.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-100" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-41" target="SDpw32q9kxCI3RyRmRBe-92" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-102" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-41" target="SDpw32q9kxCI3RyRmRBe-93" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-41" value="删除<br>1020400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8893.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-111" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-103" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-112" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-104" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-113" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-105" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-42" value="查询<br style="font-size: 12px;">1030100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8663" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-114" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-43" target="SDpw32q9kxCI3RyRmRBe-106" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-43" value="增加<br style="font-size: 12px;">1030200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8487" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-115" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-44" target="SDpw32q9kxCI3RyRmRBe-107" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-116" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-44" target="SDpw32q9kxCI3RyRmRBe-108" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-44" value="修改<br>1030300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8354" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-117" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-45" target="SDpw32q9kxCI3RyRmRBe-109" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-118" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-45" target="SDpw32q9kxCI3RyRmRBe-110" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-45" value="删除<br>1030400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8201" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-120" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-54" target="SDpw32q9kxCI3RyRmRBe-119" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-54" value="查询<br>1040100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-8073" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-123" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-56" target="SDpw32q9kxCI3RyRmRBe-122" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-56" value="查询<br>10520100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-7734" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-132" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="SDpw32q9kxCI3RyRmRBe-124" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-133" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="SDpw32q9kxCI3RyRmRBe-127" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-13" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="JPuPo5tm-n4Eqjx5owfL-11">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-14" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="JPuPo5tm-n4Eqjx5owfL-12">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-58" value="查询<br>1530100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14020" y="-7509" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-134" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="SDpw32q9kxCI3RyRmRBe-130" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-136" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="SDpw32q9kxCI3RyRmRBe-131" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-19" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="JPuPo5tm-n4Eqjx5owfL-17">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-20" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="JPuPo5tm-n4Eqjx5owfL-18">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-60" value="修改<br>1530300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-14018.5" y="-7180" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-62" value="单个<br style="font-size: 12px;">1010101<br style="font-size: 12px;">system:user:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-10055" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-69" value="全部<br>1010102<br>system:user:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9979" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-70" value="" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13056" y="-8941" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-71" value="列表<br>1010103<br>system:user:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13753" y="-9903" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-72" value="单个<br>1010201<br>system:user:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9818" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-73" value="单个<br>1010301<br>system:user:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9743" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-74" value="密码<br>1010302<br>system:user:modify:password" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9669" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-75" value="单个<br>1010401<br>system:user:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9592" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-77" value="多个<br>1010402<br>system:user:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9522" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-86" value="单个<br style="font-size: 12px;">1020101<br style="font-size: 12px;">system:role:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9442" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-87" value="全部<br>1020102<br>system:role:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9366" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-88" value="列表<br>1020103<br>system:role:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9290" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-89" value="单个<br>1020201<br>system:role:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9184" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-90" value="单个<br>1020301<br>system:role:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9090" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-91" value="状态<br>1020302<br>system:role:modify:status" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-9015" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-92" value="单个<br>1020401<br>system:role:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8930" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-93" value="多个<br>1020402<br>system:role:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8857" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-103" value="单个<br style="font-size: 12px;">1030101<br style="font-size: 12px;">system:group:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8739" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-104" value="全部<br>1030102<br>system:group:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8663" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-105" value="列表<br>1030103<br>system:group:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8587" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-106" value="单个<br>1030201<br>system:group:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8487" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-107" value="单个<br>1030301<br>system:group:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8391.5" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-108" value="状态<br>1030302<br>system:group:modify:status" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8316.5" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-109" value="单个<br>1030401<br>system:group:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8233" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-110" value="多个<br>1030402<br>system:group:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8160" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-119" value="列表<br>1040103<br>system:power:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-8073" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-122" value="全部<br>1520101<br>system:log:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-7734" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-124" value="基础<br>1520101<br>system:settings:query:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-7629" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-127" value="邮件<br>1520102<br>system:settings:query:mail" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-7552" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-130" value="基础<br>1530301<br>system:settings:modify:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-7299" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-131" value="邮件<br>1530302<br>system:settings:modify:mail" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" parent="1" vertex="1">
|
||||
<mxGeometry x="-13754" y="-7222" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-1" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" source="JPuPo5tm-n4Eqjx5owfL-2" target="JPuPo5tm-n4Eqjx5owfL-4" parent="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-2" value="系统概况<br style="font-size: 12px;">1510000<br>^/system/statistic$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14327.5" y="-7900" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-3" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" source="JPuPo5tm-n4Eqjx5owfL-4" target="JPuPo5tm-n4Eqjx5owfL-5" parent="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-8" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-4" target="JPuPo5tm-n4Eqjx5owfL-7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-9" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-4" target="JPuPo5tm-n4Eqjx5owfL-6">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-4" value="查询<br>10510100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14018.5" y="-7900" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-5" value="使用情况<br>1510101<br>system:statistics:query:usage" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-7980" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-6" value="实时信息<br>1510103<br>system:statistics:query:real" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-7820" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-7" value="基础信息<br>1510102<br>system:statistics:query:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-7900" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-11" value="敏感词<br>1520103<br>system:settings:query:sensitive" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7470" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-12" value="双因素<br>1520104<br>system:settings:query:two-factor" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7393" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-17" value="敏感词<br>1530303<br>system:settings:modify:sensitive" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7140" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-18" value="双因素<br>1530304<br>system:settings:modify:two-factor" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7063" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-75" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-21" target="JPuPo5tm-n4Eqjx5owfL-22">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-76" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-21" target="JPuPo5tm-n4Eqjx5owfL-23">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-78" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-21" target="JPuPo5tm-n4Eqjx5owfL-24">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-79" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-21" target="JPuPo5tm-n4Eqjx5owfL-25">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-21" value="工具配置<br style="font-size: 12px;">1540000<br>^/system/tools(/.*)?$" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-6350" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-59" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-22" target="JPuPo5tm-n4Eqjx5owfL-26">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-60" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-22" target="JPuPo5tm-n4Eqjx5owfL-34">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-61" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-22" target="JPuPo5tm-n4Eqjx5owfL-39">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-62" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-22" target="JPuPo5tm-n4Eqjx5owfL-43">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-22" value="查询<br>1540100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14018.5" y="-6850" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-63" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-23" target="JPuPo5tm-n4Eqjx5owfL-47">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-64" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-23" target="JPuPo5tm-n4Eqjx5owfL-48">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-65" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-23" target="JPuPo5tm-n4Eqjx5owfL-49">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-66" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-23" target="JPuPo5tm-n4Eqjx5owfL-50">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-23" value="增加<br>1540200" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14018.5" y="-6520" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-67" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-24" target="JPuPo5tm-n4Eqjx5owfL-51">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-68" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-24" target="JPuPo5tm-n4Eqjx5owfL-52">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-69" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-24" target="JPuPo5tm-n4Eqjx5owfL-53">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-70" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-24" target="JPuPo5tm-n4Eqjx5owfL-54">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-24" value="修改<br>1540300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14018.5" y="-6190" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-71" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-25" target="JPuPo5tm-n4Eqjx5owfL-55">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-72" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-25" target="JPuPo5tm-n4Eqjx5owfL-56">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-73" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-25" target="JPuPo5tm-n4Eqjx5owfL-57">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-74" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="JPuPo5tm-n4Eqjx5owfL-25" target="JPuPo5tm-n4Eqjx5owfL-58">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-25" value="删除<br>1540400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14018.5" y="-5860" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-26" value="类别<br>1540101<br>system:tool:query:category" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-6970" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-34" value="基板<br>1540102<br>system:tool:query:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-6890" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-39" value="模板<br>1540103<br>system:tool:query:template" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-6810" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-43" value="工具<br>1540104<br>system:tool:query:tool" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-6730" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-47" value="类别<br>1540201<br>system:tool:add:category" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-6640" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-48" value="基板<br>1540202<br>system:tool:add:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13751" y="-6560" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-49" value="模板<br>1540203<br>system:tool:add:template" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13751" y="-6480" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-50" value="工具<br>1540204<br>system:tool:add:tool" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13752.5" y="-6400" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-51" value="类别<br>1540301<br>system:tool:modify:category" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754.75" y="-6310" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-52" value="基板<br>1540302<br>system:tool:modify:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13753.25" y="-6230" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-53" value="模板<br>1540303<br>system:tool:modify:template" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13753.25" y="-6150" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-54" value="工具<br>1540304<br>system:tool:modify:tool" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754.75" y="-6070" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-55" value="类别<br>1540401<br>system:tool:delete:category" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13756.25" y="-5980" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-56" value="基板<br>1540402<br>system:tool:delete:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754.75" y="-5900" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-57" value="模板<br>1540403<br>system:tool:delete:template" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754.75" y="-5820" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JPuPo5tm-n4Eqjx5owfL-58" value="工具<br>1540404<br>system:tool:delete:tool" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13756.25" y="-5740" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
354
pom.xml
354
pom.xml
@@ -5,86 +5,96 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.4</version>
|
||||
<version>3.2.1</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>top.fatweb</groupId>
|
||||
|
||||
<groupId>top.fatweb.oxygen</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>fatweb-api</name>
|
||||
<description>fatweb-api</description>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<name>oxygen-api</name>
|
||||
<description>API of Oxygen Toolbox</description>
|
||||
<url>https://github.com/FatttSnake/oxygen-api</url>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<kotlin.version>1.8.22</kotlin.version>
|
||||
<kotlin.version>1.9.21</kotlin.version>
|
||||
<build.timestamp>${maven.build.timestamp}</build.timestamp>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss</maven.build.timestamp.format>
|
||||
<retrofit.version>3.0.3</retrofit.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<mybatis-plus.version>3.5.7</mybatis-plus.version>
|
||||
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
|
||||
<flyway.version>9.22.3</flyway.version>
|
||||
<jwt.version>4.4.0</jwt.version>
|
||||
<avatar-generator.version>1.1.0</avatar-generator.version>
|
||||
<oshi.version>6.4.9</oshi.version>
|
||||
<zxing.version>3.5.3</zxing.version>
|
||||
<knife4j.version>4.4.0</knife4j.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<organization>
|
||||
<name>FatWeb</name>
|
||||
<url>https://fatweb.top</url>
|
||||
</organization>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU General Public License v3.0 or later</name>
|
||||
<url>https://www.gnu.org/licenses/gpl-3.0-standalone.html</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>fatttsnake</id>
|
||||
<name>FatttSnake</name>
|
||||
<email>fatttsnake@gmail.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<build>
|
||||
<finalName>${project.name}-${project.version}</finalName>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.graalvm.buildtools</groupId>
|
||||
<artifactId>native-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<source>src/main/kotlin</source>
|
||||
<source>target/generated-sources/annotations</source>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<source>src/main/kotlin</source>
|
||||
<source>target/generated-sources/annotations</source>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-Xjsr305=strict</arg>
|
||||
@@ -101,7 +111,229 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.dokka</groupId>
|
||||
<artifactId>dokka-maven-plugin</artifactId>
|
||||
<version>1.9.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>pre-site</phase>
|
||||
<goals>
|
||||
<goal>dokka</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>attach-javadocJar</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>javadocJar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.lianjiatech</groupId>
|
||||
<artifactId>retrofit-spring-boot-starter</artifactId>
|
||||
<version>${retrofit.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||
<version>${dynamic-datasource.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-mysql</artifactId>
|
||||
<version>${flyway.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>${jwt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>top.fatweb</groupId>
|
||||
<artifactId>avatar-generator</artifactId>
|
||||
<version>${avatar-generator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>${oshi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${zxing.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter-test</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
<property>
|
||||
<name>env</name>
|
||||
<value>dev</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env</name>
|
||||
<value>release</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-ui</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>swagger-ui</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifact</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package top.fatweb.api
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication
|
||||
class FatWebApiApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<FatWebApiApplication>(*args)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import org.springframework.scheduling.annotation.EnableScheduling
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Application main class
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
@EnableScheduling
|
||||
class OxygenApiApplication
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*
|
||||
* @param args
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
val logger = LoggerFactory.getLogger("main")
|
||||
|
||||
if (!File("data").isDirectory) {
|
||||
if (!File("data").mkdir()) {
|
||||
logger.error("Can not create directory 'data', please try again later.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!File("data/db").isDirectory) {
|
||||
if (!File("data/db").mkdir()) {
|
||||
logger.error("Can not create directory 'data/db', please try again later.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!File("data/db/sqlite.db").isFile || File("data/db/sqlite.db").inputStream()
|
||||
.use { it.readNBytes(15).toString(Charsets.UTF_8) != "SQLite format 3" }
|
||||
) {
|
||||
logger.warn("The 'data/db/sqlite.db' database is lost or damaged, recreating...")
|
||||
if (File("data/db/sqlite.db").exists() && !File("data/db/sqlite.db").delete()) {
|
||||
logger.error("Can not recreate database 'data/db/sqlite.db', please try again later.")
|
||||
}
|
||||
}
|
||||
|
||||
if (File("application-config.yml").exists() || File("data/application-config.yml").exists()) {
|
||||
runApplication<OxygenApiApplication>(*args)
|
||||
} else {
|
||||
logger.warn("File 'application-config.yml' cannot be found in the running path or the data path. The configuration file template 'application-config.example.yml' has been created in directory 'data'. Please change the configuration file content, move it to the running path, rename it to 'application-config.yml', and then restart the server.")
|
||||
OxygenApiApplication::class.java.getResource("/application-config-template.yml")?.readText()?.let {
|
||||
File("data/application-config.example.yml").writeText(
|
||||
it.replace(
|
||||
"\$uuid\$", UUID.randomUUID().toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* API controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Tag
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Tag(name = "")
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ApiController(
|
||||
val version: Int = 1,
|
||||
|
||||
@get:AliasFor(annotation = RestController::class, attribute = "value") val value: String = "",
|
||||
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""],
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "name") val name: String,
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "description") val description: String
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* Base controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Tag(name = "")
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class BaseController(
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""],
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "name") val name: String,
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "description") val description: String
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import top.fatweb.oxygen.api.entity.system.EventLog
|
||||
|
||||
/**
|
||||
* Event log record annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class EventLogRecord(
|
||||
val event: EventLog.Event
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* Hidden controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Hidden
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Hidden
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class HiddenController(
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""]
|
||||
)
|
||||
15
src/main/kotlin/top/fatweb/oxygen/api/annotation/Trim.kt
Normal file
15
src/main/kotlin/top/fatweb/oxygen/api/annotation/Trim.kt
Normal file
@@ -0,0 +1,15 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import java.lang.annotation.Inherited
|
||||
|
||||
|
||||
/**
|
||||
* Trim string annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Inherited
|
||||
annotation class Trim
|
||||
@@ -0,0 +1,58 @@
|
||||
package top.fatweb.oxygen.api.aop
|
||||
|
||||
import org.aspectj.lang.JoinPoint
|
||||
import org.aspectj.lang.annotation.AfterReturning
|
||||
import org.aspectj.lang.annotation.Aspect
|
||||
import org.aspectj.lang.annotation.Pointcut
|
||||
import org.aspectj.lang.reflect.MethodSignature
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.oxygen.api.annotation.EventLogRecord
|
||||
import top.fatweb.oxygen.api.service.system.IEventLogService
|
||||
import top.fatweb.oxygen.api.util.WebUtil
|
||||
import top.fatweb.oxygen.api.vo.permission.LoginVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RegisterVo
|
||||
|
||||
/**
|
||||
* Event log record interceptor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IEventLogService
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
class EventLogInterceptor(
|
||||
private val eventLogService: IEventLogService
|
||||
) {
|
||||
/**
|
||||
* Event log record pointcut
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Pointcut("@annotation(top.fatweb.oxygen.api.annotation.EventLogRecord)")
|
||||
fun eventLogPointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do after event log record pointcut
|
||||
*
|
||||
* @param joinPoint Join point
|
||||
* @param retValue Return value
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see JoinPoint
|
||||
*/
|
||||
@AfterReturning(value = "eventLogPointcut()", returning = "retValue")
|
||||
fun doAfter(joinPoint: JoinPoint, retValue: Any?) {
|
||||
val annotation = (joinPoint.signature as MethodSignature).method.getAnnotation(EventLogRecord::class.java)
|
||||
|
||||
val userId = WebUtil.getLoginUserId() ?: when (retValue) {
|
||||
is LoginVo -> retValue.userId!!
|
||||
is RegisterVo -> retValue.userId!!
|
||||
else -> -1
|
||||
}
|
||||
|
||||
eventLogService.saveEvent(annotation, userId)
|
||||
}
|
||||
}
|
||||
136
src/main/kotlin/top/fatweb/oxygen/api/aop/SysLogInterceptor.kt
Normal file
136
src/main/kotlin/top/fatweb/oxygen/api/aop/SysLogInterceptor.kt
Normal file
@@ -0,0 +1,136 @@
|
||||
package top.fatweb.oxygen.api.aop
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.core.MethodParameter
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.converter.HttpMessageConverter
|
||||
import org.springframework.http.server.ServerHttpRequest
|
||||
import org.springframework.http.server.ServerHttpResponse
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||
import org.springframework.web.servlet.HandlerInterceptor
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.entity.system.SysLog
|
||||
import top.fatweb.oxygen.api.service.system.ISysLogService
|
||||
import top.fatweb.oxygen.api.util.WebUtil
|
||||
import top.fatweb.oxygen.api.vo.permission.LoginVo
|
||||
import java.net.URI
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
/**
|
||||
* System log interceptor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Executor
|
||||
* @see ISysLogService
|
||||
* @see HandlerInterceptor
|
||||
* @see ResponseBodyAdvice
|
||||
*/
|
||||
@ControllerAdvice
|
||||
class SysLogInterceptor(
|
||||
@Qualifier("applicationTaskExecutor") private val customThreadPoolTaskExecutor: Executor,
|
||||
private val sysLogService: ISysLogService
|
||||
) : HandlerInterceptor, ResponseBodyAdvice<Any> {
|
||||
private val sysLogThreadLocal = ThreadLocal<SysLog>()
|
||||
private val resultThreadLocal = ThreadLocal<Any>()
|
||||
|
||||
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
|
||||
val sysLog = SysLog().apply {
|
||||
operateUserId = WebUtil.getLoginUserId() ?: -1
|
||||
startTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||
requestUri = URI(request.requestURI).path
|
||||
requestParams = formatParams(request.parameterMap)
|
||||
requestMethod = request.method
|
||||
requestIp = WebUtil.getRequestIp(request)
|
||||
requestServerAddress = "${request.scheme}://${request.serverName}:${request.serverPort}"
|
||||
userAgent = request.getHeader("User-Agent")
|
||||
}
|
||||
|
||||
sysLogThreadLocal.set(sysLog)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun afterCompletion(
|
||||
request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?
|
||||
) {
|
||||
val sysLog = sysLogThreadLocal.get()
|
||||
val result = resultThreadLocal.get()
|
||||
sysLog.endTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||
sysLog.executeTime = ChronoUnit.MILLIS.between(sysLog.startTime, sysLog.endTime)
|
||||
if (result is ResponseResult<*>) {
|
||||
if (result.success) {
|
||||
sysLog.apply {
|
||||
logType = requestUri?.let {
|
||||
when {
|
||||
it.startsWith("/login") -> SysLog.LogType.LOGIN
|
||||
it.startsWith("/logout") -> SysLog.LogType.LOGOUT
|
||||
it.startsWith("/register") -> SysLog.LogType.REGISTER
|
||||
it.startsWith("/system/statistics/") -> SysLog.LogType.STATISTICS
|
||||
it.startsWith("/api/") -> SysLog.LogType.API
|
||||
else -> SysLog.LogType.INFO
|
||||
}
|
||||
} ?: SysLog.LogType.INFO
|
||||
exception = 0
|
||||
}
|
||||
if (result.data is LoginVo) {
|
||||
sysLog.operateUserId = result.data.userId ?: -1
|
||||
}
|
||||
} else {
|
||||
sysLog.apply {
|
||||
logType = SysLog.LogType.ERROR
|
||||
exception = 1
|
||||
exceptionInfo = result.msg
|
||||
}
|
||||
}
|
||||
|
||||
customThreadPoolTaskExecutor.execute(SaveLogThread(sysLog, sysLogService))
|
||||
}
|
||||
sysLogThreadLocal.remove()
|
||||
}
|
||||
|
||||
private fun formatParams(parameterMap: Map<String, Array<String>>): String {
|
||||
val params = StringJoiner("&")
|
||||
|
||||
parameterMap.forEach {
|
||||
params.add("${it.key}=${if (it.key.endsWith("password", true)) "*" else it.value.joinToString(",")}")
|
||||
}
|
||||
|
||||
return params.toString()
|
||||
}
|
||||
|
||||
private class SaveLogThread(val sysLog: SysLog, val sysLogService: ISysLogService) : Thread() {
|
||||
override fun run() {
|
||||
sysLog.operateTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||
sysLogService.save(sysLog)
|
||||
}
|
||||
}
|
||||
|
||||
override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean =
|
||||
true
|
||||
|
||||
override fun beforeBodyWrite(
|
||||
body: Any?,
|
||||
returnType: MethodParameter,
|
||||
selectedContentType: MediaType,
|
||||
selectedConverterType: Class<out HttpMessageConverter<*>>,
|
||||
request: ServerHttpRequest,
|
||||
response: ServerHttpResponse
|
||||
): Any? {
|
||||
resultThreadLocal.set(body)
|
||||
|
||||
if (body is ResponseResult<*> && body.code == ResponseCode.SYSTEM_ERROR.code) {
|
||||
return ResponseResult.build(body.code, body.success, "fail", body.data)
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
}
|
||||
87
src/main/kotlin/top/fatweb/oxygen/api/aop/TrimInterceptor.kt
Normal file
87
src/main/kotlin/top/fatweb/oxygen/api/aop/TrimInterceptor.kt
Normal file
@@ -0,0 +1,87 @@
|
||||
package top.fatweb.oxygen.api.aop
|
||||
|
||||
import org.aspectj.lang.JoinPoint
|
||||
import org.aspectj.lang.annotation.Aspect
|
||||
import org.aspectj.lang.annotation.Before
|
||||
import org.aspectj.lang.annotation.Pointcut
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.servlet.HandlerInterceptor
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.full.*
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
/**
|
||||
* Trim string interceptor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HandlerInterceptor
|
||||
*/
|
||||
@Component
|
||||
@Aspect
|
||||
class TrimInterceptor : HandlerInterceptor {
|
||||
/**
|
||||
* Trim pointcut
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Pointcut("@annotation(top.fatweb.oxygen.api.annotation.Trim)")
|
||||
fun trimPointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do before trim pointcut
|
||||
*
|
||||
* @param joinPoint Join point
|
||||
* @return Arguments
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see JoinPoint
|
||||
*/
|
||||
@Before("trimPointcut()")
|
||||
fun doBefore(joinPoint: JoinPoint): Any {
|
||||
val args = joinPoint.args
|
||||
|
||||
args?.forEachIndexed { index, any ->
|
||||
if (args[index]::class.hasAnnotation<Trim>()) args[index] = trim(any)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
private fun trim(any: Any?): Any? {
|
||||
any ?: return null
|
||||
|
||||
when (any) {
|
||||
is Boolean, Short, Int, Long, Float, Double -> {
|
||||
return any
|
||||
}
|
||||
|
||||
is String -> {
|
||||
return any.trim()
|
||||
}
|
||||
|
||||
else -> {
|
||||
val members = any::class.declaredMemberProperties
|
||||
if (members.isEmpty()) {
|
||||
return any
|
||||
}
|
||||
members.forEach {
|
||||
if (!it.returnType.isSupertypeOf(String::class.starProjectedType)
|
||||
|| it !is KMutableProperty<*>
|
||||
|| !it.hasAnnotation<Trim>()
|
||||
) {
|
||||
return@forEach
|
||||
}
|
||||
it.isAccessible = true
|
||||
if (it.call(any) != null) {
|
||||
it.setter.call(any, (it.call(any) as String).trim())
|
||||
}
|
||||
}
|
||||
return any
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
|
||||
import org.springframework.boot.jackson.JsonComponent
|
||||
import org.springframework.context.annotation.Bean
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Date format configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonComponent
|
||||
class DateFormatConfig {
|
||||
/**
|
||||
* The format of the time in response when request APIs
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@set:Value("\${spring.jackson.date-format}")
|
||||
lateinit var dateFormat: String
|
||||
|
||||
/**
|
||||
* The timezone of the time in response when request APIs
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see TimeZone
|
||||
*/
|
||||
@set:Value("\${spring.jackson.time-zone}}")
|
||||
lateinit var timeZone: TimeZone
|
||||
|
||||
@Bean
|
||||
fun jackson2ObjectMapperBuilder() = Jackson2ObjectMapperBuilderCustomizer {
|
||||
val dateFormat = SimpleDateFormat(dateFormat)
|
||||
dateFormat.timeZone = timeZone
|
||||
it.failOnEmptyBeans(false).failOnUnknownProperties(false)
|
||||
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).dateFormat(dateFormat)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun jackson2ObjectMapperBuilderCustomizer() =
|
||||
Jackson2ObjectMapperBuilderCustomizer {
|
||||
it.serializerByType(
|
||||
LocalDateTime::class.java, LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateFormat))
|
||||
)
|
||||
}
|
||||
}
|
||||
22
src/main/kotlin/top/fatweb/oxygen/api/config/FilterConfig.kt
Normal file
22
src/main/kotlin/top/fatweb/oxygen/api/config/FilterConfig.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import top.fatweb.oxygen.api.filter.ExceptionFilter
|
||||
|
||||
/**
|
||||
* Filter configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class FilterConfig {
|
||||
@Bean
|
||||
fun exceptionFilterRegistrationBean(exceptionFilter: ExceptionFilter): FilterRegistrationBean<ExceptionFilter> =
|
||||
FilterRegistrationBean(exceptionFilter).apply {
|
||||
setBeanName("exceptionFilter")
|
||||
order = -100
|
||||
}
|
||||
}
|
||||
43
src/main/kotlin/top/fatweb/oxygen/api/config/FlywayConfig.kt
Normal file
43
src/main/kotlin/top/fatweb/oxygen/api/config/FlywayConfig.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource
|
||||
import jakarta.annotation.PostConstruct
|
||||
import org.flywaydb.core.Flyway
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.DependsOn
|
||||
import top.fatweb.oxygen.api.properties.FlywayProperties
|
||||
import javax.sql.DataSource
|
||||
|
||||
/**
|
||||
* Flyway configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@DependsOn("flywayProperties")
|
||||
@Configuration
|
||||
class FlywayConfig(
|
||||
private val dataSource: DataSource
|
||||
) {
|
||||
@PostConstruct
|
||||
fun migrateOrder() {
|
||||
val ds = dataSource as DynamicRoutingDataSource
|
||||
ds.dataSources.forEach { (k: String, v: DataSource?) ->
|
||||
val flyway = Flyway.configure()
|
||||
.dataSource(v)
|
||||
.locations(*FlywayProperties.locations.map { "$it/$k" }.toTypedArray())
|
||||
.baselineOnMigrate(FlywayProperties.baselineOnMigrate)
|
||||
.table(FlywayProperties.table)
|
||||
.outOfOrder(FlywayProperties.outOfOrder)
|
||||
.validateOnMigrate(FlywayProperties.validateOnMigrate)
|
||||
.encoding(FlywayProperties.encoding)
|
||||
.sqlMigrationPrefix(FlywayProperties.sqlMigrationPrefix)
|
||||
.sqlMigrationSeparator(FlywayProperties.sqlMigrationSeparator)
|
||||
.sqlMigrationSuffixes(*FlywayProperties.sqlMigrationSuffixes.toTypedArray())
|
||||
.baselineVersion(FlywayProperties.baselineVersion)
|
||||
.load()
|
||||
flyway.migrate()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
69
src/main/kotlin/top/fatweb/oxygen/api/config/InitConfig.kt
Normal file
69
src/main/kotlin/top/fatweb/oxygen/api/config/InitConfig.kt
Normal file
@@ -0,0 +1,69 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
|
||||
import jakarta.annotation.PostConstruct
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.context.annotation.DependsOn
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.avatargenerator.GitHubAvatar
|
||||
import top.fatweb.oxygen.api.entity.permission.User
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.properties.AdminProperties
|
||||
import top.fatweb.oxygen.api.service.permission.IUserInfoService
|
||||
import top.fatweb.oxygen.api.service.permission.IUserService
|
||||
import top.fatweb.oxygen.api.util.StrUtil
|
||||
|
||||
/**
|
||||
* Application initialization configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IUserService
|
||||
* @see IUserInfoService
|
||||
* @see PasswordEncoder
|
||||
*/
|
||||
@DependsOn("adminProperties")
|
||||
@Component
|
||||
class InitConfig(
|
||||
private val userService: IUserService,
|
||||
private val userInfoService: IUserInfoService,
|
||||
private val passwordEncoder: PasswordEncoder
|
||||
) {
|
||||
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||
|
||||
@PostConstruct
|
||||
fun init() {
|
||||
if (!userService.exists(KtQueryWrapper(User()).eq(User::id, 0))) {
|
||||
userInfoService.remove(KtQueryWrapper(UserInfo()).eq(UserInfo::userId, 0))
|
||||
|
||||
val rawPassword = AdminProperties.password ?: let {
|
||||
logger.warn("No default administrator password is set, a randomly generated password will be used")
|
||||
StrUtil.getRandomPassword(10)
|
||||
}
|
||||
val encodedPassword = passwordEncoder.encode(rawPassword)
|
||||
|
||||
val user = User().apply {
|
||||
id = 0
|
||||
username = AdminProperties.username
|
||||
password = encodedPassword
|
||||
locking = 0
|
||||
enable = 1
|
||||
}
|
||||
val userInfo = UserInfo().apply {
|
||||
userId = 0
|
||||
nickname = AdminProperties.nickname
|
||||
avatar =
|
||||
GitHubAvatar.newAvatarBuilder().build().createAsBase64((Long.MIN_VALUE..Long.MAX_VALUE).random())
|
||||
email = AdminProperties.email
|
||||
}
|
||||
|
||||
if (userService.save(user) && userInfoService.save(userInfo)) {
|
||||
logger.warn("First startup, create administrator - username: admin, password: $rawPassword")
|
||||
logger.warn("This information will only be shown once. Please change your password promptly after logging in.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory
|
||||
|
||||
/**
|
||||
* Jackson configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class JacksonConfig {
|
||||
@Bean
|
||||
fun jacksonConverterFactory(): JacksonConverterFactory =
|
||||
JacksonConverterFactory.create(
|
||||
JsonMapper.builder()
|
||||
.findAndAddModules()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
/**
|
||||
* Mybatis-plus configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class MybatisPlusConfig {
|
||||
@Bean
|
||||
fun mybatisPlusInterceptor(): MybatisPlusInterceptor =
|
||||
MybatisPlusInterceptor().apply {
|
||||
addInnerInterceptor(OptimisticLockerInnerInterceptor())
|
||||
addInnerInterceptor(PaginationInnerInterceptor())
|
||||
}
|
||||
}
|
||||
48
src/main/kotlin/top/fatweb/oxygen/api/config/RedisConfig.kt
Normal file
48
src/main/kotlin/top/fatweb/oxygen/api/config/RedisConfig.kt
Normal file
@@ -0,0 +1,48 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
|
||||
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.Jackson2JsonRedisSerializer
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
||||
|
||||
/**
|
||||
* Redis configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class RedisConfig {
|
||||
@Bean
|
||||
fun redisTemplate(redisConnectionFactory: RedisConnectionFactory): RedisTemplate<*, *> {
|
||||
val redisTemplate = RedisTemplate<String, Any>()
|
||||
redisTemplate.connectionFactory = redisConnectionFactory
|
||||
val stringRedisSerializer = StringRedisSerializer()
|
||||
val objectMapper = ObjectMapper().registerModules(JavaTimeModule()).apply {
|
||||
setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)
|
||||
activateDefaultTyping(
|
||||
this.polymorphicTypeValidator, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY
|
||||
)
|
||||
}
|
||||
val anyJackson2JsonRedisSerializer = Jackson2JsonRedisSerializer(objectMapper, Any::class.java)
|
||||
|
||||
// Use String Redis Serializer to serialize and deserialize redis key values
|
||||
redisTemplate.keySerializer = stringRedisSerializer
|
||||
redisTemplate.valueSerializer = anyJackson2JsonRedisSerializer
|
||||
|
||||
// The Hash key also uses the String Redis Serializer serialization method.
|
||||
redisTemplate.hashKeySerializer = stringRedisSerializer
|
||||
redisTemplate.hashValueSerializer = anyJackson2JsonRedisSerializer
|
||||
|
||||
redisTemplate.afterPropertiesSet()
|
||||
|
||||
return redisTemplate
|
||||
}
|
||||
}
|
||||
108
src/main/kotlin/top/fatweb/oxygen/api/config/SecurityConfig.kt
Normal file
108
src/main/kotlin/top/fatweb/oxygen/api/config/SecurityConfig.kt
Normal file
@@ -0,0 +1,108 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.http.SessionCreationPolicy
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||
import org.springframework.security.web.SecurityFilterChain
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||
import org.springframework.web.cors.CorsConfiguration
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
||||
import top.fatweb.oxygen.api.filter.JwtAuthenticationTokenFilter
|
||||
import top.fatweb.oxygen.api.handler.JwtAccessDeniedHandler
|
||||
import top.fatweb.oxygen.api.handler.JwtAuthenticationEntryPointHandler
|
||||
|
||||
/**
|
||||
* Spring Security configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see JwtAuthenticationTokenFilter
|
||||
* @see JwtAuthenticationEntryPointHandler
|
||||
* @see JwtAccessDeniedHandler
|
||||
*/
|
||||
@Configuration
|
||||
@EnableMethodSecurity
|
||||
class SecurityConfig(
|
||||
private val jwtAuthenticationTokenFilter: JwtAuthenticationTokenFilter,
|
||||
private val authenticationEntryPointHandler: JwtAuthenticationEntryPointHandler,
|
||||
private val accessDeniedHandler: JwtAccessDeniedHandler
|
||||
) {
|
||||
@Bean
|
||||
fun passwordEncoder() = BCryptPasswordEncoder()
|
||||
|
||||
@Bean
|
||||
fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager =
|
||||
authenticationConfiguration.authenticationManager
|
||||
|
||||
@Bean
|
||||
fun corsConfigurationSource(): UrlBasedCorsConfigurationSource {
|
||||
val corsConfiguration = CorsConfiguration()
|
||||
corsConfiguration.allowedMethods = listOf("*")
|
||||
corsConfiguration.allowedHeaders = listOf("*")
|
||||
corsConfiguration.maxAge = 3600L
|
||||
corsConfiguration.allowedOrigins = listOf("*")
|
||||
val source = UrlBasedCorsConfigurationSource()
|
||||
source.registerCorsConfiguration("/**", corsConfiguration)
|
||||
|
||||
return source
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun securityFilterChain(httpSecurity: HttpSecurity): SecurityFilterChain = httpSecurity
|
||||
// Disable CSRF
|
||||
.csrf {
|
||||
it.disable()
|
||||
}
|
||||
// Do not get SecurityContent by Session
|
||||
.sessionManagement {
|
||||
it.sessionCreationPolicy(
|
||||
SessionCreationPolicy.STATELESS
|
||||
)
|
||||
}
|
||||
.authorizeHttpRequests {
|
||||
it
|
||||
// Allow anonymous access
|
||||
.requestMatchers(
|
||||
"/error/thrown",
|
||||
"/doc.html",
|
||||
"/swagger-ui/**",
|
||||
"/webjars/**",
|
||||
"/v3/**",
|
||||
"/swagger-ui.html",
|
||||
"/favicon.ico",
|
||||
"/login",
|
||||
"/register",
|
||||
"/forget",
|
||||
"/retrieve"
|
||||
).anonymous()
|
||||
.requestMatchers("/tool/detail/**", "/tool/store", "/tool/store/*", "/system/user/info/*").permitAll()
|
||||
// Authentication required
|
||||
.anyRequest().authenticated()
|
||||
}
|
||||
|
||||
.logout {
|
||||
it.disable()
|
||||
}
|
||||
|
||||
.exceptionHandling {
|
||||
it.authenticationEntryPoint(
|
||||
authenticationEntryPointHandler
|
||||
)
|
||||
it.accessDeniedHandler(
|
||||
accessDeniedHandler
|
||||
)
|
||||
}
|
||||
|
||||
.cors {
|
||||
it.configurationSource(
|
||||
corsConfigurationSource()
|
||||
)
|
||||
}
|
||||
|
||||
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter::class.java).build()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI
|
||||
import io.swagger.v3.oas.models.info.Contact
|
||||
import io.swagger.v3.oas.models.info.Info
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import top.fatweb.oxygen.api.properties.ServerProperties
|
||||
|
||||
/**
|
||||
* Swagger API doc configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class SwaggerConfig {
|
||||
@Bean
|
||||
fun customOpenAPI(): OpenAPI? {
|
||||
val contact = Contact().name("FatttSnake").url("https://fatweb.top").email("fatttsnake@gmail.com")
|
||||
return OpenAPI().info(
|
||||
Info().title("Oxygen API 文档").description("Oxygen 后端 API 文档,包含各个 Controller 调用信息")
|
||||
.contact(contact).version(
|
||||
ServerProperties.version
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
24
src/main/kotlin/top/fatweb/oxygen/api/config/SysLogConfig.kt
Normal file
24
src/main/kotlin/top/fatweb/oxygen/api/config/SysLogConfig.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import top.fatweb.oxygen.api.aop.SysLogInterceptor
|
||||
|
||||
/**
|
||||
* System log configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SysLogInterceptor
|
||||
* @see WebMvcConfigurer
|
||||
*/
|
||||
@Configuration
|
||||
class SysLogConfig(
|
||||
private val sysLogInterceptor: SysLogInterceptor
|
||||
) : WebMvcConfigurer {
|
||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||
registry.addInterceptor(sysLogInterceptor).addPathPatterns("/**")
|
||||
.excludePathPatterns("/error/thrown", "/webjars/**")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.apache.velocity.app.VelocityEngine
|
||||
import org.apache.velocity.runtime.RuntimeConstants
|
||||
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
/**
|
||||
* Velocity engine configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class VelocityEngineConfig {
|
||||
@Bean
|
||||
fun velocityEngine() = VelocityEngine().apply {
|
||||
setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath")
|
||||
setProperty("classpath.resource.loader.class", ClasspathResourceLoader::class.java.name)
|
||||
init()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import top.fatweb.oxygen.api.annotation.ApiController
|
||||
|
||||
/**
|
||||
* Web MVC configurer configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see WebMvcRegistrations
|
||||
*/
|
||||
@Configuration
|
||||
class WebMvcConfigurerConfig : WebMvcConfigurer {
|
||||
override fun configurePathMatch(configurer: PathMatchConfigurer) {
|
||||
configurer.addPathPrefix("/api/{API_VERSION}") { it.isAnnotationPresent(ApiController::class.java) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
|
||||
import top.fatweb.oxygen.api.util.ApiResponseMappingHandlerMapping
|
||||
|
||||
/**
|
||||
* Web MVC registrations configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see WebMvcRegistrations
|
||||
*/
|
||||
@Configuration
|
||||
class WebMvcRegistrationsConfig : WebMvcRegistrations {
|
||||
override fun getRequestMappingHandlerMapping(): RequestMappingHandlerMapping = ApiResponseMappingHandlerMapping()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package top.fatweb.oxygen.api.controller
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import top.fatweb.oxygen.api.annotation.HiddenController
|
||||
|
||||
/**
|
||||
* Exception controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@HiddenController(["/error"])
|
||||
class ExceptionController {
|
||||
@RequestMapping("/thrown")
|
||||
fun thrown(request: HttpServletRequest) {
|
||||
throw request.getAttribute("filter.error") as RuntimeException
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package top.fatweb.oxygen.api.controller.api.v1
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.ApiController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.api.v1.avatar.AvatarBaseParam
|
||||
import top.fatweb.oxygen.api.param.api.v1.avatar.AvatarGitHubParam
|
||||
import top.fatweb.oxygen.api.service.api.v1.IAvatarService
|
||||
import top.fatweb.oxygen.api.vo.api.v1.avatar.AvatarBase64Vo
|
||||
|
||||
/**
|
||||
* Avatar controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IAvatarService
|
||||
*/
|
||||
@ApiController(value = "avatarControllerV1", path = ["/avatar"], name = "随机头像 V1", description = "随机头像相关接口")
|
||||
class AvatarController(
|
||||
private val avatarService: IAvatarService
|
||||
) {
|
||||
/**
|
||||
* Get random avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "获取随机头像")
|
||||
@GetMapping(produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun getRandom(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.random(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get random avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "获取随机头像 Base64")
|
||||
@GetMapping("base64")
|
||||
fun getRandomBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS, data = avatarService.randomBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get triangle avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "三角形头像")
|
||||
@GetMapping("/triangle", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun triangle(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.triangle(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get triangle avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "三角形头像 Base64")
|
||||
@GetMapping("/triangle/base64")
|
||||
fun triangleBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.triangleBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get square avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "正方形头像")
|
||||
@GetMapping("/square", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun square(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.square(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get square avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "正方形头像 Base64")
|
||||
@GetMapping("/square/base64")
|
||||
fun squareBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.squareBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get identicon avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "Identicon 头像")
|
||||
@GetMapping("/identicon", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun identicon(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.identicon(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get identicon avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "Identicon 头像 Base64")
|
||||
@GetMapping("/identicon/base64")
|
||||
fun identiconBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.identiconBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get GitHub avatar
|
||||
*
|
||||
* @param avatarGitHubParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarGitHubParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "GitHub 头像")
|
||||
@GetMapping("/github", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun github(@Valid avatarGitHubParam: AvatarGitHubParam?): ByteArray =
|
||||
avatarService.github(avatarGitHubParam)
|
||||
|
||||
/**
|
||||
* Get GitHub avatar as base64
|
||||
*
|
||||
* @param avatarGitHubParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarGitHubParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "GitHub 头像 Base64")
|
||||
@GetMapping("/github/base64")
|
||||
fun githubBase64(
|
||||
@Valid avatarGitHubParam: AvatarGitHubParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.githubBase64(avatarGitHubParam)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.*
|
||||
import top.fatweb.oxygen.api.service.permission.IAuthenticationService
|
||||
import top.fatweb.oxygen.api.util.WebUtil
|
||||
import top.fatweb.oxygen.api.vo.permission.LoginVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RegisterVo
|
||||
import top.fatweb.oxygen.api.vo.permission.TokenVo
|
||||
import top.fatweb.oxygen.api.vo.permission.TwoFactorVo
|
||||
|
||||
/**
|
||||
* Authentication controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IAuthenticationService
|
||||
*/
|
||||
@BaseController(name = "身份认证", description = "身份认证相关接口")
|
||||
class AuthenticationController(
|
||||
private val authenticationService: IAuthenticationService
|
||||
) {
|
||||
/**
|
||||
* Register
|
||||
*
|
||||
* @param registerParam Register parameters
|
||||
* @return Response object includes user ID
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RegisterParam
|
||||
* @see ResponseResult
|
||||
* @see RegisterVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "注册")
|
||||
@PostMapping("/register")
|
||||
fun register(
|
||||
request: HttpServletRequest,
|
||||
@Valid @RequestBody registerParam: RegisterParam
|
||||
): ResponseResult<RegisterVo> = ResponseResult.success(
|
||||
ResponseCode.PERMISSION_REGISTER_SUCCESS,
|
||||
data = authenticationService.register(request, registerParam)
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Send verify email
|
||||
*
|
||||
* @return Response object includes resend result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "发送验证邮件")
|
||||
@PostMapping("/resend")
|
||||
fun resend(): ResponseResult<Nothing> {
|
||||
authenticationService.resend()
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_RESEND_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify email
|
||||
*
|
||||
* @param verifyParam Verify parameters
|
||||
* @return Response object includes verify result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see VerifyParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "验证邮箱")
|
||||
@PostMapping("/verify")
|
||||
fun verify(@Valid @RequestBody verifyParam: VerifyParam): ResponseResult<Nothing> {
|
||||
authenticationService.verify(verifyParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_VERIFY_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget password
|
||||
*
|
||||
* @param request
|
||||
* @param forgetParam Forget parameters
|
||||
* @return Response object includes forget result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ForgetParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "忘记密码")
|
||||
@PostMapping("/forget")
|
||||
fun forget(request: HttpServletRequest, @Valid @RequestBody forgetParam: ForgetParam): ResponseResult<Nothing> {
|
||||
authenticationService.forget(request, forgetParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_FORGET_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve password
|
||||
*
|
||||
* @param request
|
||||
* @param retrieveParam Retrieve parameters
|
||||
* @return Response object includes retrieve result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see RetrieveParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "找回密码")
|
||||
@PostMapping("/retrieve")
|
||||
fun retrieve(
|
||||
request: HttpServletRequest,
|
||||
@Valid @RequestBody retrieveParam: RetrieveParam
|
||||
): ResponseResult<Nothing> {
|
||||
authenticationService.retrieve(request, retrieveParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_RETRIEVE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
* @param request
|
||||
* @param loginParam Login parameters
|
||||
* @return Response object includes login result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see LoginParam
|
||||
* @see ResponseResult
|
||||
* @see LoginVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
fun login(request: HttpServletRequest, @Valid @RequestBody loginParam: LoginParam): ResponseResult<LoginVo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.PERMISSION_LOGIN_SUCCESS,
|
||||
"Login success",
|
||||
authenticationService.login(request, loginParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Create two-factor
|
||||
*
|
||||
* @return Response object includes two-factor QR code
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see TwoFactorVo
|
||||
*/
|
||||
@Operation(summary = "创建双因素验证码")
|
||||
@GetMapping("/two-factor")
|
||||
fun createTwoFactor(): ResponseResult<TwoFactorVo> =
|
||||
ResponseResult.success(data = authenticationService.createTwoFactor())
|
||||
|
||||
/**
|
||||
* Validate two-factor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Operation(summary = "验证双因素")
|
||||
@PostMapping("/two-factor")
|
||||
fun validateTwoFactor(@RequestBody @Valid twoFactorValidateParam: TwoFactorValidateParam): ResponseResult<Nothing> =
|
||||
if (authenticationService.validateTwoFactor(twoFactorValidateParam)) ResponseResult.success()
|
||||
else ResponseResult.fail()
|
||||
|
||||
/**
|
||||
* Remove two-factor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Operation(summary = "移除双因素")
|
||||
@DeleteMapping("/two-factor")
|
||||
fun removeTwoFactor(@RequestBody @Valid twoFactorRemoveParam: TwoFactorRemoveParam): ResponseResult<Nothing> =
|
||||
if (authenticationService.removeTwoFactor(twoFactorRemoveParam)) ResponseResult.success()
|
||||
else ResponseResult.fail()
|
||||
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*
|
||||
* @param request
|
||||
* @return Response object includes logout result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "登出")
|
||||
@PostMapping("/logout")
|
||||
fun logout(request: HttpServletRequest): ResponseResult<Nothing> =
|
||||
when (authenticationService.logout(WebUtil.getToken(request))) {
|
||||
true -> ResponseResult.success(ResponseCode.PERMISSION_LOGOUT_SUCCESS, "Logout success", null)
|
||||
false -> ResponseResult.fail(ResponseCode.PERMISSION_LOGOUT_FAILED, "Logout failed", null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Renew token
|
||||
*
|
||||
* @param request
|
||||
* @return Response object includes new token
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ResponseResult
|
||||
* @see TokenVo
|
||||
*/
|
||||
@Operation(summary = "更新 Token")
|
||||
@GetMapping("/token")
|
||||
fun renewToken(request: HttpServletRequest): ResponseResult<TokenVo> = ResponseResult.success(
|
||||
ResponseCode.PERMISSION_TOKEN_RENEW_SUCCESS,
|
||||
"Token renew success",
|
||||
authenticationService.renewToken(WebUtil.getToken(request))
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.group.*
|
||||
import top.fatweb.oxygen.api.service.permission.IGroupService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.GroupWithRoleVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.GroupVo
|
||||
|
||||
/**
|
||||
* Group management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IGroupService
|
||||
*/
|
||||
@BaseController(path = ["/system/group"], name = "用户组管理", description = "用户组管理相关接口")
|
||||
class GroupController(
|
||||
val groupService: IGroupService
|
||||
) {
|
||||
/**
|
||||
* Get group by ID
|
||||
*
|
||||
* @param id Group ID
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
@Operation(summary = "获取单个用户组")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<GroupWithRoleVo> =
|
||||
ResponseResult.databaseSuccess(data = groupService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get group paging information
|
||||
*
|
||||
* @param groupGetParam Get group parameters
|
||||
* @return Response object includes group paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取用户组")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:all')")
|
||||
fun get(@Valid groupGetParam: GroupGetParam?): ResponseResult<PageVo<GroupWithRoleVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = groupService.getPage(groupGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get group list
|
||||
*
|
||||
* @return Response object includes group list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Operation(summary = "获取用户组列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:list', 'system:user:add:one', 'system:user:modify:one')")
|
||||
fun list(): ResponseResult<List<GroupVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = groupService.getList()
|
||||
)
|
||||
|
||||
/**
|
||||
* Add group
|
||||
*
|
||||
* @param groupAddParam Add group parameters
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupAddParam
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "添加用户组")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:add:one')")
|
||||
fun add(@Valid @RequestBody groupAddParam: GroupAddParam): ResponseResult<GroupVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = groupService.add(groupAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update group
|
||||
*
|
||||
* @param groupUpdateParam Update group parameters
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "修改用户组")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:modify:one')")
|
||||
fun update(@Valid @RequestBody groupUpdateParam: GroupUpdateParam): ResponseResult<GroupVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = groupService.update(groupUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update status of group
|
||||
*
|
||||
* @param groupUpdateStatusParam Update status of group parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateStatusParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改用户组状态")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:modify:status')")
|
||||
fun updateStatus(@Valid @RequestBody groupUpdateStatusParam: GroupUpdateStatusParam): ResponseResult<Nothing> {
|
||||
groupService.status(groupUpdateStatusParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete group by ID
|
||||
*
|
||||
* @param id Group ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除用户组")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
groupService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete group by list
|
||||
*
|
||||
* @param groupDeleteParam Delete group parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除用户组")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody groupDeleteParam: GroupDeleteParam): ResponseResult<Nothing> {
|
||||
groupService.delete(groupDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.service.permission.IPowerService
|
||||
import top.fatweb.oxygen.api.vo.permission.PowerSetVo
|
||||
|
||||
/**
|
||||
* Power management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPowerService
|
||||
*/
|
||||
@BaseController(path = ["/system/power"], name = "权限管理", description = "权限管理相关接口")
|
||||
class PowerController(
|
||||
private val powerService: IPowerService
|
||||
) {
|
||||
/**
|
||||
* Get power list
|
||||
*
|
||||
* @return Response object includes power list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see PowerSetVo
|
||||
*/
|
||||
@Operation(summary = "获取权限列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:power:query:list', 'system:role:add:one', 'system:role:modify:one')")
|
||||
fun getList(): ResponseResult<PowerSetVo> = ResponseResult.databaseSuccess(data = powerService.getList())
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.role.*
|
||||
import top.fatweb.oxygen.api.service.permission.IRoleService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RoleWithPowerVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.RoleVo
|
||||
|
||||
/**
|
||||
* Role management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IRoleService
|
||||
*/
|
||||
@BaseController(path = ["/system/role"], name = "角色管理", description = "角色管理相关接口")
|
||||
class RoleController(
|
||||
private val roleService: IRoleService
|
||||
) {
|
||||
/**
|
||||
* Get role by ID
|
||||
*
|
||||
* @param id Role ID
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
@Operation(summary = "获取单个角色")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<RoleWithPowerVo> =
|
||||
ResponseResult.databaseSuccess(data = roleService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get role paging information
|
||||
*
|
||||
* @param roleGetParam Get role parameters
|
||||
* @return Response object includes role paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleGetParam
|
||||
* @see ResponseResult
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取角色")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:all')")
|
||||
fun get(roleGetParam: RoleGetParam?): ResponseResult<PageVo<RoleWithPowerVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = roleService.getPage(roleGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get role list
|
||||
*
|
||||
* @return Response object includes role list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Operation(summary = "获取角色列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:list', 'system:group:add:one', 'system:group:modify:one', 'system:user:add:one', 'system:user:modify:one')")
|
||||
fun list(): ResponseResult<List<RoleVo>> {
|
||||
return ResponseResult.databaseSuccess(
|
||||
data = roleService.getList()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role
|
||||
*
|
||||
* @param roleAddParam Add role parameters
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleAddParam
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "添加角色")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:add:one')")
|
||||
fun add(@Valid @RequestBody roleAddParam: RoleAddParam): ResponseResult<RoleVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = roleService.add(roleAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update role
|
||||
*
|
||||
* @param roleUpdateParam Update role parameters
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "修改角色")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:modify:one')")
|
||||
fun update(@Valid @RequestBody roleUpdateParam: RoleUpdateParam): ResponseResult<RoleVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = roleService.update(roleUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update status of role
|
||||
*
|
||||
* @param roleUpdateStatusParam Update status of role parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateStatusParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改角色状态")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:modify:status')")
|
||||
fun status(@Valid @RequestBody roleUpdateStatusParam: RoleUpdateStatusParam): ResponseResult<Nothing> {
|
||||
roleService.status(roleUpdateStatusParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role by ID
|
||||
*
|
||||
* @param id
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除角色")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
roleService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role by list
|
||||
*
|
||||
* @param roleDeleteParam Delete role parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除角色")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody roleDeleteParam: RoleDeleteParam): ResponseResult<Nothing> {
|
||||
roleService.delete(roleDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.user.*
|
||||
import top.fatweb.oxygen.api.service.permission.IUserService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPasswordRoleInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPowerInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithRoleInfoVo
|
||||
|
||||
/**
|
||||
* User management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IUserService
|
||||
*/
|
||||
@BaseController(path = ["/system/user"], name = "用户管理", description = "用户管理相关接口")
|
||||
class UserController(
|
||||
private val userService: IUserService
|
||||
) {
|
||||
/**
|
||||
* Get current user information
|
||||
*
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取当前用户信息")
|
||||
@GetMapping("/info")
|
||||
fun getInfo(): ResponseResult<UserWithPowerInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getInfo())
|
||||
|
||||
/**
|
||||
* Get basic user information
|
||||
*
|
||||
* @param username Username
|
||||
* @return Response object includes user basic information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取指定用户基本信息")
|
||||
@GetMapping("/info/{username}")
|
||||
fun getBasicInfo(@PathVariable username: String): ResponseResult<UserWithInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getBasicInfo(username.trim()))
|
||||
|
||||
/**
|
||||
* Update current user information
|
||||
*
|
||||
* @param userInfoUpdateParam Update user information parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserInfoUpdateParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新当前用户信息")
|
||||
@PatchMapping("info")
|
||||
fun updateInfo(@RequestBody @Valid userInfoUpdateParam: UserInfoUpdateParam): ResponseResult<Nothing> =
|
||||
if (userService.updateInfo(userInfoUpdateParam)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
else ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_FAILED)
|
||||
|
||||
/**
|
||||
* Change password
|
||||
*
|
||||
* @param userChangePasswordParam User change password parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserChangePasswordParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "更改密码")
|
||||
@PostMapping("info")
|
||||
fun password(@RequestBody @Valid userChangePasswordParam: UserChangePasswordParam): ResponseResult<Nothing> {
|
||||
userService.password(userChangePasswordParam)
|
||||
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user by ID
|
||||
*
|
||||
* @param id User ID
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取单个用户")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:user:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<UserWithRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get user paging information
|
||||
*
|
||||
* @param userGetParam Get user parameters
|
||||
* @return Response object includes user paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserGetParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取用户")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:query:all')")
|
||||
fun get(@Valid userGetParam: UserGetParam?): ResponseResult<PageVo<UserWithRoleInfoVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = userService.getPage(userGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Add user
|
||||
*
|
||||
* @param userAddParam Add user parameters
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserAddParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithPasswordRoleInfoVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "添加用户")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:add:one')")
|
||||
fun add(@Valid @RequestBody userAddParam: UserAddParam): ResponseResult<UserWithPasswordRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = userService.add(userAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update user
|
||||
*
|
||||
* @param userUpdateParam Update user parameters
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "修改用户")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:modify:one')")
|
||||
fun update(@Valid @RequestBody userUpdateParam: UserUpdateParam): ResponseResult<UserWithRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = userService.update(userUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update user password
|
||||
*
|
||||
* @param userUpdatePasswordParam Update user password parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdatePasswordParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改密码")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:modify:password')")
|
||||
fun password(@Valid @RequestBody userUpdatePasswordParam: UserUpdatePasswordParam): ResponseResult<Nothing> {
|
||||
userService.password(userUpdatePasswordParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user by ID
|
||||
*
|
||||
* @param id User ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除用户")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:user:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
userService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user by list
|
||||
*
|
||||
* @param userDeleteParam Delete user parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除用户")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody userDeleteParam: UserDeleteParam): ResponseResult<Nothing> {
|
||||
userService.delete(userDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.*
|
||||
import top.fatweb.oxygen.api.service.system.ISensitiveWordService
|
||||
import top.fatweb.oxygen.api.service.system.ISettingsService
|
||||
import top.fatweb.oxygen.api.vo.system.BaseSettingsVo
|
||||
import top.fatweb.oxygen.api.vo.system.MailSettingsVo
|
||||
import top.fatweb.oxygen.api.vo.system.SensitiveWordVo
|
||||
import top.fatweb.oxygen.api.vo.system.TwoFactorSettingsVo
|
||||
|
||||
/**
|
||||
* System settings management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ISettingsService
|
||||
* @see ISensitiveWordService
|
||||
*/
|
||||
@BaseController(path = ["/system/settings"], name = "系统设置", description = "系统设置相关接口")
|
||||
class SettingsController(
|
||||
private val settingsService: ISettingsService,
|
||||
private val sensitiveWordService: ISensitiveWordService
|
||||
) {
|
||||
/**
|
||||
* Get base settings
|
||||
*
|
||||
* @return Response object includes base settings information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see BaseSettingsVo
|
||||
*/
|
||||
@Operation(summary = "获取基础设置")
|
||||
@GetMapping("/base")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:base')")
|
||||
fun getApp(): ResponseResult<BaseSettingsVo> =
|
||||
ResponseResult.success(data = settingsService.getBase())
|
||||
|
||||
/**
|
||||
* Update base settings
|
||||
*
|
||||
* @param baseSettingsParam Base settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see BaseSettingsParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新基础设置")
|
||||
@PutMapping("/base")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:base')")
|
||||
fun updateApp(@RequestBody baseSettingsParam: BaseSettingsParam): ResponseResult<Nothing> {
|
||||
settingsService.updateBase(baseSettingsParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mail settings
|
||||
*
|
||||
* @return Response object includes mail settings
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see MailSettingsVo
|
||||
*/
|
||||
@Operation(summary = "获取邮件设置")
|
||||
@GetMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:mail')")
|
||||
fun getMail(): ResponseResult<MailSettingsVo> =
|
||||
ResponseResult.success(data = settingsService.getMail())
|
||||
|
||||
/**
|
||||
* Update mail settings
|
||||
*
|
||||
* @param mailSettingsParam Mail settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see MailSettingsParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新邮件设置")
|
||||
@PutMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
|
||||
fun updateMail(@RequestBody mailSettingsParam: MailSettingsParam): ResponseResult<Nothing> {
|
||||
settingsService.updateMail(mailSettingsParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Send mail test
|
||||
*
|
||||
* @param mailSendParam Mail send parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see MailSendParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "邮件发送测试")
|
||||
@PostMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
|
||||
fun sendMail(@RequestBody @Valid mailSendParam: MailSendParam): ResponseResult<Nothing> {
|
||||
settingsService.sendMail(mailSendParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sensitive word settings
|
||||
*
|
||||
* @return Response object includes sensitive word settings information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see SensitiveWordVo
|
||||
*/
|
||||
@Operation(summary = "获取敏感词配置")
|
||||
@GetMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:sensitive')")
|
||||
fun getSensitive(): ResponseResult<List<SensitiveWordVo>> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_SELECT_SUCCESS, data = sensitiveWordService.get())
|
||||
|
||||
/**
|
||||
* Add sensitive word
|
||||
*
|
||||
* @param sensitiveWordAddParam Add sensitive word settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordAddParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "添加敏感词")
|
||||
@PostMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun addSensitive(@RequestBody @Valid sensitiveWordAddParam: SensitiveWordAddParam): ResponseResult<Nothing> {
|
||||
sensitiveWordService.add(sensitiveWordAddParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update sensitive word
|
||||
*
|
||||
* @param sensitiveWordUpdateParam Update sensitive word settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordUpdateParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改敏感词")
|
||||
@PutMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun updateSensitive(@RequestBody sensitiveWordUpdateParam: SensitiveWordUpdateParam): ResponseResult<Nothing> {
|
||||
sensitiveWordService.update(sensitiveWordUpdateParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete sensitive word
|
||||
*
|
||||
* @see id Sensitive word ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除敏感词")
|
||||
@DeleteMapping("/sensitive/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun deleteSensitive(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
sensitiveWordService.delete(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get two-factor settings
|
||||
*
|
||||
* @return Response object includes two-factor settings information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see TwoFactorSettingsVo
|
||||
*/
|
||||
@Operation(summary = "获取双因素设置")
|
||||
@GetMapping("/two-factor")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:two-factor')")
|
||||
fun getTwoFactor(): ResponseResult<TwoFactorSettingsVo> =
|
||||
ResponseResult.success(data = settingsService.getTwoFactor())
|
||||
|
||||
/**
|
||||
* Update two-factor settings
|
||||
*
|
||||
* @param twoFactorSettingsParam Two-factor settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see TwoFactorSettingsParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新双因素设置")
|
||||
@PutMapping("/two-factor")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:two-factor')")
|
||||
fun updateTwoFactor(@RequestBody twoFactorSettingsParam: TwoFactorSettingsParam): ResponseResult<Nothing> {
|
||||
settingsService.updateTwoFactor(twoFactorSettingsParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.ActiveInfoGetParam
|
||||
import top.fatweb.oxygen.api.param.system.OnlineInfoGetParam
|
||||
import top.fatweb.oxygen.api.service.system.IStatisticsService
|
||||
import top.fatweb.oxygen.api.vo.system.*
|
||||
|
||||
/**
|
||||
* Statistics management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IStatisticsService
|
||||
*/
|
||||
@BaseController(path = ["/system/statistics"], name = "统计接口", description = "系统信息统计相关接口")
|
||||
class StatisticsController(
|
||||
private val statisticService: IStatisticsService
|
||||
) {
|
||||
/**
|
||||
* Get software information
|
||||
*
|
||||
* @return Response object includes software information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see SoftwareInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取软件信息")
|
||||
@GetMapping("/software")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:base')")
|
||||
fun software(): ResponseResult<SoftwareInfoVo> = ResponseResult.success(data = statisticService.software())
|
||||
|
||||
/**
|
||||
* Get hardware information
|
||||
*
|
||||
* @return Response object includes hardware information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see HardwareInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取硬件信息")
|
||||
@GetMapping("/hardware")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:base')")
|
||||
fun hardware(): ResponseResult<HardwareInfoVo> = ResponseResult.success(data = statisticService.hardware())
|
||||
|
||||
/**
|
||||
* Get CPU information
|
||||
*
|
||||
* @return Response object includes CPU information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see CpuInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取 CPU 信息")
|
||||
@GetMapping("/cpu")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:real')")
|
||||
fun cpu(): ResponseResult<CpuInfoVo> = ResponseResult.success(data = statisticService.cpu())
|
||||
|
||||
/**
|
||||
* Get storage information
|
||||
*
|
||||
* @return Response object includes storage information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see StorageInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取存储信息")
|
||||
@GetMapping("/storage")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:real')")
|
||||
fun storage(): ResponseResult<StorageInfoVo> = ResponseResult.success(data = statisticService.storage())
|
||||
|
||||
/**
|
||||
* Get the history of online users information
|
||||
*
|
||||
* @param onlineInfoGetParam Get online information parameters
|
||||
* @return Response object includes online user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see OnlineInfoGetParam
|
||||
* @see ResponseResult
|
||||
* @see OnlineInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取在线用户数量信息")
|
||||
@GetMapping("/online")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:usage')")
|
||||
fun online(onlineInfoGetParam: OnlineInfoGetParam?): ResponseResult<OnlineInfoVo> =
|
||||
ResponseResult.success(data = statisticService.online(onlineInfoGetParam))
|
||||
|
||||
/**
|
||||
* Get the history of active information
|
||||
*
|
||||
* @param activeInfoGetParam Get active information parameters
|
||||
* @return Response object includes history of active information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ActiveInfoGetParam
|
||||
* @see ResponseResult
|
||||
* @see ActiveInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取用户活跃信息")
|
||||
@GetMapping("/active")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:usage')")
|
||||
fun active(activeInfoGetParam: ActiveInfoGetParam): ResponseResult<ActiveInfoVo> =
|
||||
ResponseResult.success(data = statisticService.active(activeInfoGetParam))
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.SysLogGetParam
|
||||
import top.fatweb.oxygen.api.service.system.ISysLogService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.system.SysLogVo
|
||||
|
||||
/**
|
||||
* System log viewer controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ISysLogService
|
||||
*/
|
||||
@BaseController(path = ["/system/log"], name = "系统日志", description = "系统日志相关接口")
|
||||
class SysLogController(
|
||||
private val sysLogService: ISysLogService
|
||||
) {
|
||||
/**
|
||||
* Get system log in page
|
||||
*
|
||||
* @param sysLogGetParam Get system log parameters
|
||||
* @return Response object includes system log in page
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SysLogGetParam
|
||||
* @see ResponseResult
|
||||
* @see SysLogVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:log:query:all')")
|
||||
fun get(@Valid sysLogGetParam: SysLogGetParam?): ResponseResult<PageVo<SysLogVo>> {
|
||||
return ResponseResult.success(
|
||||
ResponseCode.DATABASE_SELECT_SUCCESS, data = sysLogService.getPage(sysLogGetParam)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolBaseAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolBaseGetParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolBaseUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolBaseService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
|
||||
/**
|
||||
* Tool base management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolBaseService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/base"], name = "工具基板管理", description = "工具基板管理相关接口")
|
||||
class BaseController(
|
||||
private val toolBaseService: IToolBaseService
|
||||
) {
|
||||
/**
|
||||
* Get tool base by ID
|
||||
*
|
||||
* @param id Tool base ID
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "获取单个基板")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:base')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(data = toolBaseService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool base paging information
|
||||
*
|
||||
* @param toolBaseGetParam Get tool base parameters
|
||||
* @return Response object includes tool base paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBaseGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "获取基板")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:base')")
|
||||
fun get(toolBaseGetParam: ToolBaseGetParam?): ResponseResult<PageVo<ToolBaseVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolBaseService.get(toolBaseGetParam))
|
||||
|
||||
/**
|
||||
* Get tool base list
|
||||
*
|
||||
* @return Response object includes tool base list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "获取基板列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:template', 'system:tool:modify:template')")
|
||||
fun list(): ResponseResult<List<ToolBaseVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolBaseService.getList())
|
||||
|
||||
|
||||
/**
|
||||
* Add tool base
|
||||
*
|
||||
* @param toolBaseAddParam Add tool base parameters
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBaseAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "新增基板")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:base')")
|
||||
fun add(@RequestBody @Valid toolBaseAddParam: ToolBaseAddParam): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolBaseService.add(toolBaseAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool base
|
||||
*
|
||||
* @param toolBaseUpdateParam Update tool base parameters
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBaseUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新基板")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:base')")
|
||||
fun update(@RequestBody @Valid toolBaseUpdateParam: ToolBaseUpdateParam): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolBaseService.update(toolBaseUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool base by ID
|
||||
*
|
||||
* @param id Tool base ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除基板")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:base')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolBaseService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolCategoryService
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
|
||||
/**
|
||||
* Tool category management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolCategoryService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/category"], name = "工具类别管理", description = "工具列别管理相关接口")
|
||||
class CategoryController(
|
||||
private val toolCategoryService: IToolCategoryService
|
||||
) {
|
||||
/**
|
||||
* Get tool category by ID
|
||||
*
|
||||
* @param id Tool category ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取单个类别")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:category')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(data = toolCategoryService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool category list
|
||||
*
|
||||
* @return Response object includes tool template list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取类别")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:category')")
|
||||
fun get(): ResponseResult<List<ToolCategoryVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolCategoryService.get())
|
||||
|
||||
/**
|
||||
* Add tool category
|
||||
*
|
||||
* @param toolCategoryAddParam Add tool category parameters
|
||||
* @return Response object includes tool category information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "新增类别")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:category')")
|
||||
fun add(@RequestBody @Valid toolCategoryAddParam: ToolCategoryAddParam): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolCategoryService.add(toolCategoryAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool category
|
||||
*
|
||||
* @param toolCategoryUpdateParam Update tool category parameters
|
||||
* @return Response object includes tool category information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新类别")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:category')")
|
||||
fun update(@RequestBody @Valid toolCategoryUpdateParam: ToolCategoryUpdateParam): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolCategoryService.update(toolCategoryUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool category
|
||||
*
|
||||
* @param id Tool category ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除类别")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:category')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolCategoryService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.entity.tool.Platform
|
||||
import top.fatweb.oxygen.api.param.PageSortParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCreateParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolUpdateParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolUpgradeParam
|
||||
import top.fatweb.oxygen.api.service.tool.IEditService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool edit controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IEditService
|
||||
*/
|
||||
@BaseController(path = ["/tool"], name = "工具编辑", description = "工具编辑相关接口")
|
||||
class EditController(
|
||||
private val editService: IEditService
|
||||
) {
|
||||
/**
|
||||
* Get tool template list
|
||||
*
|
||||
* @return Response object includes tool template list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取模板")
|
||||
@GetMapping("/template")
|
||||
fun getTemplate(platform: Platform): ResponseResult<List<ToolTemplateVo>> =
|
||||
ResponseResult.databaseSuccess(data = editService.getTemplate(platform))
|
||||
|
||||
/**
|
||||
* Get tool template by ID
|
||||
*
|
||||
* @param id ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取单个模板")
|
||||
@GetMapping("/template/{id}")
|
||||
fun getTemplate(@PathVariable id: Long): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(data = editService.getTemplate(id))
|
||||
|
||||
/**
|
||||
* Get tool category list
|
||||
*
|
||||
* @return Response object includes tool category list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取类别")
|
||||
@GetMapping("/category")
|
||||
fun getCategory(): ResponseResult<List<ToolCategoryVo>> =
|
||||
ResponseResult.databaseSuccess(data = editService.getCategory())
|
||||
|
||||
/**
|
||||
* Create tool
|
||||
*
|
||||
* @param toolCreateParam Create tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCreateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "创建工具")
|
||||
@PostMapping
|
||||
fun create(@RequestBody @Valid toolCreateParam: ToolCreateParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS, data = editService.create(toolCreateParam))
|
||||
|
||||
/**
|
||||
* Upgrade tool
|
||||
*
|
||||
* @param toolUpgradeParam Upgrade tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolUpgradeParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "升级工具")
|
||||
@PatchMapping
|
||||
fun upgrade(@RequestBody @Valid toolUpgradeParam: ToolUpgradeParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = editService.upgrade(toolUpgradeParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get personal tool
|
||||
*
|
||||
* @return Response object includes tool list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PageSortParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取个人工具")
|
||||
@GetMapping
|
||||
fun get(@Valid pageSortParam: PageSortParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_SELECT_SUCCESS, data = editService.getPage(pageSortParam))
|
||||
|
||||
/**
|
||||
* Get tool detail
|
||||
*
|
||||
* @param username Username
|
||||
* @param toolId Tool ID
|
||||
* @param ver Version
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取工具内容")
|
||||
@GetMapping("/detail/{username}/{toolId}/{ver}")
|
||||
fun detail(
|
||||
@PathVariable username: String,
|
||||
@PathVariable toolId: String,
|
||||
@PathVariable ver: String,
|
||||
platform: Platform
|
||||
): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_SELECT_SUCCESS,
|
||||
data = editService.detail(username.trim(), toolId.trim(), ver.trim(), platform)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool
|
||||
*
|
||||
* @param toolUpdateParam Update tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新工具")
|
||||
@PutMapping
|
||||
fun update(@RequestBody @Valid toolUpdateParam: ToolUpdateParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = editService.update(toolUpdateParam))
|
||||
|
||||
/**
|
||||
* Submit tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "提交工具审核")
|
||||
@PostMapping("/{id}")
|
||||
fun submit(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.submit(id)) ResponseResult.success(ResponseCode.TOOL_SUBMIT_SUCCESS)
|
||||
else ResponseResult.fail(ResponseCode.TOOL_SUBMIT_ERROR)
|
||||
|
||||
/**
|
||||
* Cancel tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "取消工具审核")
|
||||
@PutMapping("/{id}")
|
||||
fun cancel(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.cancel(id)) ResponseResult.success(ResponseCode.TOOL_CANCEL_SUCCESS)
|
||||
else ResponseResult.fail(ResponseCode.TOOL_CANCEL_ERROR)
|
||||
|
||||
/**
|
||||
* Delete tool
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除工具")
|
||||
@DeleteMapping("/{id}")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolManagementGetParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolManagementPassParam
|
||||
import top.fatweb.oxygen.api.service.tool.IManagementService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IManagementService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool"], name = "工具管理", description = "工具管理相关接口")
|
||||
class ManagementController(
|
||||
private val managementService: IManagementService
|
||||
) {
|
||||
/**
|
||||
* Get tool by ID
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取单个工具")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:tool')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(data = managementService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool paging information
|
||||
*
|
||||
* @param toolManagementGetParam Get tool parameters in tool management
|
||||
* @return Response object includes tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolManagementGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取工具")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:tool')")
|
||||
fun get(toolManagementGetParam: ToolManagementGetParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = managementService.getPage(toolManagementGetParam))
|
||||
|
||||
/**
|
||||
* Pass tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @param toolManagementPassParam Pass tool parameters in tool management
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolManagementPassParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "通过审核")
|
||||
@PostMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun pass(
|
||||
@PathVariable id: Long,
|
||||
@RequestBody @Valid toolManagementPassParam: ToolManagementPassParam
|
||||
): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = managementService.pass(id, toolManagementPassParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Reject tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "驳回审核")
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun reject(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = managementService.reject(id))
|
||||
|
||||
/**
|
||||
* Put off shelve
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "下架")
|
||||
@PatchMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun offShelve(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = managementService.offShelve(id))
|
||||
|
||||
/**
|
||||
* Delete tool
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除工具")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:tool')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (managementService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.PageSortParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolFavoriteAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolFavoriteRemoveParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolStoreGetParam
|
||||
import top.fatweb.oxygen.api.service.tool.IStoreService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool store controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IStoreService
|
||||
*/
|
||||
@BaseController(path = ["/tool/store"], name = "工具商店", description = "工具商店相关接口")
|
||||
class StoreController(
|
||||
private val storeService: IStoreService
|
||||
) {
|
||||
/**
|
||||
* Get store tool paging information
|
||||
*
|
||||
* @param toolStoreGetParam Get tool parameters in tool store
|
||||
* @return Response object includes store tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolStoreGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(description = "获取商店工具")
|
||||
@GetMapping
|
||||
fun get(@Valid toolStoreGetParam: ToolStoreGetParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = storeService.getPage(toolStoreGetParam))
|
||||
|
||||
/**
|
||||
* Get store tool paging information by username
|
||||
*
|
||||
* @param username Username
|
||||
* @param pageSortParam Page sort parameters
|
||||
* @return Response object includes store tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PageSortParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(description = "获取商店指定用户工具")
|
||||
@GetMapping("/{username}")
|
||||
fun get(@PathVariable username: String, @Valid pageSortParam: PageSortParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = storeService.getPage(pageSortParam, username.trim()))
|
||||
|
||||
/**
|
||||
* Add favorite tool
|
||||
*
|
||||
* @param toolFavoriteAddParam Add favorite tool parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolFavoriteAddParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "收藏工具")
|
||||
@PostMapping("/favorite")
|
||||
fun addFavorite(@RequestBody toolFavoriteAddParam: ToolFavoriteAddParam): ResponseResult<Nothing> {
|
||||
storeService.addFavorite(toolFavoriteAddParam)
|
||||
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove favorite tool
|
||||
*
|
||||
* @param toolFavoriteRemoveParam Remove favorite tool parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolFavoriteRemoveParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "收藏工具")
|
||||
@DeleteMapping("/favorite")
|
||||
fun addFavorite(@RequestBody toolFavoriteRemoveParam: ToolFavoriteRemoveParam): ResponseResult<Nothing> {
|
||||
storeService.removeFavorite(toolFavoriteRemoveParam)
|
||||
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get favorite tool
|
||||
*
|
||||
* @param pageSortParam Page sort parameters
|
||||
* @return Response object includes favorite tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PageSortParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "获取收藏工具")
|
||||
@GetMapping("/favorite")
|
||||
fun getFavorite(@Valid pageSortParam: PageSortParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = storeService.getFavorite(pageSortParam))
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.annotation.Trim
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolTemplateAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolTemplateGetParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolTemplateUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolTemplateService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
|
||||
/**
|
||||
* Tool template management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolTemplateService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/template"], name = "工具模板管理", description = "工具模板管理相关接口")
|
||||
class TemplateController(
|
||||
private val toolTemplateService: IToolTemplateService
|
||||
) {
|
||||
/**
|
||||
* Get tool template by ID
|
||||
*
|
||||
* @param id Tool template ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取单个模板")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:template')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(data = toolTemplateService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool template paging information
|
||||
*
|
||||
* @param toolTemplateGetParam Get tool template parameters
|
||||
* @return Response object includes tool template paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplateGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取模板")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:template')")
|
||||
fun get(toolTemplateGetParam: ToolTemplateGetParam?): ResponseResult<PageVo<ToolTemplateVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolTemplateService.get(toolTemplateGetParam))
|
||||
|
||||
/**
|
||||
* Add tool template
|
||||
*
|
||||
* @param toolTemplateAddParam Add tool template parameters
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplateAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "添加模板")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:template')")
|
||||
fun add(@RequestBody @Valid toolTemplateAddParam: ToolTemplateAddParam): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolTemplateService.add(toolTemplateAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool template
|
||||
*
|
||||
* @param toolTemplateUpdateParam Update tool template parameters
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplateUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Trim
|
||||
@Operation(summary = "更新模板")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:template')")
|
||||
fun update(@RequestBody @Valid toolTemplateUpdateParam: ToolTemplateUpdateParam): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolTemplateService.update(toolTemplateUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool template
|
||||
*
|
||||
* @param id Tool template ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除模板")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:template')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolTemplateService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Func
|
||||
import top.fatweb.oxygen.api.vo.permission.base.FuncVo
|
||||
|
||||
/**
|
||||
* Function converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object FuncConverter {
|
||||
/**
|
||||
* Convert Func object into FuncVo object
|
||||
*
|
||||
* @param func Func object
|
||||
* @return FuncVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
* @see FuncVo
|
||||
*/
|
||||
fun funcToFuncVo(func: Func) = FuncVo(
|
||||
id = func.id,
|
||||
name = func.name,
|
||||
parentId = func.parentId,
|
||||
menuId = func.menuId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.permission.Group
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupUpdateParam
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupUpdateStatusParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.GroupWithRoleVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.GroupVo
|
||||
|
||||
/**
|
||||
* Group converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object GroupConverter {
|
||||
/**
|
||||
* Convert Group object into GroupVo object
|
||||
*
|
||||
* @param group Group object
|
||||
* @return GroupVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Group
|
||||
* @see GroupVo
|
||||
*/
|
||||
fun groupToGroupVo(group: Group) = GroupVo(
|
||||
id = group.id,
|
||||
name = group.name,
|
||||
enable = group.enable?.let { it == 1},
|
||||
createTime = group.createTime,
|
||||
updateTime = group.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Group object into GroupWithRoleVo object
|
||||
*
|
||||
* @param group Group object
|
||||
* @return GroupWithRoleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Group
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
fun groupToGroupWithRoleVo(group: Group) = GroupWithRoleVo(
|
||||
id = group.id,
|
||||
name = group.name,
|
||||
enable = group.enable?.let { it == 1},
|
||||
createTime = group.createTime,
|
||||
updateTime = group.updateTime,
|
||||
roles = group.roles?.map(RoleConverter::roleToRoleVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<Group> object into PageVo<GroupWithRoleVo> object
|
||||
*
|
||||
* @param groupPage IPage<Group> object
|
||||
* @return PageVo<GroupWithRoleVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see Group
|
||||
* @see PageVo
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
fun groupPageToGroupWithRolePageVo(groupPage: IPage<Group>) = PageVo(
|
||||
total = groupPage.total,
|
||||
pages = groupPage.pages,
|
||||
size = groupPage.size,
|
||||
current = groupPage.current,
|
||||
records = groupPage.records.map(::groupToGroupWithRoleVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert GroupAddParam object into Group object
|
||||
*
|
||||
* @param groupAddParam GroupAddParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupAddParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupAddParamToGroup(groupAddParam: GroupAddParam) = Group().apply {
|
||||
name = groupAddParam.name
|
||||
enable = if (groupAddParam.enable) 1 else 0
|
||||
roles = groupAddParam.roleIds?.map { Role().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GroupUpdateParam object into Group object
|
||||
*
|
||||
* @param groupUpdateParam GroupUpdateParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupUpdateParamToGroup(groupUpdateParam: GroupUpdateParam) = Group().apply {
|
||||
id = groupUpdateParam.id
|
||||
name = groupUpdateParam.name
|
||||
enable = if (groupUpdateParam.enable) 1 else 0
|
||||
roles = groupUpdateParam.roleIds?.map { Role().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GroupUpdateStatusParam object into Group object
|
||||
*
|
||||
* @param groupUpdateStatusParam GroupUpdateStatusParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateStatusParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupUpdateStatusParamToGroup(groupUpdateStatusParam: GroupUpdateStatusParam) = Group().apply {
|
||||
id = groupUpdateStatusParam.id
|
||||
enable = if (groupUpdateStatusParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Menu
|
||||
import top.fatweb.oxygen.api.vo.permission.base.MenuVo
|
||||
|
||||
/**
|
||||
* Menu converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object MenuConverter {
|
||||
/**
|
||||
* Convert Menu object into MenuVo object
|
||||
*
|
||||
* @param menu Menu object
|
||||
* @return MenuVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
* @see MenuVo
|
||||
*/
|
||||
fun menuToMenuVo(menu: Menu) = MenuVo(
|
||||
id = menu.id,
|
||||
name = menu.name,
|
||||
url = menu.url,
|
||||
parentId = menu.parentId,
|
||||
moduleId = menu.moduleId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Module
|
||||
import top.fatweb.oxygen.api.vo.permission.base.ModuleVo
|
||||
|
||||
/**
|
||||
* Module converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ModuleConverter {
|
||||
/**
|
||||
* Convert Module object into ModuleVo object
|
||||
*
|
||||
* @param module Module object
|
||||
* @return ModuleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
* @see ModuleVo
|
||||
*/
|
||||
fun moduleToModuleVo(module: Module) = ModuleVo(
|
||||
id = module.id,
|
||||
name = module.name
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Operation
|
||||
import top.fatweb.oxygen.api.vo.permission.base.OperationVo
|
||||
|
||||
/**
|
||||
* Operation converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object OperationConverter {
|
||||
/**
|
||||
* Convert Operation object into OperationVo object
|
||||
*
|
||||
* @param operation Operation object
|
||||
* @return OperationVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
* @see OperationVo
|
||||
*/
|
||||
fun operationToOperationVo(operation: Operation) = OperationVo(
|
||||
id = operation.id,
|
||||
name = operation.name,
|
||||
code = operation.code,
|
||||
funcId = operation.funcId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.PowerSet
|
||||
import top.fatweb.oxygen.api.vo.permission.PowerSetVo
|
||||
|
||||
/**
|
||||
* Power converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object PowerConverter {
|
||||
/**
|
||||
* Convert PowerSet object into PowerSetVo object
|
||||
*
|
||||
* @param powerSet PowerSet object
|
||||
* @return PowerSetVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PowerSet
|
||||
* @see PowerSetVo
|
||||
*/
|
||||
fun powerSetToPowerSetVo(powerSet: PowerSet) = PowerSetVo(
|
||||
moduleList = powerSet.moduleList?.map(ModuleConverter::moduleToModuleVo),
|
||||
menuList = powerSet.menuList?.map(MenuConverter::menuToMenuVo),
|
||||
funcList = powerSet.funcList?.map(FuncConverter::funcToFuncVo),
|
||||
operationList = powerSet.operationList?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.permission.Power
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleUpdateParam
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleUpdateStatusParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RoleWithPowerVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.RoleVo
|
||||
|
||||
/**
|
||||
* Role converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object RoleConverter {
|
||||
/**
|
||||
* Convert Role object into RoleVo object
|
||||
*
|
||||
* @param role Role object
|
||||
* @return RoleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
* @see RoleVo
|
||||
*/
|
||||
fun roleToRoleVo(role: Role) = RoleVo(
|
||||
id = role.id,
|
||||
name = role.name,
|
||||
enable = role.enable?.let { it == 1},
|
||||
createTime = role.createTime,
|
||||
updateTime = role.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Role object into RoleWithPowerVo object
|
||||
*
|
||||
* @param role Role object
|
||||
* @return RoleWithPowerVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
fun roleToRoleWithPowerVo(role: Role) = RoleWithPowerVo(
|
||||
id = role.id,
|
||||
name = role.name,
|
||||
enable = role.enable?.let { it == 1},
|
||||
createTime = role.createTime,
|
||||
updateTime = role.updateTime,
|
||||
modules = role.modules?.map(ModuleConverter::moduleToModuleVo),
|
||||
menus = role.menus?.map(MenuConverter::menuToMenuVo),
|
||||
funcs = role.funcs?.map(FuncConverter::funcToFuncVo),
|
||||
operations = role.operations?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<Role> object into PageVo object
|
||||
*
|
||||
* @param rolePage IPage<Role> object
|
||||
* @return PageVo<RoleWithPowerVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see Role
|
||||
* @see PageVo
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
fun rolePageToRoleWithPowerPageVo(rolePage: IPage<Role>) = PageVo(
|
||||
total = rolePage.total,
|
||||
pages = rolePage.pages,
|
||||
size = rolePage.size,
|
||||
current = rolePage.current,
|
||||
records = rolePage.records.map(::roleToRoleWithPowerVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert RoleAddParam object into Role object
|
||||
*
|
||||
* @param roleAddParam RoleAddParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleAddParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleAddParamToRole(roleAddParam: RoleAddParam) = Role().apply {
|
||||
name = roleAddParam.name
|
||||
enable = if (roleAddParam.enable) 1 else 0
|
||||
powers = roleAddParam.powerIds?.map { Power().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RoleUpdateParam into Role object
|
||||
*
|
||||
* @param roleUpdateParam RoleUpdateParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleUpdateParamToRole(roleUpdateParam: RoleUpdateParam) = Role().apply {
|
||||
id = roleUpdateParam.id
|
||||
name = roleUpdateParam.name
|
||||
enable = if (roleUpdateParam.enable) 1 else 0
|
||||
powers = roleUpdateParam.powerIds?.map { Power().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RoleUpdateStatusParam object into Role object
|
||||
*
|
||||
* @param roleUpdateStatusParam RoleUpdateStatusParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateStatusParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleUpdateStatusParamToRole(roleUpdateStatusParam: RoleUpdateStatusParam) = Role().apply {
|
||||
id = roleUpdateStatusParam.id
|
||||
enable = if (roleUpdateStatusParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.avatargenerator.GitHubAvatar
|
||||
import top.fatweb.oxygen.api.entity.permission.Group
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.entity.permission.User
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.param.permission.user.UserAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.user.UserUpdateParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPasswordRoleInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPowerInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithRoleInfoVo
|
||||
|
||||
/**
|
||||
* User converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object UserConverter {
|
||||
/**
|
||||
* Convert User object into UserWithPowerInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithPowerInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
fun userToUserWithPowerInfoVo(user: User) = UserWithPowerInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
twoFactor = !user.twoFactor.isNullOrBlank() && !user.twoFactor!!.endsWith("?"),
|
||||
verified = user.verify.isNullOrBlank(),
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
modules = user.modules?.map(ModuleConverter::moduleToModuleVo),
|
||||
menus = user.menus?.map(MenuConverter::menuToMenuVo),
|
||||
funcs = user.funcs?.map(FuncConverter::funcToFuncVo),
|
||||
operations = user.operations?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithRoleInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithRoleInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
fun userToUserWithRoleInfoVo(user: User) = UserWithRoleInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
twoFactor = !user.twoFactor.isNullOrBlank() && !user.twoFactor!!.endsWith("?"),
|
||||
verify = user.verify,
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
roles = user.roles?.map(RoleConverter::roleToRoleVo),
|
||||
groups = user.groups?.map(GroupConverter::groupToGroupVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithInfoVo
|
||||
*/
|
||||
fun userToUserWithInfoVo(user: User) = UserWithInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
twoFactor = !user.twoFactor.isNullOrBlank() && !user.twoFactor!!.endsWith("?"),
|
||||
verified = user.verify.isNullOrBlank(),
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithPasswordRoleInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithPasswordRoleInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithPasswordRoleInfoVo
|
||||
*/
|
||||
fun userToUserWithPasswordRoleInfoVo(user: User) = UserWithPasswordRoleInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
password = user.password,
|
||||
twoFactor = !user.twoFactor.isNullOrBlank() && !user.twoFactor!!.endsWith("?"),
|
||||
verify = user.verify,
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
roles = user.roles?.map(RoleConverter::roleToRoleVo),
|
||||
groups = user.groups?.map(GroupConverter::groupToGroupVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert UserAddParam object into User object
|
||||
*
|
||||
* @param userAddParam UserAddParam object
|
||||
* @return User object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserAddParam
|
||||
* @see User
|
||||
*/
|
||||
fun userAddParamToUser(userAddParam: UserAddParam) = User().apply {
|
||||
username = userAddParam.username
|
||||
password = userAddParam.password
|
||||
locking = if (userAddParam.locking) 1 else 0
|
||||
expiration = userAddParam.expiration
|
||||
credentialsExpiration = userAddParam.credentialsExpiration
|
||||
enable = if (userAddParam.enable) 1 else 0
|
||||
userInfo = UserInfo().apply {
|
||||
nickname = userAddParam.nickname ?: userAddParam.username
|
||||
avatar = userAddParam.avatar ?: GitHubAvatar.newAvatarBuilder().build()
|
||||
.createAsBase64((Long.MIN_VALUE..Long.MAX_VALUE).random())
|
||||
email = userAddParam.email
|
||||
}
|
||||
roles = userAddParam.roleIds?.map { Role().apply { id = it } }
|
||||
groups = userAddParam.groupIds?.map { Group().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UserUpdateParam object into User object
|
||||
*
|
||||
* @param userUpdateParam UserUpdateParam object
|
||||
* @return User object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdateParam
|
||||
* @see User
|
||||
*/
|
||||
fun userUpdateParamToUser(userUpdateParam: UserUpdateParam) = User().apply {
|
||||
id = userUpdateParam.id
|
||||
username = userUpdateParam.username
|
||||
locking = if (userUpdateParam.locking && userUpdateParam.id != 0L) 1 else 0
|
||||
expiration = if (userUpdateParam.id != 0L) userUpdateParam.expiration else null
|
||||
credentialsExpiration = userUpdateParam.credentialsExpiration
|
||||
enable = if (userUpdateParam.enable || userUpdateParam.id == 0L) 1 else 0
|
||||
userInfo = UserInfo().apply {
|
||||
nickname = userUpdateParam.nickname
|
||||
avatar = userUpdateParam.avatar
|
||||
email = userUpdateParam.email
|
||||
}
|
||||
roles = if (userUpdateParam.id != 0L) userUpdateParam.roleIds?.map { Role().apply { id = it } } else null
|
||||
groups = if (userUpdateParam.id != 0L) userUpdateParam.groupIds?.map { Group().apply { id = it } } else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert IPage<User> object into PageVo<UserWithRoleInfoVo> object
|
||||
*
|
||||
* @param userPage IPage<User> object
|
||||
* @return PageVo<UserWithRoleInfoVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see User
|
||||
* @see PageVo
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
fun userPageToUserWithRoleInfoPageVo(userPage: IPage<User>) = PageVo(
|
||||
total = userPage.total,
|
||||
pages = userPage.pages,
|
||||
size = userPage.size,
|
||||
current = userPage.current,
|
||||
records = userPage.records.map(::userToUserWithRoleInfoVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.UserInfoVo
|
||||
|
||||
/**
|
||||
* User information converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object UserInfoConverter {
|
||||
/**
|
||||
* Convert UserInfo object into UserInfoVo object
|
||||
*
|
||||
* @param userInfo UserInfo object
|
||||
* @return UserInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserInfo
|
||||
* @see UserInfoVo
|
||||
*/
|
||||
fun userInfoToUserInfoVo(userInfo: UserInfo) = UserInfoVo(
|
||||
id = userInfo.id,
|
||||
userId = userInfo.userId,
|
||||
nickname = userInfo.nickname,
|
||||
avatar = userInfo.avatar,
|
||||
email = userInfo.email,
|
||||
createTime = userInfo.createTime,
|
||||
updateTime = userInfo.updateTime
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package top.fatweb.oxygen.api.converter.system
|
||||
|
||||
import top.fatweb.oxygen.api.entity.system.SensitiveWord
|
||||
import top.fatweb.oxygen.api.param.system.SensitiveWordAddParam
|
||||
import top.fatweb.oxygen.api.vo.system.SensitiveWordVo
|
||||
|
||||
/**
|
||||
* Settings converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object SettingsConverter {
|
||||
/**
|
||||
* Convert SensitiveWord object into SensitiveWordVo object
|
||||
*
|
||||
* @param sensitiveWord SensitiveWord object
|
||||
* @return SensitiveWordVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWord
|
||||
* @see SensitiveWordVo
|
||||
*/
|
||||
fun sensitiveWordToSensitiveWordVo(sensitiveWord: SensitiveWord) = SensitiveWordVo(
|
||||
id = sensitiveWord.id,
|
||||
word = sensitiveWord.word,
|
||||
useFor = sensitiveWord.useFor?.map(SensitiveWord.Use::valueOf)?.toSet(),
|
||||
enable = sensitiveWord.enable?.let { it == 1}
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert SensitiveWordAddParam object into SensitiveWord object
|
||||
*
|
||||
* @param sensitiveWordAddParam SensitiveWordAddParam object
|
||||
* @return SensitiveWord object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordAddParam
|
||||
* @see SensitiveWord
|
||||
*/
|
||||
fun sensitiveWordAddParamToSensitiveWord(sensitiveWordAddParam: SensitiveWordAddParam) = SensitiveWord().apply {
|
||||
word = sensitiveWordAddParam.word
|
||||
useFor = sensitiveWordAddParam.useFor.map(SensitiveWord.Use::code).toSet()
|
||||
enable = if (sensitiveWordAddParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package top.fatweb.oxygen.api.converter.system
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.system.SysLog
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.system.SysLogVo
|
||||
|
||||
/**
|
||||
* System log converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object SysLogConverter {
|
||||
/**
|
||||
* Convert IPage<SysLog> object into PageVo<SysLogVo> object
|
||||
*
|
||||
* @param syslogPage IPage<Syslog> object
|
||||
* @return PageVo<SysLogVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see SysLog
|
||||
* @see PageVo
|
||||
* @see SysLogVo
|
||||
*/
|
||||
fun sysLogPageToSysLogPageVo(syslogPage: IPage<SysLog>) = PageVo(
|
||||
syslogPage.total,
|
||||
syslogPage.pages,
|
||||
syslogPage.size,
|
||||
syslogPage.current,
|
||||
syslogPage.records.map { sysLog ->
|
||||
SysLogVo(
|
||||
id = sysLog.id,
|
||||
logType = sysLog.logType,
|
||||
operateUserId = sysLog.operateUserId,
|
||||
operateTime = sysLog.operateTime,
|
||||
requestUri = sysLog.requestUri,
|
||||
requestMethod = sysLog.requestMethod,
|
||||
requestParams = sysLog.requestParams,
|
||||
requestIp = sysLog.requestIp,
|
||||
requestServerAddress = sysLog.requestServerAddress,
|
||||
exception = sysLog.exception?.let { it == 1},
|
||||
exceptionInfo = sysLog.exceptionInfo,
|
||||
startTime = sysLog.startTime,
|
||||
endTime = sysLog.endTime,
|
||||
executeTime = sysLog.executeTime,
|
||||
userAgent = sysLog.userAgent,
|
||||
operateUsername = sysLog.operateUsername
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolBase
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
|
||||
/**
|
||||
* Tool base converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolBaseConverter {
|
||||
/**
|
||||
* Convert ToolBase object into ToolBaseVo object
|
||||
*
|
||||
* @param toolBase ToolBase object
|
||||
* @return ToolBaseVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBase
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
fun toolBaseToToolBaseVo(toolBase: ToolBase) = ToolBaseVo(
|
||||
id = toolBase.id,
|
||||
name = toolBase.name,
|
||||
source = toolBase.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
dist = toolBase.dist?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
platform = toolBase.platform,
|
||||
compiled = toolBase.compiled?.let { it == 1},
|
||||
createTime = toolBase.createTime,
|
||||
updateTime = toolBase.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolBase object into ToolBaseVo object by get page
|
||||
*
|
||||
* @param toolBase ToolBase object
|
||||
* @return ToolBaseVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBase
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
fun toolBaseToToolBaseVoByGetList(toolBase: ToolBase) = ToolBaseVo(
|
||||
id = toolBase.id,
|
||||
name = toolBase.name,
|
||||
source = ToolDataVo(id = toolBase.sourceId, data = null, createTime = null, updateTime = null),
|
||||
dist = ToolDataVo(id = toolBase.distId, data = null, createTime = null, updateTime = null),
|
||||
platform = toolBase.platform,
|
||||
compiled = toolBase.compiled?.let { it == 1},
|
||||
createTime = toolBase.createTime,
|
||||
updateTime = toolBase.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<ToolBase> object into PageVo<ToolBaseVo> object
|
||||
*
|
||||
* @param toolBasePage IPage<ToolBase> object
|
||||
* @return PageVo<ToolBaseVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see ToolBase
|
||||
* @see PageVo
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
fun toolBasePageToToolBasePageVo(toolBasePage: IPage<ToolBase>) = PageVo(
|
||||
total = toolBasePage.total,
|
||||
pages = toolBasePage.pages,
|
||||
size = toolBasePage.size,
|
||||
current = toolBasePage.current,
|
||||
records = toolBasePage.records.map(::toolBaseToToolBaseVoByGetList)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolCategory
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryUpdateParam
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
|
||||
/**
|
||||
* Tool category converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolCategoryConverter {
|
||||
/**
|
||||
* Convert ToolCategory object into ToolCategoryVo object
|
||||
*
|
||||
* @param toolCategory ToolCategory object
|
||||
* @return ToolCategoryVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategory
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
fun toolCategoryToToolCategoryVo(toolCategory: ToolCategory) = ToolCategoryVo(
|
||||
id = toolCategory.id,
|
||||
name = toolCategory.name,
|
||||
enable = toolCategory.enable?.let { it == 1},
|
||||
createTime = toolCategory.createTime,
|
||||
updateTime = toolCategory.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolCategoryAddParam object into ToolCategory object
|
||||
*
|
||||
* @param toolCategoryAddParam ToolCategoryAddParam object
|
||||
* @return ToolCateGory object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryAddParam
|
||||
* @see ToolCategory
|
||||
*/
|
||||
fun toolCategoryAddParamToToolCategory(toolCategoryAddParam: ToolCategoryAddParam) = ToolCategory().apply {
|
||||
name = toolCategoryAddParam.name
|
||||
enable = if (toolCategoryAddParam.enable) 1 else 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ToolCategoryUpdateParam object into ToolCategory object
|
||||
*
|
||||
* @param toolCategoryUpdateParam ToolCategoryUpdateParam object
|
||||
* @return ToolCategory object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryUpdateParam
|
||||
* @see ToolCategory
|
||||
*/
|
||||
fun toolCategoryUpdateParamToToolCategory(toolCategoryUpdateParam: ToolCategoryUpdateParam) = ToolCategory().apply {
|
||||
id = toolCategoryUpdateParam.id
|
||||
name = toolCategoryUpdateParam.name
|
||||
enable = toolCategoryUpdateParam.enable?. let { if (it) 1 else 0 }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
|
||||
import top.fatweb.oxygen.api.converter.permission.UserConverter
|
||||
import top.fatweb.oxygen.api.entity.tool.Tool
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolConverter {
|
||||
/**
|
||||
* Convert Tool object into ToolVo object
|
||||
*
|
||||
* @param tool Tool object
|
||||
* @return ToolVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Tool
|
||||
* @see ToolVo
|
||||
*/
|
||||
fun toolToToolVo(tool: Tool) = ToolVo(
|
||||
id = tool.id,
|
||||
name = tool.name,
|
||||
toolId = tool.toolId,
|
||||
icon = tool.icon,
|
||||
platform = tool.platform,
|
||||
description = tool.description,
|
||||
base = tool.base?.let(ToolBaseConverter::toolBaseToToolBaseVo),
|
||||
author = tool.author?.let(UserConverter::userToUserWithInfoVo),
|
||||
ver = tool.ver,
|
||||
keywords = tool.keywords,
|
||||
categories = tool.categories?.map(ToolCategoryConverter::toolCategoryToToolCategoryVo),
|
||||
source = tool.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
dist = tool.dist?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
entryPoint = tool.entryPoint,
|
||||
publish = tool.publish,
|
||||
review = tool.review,
|
||||
createTime = tool.createTime,
|
||||
updateTime = tool.updateTime,
|
||||
favorite = tool.favorite?.let { it == 1}
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Page<Tool> object into PageVo<ToolVo> object
|
||||
*
|
||||
* @param toolPage Page<Tool> object
|
||||
* @return PageVo<ToolVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Page
|
||||
* @see Tool
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
fun toolPageToToolPageVo(toolPage: Page<Tool>): PageVo<ToolVo> = PageVo(
|
||||
total = toolPage.total,
|
||||
pages = toolPage.pages,
|
||||
size = toolPage.size,
|
||||
current = toolPage.current,
|
||||
records = toolPage.records.map(::toolToToolVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolData
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
|
||||
/**
|
||||
* Tool data converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolDataConverter {
|
||||
/**
|
||||
* Convert ToolData object into ToolDataVo object
|
||||
*
|
||||
* @param toolData ToolData object
|
||||
* @return ToolDataVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolData
|
||||
* @see ToolDataVo
|
||||
*/
|
||||
fun toolDataToToolDataVo(toolData: ToolData) = ToolDataVo(
|
||||
id = toolData.id,
|
||||
data = toolData.data,
|
||||
createTime = toolData.createTime,
|
||||
updateTime = toolData.updateTime
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolTemplate
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
|
||||
/**
|
||||
* Tool template converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolTemplateConverter {
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object
|
||||
*
|
||||
* @param toolTemplate ToolTemplate object
|
||||
* @return ToolTemplateVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplate
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVo(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = toolTemplate.base?.let(ToolBaseConverter::toolBaseToToolBaseVo),
|
||||
source = toolTemplate.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
platform = toolTemplate.platform,
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable?.let { it == 1},
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<ToolTemplate> object into PageVo<ToolTemplateVo> object
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun toolTemplatePageToToolTemplatePageVo(toolTemplatePage: IPage<ToolTemplate>) = PageVo(
|
||||
total = toolTemplatePage.total,
|
||||
pages = toolTemplatePage.pages,
|
||||
size = toolTemplatePage.size,
|
||||
current = toolTemplatePage.current,
|
||||
records = toolTemplatePage.records.map(::toolTemplateToToolTemplateVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object by list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVoByList(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = ToolBaseVo(
|
||||
id = toolTemplate.baseId,
|
||||
name = null,
|
||||
source = null,
|
||||
dist = null,
|
||||
platform = toolTemplate.base?.platform,
|
||||
compiled = null,
|
||||
createTime = null,
|
||||
updateTime = null
|
||||
),
|
||||
source = ToolDataVo(id = toolTemplate.sourceId, data = null, createTime = null, updateTime = null),
|
||||
platform = toolTemplate.platform,
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable?.let { it == 1},
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object with base dist
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVoWithBaseDist(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = ToolBaseVo(
|
||||
id = toolTemplate.baseId,
|
||||
name = toolTemplate.base?.name,
|
||||
source = null,
|
||||
dist = ToolDataVo(id = null, data = toolTemplate.base?.distData, createTime = null, updateTime = null),
|
||||
platform = toolTemplate.base?.platform,
|
||||
compiled = null,
|
||||
createTime = null,
|
||||
updateTime = null
|
||||
),
|
||||
source = toolTemplate.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
platform = toolTemplate.platform,
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable?.let { it == 1},
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
}
|
||||
35
src/main/kotlin/top/fatweb/oxygen/api/cron/StatisticsCron.kt
Normal file
35
src/main/kotlin/top/fatweb/oxygen/api/cron/StatisticsCron.kt
Normal file
@@ -0,0 +1,35 @@
|
||||
package top.fatweb.oxygen.api.cron
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.oxygen.api.entity.system.StatisticsLog
|
||||
import top.fatweb.oxygen.api.properties.SecurityProperties
|
||||
import top.fatweb.oxygen.api.service.system.IStatisticsLogService
|
||||
import top.fatweb.oxygen.api.util.RedisUtil
|
||||
|
||||
/**
|
||||
* Statistics scheduled tasks
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Component
|
||||
class StatisticsCron(
|
||||
private val redisUtil: RedisUtil,
|
||||
private val statisticsLogService: IStatisticsLogService
|
||||
) {
|
||||
/**
|
||||
* Auto record number of online users
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Scheduled(cron = "0 * * * * *")
|
||||
fun onlineUserCount() {
|
||||
statisticsLogService.save(StatisticsLog().apply {
|
||||
key = StatisticsLog.KeyItem.ONLINE_USERS_COUNT
|
||||
value = redisUtil.keys("${SecurityProperties.jwtIssuer}_login_*")
|
||||
.distinctBy { Regex("${SecurityProperties.jwtIssuer}_login_(.*):.*").matchEntire(it)?.groupValues?.getOrNull(1) }.size.toString()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
/**
|
||||
* Business code entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class BusinessCode(val code: Int) {
|
||||
/**
|
||||
* System
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
SYSTEM(100),
|
||||
|
||||
/**
|
||||
* Permission
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
PERMISSION(200),
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
DATABASE(300),
|
||||
|
||||
/**
|
||||
* Tool
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TOOL(400),
|
||||
|
||||
/**
|
||||
* Avatar API
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
API_AVATAR(501)
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
/**
|
||||
* Response code entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class ResponseCode(val code: Int) {
|
||||
SYSTEM_OK(BusinessCode.SYSTEM, 0),
|
||||
|
||||
SYSTEM_ERROR(BusinessCode.SYSTEM, 50),
|
||||
SYSTEM_TIMEOUT(BusinessCode.SYSTEM, 51),
|
||||
SYSTEM_REQUEST_ILLEGAL(BusinessCode.SYSTEM, 52),
|
||||
SYSTEM_ARGUMENT_NOT_VALID(BusinessCode.SYSTEM, 53),
|
||||
SYSTEM_INVALID_CAPTCHA_CODE(BusinessCode.SYSTEM, 54),
|
||||
SYSTEM_REQUEST_TOO_FREQUENT(BusinessCode.SYSTEM, 55),
|
||||
SYSTEM_MATCH_SENSITIVE_WORD(BusinessCode.SYSTEM, 56),
|
||||
|
||||
PERMISSION_LOGIN_SUCCESS(BusinessCode.PERMISSION, 0),
|
||||
PERMISSION_PASSWORD_CHANGE_SUCCESS(BusinessCode.PERMISSION, 1),
|
||||
PERMISSION_LOGOUT_SUCCESS(BusinessCode.PERMISSION, 2),
|
||||
PERMISSION_TOKEN_RENEW_SUCCESS(BusinessCode.PERMISSION, 3),
|
||||
PERMISSION_REGISTER_SUCCESS(BusinessCode.PERMISSION, 4),
|
||||
PERMISSION_RESEND_SUCCESS(BusinessCode.PERMISSION, 5),
|
||||
PERMISSION_VERIFY_SUCCESS(BusinessCode.PERMISSION, 6),
|
||||
PERMISSION_FORGET_SUCCESS(BusinessCode.PERMISSION, 7),
|
||||
PERMISSION_RETRIEVE_SUCCESS(BusinessCode.PERMISSION, 8),
|
||||
|
||||
PERMISSION_UNAUTHORIZED(BusinessCode.PERMISSION, 50),
|
||||
PERMISSION_USERNAME_NOT_FOUND(BusinessCode.PERMISSION, 51),
|
||||
PERMISSION_ACCESS_DENIED(BusinessCode.PERMISSION, 52),
|
||||
PERMISSION_USER_LOCKED(BusinessCode.PERMISSION, 53),
|
||||
PERMISSION_USER_EXPIRED(BusinessCode.PERMISSION, 54),
|
||||
PERMISSION_USER_CREDENTIALS_EXPIRED(BusinessCode.PERMISSION, 55),
|
||||
PERMISSION_USER_DISABLE(BusinessCode.PERMISSION, 56),
|
||||
PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR(BusinessCode.PERMISSION, 57),
|
||||
PERMISSION_OLD_PASSWORD_NOT_MATCH(BusinessCode.PERMISSION, 58),
|
||||
PERMISSION_LOGOUT_FAILED(BusinessCode.PERMISSION, 59),
|
||||
PERMISSION_TOKEN_ILLEGAL(BusinessCode.PERMISSION, 60),
|
||||
PERMISSION_TOKEN_HAS_EXPIRED(BusinessCode.PERMISSION, 61),
|
||||
PERMISSION_NO_VERIFICATION_REQUIRED(BusinessCode.PERMISSION, 62),
|
||||
PERMISSION_VERIFY_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 63),
|
||||
PERMISSION_ACCOUNT_NEED_INIT(BusinessCode.PERMISSION, 64),
|
||||
PERMISSION_USER_NOT_FOUND(BusinessCode.PERMISSION, 65),
|
||||
PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 66),
|
||||
PERMISSION_ACCOUNT_NEED_RESET_PASSWORD(BusinessCode.PERMISSION, 67),
|
||||
PERMISSION_NEED_TWO_FACTOR(BusinessCode.PERMISSION, 68),
|
||||
PERMISSION_ALREADY_HAS_TWO_FACTOR(BusinessCode.PERMISSION, 69),
|
||||
PERMISSION_NO_TWO_FACTOR_FOUND(BusinessCode.PERMISSION, 70),
|
||||
PERMISSION_TWO_FACTOR_VERIFICATION_CODE_ERROR(BusinessCode.PERMISSION, 71),
|
||||
|
||||
DATABASE_SELECT_SUCCESS(BusinessCode.DATABASE, 0),
|
||||
DATABASE_SELECT_FAILED(BusinessCode.DATABASE, 5),
|
||||
DATABASE_INSERT_SUCCESS(BusinessCode.DATABASE, 10),
|
||||
DATABASE_INSERT_FAILED(BusinessCode.DATABASE, 15),
|
||||
DATABASE_UPDATE_SUCCESS(BusinessCode.DATABASE, 20),
|
||||
DATABASE_UPDATE_FAILED(BusinessCode.DATABASE, 25),
|
||||
DATABASE_DELETE_SUCCESS(BusinessCode.DATABASE, 30),
|
||||
DATABASE_DELETE_FAILED(BusinessCode.DATABASE, 35),
|
||||
DATABASE_EXECUTE_ERROR(BusinessCode.DATABASE, 50),
|
||||
DATABASE_DUPLICATE_KEY(BusinessCode.DATABASE, 51),
|
||||
DATABASE_NO_RECORD_FOUND(BusinessCode.DATABASE, 52),
|
||||
DATABASE_RECORD_ALREADY_EXISTS(BusinessCode.DATABASE, 53),
|
||||
|
||||
TOOL_SUBMIT_SUCCESS(BusinessCode.TOOL, 10),
|
||||
TOOL_CANCEL_SUCCESS(BusinessCode.TOOL, 11),
|
||||
TOOL_ILLEGAL_VERSION(BusinessCode.TOOL, 50),
|
||||
TOOL_UNDER_REVIEW(BusinessCode.TOOL, 51),
|
||||
TOOL_NOT_UNDER_REVIEW(BusinessCode.TOOL, 52),
|
||||
TOOL_HAS_UNPUBLISHED_VERSION(BusinessCode.TOOL, 53),
|
||||
TOOL_HAS_NOT_BEEN_PUBLISHED(BusinessCode.TOOL, 54),
|
||||
TOOL_HAS_BEEN_PUBLISHED(BusinessCode.TOOL, 55),
|
||||
TOOL_SUBMIT_ERROR(BusinessCode.TOOL, 60),
|
||||
TOOL_CANCEL_ERROR(BusinessCode.TOOL, 61),
|
||||
|
||||
API_AVATAR_SUCCESS(BusinessCode.API_AVATAR, 0),
|
||||
API_AVATAR_ERROR(BusinessCode.API_AVATAR, 50);
|
||||
|
||||
constructor(businessCode: BusinessCode, code: Int) : this(businessCode.code * 100 + code)
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Response result entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class ResponseResult<T> private constructor(
|
||||
@Schema(description = "响应码", defaultValue = "200") val code: Int,
|
||||
|
||||
@Schema(description = "是否调用成功") val success: Boolean,
|
||||
|
||||
@Schema(description = "信息") val msg: String,
|
||||
|
||||
@Schema(description = "数据") val data: T?
|
||||
) : Serializable {
|
||||
companion object {
|
||||
/**
|
||||
* Build response result object
|
||||
*
|
||||
* @param code Response code
|
||||
* @param success Is successful
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun <T> build(code: Int, success: Boolean, msg: String, data: T?) =
|
||||
ResponseResult(code, success, msg, data)
|
||||
|
||||
/**
|
||||
* Build response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param success Is successful
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> build(code: ResponseCode, success: Boolean, msg: String, data: T?) =
|
||||
build(code.code, success, msg, data)
|
||||
|
||||
/**
|
||||
* Build successful response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> success(code: ResponseCode = ResponseCode.SYSTEM_OK, msg: String = "success", data: T? = null) =
|
||||
build(code, true, msg, data)
|
||||
|
||||
/**
|
||||
* Build failure response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> fail(code: ResponseCode = ResponseCode.SYSTEM_ERROR, msg: String = "fail", data: T? = null) =
|
||||
build(code, false, msg, data)
|
||||
|
||||
/**
|
||||
* Build database successful response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> databaseSuccess(
|
||||
code: ResponseCode = ResponseCode.DATABASE_SELECT_SUCCESS, msg: String = "success", data: T? = null
|
||||
) = build(code, true, msg, data)
|
||||
|
||||
/**
|
||||
* Build database failure response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> databaseFail(
|
||||
code: ResponseCode = ResponseCode.DATABASE_SELECT_FAILED, msg: String = "fail", data: T? = null
|
||||
) = build(code, false, msg, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Function entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_func")
|
||||
class Func : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Parent ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("parent_id")
|
||||
var parentId: Long? = null
|
||||
|
||||
/**
|
||||
* Menu ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("menu_id")
|
||||
var menuId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Func(id=$id, name=$name, parentId=$parentId, menuId=$menuId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Group entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_group")
|
||||
class Group : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Role list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var roles: List<Role>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Group(id=$id, name=$name, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, roles=$roles)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
|
||||
/**
|
||||
* Login user entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserDetails
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
||||
class LoginUser() : UserDetails {
|
||||
/**
|
||||
* User object
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
*/
|
||||
lateinit var user: User
|
||||
|
||||
@JsonIgnore
|
||||
private var authorities: List<GrantedAuthority>? = null
|
||||
|
||||
constructor(user: User) : this() {
|
||||
this.user = user
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getAuthorities(): List<GrantedAuthority> {
|
||||
authorities?.let { return it }
|
||||
authorities = user.operations?.map { SimpleGrantedAuthority(it.code) } ?: emptyList()
|
||||
|
||||
return authorities as List<GrantedAuthority>
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getPassword() = user.password
|
||||
|
||||
@JsonIgnore
|
||||
override fun getUsername() = user.username
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonExpired() =
|
||||
user.expiration == null || user.expiration!!.isAfter(LocalDateTime.now(ZoneOffset.UTC))
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonLocked() = user.locking == 0
|
||||
|
||||
@JsonIgnore
|
||||
override fun isCredentialsNonExpired() =
|
||||
user.credentialsExpiration == null || user.credentialsExpiration!!.isAfter(LocalDateTime.now(ZoneOffset.UTC))
|
||||
|
||||
@JsonIgnore
|
||||
override fun isEnabled() = user.enable == 1
|
||||
|
||||
override fun toString(): String {
|
||||
return "LoginUser(user=$user, authorities=$authorities)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Menu entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_menu")
|
||||
class Menu : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* URL
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("url")
|
||||
var url: String? = null
|
||||
|
||||
/**
|
||||
* Parent ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("parent_id")
|
||||
var parentId: Long? = null
|
||||
|
||||
/**
|
||||
* Module ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("module_id")
|
||||
var moduleId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Menu(id=$id, name=$name, url=$url, parentId=$parentId, moduleId=$moduleId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Module Entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_module")
|
||||
class Module : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Module(id=$id, name=$name)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Operation entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_operation")
|
||||
class Operation : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Code
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("code")
|
||||
var code: String? = null
|
||||
|
||||
/**
|
||||
* Function ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("func_id")
|
||||
var funcId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Operation(id=$id, name=$name, code=$code, funcId=$funcId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_power")
|
||||
class Power : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Type ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("type_id")
|
||||
var typeId: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Power(id=$id, typeId=$typeId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Set of power entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class PowerSet : Serializable {
|
||||
/**
|
||||
* Module list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
*/
|
||||
var moduleList: List<Module>? = null
|
||||
|
||||
/**
|
||||
* Menu list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
*/
|
||||
var menuList: List<Menu>? = null
|
||||
|
||||
/**
|
||||
* Function list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
*/
|
||||
var funcList: List<Func>? = null
|
||||
|
||||
/**
|
||||
* Operation list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
*/
|
||||
var operationList: List<Operation>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "PowerSet(moduleList=$moduleList, menuList=$menuList, funcList=$funcList, operationList=$operationList)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power type entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_power_type")
|
||||
class PowerType : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "PowerType(id=$id, name=$name)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power role intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_power_role")
|
||||
class RPowerRole : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Power ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("power_id")
|
||||
var powerId: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RPowerRole(id=$id, powerId=$powerId, roleId=$roleId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Role group intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_role_group")
|
||||
class RRoleGroup : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Group ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("group_id")
|
||||
var groupId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RRoleGroup(id=$id, roleId=$roleId, groupId=$groupId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* User group intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_user_group")
|
||||
class RUserGroup : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Group ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("group_id")
|
||||
var groupId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RUserGroup(id=$id, userId=$userId, groupId=$groupId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* User role intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_user_role")
|
||||
class RUserRole : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RUserRole(id=$id, userId=$userId, roleId=$roleId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
135
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/Role.kt
Normal file
135
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/Role.kt
Normal file
@@ -0,0 +1,135 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Role entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_role")
|
||||
class Role : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Module list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var modules: List<Module>? = null
|
||||
|
||||
/**
|
||||
* Menu list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var menus: List<Menu>? = null
|
||||
|
||||
/**
|
||||
* Function list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var funcs: List<Func>? = null
|
||||
|
||||
/**
|
||||
* Operation list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var operations: List<Operation>? = null
|
||||
|
||||
/**
|
||||
* Power list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Power
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var powers: List<Power>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Role(id=$id, name=$name, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, modules=$modules, menus=$menus, funcs=$funcs, operations=$operations, powers=$powers)"
|
||||
}
|
||||
}
|
||||
265
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/User.kt
Normal file
265
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/User.kt
Normal file
@@ -0,0 +1,265 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* User entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_user")
|
||||
class User() : Serializable {
|
||||
constructor(id: Long?, username: String, password: String, enable: Boolean = true) : this() {
|
||||
this.id = id
|
||||
this.username = username
|
||||
this.password = password
|
||||
this.enable = if (enable) 1 else 0
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("username")
|
||||
var username: String? = null
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("password")
|
||||
var password: String? = null
|
||||
|
||||
/**
|
||||
* Two-factor
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("two_factor")
|
||||
var twoFactor: String? = null
|
||||
|
||||
/**
|
||||
* Verify email
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("verify")
|
||||
var verify: String? = null
|
||||
|
||||
/**
|
||||
* Forget password
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("forget")
|
||||
var forget: String? = null
|
||||
|
||||
/**
|
||||
* Locking
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("locking")
|
||||
var locking: Int? = null
|
||||
|
||||
/**
|
||||
* Expiration time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("expiration")
|
||||
var expiration: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Credentials expiration time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("credentials_expiration")
|
||||
var credentialsExpiration: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Current login time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("current_login_time")
|
||||
var currentLoginTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Current login IP
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("current_login_ip")
|
||||
var currentLoginIp: String? = null
|
||||
|
||||
/**
|
||||
* Last login time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("last_login_time")
|
||||
var lastLoginTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Last login IP
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("last_login_ip")
|
||||
var lastLoginIp: String? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time")
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time")
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* User information
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserInfo
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var userInfo: UserInfo? = null
|
||||
|
||||
/**
|
||||
* Role list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var roles: List<Role>? = null
|
||||
|
||||
/**
|
||||
* Group list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Group
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var groups: List<Group>? = null
|
||||
|
||||
/**
|
||||
* Module list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var modules: List<Module>? = null
|
||||
|
||||
/**
|
||||
* Menu list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var menus: List<Menu>? = null
|
||||
|
||||
/**
|
||||
* Function list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var funcs: List<Func>? = null
|
||||
|
||||
/**
|
||||
* Operation list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var operations: List<Operation>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "User(id=$id, username=$username, password=$password, twoFactor=$twoFactor, verify=$verify, forget=$forget, locking=$locking, expiration=$expiration, credentialsExpiration=$credentialsExpiration, enable=$enable, currentLoginTime=$currentLoginTime, currentLoginIp=$currentLoginIp, lastLoginTime=$lastLoginTime, lastLoginIp=$lastLoginIp, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, userInfo=$userInfo, roles=$roles, groups=$groups, modules=$modules, menus=$menus, funcs=$funcs, operations=$operations)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* User information entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_user_info")
|
||||
class UserInfo : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Nickname
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("nickname")
|
||||
var nickname: String? = null
|
||||
|
||||
/**
|
||||
* Avatar in base64
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("avatar")
|
||||
var avatar: String? = null
|
||||
|
||||
/**
|
||||
* Email
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("email")
|
||||
var email: String? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "UserInfo(id=$id, userId=$userId, nickname=$nickname, avatar=$avatar, email=$email, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.system
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import com.fasterxml.jackson.annotation.JsonFormat
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Event log entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_l_event_log")
|
||||
class EventLog : Serializable {
|
||||
enum class Event(@field:EnumValue @field:JsonValue val code: String) {
|
||||
LOGIN("LOGIN"), LOGOUT("LOGOUT"), REGISTER("REGISTER"), VERIFY("VERIFY"), API("API")
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Event
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("event")
|
||||
var event: Event? = null
|
||||
|
||||
/**
|
||||
* Operate user ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("operate_user_id")
|
||||
var operateUserId: Long? = null
|
||||
|
||||
/**
|
||||
* Operate time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
|
||||
@TableField("operate_time")
|
||||
var operateTime: LocalDateTime? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "EventLog(id=$id, event=$event, operateUserId=$operateUserId, operateTime=$operateTime)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package top.fatweb.oxygen.api.entity.system
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Sensitive word entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_sensitive_word", autoResultMap = true)
|
||||
class SensitiveWord : Serializable {
|
||||
enum class Use(@field:EnumValue @field:JsonValue val code: String) {
|
||||
USERNAME("USERNAME"), TITLE("TITLE");
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Word
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("word")
|
||||
var word: String? = null
|
||||
|
||||
/**
|
||||
* Use for
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(value = "use_for", typeHandler = JacksonTypeHandler::class)
|
||||
@JvmField
|
||||
var useFor: Set<String>? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "SensitiveWord(id=$id, word=$word, useFor=$useFor, enable=$enable)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.system
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import com.fasterxml.jackson.annotation.JsonFormat
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Statistics log entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_l_statistics_log")
|
||||
class StatisticsLog : Serializable {
|
||||
enum class KeyItem(@field:EnumValue @field:JsonValue val code: String) {
|
||||
ONLINE_USERS_COUNT("ONLINE_USER_COUNT")
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("key")
|
||||
var key: KeyItem? = null
|
||||
|
||||
/**
|
||||
* Value
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("value")
|
||||
var value: String? = null
|
||||
|
||||
/**
|
||||
* Record time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
|
||||
@TableField("record_time")
|
||||
var recordTime: LocalDateTime? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "StatisticsLog(id=$id, key=$key, value=$value, recordTime=$recordTime)"
|
||||
}
|
||||
}
|
||||
186
src/main/kotlin/top/fatweb/oxygen/api/entity/system/SysLog.kt
Normal file
186
src/main/kotlin/top/fatweb/oxygen/api/entity/system/SysLog.kt
Normal file
@@ -0,0 +1,186 @@
|
||||
package top.fatweb.oxygen.api.entity.system
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import com.fasterxml.jackson.annotation.JsonFormat
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* System log entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_l_sys_log")
|
||||
class SysLog : Serializable {
|
||||
/**
|
||||
* Log type enum
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class LogType(@field:EnumValue @field:JsonValue val code: String) {
|
||||
INFO("INFO"), ERROR("ERROR"), LOGIN("LOGIN"), LOGOUT("LOGOUT"), REGISTER("REGISTER"), STATISTICS("STATISTICS"), API(
|
||||
"API"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Log type
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LogType
|
||||
*/
|
||||
@TableField("log_type")
|
||||
var logType: LogType? = null
|
||||
|
||||
/**
|
||||
* Operate user ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("operate_user_id")
|
||||
var operateUserId: Long? = null
|
||||
|
||||
/**
|
||||
* Operate time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
|
||||
@TableField("operate_time")
|
||||
var operateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Request URI
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("request_uri")
|
||||
var requestUri: String? = null
|
||||
|
||||
/**
|
||||
* Request method
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("request_method")
|
||||
var requestMethod: String? = null
|
||||
|
||||
/**
|
||||
* Request parameters
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("request_params")
|
||||
var requestParams: String? = null
|
||||
|
||||
/**
|
||||
* Request IP
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("request_ip")
|
||||
var requestIp: String? = null
|
||||
|
||||
/**
|
||||
* Request server address
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("request_server_address")
|
||||
var requestServerAddress: String? = null
|
||||
|
||||
/**
|
||||
* Is exception
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("exception")
|
||||
var exception: Int? = null
|
||||
|
||||
/**
|
||||
* Exception information
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("exception_info")
|
||||
var exceptionInfo: String? = null
|
||||
|
||||
/**
|
||||
* Start time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
|
||||
@TableField("start_time")
|
||||
var startTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* End time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
|
||||
@TableField("end_time")
|
||||
var endTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Execute time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("execute_time")
|
||||
var executeTime: Long? = null
|
||||
|
||||
/**
|
||||
* User agent
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_agent")
|
||||
var userAgent: String? = null
|
||||
|
||||
/**
|
||||
* Operate username
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var operateUsername: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "SysLog(id=$id, logType=$logType, operateUserId=$operateUserId, operateTime=$operateTime, requestUri=$requestUri, requestMethod=$requestMethod, requestParams=$requestParams, requestIp=$requestIp, requestServerAddress=$requestServerAddress, exception=$exception, exceptionInfo=$exceptionInfo, startTime=$startTime, endTime=$endTime, executeTime=$executeTime, userAgent=$userAgent, operateUsername=$operateUsername)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
|
||||
/**
|
||||
* Platform enum
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class Platform(@field:EnumValue @field:JsonValue val code: String) {
|
||||
WEB("WEB"), DESKTOP("DESKTOP"), ANDROID("ANDROID")
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Tool category intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_tool_main_category")
|
||||
class RToolCategory : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Tool ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("tool_id")
|
||||
var toolId: Long? = null
|
||||
|
||||
/**
|
||||
* Category ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("category_id")
|
||||
var categoryId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RToolCategory(id=$id, toolId=$toolId, categoryId=$categoryId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
262
src/main/kotlin/top/fatweb/oxygen/api/entity/tool/Tool.kt
Normal file
262
src/main/kotlin/top/fatweb/oxygen/api/entity/tool/Tool.kt
Normal file
@@ -0,0 +1,262 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler
|
||||
import com.fasterxml.jackson.annotation.JsonValue
|
||||
import top.fatweb.oxygen.api.entity.permission.User
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Tool entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_b_tool_main", autoResultMap = true)
|
||||
class Tool : Serializable {
|
||||
/**
|
||||
* Tool review type enum
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class ReviewType(@field:EnumValue @field:JsonValue val code: String) {
|
||||
NONE("NONE"), PROCESSING("PROCESSING"), PASS("PASS"), REJECT("REJECT")
|
||||
}
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Tool ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("tool_id")
|
||||
var toolId: String? = null
|
||||
|
||||
/**
|
||||
* Icon
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("icon")
|
||||
var icon: String? = null
|
||||
|
||||
/**
|
||||
* Platform
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Platform
|
||||
*/
|
||||
@TableField("platform")
|
||||
var platform: Platform? = null
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("description")
|
||||
var description: String? = null
|
||||
|
||||
/**
|
||||
* Base ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("base_id")
|
||||
var baseId: Long? = null
|
||||
|
||||
/**
|
||||
* Author ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("author_id")
|
||||
var authorId: Long? = null
|
||||
|
||||
/**
|
||||
* Version of tool
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("ver")
|
||||
var ver: String? = null
|
||||
|
||||
/**
|
||||
* Keywords
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("keywords", typeHandler = JacksonTypeHandler::class)
|
||||
var keywords: List<String>? = null
|
||||
|
||||
/**
|
||||
* Source code ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("source_id")
|
||||
var sourceId: Long? = null
|
||||
|
||||
/**
|
||||
* Compile product ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("dist_id")
|
||||
var distId: Long? = null
|
||||
|
||||
/**
|
||||
* Entry point
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("entry_point")
|
||||
var entryPoint: String? = null
|
||||
|
||||
/**
|
||||
* Publish
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("publish")
|
||||
var publish: Long? = null
|
||||
|
||||
/**
|
||||
* Review
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ReviewType
|
||||
*/
|
||||
@TableField("review")
|
||||
var review: ReviewType? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Author
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var author: User? = null
|
||||
|
||||
/**
|
||||
* Base
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var base: ToolBase? = null
|
||||
|
||||
/**
|
||||
* Categories
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var categories: List<ToolCategory>? = null
|
||||
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var source: ToolData? = null
|
||||
|
||||
/**
|
||||
* Dist
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var dist: ToolData? = null
|
||||
|
||||
/**
|
||||
* Favorite
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var favorite: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Tool(id=$id, name=$name, toolId=$toolId, icon=$icon, platform=$platform, description=$description, baseId=$baseId, authorId=$authorId, ver=$ver, keywords=$keywords, sourceId=$sourceId, distId=$distId, entryPoint=$entryPoint, publish=$publish, review=$review, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, author=$author, base=$base, categories=$categories, source=$source, dist=$dist, favorite=$favorite)"
|
||||
}
|
||||
}
|
||||
140
src/main/kotlin/top/fatweb/oxygen/api/entity/tool/ToolBase.kt
Normal file
140
src/main/kotlin/top/fatweb/oxygen/api/entity/tool/ToolBase.kt
Normal file
@@ -0,0 +1,140 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Tool base entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_b_tool_base")
|
||||
class ToolBase : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Source ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("source_id")
|
||||
var sourceId: Long? = null
|
||||
|
||||
/**
|
||||
* Dist ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("dist_id")
|
||||
var distId: Long? = null
|
||||
|
||||
/**
|
||||
* Platform
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Platform
|
||||
*/
|
||||
@TableField("platform")
|
||||
var platform: Platform? = null
|
||||
|
||||
/**
|
||||
* Has compiled
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("compiled")
|
||||
var compiled: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var source: ToolData? = null
|
||||
|
||||
/**
|
||||
* Dist
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var dist: ToolData? = null
|
||||
|
||||
/**
|
||||
* Dist data
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var distData: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "ToolBase(id=$id, name=$name, sourceId=$sourceId, distId=$distId, platform=$platform, compiled=$compiled, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, source=$source, dist=$dist, distData=$distData)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Tool category entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_b_tool_category")
|
||||
class ToolCategory : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Enabel
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "ToolCategory(id=$id, name=$name, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Tool data entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_b_tool_data")
|
||||
class ToolData : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("data")
|
||||
var data: String? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "ToolData(id=$id, data=$data, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
@TableName("t_b_tool_favorite")
|
||||
class ToolFavorite : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Author ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("author_id")
|
||||
var authorId: Long? = null
|
||||
|
||||
/**
|
||||
* Tool ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("tool_id")
|
||||
var toolId: String? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "ToolFavorite(id=$id, userId=$userId, authorId=$authorId, toolId=$toolId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package top.fatweb.oxygen.api.entity.tool
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Tool template entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_b_tool_template")
|
||||
class ToolTemplate : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Base ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("base_id")
|
||||
var baseId: Long? = null
|
||||
|
||||
/**
|
||||
* Source ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("source_id")
|
||||
var sourceId: Long? = null
|
||||
|
||||
/**
|
||||
* Platform
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Platform
|
||||
*/
|
||||
@TableField("platform")
|
||||
var platform: Platform? = null
|
||||
|
||||
/**
|
||||
* Entry point
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("entry_point")
|
||||
var entryPoint: String? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var source: ToolData? = null
|
||||
|
||||
/**
|
||||
* Base
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var base: ToolBase? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "ToolTemplate(id=$id, name=$name, baseId=$baseId, sourceId=$sourceId, platform=$platform, entryPoint=$entryPoint, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, source=$source, base=$base)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package top.fatweb.oxygen.api.exception
|
||||
|
||||
/**
|
||||
* Account need initialize exception
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RuntimeException
|
||||
*/
|
||||
class AccountNeedInitException : RuntimeException("Account need initialize")
|
||||
@@ -0,0 +1,10 @@
|
||||
package top.fatweb.oxygen.api.exception
|
||||
|
||||
/**
|
||||
* Account need reset password exception
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RuntimeException
|
||||
*/
|
||||
class AccountNeedResetPasswordException : RuntimeException("Account need reset password")
|
||||
@@ -0,0 +1,10 @@
|
||||
package top.fatweb.oxygen.api.exception
|
||||
|
||||
/**
|
||||
* Already has two-factor exception
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RuntimeException
|
||||
*/
|
||||
class AlreadyHasTwoFactorException : RuntimeException("Already has two-factor")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user