2026-4-30:

1.后端代码初始化
This commit is contained in:
朱春声99
2026-04-30 15:10:28 +08:00
parent 8bb8f4e30b
commit 0bc6dd7761
242 changed files with 27196 additions and 0 deletions

2
rc_autoplc_backend/.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

26
rc_autoplc_backend/.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
# Compiled class file
*.class
*.bak
*.swp
target/
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

8
rc_autoplc_backend/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

26
rc_autoplc_backend/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Annotation profile for Rc-autoplc-backend" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$PROJECT_DIR$/../../../../maven/maven-respository/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" />
</processorPath>
<module name="rczn-common" />
<module name="rczn-admin" />
<module name="rczn-autoplc" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="rczn-admin" options="-parameters" />
<module name="rczn-autoplc" options="-parameters" />
<module name="rczn-common" options="-parameters" />
</option>
</component>
</project>

10
rc_autoplc_backend/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/rczn-admin/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/rczn-autoplc/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/rczn-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="ias-snapshots" />
<option name="name" value="Infinite Automation Snapshot Repository" />
<option name="url" value="https://maven.mangoautomation.net/repository/ias-snapshot/" />
</remote-repository>
<remote-repository>
<option name="id" value="spring-milestones" />
<option name="name" value="Spring Milestones" />
<option name="url" value="https://repo.spring.io/milestone" />
</remote-repository>
<remote-repository>
<option name="id" value="spring-releases" />
<option name="name" value="Spring Releases" />
<option name="url" value="https://repo.spring.io/release" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="ias-releases" />
<option name="name" value="Infinite Automation Release Repository" />
<option name="url" value="https://maven.mangoautomation.net/repository/ias-release/" />
</remote-repository>
</component>
</project>

12
rc_autoplc_backend/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

124
rc_autoplc_backend/.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
rc_autoplc_backend/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,28 @@
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/3.4.12/maven-plugin)
* [Create an OCI image](https://docs.spring.io/spring-boot/3.4.12/maven-plugin/build-image.html)
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/3.4.12/reference/using/devtools.html)
* [Spring Web](https://docs.spring.io/spring-boot/3.4.12/reference/web/servlet.html)
### Guides
The following guides illustrate how to use some features concretely:
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
### Maven Parent overrides
Due to Maven's design, elements are inherited from the parent POM to the project POM.
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the
parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

661
rc_autoplc_backend/LICENSE Normal file
View File

@@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are 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.
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.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
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 Affero 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 userBusy through
a computer network, with no transfer of a copy, is not conveying.
An interactive userBusy 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 userBusy 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 userBusy 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 userBusy 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 userBusy, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular userBusy or of the way in which the particular userBusy
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. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
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 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 work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero 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 your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
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 AGPL, see
<https://www.gnu.org/licenses/>.

View File

@@ -0,0 +1,36 @@
# 融创智能PLC后台系统
#### Description
智能plc管理后台系统
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@@ -0,0 +1,42 @@
# 融创智能PLC后台系统
#### 介绍
智能plc管理后台系统
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
#### 增加日志生成:
1. 2026-4-3用户登录日志信息
2. 2026-4-3SOP用户操作日志信息
3. 2026-4-3基础数据功能岛、SOP序列用户操作增-删-改)日志

295
rc_autoplc_backend/mvnw vendored Normal file
View File

@@ -0,0 +1,295 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.4
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
scriptDir="$(dirname "$0")"
scriptName="$(basename "$0")"
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
# Find the actual extracted directory name (handles snapshots where filename != directory name)
actualDistributionDir=""
# First try the expected directory name (for regular distributions)
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
actualDistributionDir="$distributionUrlNameMain"
fi
fi
# If not found, search for any directory with the Maven executable (for snapshots)
if [ -z "$actualDistributionDir" ]; then
# enable globbing to iterate over items
set +f
for dir in "$TMP_DOWNLOAD_DIR"/*; do
if [ -d "$dir" ]; then
if [ -f "$dir/bin/$MVN_CMD" ]; then
actualDistributionDir="$(basename "$dir")"
break
fi
fi
done
set -f
fi
if [ -z "$actualDistributionDir" ]; then
verbose "Contents of $TMP_DOWNLOAD_DIR:"
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
die "Could not find Maven distribution directory in extracted archive"
fi
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

189
rc_autoplc_backend/mvnw.cmd vendored Normal file
View File

@@ -0,0 +1,189 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.4
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - userBusy and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_M2_PATH = "$HOME/.m2"
if ($env:MAVEN_USER_HOME) {
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
}
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
}
$MAVEN_WRAPPER_DISTS = $null
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
} else {
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
}
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
# Find the actual extracted directory name (handles snapshots where filename != directory name)
$actualDistributionDir = ""
# First try the expected directory name (for regular distributions)
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
$actualDistributionDir = $distributionUrlNameMain
}
# If not found, search for any directory with the Maven executable (for snapshots)
if (!$actualDistributionDir) {
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
if (Test-Path -Path $testPath -PathType Leaf) {
$actualDistributionDir = $_.Name
}
}
}
if (!$actualDistributionDir) {
Write-Error "Could not find Maven distribution directory in extracted archive"
}
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

133
rc_autoplc_backend/pom.xml Normal file
View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.12</version>
<relativePath/>
</parent>
<groupId>com.rczn</groupId>
<artifactId>Rc-autoplc-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Rc-autoplc-backend</name>
<description>Rc-autoplc-backend 聚合父模块</description>
<packaging>pom</packaging>
<modules>
<module>rczn-common</module>
<module>rczn-autoplc</module>
<module>rczn-admin</module>
</modules>
<properties>
<java.version>17</java.version>
<!-- 项目特定依赖版本 -->
<mybatis.version>3.0.3</mybatis.version>
<pagehelper.version>2.1.0</pagehelper.version>
<jwt.version>4.4.0</jwt.version>
<knife4j.version>4.5.0</knife4j.version>
<jakarta.servlet-api.version>6.0.0</jakarta.servlet-api.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<!-- 使用 dependencyManagement 管理项目特定版本 -->
<dependencyManagement>
<dependencies>
<!-- 项目内部模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-autoplc</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 项目特定的外部依赖版本管理 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- Jakarta Servlet API -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${jakarta.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- 在父模块的 dependencyManagement 中添加 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.15.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.github.s7connector</groupId>
<artifactId>s7connector</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rczn</groupId>
<artifactId>Rc-autoplc-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>rczn-admin</artifactId>
<name>rczn-admin</name>
<description>rczn-admin后台管理模块</description>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖公共模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-common</artifactId>
</dependency>
<!-- 依赖PLC模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-autoplc</artifactId>
</dependency>
<!-- Spring Boot Web 依赖包含Servlet API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 如果 spring-boot-starter-web 仍然找不到,显式添加 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring Boot 其他依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springdoc</groupId>-->
<!-- <artifactId>springdoc-openapi-starter-common</artifactId>-->
<!-- <version>2.3.0</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 其他依赖 -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- modbus4j 核心依赖Java8+Spring Boot2/3均兼容 -->
<!-- <dependency>-->
<!-- <groupId>com.infiniteautomation</groupId>-->
<!-- <artifactId>modbus4j</artifactId>-->
<!-- <version>3.0.3</version>-->
<!-- </dependency>-->
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.rczn.RcznAdminApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,17 @@
package com.rczn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@ComponentScan(value = "com.rczn.*")
@EnableScheduling
public class RcznAdminApplication {
public static void main(String[] args) {
SpringApplication.run(RcznAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,45 @@
package com.rczn.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口允许跨域
// 替换allowedOrigins为allowedOriginPatterns支持通配符*
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST","PATCH", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true) // 允许携带Cookie
.maxAge(3600); // 预检请求缓存1小时
}
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 1. 允许前端源(不要用*和withCredentials=true配合需指定具体源或用allowedOriginPatterns
config.addAllowedOriginPattern("*");
// 2. 允许携带凭证和前端withCredentials=true对应
config.setAllowCredentials(true);
// 3. 允许所有请求方法包含OPTIONS
config.addAllowedMethod("*");
// 4. 允许所有请求头包含Authorization
config.addAllowedHeader("*");
// 5. 预检请求缓存时间减少OPTIONS请求次数
config.setMaxAge(3600L);
// 配置生效路径
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}

View File

@@ -0,0 +1,38 @@
package com.rczn.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI customOpenAPI() {
// 1. 声明JWT认证规则
String securitySchemeName = "Authorization";
return new OpenAPI()
// 2. 文档基础信息(可选)
.info(new Info()
.title("XX自动化编程系统API")
.version("1.0.0")
.description("集成JWT认证的Knife4j接口文档"))
// 3. 配置全局认证规则所有接口默认需要Token
.addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
// 4. 定义Token的传递方式请求头+Bearer格式
.components(new Components()
.addSecuritySchemes(securitySchemeName,
new SecurityScheme()
.name(securitySchemeName)
.type(SecurityScheme.Type.HTTP) // HTTP认证
.scheme("bearer") // Bearer格式
.bearerFormat("JWT") // Token类型为JWT
.in(SecurityScheme.In.HEADER) // 放在请求头
)
);
}
}

View File

@@ -0,0 +1,55 @@
package com.rczn.config;
import com.rczn.interceptors.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 必须启用@Configuration让Spring扫描到
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 必须注入拦截器(取消注释)
@Autowired
LoginInterceptor loginInterceptor;
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
// 拦截所有请求
.addPathPatterns("/**")
// 放行Swagger/Knife4j所有相关路径关键补充/doc.html
.excludePathPatterns(
// Knife4j自定义UI路径核心
"/doc.html",
// Swagger UI页面相关
"/swagger-ui/**",
"/webjars/**",
// SpringDoc接口文档数据相关
"/v3/api-docs/**",
"/v3/api-docs.yaml",
// 旧版Swagger兼容
"/swagger-resources/**",
"/swagger-ui.html"
)
// 放行登录/注册接口
.excludePathPatterns("/user/login", "/user/register");
}
// 静态资源映射适配Knife4j+SpringDoc
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Knife4j静态资源核心补充
registry.addResourceHandler("/doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
// Swagger UI静态资源
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springdoc-openapi-ui/");
// Webjars通用资源
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@@ -0,0 +1,120 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Department;
import com.rczn.system.service.DepartmentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/depart")
@Tag(name = "部门管理", description = "部门增删改查+分页查询接口")
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
/**
* 分页查询部门
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询部门", description = "支持部门名称、编码、父ID模糊/精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "deptName", description = "部门名称(可选,模糊查询)", required = false, example = "技术部", in = ParameterIn.QUERY),
@Parameter(name = "deptCode", description = "部门编码(可选,模糊查询)", required = false, example = "TECH", in = ParameterIn.QUERY),
@Parameter(name = "parentId", description = "父部门ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY)
})
public Result<PageBean<Department>> getDeptPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String deptName,
@RequestParam(required = false) String deptCode,
@RequestParam(required = false) Integer parentId) {
PageBean<Department> pageBean = departmentService.selectPage(pageNum, pageSize, deptName, deptCode, parentId);
return Result.success(pageBean);
}
/**
* 根据ID查询部门
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个部门", description = "根据部门ID查询详情")
public Result getDeptById(@PathVariable Long id) {
Department department = departmentService.selectById(id);
return department != null ? Result.success(department) : Result.error("部门不存在");
}
/**
* 新增部门
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增部门", description = "部门名称和编码为必填项")
public Result addDept(@RequestBody Department department) {
try {
Long deptId = departmentService.insert(department);
return Result.success(deptId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 修改部门
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改部门", description = "需传入部门ID其他字段可选非空则更新")
public Result updateDept(@RequestBody Department department) {
try {
Boolean success = departmentService.update(department);
return success ? Result.success(true) : Result.error("修改失败(部门不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 删除部门(逻辑删除)
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除部门", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteDept(@PathVariable Long id) {
try {
Boolean success = departmentService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(部门不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 新增接口:获取完整部门树(包含所有字段)
*/
@GetMapping(value = "/tree", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "获取完整部门树", description = "返回包含所有字段的部门层级结构")
public Result getDeptTree() {
List<Department> deptTree = departmentService.getDeptTree();
return Result.success(deptTree);
}
/**
* 新增接口获取简化部门树仅ID、名称、子部门用于下拉选择
*/
@GetMapping(value = "/simple-tree", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "获取简化部门树", description = "仅返回ID、名称、子部门适用于下拉选择框等场景")
public Result getSimpleDeptTree() {
List<Department> simpleDeptTree = departmentService.getSimpleDeptTree();
return Result.success(simpleDeptTree);
}
}

View File

@@ -0,0 +1,19 @@
package com.rczn.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin")
@Tag(name = "用户管理", description = "用户新增、查询、修改接口")
public class HellowAdminController {
@GetMapping("/hellow")
@Operation(summary = "查询用户", description = "根据ID查询用户详情") // 替代@ApiOperation
public String hellow(){
return "hellow admin!!!";
}
}

View File

@@ -0,0 +1,95 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Position;
import com.rczn.system.service.PositionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/position")
@Tag(name = "职位管理", description = "职位增删改查+分页查询接口")
public class PositionController {
@Autowired
private PositionService positionService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询职位", description = "支持职位名称、编码模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "posiName", description = "职位名称(可选,模糊查询)", required = false, example = "工程师", in = ParameterIn.QUERY),
@Parameter(name = "posiCode", description = "职位编码(可选,模糊查询)", required = false, example = "ENG", in = ParameterIn.QUERY)
})
public Result<PageBean<Position>> getPosiPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String posiName,
@RequestParam(required = false) String posiCode) {
PageBean<Position> pageBean = positionService.selectPage(pageNum, pageSize, posiName, posiCode);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "条件查询列表", description = "支持职位名称、编码模糊查询")
@Parameters({
@Parameter(name = "posiName", description = "职位名称(可选,模糊查询)", required = false, example = "工程师", in = ParameterIn.QUERY),
@Parameter(name = "posiCode", description = "职位编码(可选,模糊查询)", required = false, example = "ENG", in = ParameterIn.QUERY)
})
public Result getList(
@RequestParam(required = false) String posiName,
@RequestParam(required = false) String posiCode) {
List<Position> list = positionService.selectList( posiName, posiCode);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个职位", description = "根据职位ID查询详情")
public Result getPosiById(@PathVariable Long id) {
Position position = positionService.selectById(id);
return position != null ? Result.success(position) : Result.error("职位不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增职位", description = "职位名称和编码为必填项")
public Result addPosi(@RequestBody Position position) {
try {
Long posiId = positionService.insert(position);
return Result.success(posiId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改职位", description = "需传入职位ID其他字段可选非空则更新")
public Result updatePosi(@RequestBody Position position) {
try {
Boolean success = positionService.update(position);
return success ? Result.success(true) : Result.error("修改失败(职位不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除职位", description = "逻辑删除设置delSign=1")
public Result deletePosi(@PathVariable Long id) {
try {
Boolean success = positionService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(职位不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,145 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Role;
import com.rczn.system.service.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 角色管理 CRUD APIMyBatis+PageHelper 实现)
*/
@RestController
@RequestMapping("/role") // RESTful 规范:复数形式
@Tag(name = "角色管理", description = "角色增删改查接口(支持分页+多条件查询+编码唯一性校验)")
public class RoleController {
@Autowired
RoleService roleService;
/**
* 1. 分页查询角色(多条件模糊查询)
*/
@GetMapping("/listPage")
@Operation(summary = "分页查询角色", description = "支持角色名、角色编码模糊查询页码从1开始")
@Parameters({
@Parameter(name = "pageNum", description = "页码必填从1开始", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "roleName", description = "角色名(模糊查询,可选)", required = false, example = "管理员", in = ParameterIn.QUERY),
@Parameter(name = "roleCode", description = "角色编码(模糊查询,可选)", required = false, example = "ADMIN", in = ParameterIn.QUERY)
})
public Result<PageBean<Role>> getRolePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String roleName,
@RequestParam(required = false) String roleCode) {
PageBean<Role> pageBean = roleService.selectRolePage(pageNum, pageSize, roleName, roleCode);
return Result.success(pageBean);
}
/**
* 1. 分页查询角色(多条件模糊查询)
*/
@GetMapping("/list")
@Operation(summary = "查询角色列表", description = "支持角色名、角色编码模糊查询")
@Parameters({
@Parameter(name = "roleName", description = "角色名(模糊查询,可选)", required = false, example = "管理员", in = ParameterIn.QUERY),
@Parameter(name = "roleCode", description = "角色编码(模糊查询,可选)", required = false, example = "ADMIN", in = ParameterIn.QUERY)
})
public Result getRoleList(
@RequestParam(required = false) String roleName,
@RequestParam(required = false) String roleCode) {
List<Role> list = roleService.selectRoleList( roleName, roleCode);
return Result.success(list);
}
/**
* 2. 根据ID查询单个角色
*/
@GetMapping("/getById/{id}")
@Operation(summary = "查询单个角色", description = "根据角色ID查询详情")
public Result getRoleById(
@Parameter(name = "id", description = "角色ID必填", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Role role = roleService.selectById(id);
if (role == null) {
return Result.error("角色ID" + id + " 不存在");
}
return Result.success(role);
}
/**
* 3. 新增角色(校验编码唯一性)
*/
@PostMapping("/add")
@Operation(summary = "新增角色", description = "提交角色信息角色编码不可重复ID无需传入")
public Result addRole(
@Parameter(name = "role", description = "角色信息ID无需传入roleName和roleCode必填", required = true)
@RequestBody Role role) {
try {
// 校验必填字段也可通过JSR-380注解+@Valid实现
if (role.getRoleName() == null || role.getRoleName().trim().isEmpty()) {
return Result.error("角色名不能为空");
}
if (role.getRoleCode() == null || role.getRoleCode().trim().isEmpty()) {
return Result.error("角色编码不能为空");
}
Long roleId = roleService.insert(role);
return Result.success(roleId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 4. 修改角色(部分字段更新+编码唯一性校验)
*/
@PutMapping("/update")
@Operation(summary = "修改角色", description = "传入角色ID和需要修改的字段角色编码不可重复")
public Result updateRole(
@Parameter(name = "role", description = "角色信息ID必填roleName/roleCode可选但至少传一个", required = true)
@RequestBody Role role) {
try {
// 校验必填字段
if (role.getId() == null) {
return Result.error("角色ID不能为空");
}
if ((role.getRoleName() == null || role.getRoleName().trim().isEmpty())
&& (role.getRoleCode() == null || role.getRoleCode().trim().isEmpty())) {
return Result.error("至少需要修改角色名或角色编码");
}
Boolean success = roleService.update(role);
return success ? Result.success("修改角色成功") : Result.error("修改失败(角色不存在)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 5. 根据ID删除角色
*/
@DeleteMapping("/del/{id}")
@Operation(summary = "删除角色", description = "根据角色ID删除角色")
public Result deleteRole(
@Parameter(name = "id", description = "角色ID必填", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Boolean success = roleService.deleteById(id);
return success ? Result.success("删除角色成功") : Result.error("删除失败(角色不存在)");
}
}

View File

@@ -0,0 +1,65 @@
package com.rczn.controller;
import com.rczn.domain.Result;
import com.rczn.system.domain.RolePermission;
import com.rczn.system.domain.query.RolePermissionQuery;
import com.rczn.system.service.RolePermissionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/rolePermission")
@Tag(name = "角色权限管理", description = "角色权限关联接口")
public class RolePermissionController {
@Autowired
RolePermissionService rolePermissionService;
@GetMapping("/listByRoleId/{roleId}")
@Operation(summary = "根据角色ID查询权限ID列表")
public Result getListByRoleId(
@Parameter(name = "roleId", required = true) @PathVariable Integer roleId) {
List<RolePermission> list = rolePermissionService.selectListByRoleId(roleId);
return Result.success(list);
}
@PostMapping("/add")
@Operation(summary = "给角色添加权限")
public Result add(@RequestBody RolePermissionQuery rolePermission) {
if (rolePermission.getRoleId() == null || rolePermission.getPermissionId() == null) {
return Result.error("角色ID和权限ID不能为空");
}
try {
RolePermission rolePermissionEntity = new RolePermission();
rolePermissionEntity.setRoleId(rolePermission.getRoleId());
rolePermissionEntity.setPermissionId(rolePermission.getPermissionId());
rolePermissionService.insert(rolePermissionEntity);
return Result.success("添加成功");
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping("/del")
@Operation(summary = "删除角色权限关联")
public Result delete(
@RequestParam Integer roleId,
@RequestParam(required = false) Integer permissionId) {
boolean success = rolePermissionService.delete(roleId, permissionId);
return success ? Result.success("删除成功") : Result.error("删除失败");
}
@DeleteMapping("/clearByRoleId/{roleId}")
@Operation(summary = "清空某个角色的所有权限")
public Result clearByRoleId(
@Parameter(name = "roleId", required = true) @PathVariable Integer roleId) {
rolePermissionService.deleteByRoleId(roleId);
return Result.success("清空成功");
}
}

View File

@@ -0,0 +1,109 @@
package com.rczn.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.Result;
import com.rczn.system.domain.SysDicData;
import com.rczn.system.service.SysDicDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/sysDicData")
@Tag(name = "字典数据管理", description = "字典数据增删改查+分页查询+按类型查询接口")
public class SysDicDataController {
@Autowired
private SysDicDataService sysDicDataService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询字典数据", description = "支持字典类型ID、标签、值查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "dicId", description = "字典类型ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "dicLabel", description = "数据标签(可选,模糊查询)", required = false, example = "运行", in = ParameterIn.QUERY),
@Parameter(name = "dicValue", description = "数据值(可选,模糊查询)", required = false, example = "1", in = ParameterIn.QUERY)
})
public Result getDicDataPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer dicId,
@RequestParam(required = false) String dicLabel,
@RequestParam(required = false) String dicValue) {
PageInfo<SysDicData> pageBean = sysDicDataService.selectPage(pageNum, pageSize, dicId, dicLabel, dicValue);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询字典数据", description = "支持字典类型ID、标签、值查询")
@Parameters({
@Parameter(name = "dicId", description = "字典类型ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "dicLabel", description = "数据标签(可选,模糊查询)", required = false, example = "运行", in = ParameterIn.QUERY),
@Parameter(name = "dicValue", description = "数据值(可选,模糊查询)", required = false, example = "1", in = ParameterIn.QUERY)
})
public Result getList(
@RequestParam(required = false) Integer dicId,
@RequestParam(required = false) String dicLabel,
@RequestParam(required = false) String dicValue) {
List<SysDicData> list = sysDicDataService.selectList( dicId, dicLabel, dicValue);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个字典数据", description = "根据字典数据ID查询详情")
public Result getDicDataById(@PathVariable Long id) {
SysDicData sysDicData = sysDicDataService.selectById(id);
return sysDicData != null ? Result.success(sysDicData) : Result.error("字典数据不存在");
}
@GetMapping(value = "/listByDicId/{dicId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "按字典类型ID查询数据列表", description = "查询指定字典类型下的所有有效数据")
public Result getDicDataByDicId(@PathVariable Integer dicId) {
try {
List<SysDicData> list = sysDicDataService.selectByDicId(dicId);
return Result.success(list);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增字典数据", description = "字典类型ID、数据标签为必填项")
public Result addDicData(@RequestBody SysDicData sysDicData) {
try {
Long dicDataId = sysDicDataService.insert(sysDicData);
return Result.success(dicDataId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改字典数据", description = "需传入字典数据ID其他字段可选非空则更新")
public Result updateDicData(@RequestBody SysDicData sysDicData) {
try {
Boolean success = sysDicDataService.update(sysDicData);
return success ? Result.success(true) : Result.error("修改失败(字典数据不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除字典数据", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteDicData(@PathVariable Long id) {
try {
Boolean success = sysDicDataService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(字典数据不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,95 @@
package com.rczn.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.Result;
import com.rczn.system.domain.SysDicType;
import com.rczn.system.service.SysDicTypeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/sysDicType")
@Tag(name = "字典类型管理", description = "字典类型增删改查+分页查询接口")
public class SysDicTypeController {
@Autowired
private SysDicTypeService sysDicTypeService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询字典类型", description = "支持字典名称、编码模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "dicName", description = "字典名称(可选,模糊查询)", required = false, example = "设备状态", in = ParameterIn.QUERY),
@Parameter(name = "dicCode", description = "字典编码(可选,模糊查询)", required = false, example = "DEV_STATUS", in = ParameterIn.QUERY)
})
public Result getDicTypePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String dicName,
@RequestParam(required = false) String dicCode) {
PageInfo<SysDicType> pageBean = sysDicTypeService.selectPage(pageNum, pageSize, dicName, dicCode);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询字典类型列表", description = "支持字典名称、编码模糊查询")
@Parameters({
@Parameter(name = "dicName", description = "字典名称(可选,模糊查询)", required = false, example = "设备状态", in = ParameterIn.QUERY),
@Parameter(name = "dicCode", description = "字典编码(可选,模糊查询)", required = false, example = "DEV_STATUS", in = ParameterIn.QUERY)
})
public Result getList(
@RequestParam(required = false) String dicName,
@RequestParam(required = false) String dicCode) {
List<SysDicType> list = sysDicTypeService.selectList( dicName, dicCode);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个字典类型", description = "根据字典类型ID查询详情")
public Result getDicTypeById(@PathVariable Long id) {
SysDicType sysDicType = sysDicTypeService.selectById(id);
return sysDicType != null ? Result.success(sysDicType) : Result.error("字典类型不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增字典类型", description = "字典名称为必填项")
public Result addDicType(@RequestBody SysDicType sysDicType) {
try {
Long dicTypeId = sysDicTypeService.insert(sysDicType);
return Result.success(dicTypeId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改字典类型", description = "需传入字典类型ID其他字段可选非空则更新")
public Result updateDicType(@RequestBody SysDicType sysDicType) {
try {
Boolean success = sysDicTypeService.update(sysDicType);
return success ? Result.success(true) : Result.error("修改失败(字典类型不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除字典类型", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteDicType(@PathVariable Long id) {
try {
Boolean success = sysDicTypeService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(字典类型不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,128 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.Role;
import com.rczn.system.service.SysPermissionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 权限管理 APIMyBatis 树形结构实现)
*/
@RestController
@RequestMapping("/permission")
@Tag(name = "权限管理", description = "权限增删改查接口(树形结构)")
public class SysPermissionController {
@Autowired
private SysPermissionService sysPermissionService;
/**
* 1. 分页查询权限(多条件模糊查询)
*/
@GetMapping("/listPage")
@Operation(summary = "分页查询权限", description = "支持角色名、角色编码模糊查询页码从1开始")
@Parameters({
@Parameter(name = "pageNum", description = "页码必填从1开始", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "parentId", description = "父级ID可选", required = false, example = "0", in = ParameterIn.QUERY),
@Parameter(name = "permissionName", description = "权限名称(模糊查询,可选)", required = false, example = "用户添加", in = ParameterIn.QUERY)
})
public Result<PageBean<Permission>> getRolePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer parentId,
@RequestParam(required = false) String permissionName) {
PageBean<Permission> pageBean = sysPermissionService.selectRolePage(pageNum, pageSize, parentId,permissionName);
return Result.success(pageBean);
}
/**
* 1. 查询权限树形结构列表
*/
@GetMapping("/list")
@Operation(summary = "查询权限树形列表", description = "返回权限树形结构parentId为0或null为顶级")
public Result<List<Permission>> getPermissionList() {
List<Permission> treeList = sysPermissionService.getPermissionList();
return Result.success(treeList);
}
/**
* 1. 查询权限树形结构列表
*/
// @GetMapping("/listByParentId/{parentId}")
// @Operation(summary = "查询权限树形列表", description = "返回权限树形结构parentId为0或null为顶级")
// public Result<List<Permission>> getPermissionListByParentId(@PathVariable Integer parentId) {
// List<Permission> treeList = sysPermissionService.getPermissionListByParentId(parentId);
// return Result.success(treeList);
// }
/**
* 2. 根据ID查询单个权限
*/
@GetMapping("/getById/{id}")
@Operation(summary = "查询单个权限", description = "根据权限ID查询详情")
public Result getPermissionById(
@Parameter(name = "id", description = "权限ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Integer id) {
Permission permission = sysPermissionService.getPermissionById(id);
if (permission == null) {
return Result.error("权限ID" + id + " 不存在");
}
return Result.success(permission);
}
/**
* 3. 新增权限
*/
@PostMapping("/add")
@Operation(summary = "新增权限", description = "提交权限信息创建新权限")
public Result addPermission(
@Parameter(name = "permission", description = "权限信息", required = true)
@RequestBody Permission permission) {
boolean success = sysPermissionService.addPermission(permission);
return success ? Result.success("新增权限成功") : Result.error("新增失败");
}
/**
* 4. 修改权限
*/
@PutMapping("/update")
@Operation(summary = "修改权限", description = "传入权限ID和需要修改的字段")
public Result updatePermission(
@Parameter(name = "permission", description = "权限信息必须包含ID", required = true)
@RequestBody Permission permission) {
try {
boolean success = sysPermissionService.updatePermission(permission);
return success ? Result.success("修改权限成功") : Result.error("修改失败(权限不存在)");
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 5. 根据ID删除权限逻辑删除
*/
@DeleteMapping("/del/{id}")
@Operation(summary = "删除权限", description = "根据权限ID逻辑删除")
public Result deletePermission(
@Parameter(name = "id", description = "权限ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Integer id) {
boolean success = sysPermissionService.deletePermission(id);
return success ? Result.success("删除权限成功") : Result.error("删除失败(权限不存在)");
}
}

View File

@@ -0,0 +1,239 @@
package com.rczn.controller;
import com.fasterxml.jackson.databind.annotation.JsonAppend;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.ManageLog;
import com.rczn.rcznautoplc.domain.RecordInfo;
import com.rczn.rcznautoplc.service.ManageLogService;
import com.rczn.rcznautoplc.service.RecordInfoService;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.User;
import com.rczn.system.service.UserService;
import com.rczn.utils.JwtUtil;
import com.rczn.utils.Md5Util;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.Pattern;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 用户管理 CRUD APIMyBatis+PageHelper 实现)
*/
@RestController
@RequestMapping("/user") // RESTful 规范:复数形式+api前缀
@Tag(name = "用户管理", description = "用户增删改查接口(支持分页+模糊查询)")
public class UserController {
// 注入 Service 层(构造器注入,推荐)
@Autowired
UserService userService;
/**
* 1. 分页查询用户(支持用户名模糊查询)
*/
@GetMapping("/listPage")
@Operation(summary = "分页查询用户", description = "支持分页、用户名模糊查询页码从1开始")
@Parameters({
@Parameter(name = "pageNum", description = "页码从1开始", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "userName", description = "用户名(模糊查询,可选)", required = false, example = "张三", in = ParameterIn.QUERY)
})
public Result<PageBean<User>> getUserPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String userName) {
// 调用 Service 分页查询
PageBean<User> pageBean = userService.selectUserPage(pageNum, pageSize, userName);
return Result.success(pageBean);
}
@GetMapping("/list")
@Operation(summary = "查询用户列表", description = "用户名模糊查询,查询全部")
@Parameters({
@Parameter(name = "userName", description = "用户名(模糊查询,可选)", required = false, example = "张三", in = ParameterIn.QUERY)
})
public Result<List<User>> getUserList(
@RequestParam(required = false) String userName) {
// 调用 Service 查询列表
List<User> userList = userService.selectUserList(userName);
return Result.success(userList);
}
/**
* 2. 根据ID查询单个用户
*/
@GetMapping("/getById/{id}")
@Operation(summary = "查询单个用户", description = "根据用户ID查询详情")
public Result getUserById(
@Parameter(name = "id", description = "用户ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
User user = userService.selectById(id);
if (user == null) {
return Result.error("用户ID" + id + " 不存在");
}
return Result.success(user);
}
/**
* 3. 新增用户
*/
@PostMapping("/add")
@Operation(summary = "新增用户", description = "提交用户完整信息创建新用户ID无需传入")
public Result addUser(
@Parameter(name = "user", description = "用户信息ID无需传入", required = true)
@RequestBody User user) {
Long userId = userService.insert(user);
return Result.success("新增用户成功");
}
/**
* 4. 修改用户(支持部分字段更新)
*/
@PutMapping("/update")
@Operation(summary = "修改用户", description = "传入用户ID和需要修改的字段非空字段才会更新")
public Result updateUser(
@Parameter(name = "user", description = "用户信息必须包含ID", required = true)
@RequestBody User user) {
try {
Boolean success = userService.update(user);
return success ? Result.success("修改用户成功") : Result.error("修改失败(用户不存在或无字段更新)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 5. 根据ID删除用户
*/
@DeleteMapping("/del/{id}")
@Operation(summary = "删除用户", description = "根据用户ID删除用户")
public Result deleteUser(
@Parameter(name = "id", description = "用户ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Boolean success = userService.deleteById(id);
return success ? Result.success("删除用户成功") : Result.error("删除失败(用户不存在)");
}
@PostMapping("/register")
@Operation(summary = "注册", description = "用户名必须是2-16位的字母、数字、下划线或减号")
public Result register(@Pattern(regexp = "^[a-zA-Z0-9_-]{2,16}$", message = "用户名必须是2-16位的字母、数字、下划线或减号")
@Parameter(
name = "username",
description = "用户名"
)
@RequestParam
String username,
@Parameter(
name = "password",
description = "密码..."
)
@RequestParam
String password) {
//查询数据库是否有该用户
User user = userService.findeUserByUsername(username);
//注册
if (user == null) {
//如果用户不存在,则注册
int result = userService.register(username, password);
return Result.success("用户注册成功");
} else {
//用户存在,返回错误信息
return Result.error("该用户名已存在!");
}
}
@GetMapping("/getUserByUsername")
public Result getUserByUsername(String username) {
User user = userService.findeUserByUsername(username);
if (user == null) {
return Result.error("该用户不存在!");
} else {
return Result.success(user);
}
}
@Autowired
ManageLogService manageLogService;
@PostMapping("/login")
@Operation(summary = "用户登录接口",description = "根据用户名和密码登录返回JWT Token")
public Result login(
@Parameter(
name = "username",
description = "登录用户名2-16位的字母、数字、下划线或减号",
required = true, // 标记为必填参数
example = "string"
)
@RequestParam
String username,
@Parameter(
name = "password",
description = "登录密码",
required = true
)
@RequestParam
String password) {
//TODO 登录逻辑
//查询数据库是否有该用户
User user = userService.findeUserByUsername(username);
//登录
if (user == null) {
//如果用户不存在,返回错误信息
return Result.error("该用户不存在!");
} else {
//校验密码:
String encryptPassword = user.getPassword();
if (encryptPassword.equals(password)) {
//登录成功,增加登录日志:
LocalDateTime loginTime = LocalDateTime.now();
ManageLog info = new ManageLog();
info.setCreateId(user.getId());
info.setLogName("登录日志");
info.setLogType("登录日志");//1登录日志、2SOP操作日志、3基础数据操作日志
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("用户名:").append(user.getUserName()).append(",登录操作时间:").append(loginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
info.setLogContent(stringBuilder.toString());
info.setCreateTime(loginTime);
manageLogService.insert(info);
// if (Md5Util.checkPassword(password, encryptPassword)) {
//生产token
Map<String, Object> claims = new HashMap<>();
claims.put("id", user.getId());
claims.put("username", user.getUserName());
//获取权限列表:
List<Permission> permissions = userService.findUserPermissions(user.getId());
List<String> permissionList = permissions.stream().map(Permission::getPermissionCode).collect(Collectors.toList());
claims.put("permissions", permissionList);
String jwtToken = JwtUtil.genToken(claims);
//密码正确,返回成功信息
return Result.success(jwtToken);
} else {
//密码错误,返回错误信息
return Result.error("密码错误!");
}
}
}
}

View File

@@ -0,0 +1,100 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.UserRole;
import com.rczn.system.service.UserRoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user-role")
@Tag(name = "用户角色关联管理", description = "用户与角色的关联增删改查接口")
public class UserRoleController {
@Autowired
private UserRoleService userRoleService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询关联", description = "支持用户ID、角色ID精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "userId", description = "用户ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "roleId", description = "角色ID可选", required = false, example = "2", in = ParameterIn.QUERY)
})
public Result<PageBean<UserRole>> getUserRolePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer userId,
@RequestParam(required = false) Integer roleId) {
PageBean<UserRole> pageBean = userRoleService.selectPage(pageNum, pageSize, userId, roleId);
return Result.success(pageBean);
}
@GetMapping(value = "/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据用户ID查询关联角色", description = "查询指定用户的所有关联角色")
public Result<List<UserRole>> getByUserId(@PathVariable Integer userId) {
List<UserRole> userRoles = userRoleService.selectByUserId(userId);
return Result.success(userRoles);
}
@GetMapping(value = "/role/{roleId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据角色ID查询关联用户", description = "查询指定角色的所有关联用户")
public Result<List<UserRole>> getByRoleId(@PathVariable Integer roleId) {
List<UserRole> userRoles = userRoleService.selectByRoleId(roleId);
return Result.success(userRoles);
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增用户角色关联", description = "用户ID和角色ID为必填项")
public Result addUserRole(@RequestBody UserRole userRole) {
try {
Long id = userRoleService.insert(userRole);
return Result.success(id);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据关联ID删除", description = "删除单个用户-角色关联")
public Result deleteById(@PathVariable Long id) {
try {
Boolean success = userRoleService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(关联不存在)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据用户ID删除所有关联", description = "删除指定用户的所有角色关联")
public Result deleteByUserId(@PathVariable Integer userId) {
try {
Boolean success = userRoleService.deleteByUserId(userId);
return success ? Result.success(true) : Result.error("删除失败(无关联数据)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/role/{roleId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据角色ID删除所有关联", description = "删除指定角色的所有用户关联")
public Result deleteByRoleId(@PathVariable Integer roleId) {
try {
Boolean success = userRoleService.deleteByRoleId(roleId);
return success ? Result.success(true) : Result.error("删除失败(无关联数据)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,88 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
import java.util.List;
public class Department extends BaseBean {
private String deptName;
private String deptCode;
private Integer parentId;
private Integer leaderId;
private User leader;
// 新增:子部门列表(核心字段,用于存储树形结构)
private List<Department> children;
public Department() {
}
public Department(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptCode() {
return deptCode;
}
public void setDeptCode(String deptCode) {
this.deptCode = deptCode;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public Integer getLeaderId() {
return leaderId;
}
public void setLeaderId(Integer leaderId) {
this.leaderId = leaderId;
}
public User getLeader() {
return leader;
}
public void setLeader(User leader) {
this.leader = leader;
}
public List<Department> getChildren() {
return children;
}
public void setChildren(List<Department> children) {
this.children = children;
}
@Override
public String toString() {
return "Department{" +
"deptName='" + deptName + '\'' +
", deptCode='" + deptCode + '\'' +
", parentId=" + parentId +
", leaderId=" + leaderId +
", leader=" + leader +
", children=" + children +
'}';
}
}

View File

@@ -0,0 +1,31 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.util.List;
public class Permission extends BaseBean{
private Integer parentId;
private String permissionName;
private String permissionCode;
// 树形结构子节点 ✅
private List<Permission> children;
// getter & setter
public Integer getParentId() { return parentId; }
public void setParentId(Integer parentId) { this.parentId = parentId; }
public String getPermissionName() { return permissionName; }
public void setPermissionName(String permissionName) { this.permissionName = permissionName; }
public String getPermissionCode() { return permissionCode; }
public void setPermissionCode(String permissionCode) { this.permissionCode = permissionCode; }
// children
public List<Permission> getChildren() {
return children;
}
public void setChildren(List<Permission> children) {
this.children = children;
}
}

View File

@@ -0,0 +1,42 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class Position extends BaseBean {
private String posiName;
private String posiCode;
public Position() {
}
public Position(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
@Override
public String toString() {
return "Position{" +
"posiName='" + posiName + '\'' +
", posiCode='" + posiCode + '\'' +
'}';
}
public String getPosiName() {
return posiName;
}
public void setPosiName(String posiName) {
this.posiName = posiName;
}
public String getPosiCode() {
return posiCode;
}
public void setPosiCode(String posiCode) {
this.posiCode = posiCode;
}
}

View File

@@ -0,0 +1,27 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class Role extends BaseBean {
private String roleName;
private String roleCode;
// 全参构造器同步修改 delSign 类型Boolean → boolean
public Role(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark, String roleName, String roleCode) {
super(id, createId, createTime, updateId, updateTime, delSign, remark); // 父类参数类型同步
this.roleName = roleName;
this.roleCode = roleCode;
}
// 其他构造器、getter/setter 保持不变
public Role() { }
public Role(String roleName, String roleCode) {
this.roleName = roleName;
this.roleCode = roleCode;
}
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
public String getRoleCode() { return roleCode; }
public void setRoleCode(String roleCode) { this.roleCode = roleCode; }
}

View File

@@ -0,0 +1,56 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class RolePermission extends BaseBean {
private Integer roleId;
private Integer permissionId;
private Role role;
private Permission permission;
public RolePermission() {
}
public RolePermission(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public Integer getPermissionId() {
return permissionId;
}
public void setPermissionId(Integer permissionId) {
this.permissionId = permissionId;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
}

View File

@@ -0,0 +1,52 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
/**
* 字典数据实体类
* 对应表sys_dic_data
*/
public class SysDicData extends BaseBean {
// 字典类型id外键
private Integer dicId;
// 数据标签
private String dicLabel;
// 数据字典值
private String dicValue;
public SysDicData() {
}
public SysDicData(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
// getter/setter
public Integer getDicId() {
return dicId;
}
public void setDicId(Integer dicId) {
this.dicId = dicId;
}
public String getDicLabel() {
return dicLabel;
}
public void setDicLabel(String dicLabel) {
this.dicLabel = dicLabel;
}
public String getDicValue() {
return dicValue;
}
public void setDicValue(String dicValue) {
this.dicValue = dicValue;
}
}

View File

@@ -0,0 +1,41 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
/**
* 字典类型实体类
* 对应表sys_dic_type
*/
public class SysDicType extends BaseBean {
// 字典名称(必填)
private String dicName;
// 字典编码
private String dicCode;
public SysDicType() {
}
public SysDicType(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
// getter/setter
public String getDicName() {
return dicName;
}
public void setDicName(String dicName) {
this.dicName = dicName;
}
public String getDicCode() {
return dicCode;
}
public void setDicCode(String dicCode) {
this.dicCode = dicCode;
}
}

View File

@@ -0,0 +1,152 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class User extends BaseBean {
private String userName;
private String password;
private String salt;
private String nicke;
private Boolean sex; // 0-女, 1-男
private String emailAddr;
private String address;
private String telephone;
private Integer depId;
private Integer posId;
private Department department;
private Position position;
public User() {
}
public User(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
", salt='" + salt + '\'' +
", nicke='" + nicke + '\'' +
", sex=" + sex +
", emailAddr='" + emailAddr + '\'' +
", address='" + address + '\'' +
", telephone='" + telephone + '\'' +
", depId=" + depId +
", posId=" + posId +
", department=" + department +
", position=" + position +
'}';
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getNicke() {
return nicke;
}
public void setNicke(String nicke) {
this.nicke = nicke;
}
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public String getEmailAddr() {
return emailAddr;
}
public void setEmailAddr(String emailAddr) {
this.emailAddr = emailAddr;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public Integer getDepId() {
return depId;
}
public void setDepId(Integer depId) {
this.depId = depId;
}
public Integer getPosId() {
return posId;
}
public void setPosId(Integer posId) {
this.posId = posId;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
}

View File

@@ -0,0 +1,89 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class UserRole extends BaseBean {
private Long id;
private Integer userId;
private Integer roleId;
private User user;
private Role role;
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public UserRole() {
}
public UserRole(Long id, Integer userId, Integer roleId, User user, Role role) {
this.id = id;
this.userId = userId;
this.roleId = roleId;
this.user = user;
this.role = role;
}
public UserRole(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark, Long id1, Integer userId, Integer roleId, User user, Role role) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
this.id = id1;
this.userId = userId;
this.roleId = roleId;
this.user = user;
this.role = role;
}
@Override
public String toString() {
return "UserRole{" +
"id=" + id +
", userId=" + userId +
", roleId=" + roleId +
", user=" + user +
", role=" + role +
'}';
}
}

View File

@@ -0,0 +1,27 @@
package com.rczn.system.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 用户实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Schema(description = "用户实体类") // 替代@ApiModel
public class UserTest {
@Schema(description = "用户ID", example = "1001") // 替代@ApiModelProperty
private Long id;
@Schema(description = "用户名", required = true, example = "张三")
private String name;
@Schema(description = "年龄", example = "25")
private Integer age;
}

View File

@@ -0,0 +1,34 @@
package com.rczn.system.domain.query;
public class RolePermissionQuery {
//角色id
private Integer roleId;
//权限id
private Integer permissionId;
public RolePermissionQuery(Integer roleId, Integer permissionId) {
this.roleId = roleId;
this.permissionId = permissionId;
}
public RolePermissionQuery() {
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public Integer getPermissionId() {
return permissionId;
}
public void setPermissionId(Integer permissionId) {
this.permissionId = permissionId;
}
}

View File

@@ -0,0 +1,44 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface DepartmentMapper {
// 新增部门
int insert(Department department);
// 根据ID删除部门逻辑删除更新delSign=1
int deleteById(Long id);
// 根据ID更新部门
int updateById(Department department);
// 根据ID查询部门
Department selectById(Long id);
// 分页查询部门(支持模糊查询)
List<Department> selectPage(
@Param("deptName") String deptName,
@Param("deptCode") String deptCode,
@Param("parentId") Integer parentId
);
// 查询分页总数(配合分页查询)
int selectTotal(
@Param("deptName") String deptName,
@Param("deptCode") String deptCode,
@Param("parentId") Integer parentId
);
// 新增:查询所有未删除的部门(用于递归组装树)
List<Department> selectAllDept();
// 新增按父部门ID查询子部门用于递归查询
List<Department> selectChildrenByParentId(@Param("parentId") Integer parentId);
// 新增查询顶级部门parent_id IS NULL
List<Department> selectTopDept();
}

View File

@@ -0,0 +1,26 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Position;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface PositionMapper {
int insert(Position position);
int deleteById(Long id);
int updateById(Position position);
Position selectById(Long id);
List<Position> selectPage(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
int selectTotal(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
List<Position> selectList(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
}

View File

@@ -0,0 +1,55 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Role MyBatis Mapper 接口
*/
@Mapper
public interface RoleMapper {
/**
* 分页查询角色(支持角色名/角色编码模糊查询)
*/
List<Role> selectRolePage(
@Param("roleName") String roleName,
@Param("roleCode") String roleCode);
/**
* 根据ID查询单个角色
*/
Role selectById(@Param("id") Long id);
/**
* 新增角色
*/
int insert(Role role);
/**
* 修改角色(部分字段更新)
*/
int update(Role role);
/**
* 根据ID删除角色
*/
int deleteById(@Param("id") Long id);
/**
* 查询总条数(支持模糊查询条件)
*/
Long selectTotal(
@Param("roleName") String roleName,
@Param("roleCode") String roleCode);
/**
* 校验角色编码唯一性(新增/修改时使用)
*/
Integer checkRoleCodeUnique(
@Param("roleCode") String roleCode,
@Param("id") Long id);
}

View File

@@ -0,0 +1,18 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.RolePermission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface RolePermissionMapper {
List<RolePermission> selectListByRoleId(@Param("roleId") Integer roleId);
int insert(RolePermission rolePermission);
int delete(@Param("roleId") Integer roleId, @Param("permissionId") Integer permissionId);
int deleteByRoleId(@Param("roleId") Integer roleId);
}

View File

@@ -0,0 +1,39 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.SysDicData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SysDicDataMapper {
/**
* 新增字典数据
*/
int insert(SysDicData sysDicData);
/**
* 修改字典数据
*/
int update(SysDicData sysDicData);
/**
* 逻辑删除字典数据
*/
int deleteById(Long id);
/**
* 根据ID查询字典数据
*/
SysDicData selectById(Long id);
/**
* 分页查询字典数据(参数可选)
*/
List<SysDicData> selectPage(SysDicData sysDicData);
/**
* 根据字典类型ID查询字典数据列表
*/
List<SysDicData> selectByDicId(Integer dicId);
}

View File

@@ -0,0 +1,34 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.SysDicType;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SysDicTypeMapper {
/**
* 新增字典类型
*/
int insert(SysDicType sysDicType);
/**
* 修改字典类型
*/
int update(SysDicType sysDicType);
/**
* 逻辑删除字典类型
*/
int deleteById(Long id);
/**
* 根据ID查询字典类型
*/
SysDicType selectById(Long id);
/**
* 分页查询字典类型(参数可选)
*/
List<SysDicType> selectPage(SysDicType sysDicType);
}

View File

@@ -0,0 +1,52 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysPermissionMapper {
/**
* 分页查询角色(支持角色名/角色编码模糊查询)
*/
List<Permission> selectPermissionPage(
@Param("parentId") Integer parentId,
@Param("permissionName") String permissionName);
/**
* 查询总条数(支持模糊查询条件)
*/
Long selectTotal(
@Param("parentId") Integer parentId,
@Param("permissionName") String permissionName);
/**
* 查询所有权限(未删除)
*/
List<Permission> selectPermissionList();
/**
* 根据ID查询
*/
Permission selectPermissionById(Integer id);
/**
* 新增
*/
int insertPermission(Permission permission);
/**
* 修改
*/
int updatePermission(Permission permission);
/**
* 逻辑删除
*/
int deletePermissionById(Integer id);
}

View File

@@ -0,0 +1,43 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
// 分页查询(参数支持空值,为空时忽略该条件)
List<User> selectUserPage(User user);
// 根据ID查询支持传delSign筛选状态
User selectById(@Param("id") Long id, @Param("delSign") Boolean delSign);
// 新增用户空参数会插入默认值或null
int insert(User user);
// 修改用户(仅更新非空字段)
int update(User user);
// 逻辑删除用户
int deleteById(@Param("id") Long id, @Param("updateId") Long updateId);
// 查询总条数(与分页查询参数一致)
Long selectTotal(
@Param("userName") String userName,
@Param("depId") Integer depId,
@Param("posId") Integer posId,
@Param("createId") Long createId,
@Param("sex") Integer sex,
@Param("delSign") Boolean delSign
);
@Select("SELECT * FROM sys_user WHERE user_name = #{userName}")
User selectByUsername(String userName);
//根据用户id查询出对应的权限列表
List<Permission> findUserPermissions(Long userId);
}

View File

@@ -0,0 +1,42 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.UserRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserRoleMapper {
// 新增用户-角色关联
int insert(UserRole userRole);
// 根据ID删除关联
int deleteById(Long id);
// 根据用户ID删除所有关联
int deleteByUserId(Integer userId);
// 根据角色ID删除所有关联
int deleteByRoleId(Integer roleId);
// 根据ID查询关联
UserRole selectById(Long id);
// 根据用户ID查询关联的角色列表
List<UserRole> selectByUserId(Integer userId);
// 根据角色ID查询关联的用户列表
List<UserRole> selectByRoleId(Integer roleId);
// 分页查询所有关联
List<UserRole> selectPage(
@Param("userId") Integer userId,
@Param("roleId") Integer roleId
);
// 查询分页总数
int selectTotal(
@Param("userId") Integer userId,
@Param("roleId") Integer roleId
);
}

View File

@@ -0,0 +1,35 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import java.util.List;
public interface DepartmentService {
// 新增部门
Long insert(Department department);
// 根据ID删除部门
Boolean deleteById(Long id);
// 根据ID更新部门
Boolean update(Department department);
// 根据ID查询部门
Department selectById(Long id);
// 分页查询部门
PageBean<Department> selectPage(
Integer pageNum,
Integer pageSize,
String deptName,
String deptCode,
Integer parentId
);
// 新增:获取完整部门树(递归组装)
List<Department> getDeptTree();
// 新增获取简化版部门树仅包含ID、名称、子部门用于下拉选择
List<Department> getSimpleDeptTree();
}

View File

@@ -0,0 +1,15 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Position;
import java.util.List;
public interface PositionService {
Long insert(Position position);
Boolean deleteById(Long id);
Boolean update(Position position);
Position selectById(Long id);
PageBean<Position> selectPage(Integer pageNum, Integer pageSize, String posiName, String posiCode);
List<Position> selectList(String posiName, String posiCode);
}

View File

@@ -0,0 +1,15 @@
package com.rczn.system.service;
import com.rczn.system.domain.RolePermission;
import java.util.List;
public interface RolePermissionService {
List<RolePermission> selectListByRoleId(Integer roleId);
void insert(RolePermission rolePermission);
boolean delete(Integer roleId, Integer permissionId);
void deleteByRoleId(Integer roleId);
}

View File

@@ -0,0 +1,60 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Role;
import java.util.List;
/**
* Role 业务逻辑层接口
*/
public interface RoleService {
/**
* 分页查询角色(支持多条件模糊查询)
* @param pageNum 页码从1开始
* @param pageSize 每页条数
* @param roleName 角色名(可选)
* @param roleCode 角色编码(可选)
* @return 分页结果
*/
PageBean<Role> selectRolePage(Integer pageNum, Integer pageSize, String roleName, String roleCode);
/**
* 根据ID查询单个角色
* @param id 角色ID
* @return 角色实体
*/
Role selectById(Long id);
/**
* 新增角色(校验角色编码唯一性)
* @param role 角色实体
* @return 新增成功的角色ID
* @throws IllegalArgumentException 角色编码已存在时抛出
*/
Long insert(Role role);
/**
* 修改角色(校验角色编码唯一性+部分字段更新)
* @param role 角色实体需包含ID
* @return 是否修改成功
* @throws IllegalArgumentException 角色编码已存在或未传ID时抛出
*/
Boolean update(Role role);
/**
* 根据ID删除角色
* @param id 角色ID
* @return 是否删除成功
*/
Boolean deleteById(Long id);
/**
* 根据角色名或角色编码模糊查询角色列表
* @param roleName 角色名(可选)
* @param roleCode 角色编码(可选)
* @return 角色列表
*/
List<Role> selectRoleList(String roleName, String roleCode);
}

View File

@@ -0,0 +1,44 @@
package com.rczn.system.service;
import com.github.pagehelper.PageInfo;
import com.rczn.system.domain.SysDicData;
import java.util.List;
public interface SysDicDataService {
/**
* 分页查询字典数据
*/
PageInfo<SysDicData> selectPage(Integer pageNum, Integer pageSize, Integer dicId, String dicLabel, String dicValue);
/**
* 查询字典数据列表
*/
List<SysDicData> selectList(Integer dicId, String dicLabel, String dicValue);
/**
* 根据ID查询字典数据
*/
SysDicData selectById(Long id);
/**
* 根据字典类型ID查询字典数据列表
*/
List<SysDicData> selectByDicId(Integer dicId);
/**
* 新增字典数据
*/
Long insert(SysDicData sysDicData);
/**
* 修改字典数据
*/
Boolean update(SysDicData sysDicData);
/**
* 逻辑删除字典数据
*/
Boolean deleteById(Long id);
}

View File

@@ -0,0 +1,40 @@
package com.rczn.system.service;
import com.github.pagehelper.PageInfo;
import com.rczn.system.domain.SysDicType;
import java.util.List;
public interface SysDicTypeService {
/**
* 分页查询字典类型
*/
PageInfo<SysDicType> selectPage(Integer pageNum, Integer pageSize, String dicName, String dicCode);
/**
* 查询字典类型列表
*/
List<SysDicType> selectList( String dicName, String dicCode);
/**
* 根据ID查询字典类型
*/
SysDicType selectById(Long id);
/**
* 新增字典类型
*/
Long insert(SysDicType sysDicType);
/**
* 修改字典类型
*/
Boolean update(SysDicType sysDicType);
/**
* 逻辑删除字典类型
*/
Boolean deleteById(Long id);
}

View File

@@ -0,0 +1,26 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.Role;
import java.util.List;
public interface SysPermissionService {
List<Permission> getPermissionList();
//根据父ID查询权限列表
List<Permission> getPermissionListByParentId(Integer parentId);
Permission getPermissionById(Integer id);
boolean addPermission(Permission permission);
boolean updatePermission(Permission permission);
boolean deletePermission(Integer id);
/**
* 1. 分页查询角色(多条件模糊查询)
* @param pageNum
* @param pageSize
* @param permissionName
* @return
*/
PageBean<Permission> selectRolePage(Integer pageNum, Integer pageSize,Integer parentId, String permissionName);
}

View File

@@ -0,0 +1,23 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.UserRole;
import java.util.List;
public interface UserRoleService {
Long insert(UserRole userRole);
Boolean deleteById(Long id);
Boolean deleteByUserId(Integer userId);
Boolean deleteByRoleId(Integer roleId);
UserRole selectById(Long id);
List<UserRole> selectByUserId(Integer userId);
/**
* Selects user roles by the given role ID
*
* @param roleId The ID of the role to search for
* @return List of UserRole objects associated with the given role ID
*/
List<UserRole> selectByRoleId(Integer roleId);
PageBean<UserRole> selectPage(Integer pageNum, Integer pageSize, Integer userId, Integer roleId);
}

View File

@@ -0,0 +1,78 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.User;
import java.util.List;
/**
* User 业务逻辑层接口
*/
public interface UserService {
/**
* 1. 分页查询用户(支持用户名模糊查询)
* @param pageNum 页码从1开始
* @param pageSize 每页条数
* @param userName 用户名(模糊查询,可选)
* @return 分页结果PageBean
*/
PageBean<User> selectUserPage(Integer pageNum, Integer pageSize, String userName);
/**
* 1. 查询用户列表(支持用户名模糊查询)
* @param userName 用户名(模糊查询,可选)
* @return 结果listUser
*/
List<User> selectUserList(String userName);
/**
* 2. 根据ID查询单个用户
* @param id 用户ID
* @return 单个用户实体
*/
User selectById(Long id);
/**
* 3. 新增用户
* @param user 用户实体
* @return 新增成功的用户ID
*/
Long insert(User user);
/**
* 4. 修改用户(部分字段更新)
* @param user 用户实体需包含ID仅更新非空字段
* @return 是否修改成功true/false
*/
Boolean update(User user);
/**
* 5. 根据ID删除用户
* @param id 用户ID
* @return 是否删除成功true/false
*/
Boolean deleteById(Long id);
/**
* 6. 根据用户名查询用户
* @param username 用户名
* @return 用户实体
*/
User findeUserByUsername(String username);
/**
* 7. 注册用户
* @param username 用户名
* @param password 密码
*/
int register(String username, String password);
/**
* 根据用户id查询出关联的用户权限对象列表
* 表直接的关系是:
* 用户表user--用户权限表user_role--权限表role-- 权限资源表role_resource--资源表resource
*/
List<Permission> findUserPermissions(Long userId);
}

View File

@@ -0,0 +1,186 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import com.rczn.system.mapper.DepartmentMapper;
import com.rczn.system.service.DepartmentService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Override
public Long insert(Department department) {
// 校验必填字段
Assert.notNull(department.getDeptName(), "部门名称不能为空");
Assert.notNull(department.getDeptCode(), "部门编码不能为空");
// 补充创建时间字段
// department.setCreateId(getCurrentUserId());
if (department.getCreateTime() == null) {
department.setCreateTime(LocalDateTime.now());
}
int rows = departmentMapper.insert(department);
return rows > 0 ? department.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "部门ID不能为空");
int rows = departmentMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean update(Department department) {
Assert.notNull(department.getId(), "部门ID不能为空");
// department.setUpdateId(null);
if (department.getUpdateTime() == null) {
department.setUpdateTime(LocalDateTime.now());
}
int rows = departmentMapper.updateById(department);
return rows > 0;
}
@Override
public Department selectById(Long id) {
Assert.notNull(id, "部门ID不能为空");
return departmentMapper.selectById(id);
}
@Override
public PageBean<Department> selectPage(Integer pageNum, Integer pageSize, String deptName, String deptCode, Integer parentId) {
// 校验分页参数
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 查询分页数据和总数
List<Department> items = departmentMapper.selectPage(deptName, deptCode, parentId);
Page<Department> page = (Page<Department>) items;
PageBean<Department> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
/**
* 核心:获取完整部门树(包含所有字段和层级关系)
*/
@Override
public List<Department> getDeptTree() {
// 1. 查询所有未删除的部门(一次性查询,减少数据库交互)
List<Department> allDept = departmentMapper.selectAllDept();
// 2. 递归组装树形结构(从顶级部门开始)
return buildDeptTree(allDept, null);
}
/**
* 核心获取简化版部门树仅ID、名称、子部门用于下拉选择框等场景
*/
@Override
public List<Department> getSimpleDeptTree() {
List<Department> allDept = departmentMapper.selectAllDept();
List<Department> deptTree = buildDeptTree(allDept, null);
// 简化部门树字段(仅保留必要字段,减少返回数据量)
return simplifyDeptTree(deptTree);
}
/**
* 递归组装部门树
* @param allDept 所有部门列表
* @param parentId 父部门IDnull 表示查询顶级部门)
* @return 组装后的子部门列表
*/
private List<Department> buildDeptTree(List<Department> allDept, Integer parentId) {
// 筛选当前父部门的所有子部门
List<Department> childrenDept = allDept.stream()
.filter(dept -> {
// 父部门ID为null时筛选parent_id IS NULL的顶级部门否则筛选parent_id等于当前parentId的部门
if (parentId == null) {
return dept.getParentId() == null;
} else {
return parentId.equals(dept.getParentId());
}
})
.collect(Collectors.toList());
// 递归为每个子部门设置下属子部门
for (Department dept : childrenDept) {
List<Department> children = buildDeptTree(allDept, dept.getId().intValue()); // dept.id是Long转Integer匹配parentId类型
dept.setLeader(null); // 简化场景可清空负责人,如需保留可删除此句
dept.setChildren(children); // 给当前部门设置子部门
}
return childrenDept;
}
/**
* 简化部门树字段仅保留ID、名称、子部门
* @param deptTree 完整部门树
* @return 简化后的部门树
*/
private List<Department> simplifyDeptTree(List<Department> deptTree) {
List<Department> simpleTree = new ArrayList<>();
for (Department dept : deptTree) {
Department simpleDept = new Department();
simpleDept.setId(dept.getId());
simpleDept.setDeptName(dept.getDeptName());
simpleDept.setDeptCode(dept.getDeptCode());
// 递归简化子部门
if (dept.getChildren() != null && !dept.getChildren().isEmpty()) {
simpleDept.setChildren(simplifyDeptTree(dept.getChildren()));
}
simpleTree.add(simpleDept);
}
return simpleTree;
}
/**
* 辅助方法获取当前登录用户ID需替换为你的实际获取逻辑如从Token中解析
*/
private Long getCurrentUserId() {
// 示例临时返回1实际项目中需替换为真实的用户ID获取逻辑如SecurityContext、ThreadLocal等
return 1L;
}
// 为Department实体类添加children字段的setter因为原实体类没有需动态设置子部门
// 注意这里是通过反射或直接在实体类中添加children字段推荐在实体类中显式添加
// 下面是临时解决方案实际需修改Department实体类见步骤六
private void setChildren(Department dept, List<Department> children) {
try {
// 通过反射给Department设置children字段若实体类已添加可直接调用setChildren
java.lang.reflect.Field field = Department.class.getDeclaredField("children");
field.setAccessible(true);
field.set(dept, children);
} catch (Exception e) {
throw new RuntimeException("设置部门子节点失败", e);
}
}
}

View File

@@ -0,0 +1,83 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import com.rczn.system.domain.Position;
import com.rczn.system.mapper.PositionMapper;
import com.rczn.system.service.PositionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.List;
@Service
public class PositionServiceImpl implements PositionService {
@Autowired
private PositionMapper positionMapper;
@Override
public Long insert(Position position) {
Assert.notNull(position.getPosiName(), "职位名称不能为空");
Assert.notNull(position.getPosiCode(), "职位编码不能为空");
int rows = positionMapper.insert(position);
return rows > 0 ? position.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "职位ID不能为空");
int rows = positionMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean update(Position position) {
Assert.notNull(position.getId(), "职位ID不能为空");
int rows = positionMapper.updateById(position);
return rows > 0;
}
@Override
public Position selectById(Long id) {
Assert.notNull(id, "职位ID不能为空");
return positionMapper.selectById(id);
}
@Override
public PageBean<Position> selectPage(Integer pageNum, Integer pageSize, String posiName, String posiCode) {
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 查询分页数据和总数
List<Position> items = positionMapper.selectPage(posiName, posiCode);
Page<Position> page = (Page<Position>) items;
PageBean<Position> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
/**
* 条件查询职位列表
* @param posiName 职位名称
* @param posiCode 职位编码
* @return 职位列表
*/
@Override
public List<Position> selectList(String posiName, String posiCode) {
return positionMapper.selectList(posiName, posiCode);
}
}

View File

@@ -0,0 +1,42 @@
package com.rczn.system.service.impl;
import com.rczn.system.domain.RolePermission;
import com.rczn.system.mapper.RolePermissionMapper;
import com.rczn.system.service.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class RolePermissionServiceImpl implements RolePermissionService {
@Autowired
RolePermissionMapper rolePermissionMapper;
@Override
public List<RolePermission> selectListByRoleId(Integer roleId) {
return rolePermissionMapper.selectListByRoleId(roleId);
}
@Override
@Transactional
public void insert(RolePermission rolePermission) {
rolePermission.setCreateTime(LocalDateTime.now());
rolePermissionMapper.insert(rolePermission);
}
@Override
@Transactional
public boolean delete(Integer roleId, Integer permissionId) {
return rolePermissionMapper.delete(roleId, permissionId) > 0;
}
@Override
@Transactional
public void deleteByRoleId(Integer roleId) {
rolePermissionMapper.deleteByRoleId(roleId);
}
}

View File

@@ -0,0 +1,110 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Role;
import com.rczn.system.mapper.RoleMapper;
import com.rczn.system.service.RoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
/**
* Role 业务逻辑层实现
*/
@Service
@Transactional
public class RoleServiceImpl implements RoleService {
@Autowired
RoleMapper roleMapper;
@Override
public PageBean<Role> selectRolePage(Integer pageNum, Integer pageSize, String roleName, String roleCode) {
// 1. PageHelper 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询
List<Role> roleList = roleMapper.selectRolePage(roleName, roleCode);
// 3. 查询总条数
Long total = roleMapper.selectTotal(roleName, roleCode);
// 4. 封装分页结果
return new PageBean<Role>() {{
setTotal(total);
setItems(roleList);
}};
}
@Override
public Role selectById(Long id) {
return roleMapper.selectById(id);
}
@Override
public Long insert(Role role) {
// 校验角色编码唯一性
Integer count = roleMapper.checkRoleCodeUnique(role.getRoleCode(), null);
if (count != null && count > 0) {
throw new IllegalArgumentException("角色编码:" + role.getRoleCode() + " 已存在");
}
// 更新创建时间、创建者
// TODO 待实现
// role.setCreateId(1L);
if (role.getCreateTime() == null) {
role.setCreateTime(LocalDateTime.now());
}
// 执行新增自动回填ID
roleMapper.insert(role);
return role.getId();
}
@Override
public Boolean update(Role role) {
// 校验ID是否存在
if (role.getId() == null) {
throw new IllegalArgumentException("修改角色必须传入ID");
}
// 校验角色编码唯一性(排除自身)
Integer count = roleMapper.checkRoleCodeUnique(role.getRoleCode(), role.getId());
if (count != null && count > 0) {
throw new IllegalArgumentException("角色编码:" + role.getRoleCode() + " 已存在");
}
// 更新更新时间、更新者
// TODO 待实现
// role.setUpdateId(1L);
if (role.getUpdateTime() == null) {
role.setUpdateTime(LocalDateTime.now());
}
// 执行修改
int rows = roleMapper.update(role);
return rows > 0;
}
@Override
public Boolean deleteById(Long id) {
// 先校验角色是否存在
Role role = roleMapper.selectById(id);
if (role == null) {
return false;
}
// 执行删除
int rows = roleMapper.deleteById(id);
return rows > 0;
}
/**
* 根据角色名或角色编码模糊查询角色列表
*
* @param roleName 角色名(可选)
* @param roleCode 角色编码(可选)
* @return 角色列表
*/
@Override
public List<Role> selectRoleList(String roleName, String roleCode) {
return roleMapper.selectRolePage(roleName, roleCode);
}
}

View File

@@ -0,0 +1,97 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rczn.system.domain.SysDicData;
import com.rczn.system.mapper.SysDicDataMapper;
import com.rczn.system.service.SysDicDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysDicDataServiceImpl implements SysDicDataService {
@Autowired
private SysDicDataMapper sysDicDataMapper;
@Override
public PageInfo<SysDicData> selectPage(Integer pageNum, Integer pageSize, Integer dicId, String dicLabel, String dicValue) {
PageHelper.startPage(pageNum, pageSize);
SysDicData query = new SysDicData();
query.setDicId(dicId);
query.setDicLabel(dicLabel);
query.setDicValue(dicValue);
return new PageInfo<>(sysDicDataMapper.selectPage(query));
}
/**
* 查询字典数据列表
*
* @param dicId
* @param dicLabel
* @param dicValue
*/
@Override
public List<SysDicData> selectList(Integer dicId, String dicLabel, String dicValue) {
SysDicData query = new SysDicData();
query.setDicId(dicId);
query.setDicLabel(dicLabel);
query.setDicValue(dicValue);
return sysDicDataMapper.selectPage(query);
}
@Override
public SysDicData selectById(Long id) {
return sysDicDataMapper.selectById(id);
}
@Override
public List<SysDicData> selectByDicId(Integer dicId) {
if (dicId == null) {
throw new IllegalArgumentException("字典类型ID不能为空");
}
return sysDicDataMapper.selectByDicId(dicId);
}
@Override
public Long insert(SysDicData sysDicData) {
// 校验必填项
if (sysDicData.getDicId() == null) {
throw new IllegalArgumentException("字典类型ID不能为空");
}
if (sysDicData.getDicLabel() == null || sysDicData.getDicLabel().trim().isEmpty()) {
throw new IllegalArgumentException("数据标签不能为空");
}
int count = sysDicDataMapper.insert(sysDicData);
return count > 0 ? sysDicData.getId() : null;
}
@Override
public Boolean update(SysDicData sysDicData) {
if (sysDicData.getId() == null) {
throw new IllegalArgumentException("字典数据ID不能为空");
}
// 校验是否存在
SysDicData exist = sysDicDataMapper.selectById(sysDicData.getId());
if (exist == null) {
return false;
}
int count = sysDicDataMapper.update(sysDicData);
return count > 0;
}
@Override
public Boolean deleteById(Long id) {
if (id == null) {
throw new IllegalArgumentException("字典数据ID不能为空");
}
// 校验是否存在
SysDicData exist = sysDicDataMapper.selectById(id);
if (exist == null) {
return false;
}
int count = sysDicDataMapper.deleteById(id);
return count > 0;
}
}

View File

@@ -0,0 +1,84 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rczn.system.domain.SysDicType;
import com.rczn.system.mapper.SysDicTypeMapper;
import com.rczn.system.service.SysDicTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysDicTypeServiceImpl implements SysDicTypeService {
@Autowired
private SysDicTypeMapper sysDicTypeMapper;
@Override
public PageInfo<SysDicType> selectPage(Integer pageNum, Integer pageSize, String dicName, String dicCode) {
PageHelper.startPage(pageNum, pageSize);
SysDicType query = new SysDicType();
query.setDicName(dicName);
query.setDicCode(dicCode);
return new PageInfo<>(sysDicTypeMapper.selectPage(query));
}
/**
* 查询字典类型列表
*
* @param dicName
* @param dicCode
*/
@Override
public List<SysDicType> selectList(String dicName, String dicCode) {
SysDicType query = new SysDicType();
query.setDicName(dicName);
query.setDicCode(dicCode);
return sysDicTypeMapper.selectPage(query);
}
@Override
public SysDicType selectById(Long id) {
return sysDicTypeMapper.selectById(id);
}
@Override
public Long insert(SysDicType sysDicType) {
// 校验必填项
if (sysDicType.getDicName() == null || sysDicType.getDicName().trim().isEmpty()) {
throw new IllegalArgumentException("字典名称不能为空");
}
int count = sysDicTypeMapper.insert(sysDicType);
return count > 0 ? sysDicType.getId() : null;
}
@Override
public Boolean update(SysDicType sysDicType) {
if (sysDicType.getId() == null) {
throw new IllegalArgumentException("字典类型ID不能为空");
}
// 校验是否存在
SysDicType exist = sysDicTypeMapper.selectById(sysDicType.getId());
if (exist == null) {
return false;
}
int count = sysDicTypeMapper.update(sysDicType);
return count > 0;
}
@Override
public Boolean deleteById(Long id) {
if (id == null) {
throw new IllegalArgumentException("字典类型ID不能为空");
}
// 校验是否存在
SysDicType exist = sysDicTypeMapper.selectById(id);
if (exist == null) {
return false;
}
int count = sysDicTypeMapper.deleteById(id);
return count > 0;
}
}

View File

@@ -0,0 +1,140 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.Role;
import com.rczn.system.mapper.SysPermissionMapper;
import com.rczn.system.service.SysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class SysPermissionServiceImpl implements SysPermissionService {
@Autowired
private SysPermissionMapper sysPermissionMapper;
@Override
public Permission getPermissionById(Integer id) {
return sysPermissionMapper.selectPermissionById(id);
}
@Override
public boolean addPermission(Permission permission) {
return sysPermissionMapper.insertPermission(permission) > 0;
}
@Override
public boolean updatePermission(Permission permission) {
return sysPermissionMapper.updatePermission(permission) > 0;
}
@Override
public boolean deletePermission(Integer id) {
return sysPermissionMapper.deletePermissionById(id) > 0;
}
/**
* 1. 分页查询角色(多条件模糊查询)
*
* @param pageNum
* @param pageSize
* @param permissionName
* @return
*/
@Override
public PageBean<Permission> selectRolePage(Integer pageNum, Integer pageSize,Integer parentId, String permissionName) {
// 1. PageHelper 设置分页参数
PageHelper.startPage(pageNum, pageSize);
//加一层过滤:
if(parentId == 0){
parentId = null;
}
// 2. 执行查询
List<Permission> permissionList = sysPermissionMapper.selectPermissionPage(parentId,permissionName);
// 3. 查询总条数
Long total = sysPermissionMapper.selectTotal(parentId,permissionName);
// 4. 封装分页结果
return new PageBean<Permission>() {{
setTotal(total);
setItems(permissionList);
}};
}
@Override
public List<Permission> getPermissionList() {
// 1. 查询所有平级权限
List<Permission> allPermissions = sysPermissionMapper.selectPermissionList();
// 2. 找到顶层节点parentId = null 或 0
List<Permission> topNodes = new ArrayList<>();
for (Permission p : allPermissions) {
if (p.getParentId() == null || p.getParentId() == 0) {
topNodes.add(p);
}
}
// 3. 循环给每个顶层节点设置子节点(递归)
for (Permission node : topNodes) {
node.setChildren(findChildren(node, allPermissions));
}
return topNodes;
}
/***
* 根据父ID查询权限列表
* @param parentId
* @return
*/
@Override
public List<Permission> getPermissionListByParentId(Integer parentId) {
// 1. 查询所有平级权限
List<Permission> allPermissions = sysPermissionMapper.selectPermissionList();
// 2. 找到顶层节点parentId = null 或 0
List<Permission> topNodes = new ArrayList<>();
for (Permission p : allPermissions) {
if(parentId == null || parentId == 0){
if (p.getParentId() == null || p.getParentId() == 0) {
topNodes.add(p);
}
}else {
if (p.getParentId() == parentId) {
topNodes.add(p);
}
}
}
// 3. 循环给每个顶层节点设置子节点(递归)
for (Permission node : topNodes) {
node.setChildren(findChildren(node, allPermissions));
}
return topNodes;
}
/**
* 递归查找子节点(最稳妥、最清晰、不会漏)
*/
private List<Permission> findChildren(Permission parent, List<Permission> allList) {
List<Permission> children = new ArrayList<>();
for (Permission p : allList) {
// 子节点的 parentId == 父节点 id
if (parent.getId().equals(p.getParentId()==null?0:p.getParentId().longValue())) {
children.add(p);
// 递归给子节点设置孙子节点
p.setChildren(findChildren(p, allList));
}
}
return children;
}
}

View File

@@ -0,0 +1,88 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.Position;
import com.rczn.system.domain.UserRole;
import com.rczn.system.mapper.UserRoleMapper;
import com.rczn.system.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.List;
@Service
public class UserRoleServiceImpl implements UserRoleService {
@Autowired
private UserRoleMapper userRoleMapper;
@Override
public Long insert(UserRole userRole) {
Assert.notNull(userRole.getUserId(), "用户ID不能为空");
Assert.notNull(userRole.getRoleId(), "角色ID不能为空");
int rows = userRoleMapper.insert(userRole);
return rows > 0 ? userRole.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "关联ID不能为空");
int rows = userRoleMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean deleteByUserId(Integer userId) {
Assert.notNull(userId, "用户ID不能为空");
int rows = userRoleMapper.deleteByUserId(userId);
return rows > 0;
}
@Override
public Boolean deleteByRoleId(Integer roleId) {
Assert.notNull(roleId, "角色ID不能为空");
int rows = userRoleMapper.deleteByRoleId(roleId);
return rows > 0;
}
@Override
public UserRole selectById(Long id) {
Assert.notNull(id, "关联ID不能为空");
return userRoleMapper.selectById(id);
}
@Override
public List<UserRole> selectByUserId(Integer userId) {
Assert.notNull(userId, "用户ID不能为空");
return userRoleMapper.selectByUserId(userId);
}
@Override
public List<UserRole> selectByRoleId(Integer roleId) {
Assert.notNull(roleId, "角色ID不能为空");
return userRoleMapper.selectByRoleId(roleId);
}
@Override
public PageBean<UserRole> selectPage(Integer pageNum, Integer pageSize, Integer userId, Integer roleId) {
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
PageHelper.startPage(pageNum,pageSize);
List<UserRole> items = userRoleMapper.selectPage(userId, roleId);
Page<UserRole> page = (Page<UserRole>) items;
PageBean<UserRole> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
}

View File

@@ -0,0 +1,131 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Permission;
import com.rczn.system.domain.User;
import com.rczn.system.mapper.UserMapper;
import com.rczn.system.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* User 业务逻辑层实现
*/
@Service
@Transactional // 事务管理(增删改操作需事务)
public class UserServiceImpl implements UserService {
// 注入 MapperLombok @RequiredArgsConstructor 自动生成构造器)
@Autowired
UserMapper userMapper;
@Override
public PageBean<User> selectUserPage(Integer pageNum, Integer pageSize, String userName) {
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询MyBatis 会自动添加 LIMIT 分页)
User user = new User();
user.setUserName(userName);
List<User> userList = userMapper.selectUserPage(user);
Page<User> userPage = (Page<User>) userList;
// 3. 查询总条数(支持模糊查询条件)
PageBean<User> pageBean = new PageBean<>();
pageBean.setTotal(userPage.getTotal());
pageBean.setItems(userPage);
// 4. 封装分页结果(使用你的自定义 PageBean
return pageBean;
}
/**
* 1. 查询用户列表(支持用户名模糊查询)
*
* @param userName 用户名(模糊查询,可选)
* @return 结果listUser
*/
@Override
public List<User> selectUserList(String userName) {
// 2. 执行查询MyBatis 会自动添加 LIMIT 分页)
User user = new User();
user.setUserName(userName);
List<User> userList = userMapper.selectUserPage(user);
return userList;
}
@Override
public User selectById(Long id) {
// 查询不到返回 null后续 Controller 处理)
return userMapper.selectById(id, false);
}
@Override
public Long insert(User user) {
// 执行新增XML 中已配置 useGeneratedKeys会自动回填 ID 到 user 对象)
userMapper.insert(user);
return user.getId(); // 返回新增用户的 ID
}
@Override
public Boolean update(User user) {
if (user.getId() == null) {
throw new IllegalArgumentException("修改用户必须传入 ID");
}
// 执行修改(返回影响行数,>0 表示修改成功)
int rows = userMapper.update(user);
return rows > 0;
}
@Override
public Boolean deleteById(Long id) {
// 执行删除(返回影响行数,>0 表示删除成功)
int rows = userMapper.deleteById(id,null);
return rows > 0;
}
/**
* 6. 根据用户名查询用户
*
* @param username 用户名
* @return 用户实体
*/
@Override
public User findeUserByUsername(String username) {
return userMapper.selectByUsername(username);
}
/**
* 7. 注册用户
*
* @param username 用户名
* @param password 密码
*/
@Override
public int register(String username, String password) {
User user = new User();
user.setUserName(username);
user.setPassword(password);
return userMapper.insert(user);
}
/**
* 根据用户id查询出关联的用户权限对象列表
* 表直接的关系是:
* 用户表user--用户权限表user_role--权限表role-- 权限资源表role_resource--资源表resource
*
* @param userId
*/
@Override
public List<Permission> findUserPermissions(Long userId) {
return userMapper.findUserPermissions(userId);
}
}

View File

@@ -0,0 +1,163 @@
# 服务器配置
server:
port: 9090 # 项目端口
servlet:
encoding:
charset: UTF-8 # 解决中文乱码(含接口文档/响应)
enabled: true
force: true
# Spring核心配置
spring:
application:
name: rczn-admin # 应用名称
# 数据源配置MySQL 8.x
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://47.116.126.33:3306/rc_autoplc_program?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&allowMultiQueries=true
username: nianke
password: Jy@.niankeCrm2025
# 解决跨域可选配合之前的CorsConfig
web:
cors:
allowed-origins: false # 禁用默认CORS使用自定义CorsConfig
# 关键Jackson 序列化配置(替代 JacksonConfig
jackson:
# 允许空对象序列化(解决 HttpMediaTypeNotAcceptableException 核心)
serialization:
fail-on-empty-beans: false
# 格式化 JSON 输出(可选,便于调试)
indent-output: true
# 忽略未知字段(避免前端传多余字段报错)
deserialization:
fail-on-unknown-properties: false
# 支持 Java 8 日期类型LocalDateTime
modules:
- com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
# 日期格式化(可选,统一日期返回格式)
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# MyBatis配置
mybatis:
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 关键SQL 打印到控制台
log-prefix: "[MyBatis] " # 可选:日志前缀,便于区分 SQL 日志
default-statement-timeout: 30 # 可选SQL 执行超时时间(秒)
mapper-locations: classpath:mapper/**/*.xml # 补充指定Mapper.xml文件路径必加
type-aliases-package: com.rczn.**.domain # 补充:实体类别名包(可选)
# HikariCP 连接池配置(关键)
hikari:
max-lifetime: 1800000 # 连接最大生命周期30 分钟,必须小于 MySQL wait_timeout默认 8 小时)
idle-timeout: 600000 # 连接空闲超时时间10 分钟)
connection-timeout: 30000 # 连接超时时间30 秒)
minimum-idle: 5 # 最小空闲连接数
maximum-pool-size: 10 # 最大连接池大小
test-while-idle: true # 空闲时检测连接有效性
validation-timeout: 5000 # 连接校验超时时间5 秒)
connection-test-query: SELECT 1 # 连接校验 SQLMySQL 可用此简单查询)
# PageHelper 分页插件配置
pagehelper:
helper-dialect: mysql # 数据库方言(适配 MySQL
reasonable: true # 合理化分页页码≤0时查第1页页码超出总页数时查最后1页
support-methods-arguments: true # 支持通过 Mapper 接口参数传递分页参数
params: count=countSql # 分页参数名映射
#
## SpringDoc OpenAPI 3 核心配置适配Spring Boot 3.x
#springdoc:
# packages-to-scan: com.rczn # 扫描的基础包Controller所在包
# api-docs:
# enabled: true # 启用/v3/api-docs接口
# path: /v3/api-docs # OpenAPI JSON数据路径默认
# swagger-ui:
# path: /swagger-ui.html # 自定义Swagger UI访问路径兼容Spring Boot 2.x习惯
# tags-sorter: alpha # 标签字母排序
# operations-sorter: alpha # 接口字母排序
# disable-swagger-default-url: true # 禁用默认PetStore示例
# default-flat-param-object: false # 禁用扁平参数对象
# paths-to-exclude: /error, /actuator/** # 排除错误接口/监控接口(可选)
#
## OpenAPI文档基础信息中文正常显示
openapi:
info:
title: XX自动化编程系统API文档
description: SpringBoot 3.x + SpringDoc OpenAPI 3 接口文档
version: 1.0.0
contact:
name: 研发组
email: xxx@xxx.com
servers:
- url: http://localhost:9090 # 开发环境地址
description: 本地开发环境
- url: http://47.116.126.33:9090 # 测试环境地址
description: 测试环境
# SpringDoc + Knife4j 核心配置
springdoc:
packages-to-scan: com.rczn # 扫描Controller所在包
api-docs:
enabled: true
path: /v3/api-docs
swagger-ui:
tags-sorter: alpha
operations-sorter: alpha
paths-to-exclude: /error, /actuator/**
# Knife4j增强配置可选开启中文UI
knife4j:
enable: true
setting:
language: zh_cn # 中文界面
enable-swagger-models: true # 显示模型
enable-document-manage: false # 关闭文档管理(开发环境)
# OpenAPI文档信息
#openapi:
# info:
# title: XX自动化编程系统API文档
# description: SpringBoot 3.x + Knife4j + OpenAPI 3 接口文档
# version: 1.0.0
# contact:
# name: 研发组
# email: xxx@xxx.com
# servers:
# - url: http://localhost:9090
# description: 本地开发环境
# - url: http://47.116.126.33:9090
# description: 测试环境
# Spring Boot 日志核心配置
logging:
# 1. 全局日志级别(可细化到包/类)
level:
root: INFO # 根日志级别(默认)
com.rczn.rcznautoplc: DEBUG # 自定义包级别(调试业务代码)
org.springframework: INFO # Spring 框架日志级别(减少冗余)
com.zaxxer.hikari: ERROR # 数据库连接池日志级别(仅输出错误)
mybatis: DEBUG # MyBatis SQL 日志级别(输出执行的 SQL
# 2. 日志输出配置(控制台 + 文件)
pattern:
# console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" # 控制台格式
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" # 文件格式
# 3. 文件输出配置
file:
name: ./logs/rczn-autoplc.log # 日志文件路径(相对路径/绝对路径)
max-size: 10MB # 单个日志文件大小上限(超过则分割)
max-history: 30 # 日志文件保留天数
total-size-cap: 1GB # 日志文件总大小上限
clean-history-on-start: false # 启动时是否清理历史日志
# 4. 日志分割(按大小/时间Logback 原生支持)
logback:
rollingpolicy:
file-name-pattern: ./logs/rczn-autoplc-%d{yyyy-MM-dd}.%i.log # 分割后的文件名(%i 是序号,处理同天多文件)
max-file-size: 100MB # 单个文件大小(覆盖上面的 max-size
max-history: 30 # 保留天数
total-size-cap: 1GB # 总大小

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.DepartmentMapper">
<!-- 通用字段BaseBean继承的字段 -->
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- Department专属字段 -->
<sql id="deptColumn">
dept_name, dept_code, parent_id, leader_id
</sql>
<!-- 新增部门(修复多余逗号问题,支持空字段忽略) -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_department (
<!-- 用 trim 标签prefix="(" suffix=")" suffixOverrides="," 去除末尾多余逗号 -->
<trim prefix="" suffix="" suffixOverrides=",">
<!-- 通用字段:非空才添加字段 -->
<if test="createId != null">create_id,</if>
<if test="createTime != null">create_time,</if>
<if test="remark != null and remark != ''">remark,</if>
<!-- 部门专属字段:非空才添加字段 -->
<if test="deptName != null and deptName != ''">dept_name,</if>
<if test="deptCode != null and deptCode != ''">dept_code,</if>
<if test="parentId != null">parent_id,</if>
<if test="leaderId != null">leader_id,</if>
</trim>
) VALUES (
<!-- 用 trim 标签去除值列表末尾多余逗号 -->
<trim prefix="" suffix="" suffixOverrides=",">
<!-- 通用字段:非空才添加值 -->
<if test="createId != null">#{createId},</if>
<if test="createTime != null">#{createTime},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<!-- 部门专属字段:非空才添加值 -->
<if test="deptName != null and deptName != ''">#{deptName},</if>
<if test="deptCode != null and deptCode != ''">#{deptCode},</if>
<if test="parentId != null">#{parentId},</if>
<if test="leaderId != null">#{leaderId},</if>
</trim>
)
</insert>
<!-- 逻辑删除部门 -->
<update id="deleteById">
UPDATE sys_department
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 更新部门 -->
<update id="updateById">
UPDATE sys_department
<set>
<if test="deptName != null and deptName != ''">dept_name = #{deptName},</if>
<if test="deptCode != null and deptCode != ''">dept_code = #{deptCode},</if>
<if test="parentId != null">parent_id = #{parentId},</if>
<if test="leaderId != null">leader_id = #{leaderId},</if>
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 根据ID查询部门 -->
<select id="selectById" resultType="com.rczn.system.domain.Department">
SELECT
<include refid="baseColumn"/>, <include refid="deptColumn"/>
FROM sys_department
WHERE id = #{id} AND del_sign = 0
</select>
<!-- 分页查询部门 -->
<select id="selectPage" resultType="com.rczn.system.domain.Department">
SELECT
<include refid="baseColumn"/>, <include refid="deptColumn"/>
FROM sys_department
WHERE del_sign = 0
<if test="deptName != null and deptName != ''">
AND dept_name LIKE CONCAT('%', #{deptName}, '%')
</if>
<if test="deptCode != null and deptCode != ''">
AND dept_code LIKE CONCAT('%', #{deptCode}, '%')
</if>
<if test="parentId != null">
AND parent_id = #{parentId}
</if>
ORDER BY id DESC
</select>
<!-- 查询分页总数 -->
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_department
WHERE del_sign = 0
<if test="deptName != null and deptName != ''">
AND dept_name LIKE CONCAT('%', #{deptName}, '%')
</if>
<if test="deptCode != null and deptCode != ''">
AND dept_code LIKE CONCAT('%', #{deptCode}, '%')
</if>
<if test="parentId != null">
AND parent_id = #{parentId}
</if>
</select>
<!-- 公共字段映射复用原有resultMap新增parent/leader关联 -->
<resultMap id="DeptResultMap" type="com.rczn.system.domain.Department">
<!-- 基础字段继承BaseBean -->
<id column="id" property="id"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
<!-- 部门专属字段 -->
<result column="dept_name" property="deptName"/>
<result column="dept_code" property="deptCode"/>
<result column="parent_id" property="parentId"/>
<result column="leader_id" property="leaderId"/>
<!-- &lt;!&ndash; 关联父部门(可选,用于显示父部门名称) &ndash;&gt;-->
<!-- <association property="parent" javaType="com.rczn.system.domain.Department">-->
<!-- <id column="parent_id" property="id"/>-->
<!-- <result column="parent_dept_name" property="deptName"/>-->
<!-- </association>-->
<!-- &lt;!&ndash; 关联部门负责人(可选,用于显示负责人名称) &ndash;&gt;-->
<!-- <association property="leader" javaType="com.rczn.system.domain.User">-->
<!-- <id column="leader_id" property="id"/>-->
<!-- <result column="leader_name" property="userName"/>-->
<!-- </association>-->
</resultMap>
<!-- 1. 查询所有未删除的部门(用于递归组装树) -->
<select id="selectAllDept" resultMap="DeptResultMap">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name, -- 父部门名称(关联查询)
-- u.user_name AS leader_name -- 负责人名称(关联查询)
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0 -- 关联父部门(未删除)
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0 -- 关联负责人(未删除)
WHERE d.del_sign = 0 -- 仅查询未删除的部门
ORDER BY d.id ASC
</select>
<!-- 2. 按父部门ID查询子部门用于递归查询 -->
<select id="selectChildrenByParentId" resultMap="DeptResultMap" parameterType="java.lang.Integer">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name,
-- u.user_name AS leader_name
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0
WHERE d.del_sign = 0
AND d.parent_id = #{parentId} -- 按父部门ID筛选
ORDER BY d.id ASC
</select>
<!-- 3. 查询顶级部门parent_id IS NULL -->
<select id="selectTopDept" resultMap="DeptResultMap">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name,
-- u.user_name AS leader_name
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0
WHERE d.del_sign = 0
AND d.parent_id IS NULL -- 顶级部门(无父部门)
ORDER BY d.id ASC
</select>
</mapper>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.PositionMapper">
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<sql id="posiColumn">
posi_name, posi_code
</sql>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_position (
<include refid="posiColumn"/>, create_time, update_time, del_sign
) VALUES (
#{posiName}, #{posiCode}, NOW(), NOW(), 0
)
</insert>
<update id="deleteById">
UPDATE sys_position
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<update id="updateById">
UPDATE sys_position
<set>
<if test="posiName != null and posiName != ''">posi_name = #{posiName},</if>
<if test="posiCode != null and posiCode != ''">posi_code = #{posiCode},</if>
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<select id="selectById" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE id = #{id} AND del_sign = 0
</select>
<select id="selectPage" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
ORDER BY id DESC
</select>
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
</select>
<select id="selectList" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
ORDER BY id DESC
</select>
</mapper>

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.RoleMapper">
<!-- 通用结果集映射 -->
<resultMap id="RoleResultMap" type="com.rczn.system.domain.Role">
<id column="id" property="id"/>
<result column="role_name" property="roleName"/>
<result column="role_code" property="roleCode"/>
</resultMap>
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- 1. 分页查询角色(支持多条件模糊查询) -->
<select id="selectRolePage" resultMap="RoleResultMap">
SELECT id, role_name, role_code
FROM sys_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE CONCAT('%', #{roleName}, '%')
</if>
<if test="roleCode != null and roleCode != ''">
AND role_code LIKE CONCAT('%', #{roleCode}, '%')
</if>
</where>
ORDER BY id DESC
</select>
<!-- 2. 根据ID查询角色 -->
<select id="selectById" resultMap="RoleResultMap">
SELECT <include refid="baseColumn"></include>, role_name, role_code
FROM sys_role
WHERE id = #{id}
</select>
<!-- 3. 新增角色 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_role (
<trim suffixOverrides=",">
<if test="roleName != null ">role_name,</if>
<if test="roleCode != null ">role_code,</if>
<if test="createId != null ">create_id,</if>
<if test="createTime != null ">create_time,</if>
<if test="updateId != null ">update_id,</if>
<if test="updateTime != null ">update_time,</if>
<if test="delSign != null ">del_sign,</if>
<if test="remark != null ">remark,</if>
</trim>
)
VALUES (
<trim suffixOverrides=",">
<if test="roleName != null ">#{roleName},</if>
<if test="roleCode != null ">#{roleCode},</if>
<if test="createId != null ">#{createId},</if>
<if test="createTime != null ">#{createTime},</if>
<if test="updateId != null ">#{updateId},</if>
<if test="updateTime != null ">#{updateTime},</if>
<if test="delSign != null ">#{delSign},</if>
<if test="remark != null ">#{remark},</if>
</trim>
)
</insert>
<!-- 4. 修改角色(仅更新非空字段) -->
<update id="update">
UPDATE sys_role
<set>
<if test="roleName != null ">role_name = #{roleName},</if>
<if test="roleCode != null ">role_code = #{roleCode},</if>
<if test="updateId != null ">update_id = #{updateId},</if>
<if test="updateTime != null ">update_time = now(),</if>
<if test="remark != null ">remark = #{remark},</if>
</set>
WHERE id = #{id}
</update>
<!-- 5. 根据ID删除角色 -->
<delete id="deleteById">
DELETE FROM sys_role WHERE id = #{id}
</delete>
<!-- 6. 查询总条数(支持多条件模糊查询) -->
<select id="selectTotal" resultType="java.lang.Long">
SELECT COUNT(*) FROM sys_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE CONCAT('%', #{roleName}, '%')
</if>
<if test="roleCode != null and roleCode != ''">
AND role_code LIKE CONCAT('%', #{roleCode}, '%')
</if>
</where>
</select>
<!-- 7. 校验角色编码唯一性 -->
<select id="checkRoleCodeUnique" resultType="java.lang.Integer">
SELECT COUNT(*) FROM sys_role
WHERE role_code = #{roleCode}
<if test="id != null">
AND id != #{id} <!-- 修改时排除自身ID -->
</if>
</select>
</mapper>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.RolePermissionMapper">
<resultMap id="RolePermissionResultMap" type="com.rczn.system.domain.RolePermission">
<id column="id" property="id"/>
<result column="role_id" property="roleId"/>
<result column="permission_id" property="permissionId"/>
</resultMap>
<sql id="baseColumn">
id, role_id, permission_id
</sql>
<select id="selectListByRoleId" resultMap="RolePermissionResultMap">
SELECT <include refid="baseColumn"/>
FROM sys_role_permission
WHERE role_id = #{roleId}
</select>
<insert id="insert">
INSERT INTO sys_role_permission (role_id, permission_id)
VALUES (#{roleId}, #{permissionId})
</insert>
<delete id="delete">
DELETE FROM sys_role_permission
<where>
<if test="roleId != null">
role_id = #{roleId}
</if>
<if test="permissionId != null">
AND permission_id = #{permissionId}
</if>
</where>
</delete>
<delete id="deleteByRoleId">
DELETE FROM sys_role_permission
WHERE role_id = #{roleId}
</delete>
</mapper>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.SysDicDataMapper">
<sql id="baseColumn">
id, create_by, create_time, update_by, update_time, del_sign, remark
</sql>
<sql id="dicDataColumn">
dic_id, dic_label, dic_value
</sql>
<!-- 新增字典数据 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_dic_data (
<include refid="dicDataColumn"/>,
create_by, create_time, update_by, update_time, del_sign
) VALUES (
#{dicId}, #{dicLabel}, #{dicValue},
#{createId}, NOW(), #{updateId}, NOW(), 0
)
</insert>
<!-- 修改字典数据 -->
<update id="update">
UPDATE sys_dic_data
<set>
<if test="dicId != null">dic_id = #{dicId},</if>
<if test="dicLabel != null and dicLabel != ''">dic_label = #{dicLabel},</if>
<if test="dicValue != null and dicValue != ''">dic_value = #{dicValue},</if>
<if test="updateId != null">update_by = #{updateId},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 逻辑删除字典数据 -->
<update id="deleteById">
UPDATE sys_dic_data
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 根据ID查询字典数据 -->
<select id="selectById" resultType="com.rczn.system.domain.SysDicData">
SELECT
<include refid="baseColumn"/>,
<include refid="dicDataColumn"/>
FROM sys_dic_data
WHERE id = #{id} AND del_sign = 0
</select>
<!-- 分页查询字典数据支持按字典类型ID、标签、值查询 -->
<select id="selectPage" resultType="com.rczn.system.domain.SysDicData">
SELECT
<include refid="baseColumn"/>,
<include refid="dicDataColumn"/>
FROM sys_dic_data
WHERE del_sign = 0
<if test="dicId != null">AND dic_id = #{dicId}</if>
<if test="dicLabel != null and dicLabel != ''">AND dic_label LIKE CONCAT('%', #{dicLabel}, '%')</if>
<if test="dicValue != null and dicValue != ''">AND dic_value LIKE CONCAT('%', #{dicValue}, '%')</if>
ORDER BY create_time DESC
</select>
<!-- 根据字典类型ID查询字典数据列表 -->
<select id="selectByDicId" resultType="com.rczn.system.domain.SysDicData">
SELECT
<include refid="baseColumn"/>,
<include refid="dicDataColumn"/>
FROM sys_dic_data
WHERE dic_id = #{dicId} AND del_sign = 0
ORDER BY create_time DESC
</select>
</mapper>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.SysDicTypeMapper">
<sql id="baseColumn">
id, create_by, create_time, update_by, update_time, del_sign, remark
</sql>
<sql id="dicTypeColumn">
dic_name, dic_code
</sql>
<!-- 新增字典类型 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_dic_type (
<include refid="dicTypeColumn"/>,
create_by, create_time, update_by, update_time, del_sign
) VALUES (
#{dicName}, #{dicCode},
#{createId}, NOW(), #{updateId}, NOW(), 0
)
</insert>
<!-- 修改字典类型 -->
<update id="update">
UPDATE sys_dic_type
<set>
<if test="dicName != null and dicName != ''">dic_name = #{dicName},</if>
<if test="dicCode != null and dicCode != ''">dic_code = #{dicCode},</if>
<if test="updateId != null">update_by = #{updateId},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 逻辑删除字典类型 -->
<update id="deleteById">
UPDATE sys_dic_type
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 根据ID查询字典类型 -->
<select id="selectById" resultType="com.rczn.system.domain.SysDicType">
SELECT
<include refid="baseColumn"/>,
<include refid="dicTypeColumn"/>
FROM sys_dic_type
WHERE id = #{id} AND del_sign = 0
</select>
<!-- 分页查询字典类型 -->
<select id="selectPage" resultType="com.rczn.system.domain.SysDicType">
SELECT
<include refid="baseColumn"/>,
<include refid="dicTypeColumn"/>
FROM sys_dic_type
WHERE del_sign = 0
<if test="dicName != null and dicName != ''">AND dic_name LIKE CONCAT('%', #{dicName}, '%')</if>
<if test="dicCode != null and dicCode != ''">AND dic_code LIKE CONCAT('%', #{dicCode}, '%')</if>
ORDER BY create_time DESC
</select>
</mapper>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.SysPermissionMapper">
<resultMap id="PermissionResultMap" type="com.rczn.system.domain.Permission">
<id column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="permission_name" property="permissionName"/>
<result column="permission_code" property="permissionCode"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
</resultMap>
<!-- 查询所有 -->
<select id="selectPermissionList" resultMap="PermissionResultMap">
SELECT * FROM sys_permission
WHERE del_sign = 0
</select>
<!-- 根据ID查询 -->
<select id="selectPermissionById" resultMap="PermissionResultMap">
SELECT * FROM sys_permission
WHERE id = #{id} AND del_sign = 0
</select>
<!-- 查询总数量 -->
<select id="selectTotal" resultType="java.lang.Long">
SELECT COUNT(*) FROM sys_permission
WHERE del_sign = 0
<if test="parentId != null "> and parent_id = #{parentId}</if>
<if test="permissionName != null and permissionName != ''"> AND permission_name LIKE CONCAT('%', #{permissionName}, '%')</if>
</select>
<!-- 根据条件分页查询权限数据: -->
<select id="selectPermissionPage" resultType="com.rczn.system.domain.Permission">
SELECT * FROM sys_permission
WHERE del_sign = 0
<if test="parentId != null "> and parent_id = #{parentId}</if>
<if test="permissionName != null and permissionName != ''"> AND permission_name LIKE CONCAT('%', #{permissionName}, '%')</if>
</select>
<!-- 新增 -->
<insert id="insertPermission">
INSERT INTO sys_permission
(parent_id, permission_name, permission_code, create_id, remark, del_sign)
VALUES
(#{parentId}, #{permissionName}, #{permissionCode}, #{createId}, #{remark}, 0)
</insert>
<!-- 修改 -->
<update id="updatePermission">
UPDATE sys_permission
SET
parent_id = #{parentId},
permission_name = #{permissionName},
permission_code = #{permissionCode},
update_id = #{updateId},
remark = #{remark}
WHERE id = #{id}
</update>
<!-- 逻辑删除 -->
<update id="deletePermissionById">
UPDATE sys_permission SET del_sign = 1 WHERE id = #{id}
</update>
</mapper>

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 对应 Mapper 接口全路径 -->
<mapper namespace="com.rczn.system.mapper.UserMapper">
<!-- 通用结果集映射(复用,避免重复编写) -->
<resultMap id="UserResultMap" type="com.rczn.system.domain.User">
<id column="id" property="id"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
<result column="user_name" property="userName"/>
<result column="password" property="password"/>
<result column="salt" property="salt"/>
<result column="nicke" property="nicke"/>
<result column="sex" property="sex"/>
<result column="email_addr" property="emailAddr"/>
<result column="address" property="address"/>
<result column="telephone" property="telephone"/>
<result column="dep_id" property="depId"/>
<result column="pos_id" property="posId"/>
</resultMap>
<!-- 公共字段BaseBean 继承的字段) -->
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- 用户专属字段 -->
<sql id="userColumn">
user_name, password, salt, nicke, sex, email_addr, address, telephone, dep_id, pos_id
</sql>
<!-- 1. 分页查询用户(所有传参为空时忽略该条件) -->
<select id="selectUserPage" resultMap="UserResultMap" parameterType="com.rczn.system.domain.User">
SELECT
<include refid="baseColumn"/>,
<include refid="userColumn"/>
FROM sys_user
<where>
<!-- 逻辑删除标识默认查未删除del_sign=0传参不为空时按传参筛选 -->
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<!-- 用户名:为空时忽略模糊查询 -->
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<!-- 部门ID为空时忽略 -->
<if test="depId != null">
AND dep_id = #{depId}
</if>
<!-- 职位ID为空时忽略 -->
<if test="posId != null">
AND pos_id = #{posId}
</if>
<!-- 创建人ID为空时忽略 -->
<if test="createId != null">
AND create_id = #{createId}
</if>
<!-- 性别:为空时忽略 -->
<if test="sex != null">
AND sex = #{sex}
</if>
</where>
ORDER BY id DESC
</select>
<!-- 2. 根据ID查询用户支持查询已删除数据传参为空时返回null -->
<select id="selectById" resultMap="UserResultMap">
SELECT
<include refid="baseColumn"/>,
<include refid="userColumn"/>
FROM sys_user
WHERE id = #{id}
<!-- 可选:添加删除标识筛选(为空时查所有状态,不为空时按状态筛选) -->
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
</select>
<!-- 3. 新增用户(传参为空时用默认值,非空时用传参值) -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_user (
<trim suffixOverrides=",">
<if test="userName != null and userName != ''"> user_name,</if>
<if test="password != null and password != ''"> password,</if>
<if test="salt != null and salt != ''"> salt,</if>
<if test="nicke != null and nicke != ''"> nicke,</if>
<if test="sex != null"> sex,</if>
<if test="emailAddr != null and emailAddr != ''"> email_addr,</if>
<if test="address != null and address != ''"> address,</if>
<if test="telephone != null and telephone != ''"> telephone,</if>
<if test="depId != null"> dep_id,</if>
<if test="posId != null"> pos_id,</if>
<!-- 公共字段:为空时用默认值,非空时用传参 -->
<if test="createId != null"> create_id,</if>
<if test="createTime != null"> create_time,</if>
<if test="updateId != null"> update_id,</if>
<if test="updateTime != null"> update_time,</if>
<!-- 方案1delSign 为空时设为 0 -->
<if test="delSign != null"> del_sign,</if>
<if test="remark != null and remark != ''"> remark,</if>
</trim>
) VALUES (
<trim suffixOverrides=",">
<if test="userName != null and userName != ''"> #{userName},</if>
<if test="password != null and password != ''"> #{password},</if>
<if test="salt != null and salt != ''"> #{salt},</if>
<if test="nicke != null and nicke != ''"> #{nicke},</if>
<if test="sex != null"> #{sex},</if>
<if test="emailAddr != null and emailAddr != ''"> #{emailAddr},</if>
<if test="address != null and address != ''"> #{address},</if>
<if test="telephone != null and telephone != ''"> #{telephone},</if>
<if test="depId != null"> #{depId},</if>
<if test="posId != null"> #{posId},</if>
<!-- 公共字段:为空时用默认值,非空时用传参 -->
<if test="createId != null"> #{createId},</if>
<if test="createTime != null"> #{createTime},</if>
<if test="updateId != null"> #{updateId},</if>
<if test="updateTime != null"> #{updateTime},</if>
<!-- 方案1delSign 为空时设为 0 -->
<if test="delSign != null"> #{delSign},</if>
<if test="remark != null and remark != ''"> #{remark},</if>
</trim>
)
</insert>
<!-- 4. 修改用户(仅更新非空字段,空字段不更新) -->
<update id="update">
UPDATE sys_user
<set>
<!-- 用户专属字段:非空才更新 -->
<if test="userName != null and userName != ''">user_name = #{userName},</if>
<if test="password != null and password != ''">password = #{password},</if>
<if test="salt != null and salt != ''">salt = #{salt},</if>
<if test="nicke != null and nicke != ''">nicke = #{nicke},</if>
<if test="sex != null">sex = #{sex},</if>
<if test="emailAddr != null and emailAddr != ''">email_addr = #{emailAddr},</if>
<if test="address != null and address != ''">address = #{address},</if>
<if test="telephone != null and telephone != ''">telephone = #{telephone},</if>
<if test="depId != null">dep_id = #{depId},</if>
<if test="posId != null">pos_id = #{posId},</if>
<!-- 公共字段:非空才更新 -->
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if>
<if test="delSign != null">del_sign = #{delSign},</if>
<!-- 更新时间:强制更新为当前时间(无论是否传参) -->
update_time = NOW()
</set>
WHERE id = #{id}
</update>
<!-- 5. 根据ID删除用户逻辑删除替代物理删除传参为空时不执行 -->
<delete id="deleteById">
UPDATE sys_user
SET
del_sign = 1,
update_time = NOW()
<if test="updateId != null">, update_id = #{updateId}</if>
WHERE id = #{id}
AND del_sign = 0 <!-- 避免重复删除 -->
</delete>
<!-- 6. 查询总条数(与分页查询条件一致,传参为空时忽略) -->
<select id="selectTotal" resultType="java.lang.Long">
SELECT COUNT(*)
FROM sys_user
<where>
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<if test="depId != null">
AND dep_id = #{depId}
</if>
<if test="posId != null">
AND pos_id = #{posId}
</if>
<if test="createId != null">
AND create_id = #{createId}
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
</where>
</select>
<select id="findUserPermissions" resultType="com.rczn.system.domain.Permission">
SELECT
p.*
FROM
sys_user u
JOIN
sys_user_role ur ON u.id = ur.user_id
JOIN
sys_role r ON ur.role_id = r.id
JOIN
sys_role_permission rp ON r.id = rp.role_id
JOIN
sys_permission p ON rp.permission_id = p.id
WHERE
u.id = #{userId}
AND u.del_sign = 0
AND r.del_sign = 0
AND p.del_sign = 0;
</select>
</mapper>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.UserRoleMapper">
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<sql id="userRoleColumn">
user_id, role_id
</sql>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_user_role (
<include refid="userRoleColumn"/>,remark, create_time, del_sign
) VALUES (
#{userId}, #{roleId}, #{remark},NOW(), 0
)
</insert>
<delete id="deleteById">
DELETE FROM sys_user_role WHERE id = #{id}
</delete>
<delete id="deleteByUserId">
DELETE FROM sys_user_role WHERE user_id = #{userId}
</delete>
<delete id="deleteByRoleId">
DELETE FROM sys_user_role WHERE role_id = #{roleId}
</delete>
<select id="selectById" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE id = #{id}
</select>
<select id="selectByUserId" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE user_id = #{userId}
</select>
<select id="selectByRoleId" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE role_id = #{roleId}
</select>
<select id="selectPage" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE 1=1
<if test="userId != null">AND user_id = #{userId}</if>
<if test="roleId != null">AND role_id = #{roleId}</if>
ORDER BY id DESC
</select>
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_user_role
WHERE 1=1
<if test="userId != null">AND user_id = #{userId}</if>
<if test="roleId != null">AND role_id = #{roleId}</if>
</select>
</mapper>

View File

@@ -0,0 +1,13 @@
package com.rczn;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RcznAdminApplicationTests {
// @Test
void contextLoads() {
}
}

View File

@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rczn</groupId>
<artifactId>Rc-autoplc-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>rczn-autoplc</artifactId>
<name>rczn-autoplc</name>
<description>rczn-autoplcPLC业务模块</description>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖公共模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-common</artifactId>
</dependency>
<!-- Spring Boot 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 如果需要Web功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.14</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models-jakarta</artifactId>
<version>2.2.19</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<!-- 这里可以添加PLC通信相关的依赖 -->
<!-- 例如:
<dependency>
<groupId>com.github.s7connector</groupId>
<artifactId>s7connector</artifactId>
<version>2.1</version>
</dependency>
-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip> <!-- 不作为可执行模块 -->
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,28 @@
package com.rczn.rcznautoplc.cache;
import java.util.HashMap;
import java.util.Map;
/**
* 1-功能岛>plc地址
* 2-动作单元>plc地址
* 3-参数名字>plc地址
* 三个映射关系Map表
*/
public class IsLandActionParamToPlc {
// 1-功能岛>plc地址:key-功能岛idvalue-功能岛plc地址
public static final Map<Integer, Integer> islandToPlc = new HashMap<>();
// 2-动作单元>plc地址:key-动作单元idvalue-动作单元plc地址
public static final Map<Integer, Integer> actionToPlc = new HashMap<>();
// 3-参数名字>plc地址:key-参数名字value-参数plc地址
public static final Map<String, Integer> paramToPlc = new HashMap<>();
//4-参数id>plc地址:key-参数idvalue-参数plc地址
public static final Map<Integer,Integer> paramIdToPlc = new HashMap<>();
//更新三种数据的方法
//获取spring里面bean
//1-功能岛>plc地址
}

View File

@@ -0,0 +1,110 @@
package com.rczn.rcznautoplc.cache;
//样品准备状态
public class PlcRunStatus {
//定容岛:状态属性:
public static int goodsScanStatus = 0; //货物扫描:0-准备1-扫描完毕
//plc系统运行状态
public static int systemPlcRunStatus = 0; //系统准备:0-未准备1-空闲2-忙4异常
public static int goodsCount = 0;//样品处理数量
public static int goodsCurrentIndex = 0;//当前样品处理索引
//404内照射项目默认样品尿液液体
public static String defaultGoodsName = "尿液";
public static String defaultGoodsType = "液体";
//目标监测物
public static String defaultGoalDetect = "总氮";
public static class PlcRunStatusResponse{
private int goodsScanStatus = 0; //货物扫描:0-准备1-扫描完毕
private int systemPlcRunStatus = 0; //系统准备:0-未准备1-空闲2-忙4异常
private int goodsCount = 0;//样品处理数量
private int goodsCurrentIndex = 0;//当前样品处理索引
private String defaultGoodsName = "尿液";//默认样品名称
private String defaultGoodsType = "液体";//默认样品类型
private String defaultGoalDetect = "总氮";//默认目标监测物
public PlcRunStatusResponse() {
}
public PlcRunStatusResponse(int goodsScanStatus, int systemPlcRunStatus, int goodsCount, int goodsCurrentIndex, String defaultGoodsName, String defaultGoodsType, String defaultGoalDetect) {
this.goodsScanStatus = goodsScanStatus;
this.systemPlcRunStatus = systemPlcRunStatus;
this.goodsCount = goodsCount;
this.goodsCurrentIndex = goodsCurrentIndex;
this.defaultGoodsName = defaultGoodsName;
this.defaultGoodsType = defaultGoodsType;
this.defaultGoalDetect = defaultGoalDetect;
}
public int getGoodsScanStatus() {
return goodsScanStatus;
}
public void setGoodsScanStatus(int goodsScanStatus) {
this.goodsScanStatus = goodsScanStatus;
}
public int getSystemPlcRunStatus() {
return systemPlcRunStatus;
}
public void setSystemPlcRunStatus(int systemPlcRunStatus) {
this.systemPlcRunStatus = systemPlcRunStatus;
}
public int getGoodsCount() {
return goodsCount;
}
public void setGoodsCount(int goodsCount) {
this.goodsCount = goodsCount;
}
public int getGoodsCurrentIndex() {
return goodsCurrentIndex;
}
public void setGoodsCurrentIndex(int goodsCurrentIndex) {
this.goodsCurrentIndex = goodsCurrentIndex;
}
public String getDefaultGoodsName() {
return defaultGoodsName;
}
public void setDefaultGoodsName(String defaultGoodsName) {
this.defaultGoodsName = defaultGoodsName;
}
public String getDefaultGoodsType() {
return defaultGoodsType;
}
public void setDefaultGoodsType(String defaultGoodsType) {
this.defaultGoodsType = defaultGoodsType;
}
public String getDefaultGoalDetect() {
return defaultGoalDetect;
}
public void setDefaultGoalDetect(String defaultGoalDetect) {
this.defaultGoalDetect = defaultGoalDetect;
}
}
}

View File

@@ -0,0 +1,17 @@
package com.rczn.rcznautoplc.cache;
public class RegisterAddrDic {
//主PLC寄存器地址
public final static int goodsScanRegisterArr = 5000;//样品扫描状态寄存器地址:
//整体运转状态:
public final static int wholeRunStatusRegisterArr = 1100;//整体运转状态寄存器地址:
//协议存储地址:
//1-下发plc样品sop指令协议寄存器地址
public final static int downProtcolRegisterArr = 2000;//协议存储寄存器地址:
//2-接收plc处理样品状态数据协议寄存器地址
public final static int upProtcolRegisterArr = 3000;//协议存储寄存器地址:
}

View File

@@ -0,0 +1,185 @@
package com.rczn.rcznautoplc.controller;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.DevInfo;
import com.rczn.rcznautoplc.service.DevInfoService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
/**
* 设备信息 ControllerRESTful API
*/
@RestController
@RequestMapping("/devInfo")
@Tag(name = "动作单元管理", description = "设备增删改查+分页查询+全量查询接口")
public class DevInfoController {
@Autowired
private DevInfoService devInfoService;
/**
* 新增设备
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增动作单元", description = "动作单元名称为必填项,其他字段可选(非空则入库)")
public ResponseEntity<Map<String, Object>> addDevInfo(
@Parameter(name = "动作单元信息", description = "动作单元新增请求参数", required = true)
@RequestBody DevInfo devInfo) {
Map<String, Object> result = new HashMap<>();
try {
boolean success = devInfoService.addDevInfo(devInfo);
result.put("success", success);
result.put("message", success ? "动作单元新增成功" : "动作单元新增失败");
return ResponseEntity.ok(result);
} catch (IllegalArgumentException e) {
result.put("success", false);
result.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
} catch (Exception e) {
result.put("success", false);
result.put("message", "服务器异常:" + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 根据ID删除设备逻辑删除
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除动作单元", description = "逻辑删除设置delSign=1不物理删除数据")
public ResponseEntity<Map<String, Object>> removeDevInfoById(
@Parameter(name = "id", description = "动作单元ID", required = true, example = "1")
@PathVariable Long id) {
Map<String, Object> result = new HashMap<>();
try {
boolean success = devInfoService.removeDevInfoById(id);
result.put("success", success);
result.put("message", success ? "动作单元删除成功" : "动作单元不存在或已删除");
return ResponseEntity.ok(result);
} catch (IllegalArgumentException e) {
result.put("success", false);
result.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
} catch (Exception e) {
result.put("success", false);
result.put("message", "服务器异常:" + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 更新设备
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改动作单元", description = "需传入动作单元ID其他字段可选非空则更新")
public ResponseEntity<Map<String, Object>> updateDevInfo(
@Parameter(name = "动作单元信息", description = "动作单元修改请求参数含ID", required = true)
@RequestBody DevInfo devInfo) {
Map<String, Object> result = new HashMap<>();
try {
boolean success = devInfoService.updateDevInfo(devInfo);
result.put("success", success);
result.put("message", success ? "动作单元更新成功" : "动作单元不存在或已删除");
return ResponseEntity.ok(result);
} catch (IllegalArgumentException e) {
result.put("success", false);
result.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
} catch (Exception e) {
result.put("success", false);
result.put("message", "服务器异常:" + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 根据ID查询动作单元
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个动作单元", description = "根据动作单元ID查询动作单元完整信息")
public ResponseEntity<Map<String, Object>> getDevInfoById(
@Parameter(name = "id", description = "动作单元ID", required = true, example = "1")
@PathVariable Long id) {
Map<String, Object> result = new HashMap<>();
try {
DevInfo devInfo = devInfoService.getDevInfoById(id);
if (devInfo != null) {
result.put("success", true);
result.put("data", devInfo);
} else {
result.put("success", false);
result.put("message", "动作单元不存在或已删除");
}
return ResponseEntity.ok(result);
} catch (IllegalArgumentException e) {
result.put("success", false);
result.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
} catch (Exception e) {
result.put("success", false);
result.put("message", "服务器异常:" + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 分页查询动作单元
* 示例:/devInfo/listPage?pageNum=1&pageSize=10&devName=动作单元1&status=0
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询动作单元", description = "支持动作单元名称、型号、IP、状态等多条件过滤默认查询未删除动作单元")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY)
// @Parameter(name = "devName", description = "设备名称(可选,模糊查询)", required = false, example = "PLC设备", in = ParameterIn.QUERY),
// @Parameter(name = "devModel", description = "设备型号(可选,模糊查询)", required = false, example = "S7-1200", in = ParameterIn.QUERY)
})
public Result getDevInfoPage(
@ParameterObject // 核心注解:标记该实体类从查询参数取值
@Schema(description = "设备查询条件(可选)") // 补充描述
DevInfo devInfo, // 接收查询条件devName、status等
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
try {
PageInfo<DevInfo> pageInfo = devInfoService.getDevInfoPage(devInfo, pageNum, pageSize);
Result<PageInfo<DevInfo>> success = Result.success(pageInfo);
return success;
} catch (Exception e) {
return Result.error("数据库异常!");
}
}
/**
* 查询所有设备(不分页)
*/
@GetMapping(value = "/all", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询所有设备", description = "返回所有未删除的设备完整信息(不分页,适用于设备数量较少场景)")
public ResponseEntity<Map<String, Object>> getAllDevInfo() {
Map<String, Object> result = new HashMap<>();
try {
List<DevInfo> devInfoList = devInfoService.getAllDevInfo();
result.put("success", true);
result.put("data", devInfoList);
return ResponseEntity.ok(result);
} catch (Exception e) {
result.put("success", false);
result.put("message", "服务器异常:" + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
}

View File

@@ -0,0 +1,161 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.DevParam;
import com.rczn.rcznautoplc.domain.query.DevParamQuery;
import com.rczn.rcznautoplc.service.DevParamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/devParam")
@Tag(name = "设备参数管理", description = "设备参数增删改查+分页查询接口")
public class DevParamController {
@Autowired
DevParamService devParamService;
/**
* 分页查询设备参数
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询设备参数", description = "支持设备ID精准查询、参数名称/值模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "devId", description = "设备ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "paramTypeData", description = "参数类型(可选,模糊查询)", required = false, example = "耗材,通用", in = ParameterIn.QUERY),
@Parameter(name = "paramName", description = "参数名称(可选,模糊查询)", required = false, example = "温度", in = ParameterIn.QUERY),
@Parameter(name = "paramValue", description = "参数值(可选,模糊查询)", required = false, example = "25", in = ParameterIn.QUERY)
})
public Result getDevParamPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer devId,
@RequestParam(required = false) String paramTypeData,
@RequestParam(required = false) String paramName,
@RequestParam(required = false) String paramValue) {
PageInfo<DevParam> pageBean = devParamService.selectPage(pageNum, pageSize, devId,paramTypeData, paramName, paramValue);
return Result.success(pageBean);
}
/**
* 根据条件,查询设备参数
*/
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询设备参数", description = "支持设备ID精准查询、参数名称/值模糊查询")
@Parameters({
@Parameter(name = "devId", description = "设备ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "paramTypeData", description = "参数类型(可选,模糊查询)", required = false, example = "耗材,通用", in = ParameterIn.QUERY),
@Parameter(name = "paramName", description = "参数名称(可选,模糊查询)", required = false, example = "温度", in = ParameterIn.QUERY),
@Parameter(name = "paramValue", description = "参数值(可选,模糊查询)", required = false, example = "25", in = ParameterIn.QUERY)
})
public Result getDevParamPage(
@RequestParam(required = false) Integer devId,
@RequestParam(required = false) String paramTypeData,
@RequestParam(required = false) String paramName,
@RequestParam(required = false) String paramValue) {
DevParamQuery query = new DevParamQuery();
query.setDevId(devId);
query.setParamTypeData(paramTypeData);
query.setParamName(paramName);
query.setParamValue(paramValue);
List<DevParam> pageBean = devParamService.selectList( query);
return Result.success(pageBean);
}
/**
* 根据条件,查询设备参数
*/
@PostMapping(value = "/addDevId", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "为参数增加设备的devId", description = "为参数增加设备的devId")
@Parameters({
@Parameter(name = "devId", description = "设备ID", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "paramId", description = "参数Id", required = true, example = "1", in = ParameterIn.QUERY)
})
public Result addDevId(
@RequestParam(required = true) Integer devId,
@RequestParam(required = true) Integer paramId) {
Boolean result = devParamService.addDevId( devId, paramId );
return Result.success(result);
}
/**
* 根据条件,查询设备参数
*/
@PostMapping(value = "/delDevId", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "为参数减少设备的devId", description = "为参数减少设备的devId")
@Parameters({
@Parameter(name = "devId", description = "设备ID", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "paramId", description = "参数Id", required = true, example = "1", in = ParameterIn.QUERY)
})
public Result delDevId(
@RequestParam(required = true) Integer devId,
@RequestParam(required = true) Integer paramId) {
Boolean result = devParamService.reduceDevId( devId, paramId );
return Result.success(result);
}
/**
* 根据ID查询设备参数
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个设备参数", description = "根据设备参数ID查询详情")
public Result getDevParamById(@PathVariable Long id) {
DevParam devParam = devParamService.selectById(id);
return devParam != null ? Result.success(devParam) : Result.error("设备参数不存在");
}
/**
* 新增设备参数
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增设备参数", description = "设备ID、参数名称为必填项")
public Result addDevParam(@RequestBody DevParam devParam) {
try {
Long devParamId = devParamService.insert(devParam);
return Result.success(devParamId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 修改设备参数
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改设备参数", description = "需传入设备参数ID其他字段可选非空则更新")
public Result updateDevParam(@RequestBody DevParam devParam) {
try {
Boolean success = devParamService.update(devParam);
return success ? Result.success(true) : Result.error("修改失败(设备参数不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 删除设备参数(逻辑删除)
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除设备参数", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteDevParam(@PathVariable Long id) {
try {
Boolean success = devParamService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(设备参数不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,143 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.FlowInfo;
import com.rczn.rcznautoplc.domain.ManageLog;
import com.rczn.rcznautoplc.domain.UserBusy;
import com.rczn.rcznautoplc.service.FlowInfoService;
import com.rczn.rcznautoplc.service.ManageLogService;
import com.rczn.utils.ThreadLocalUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/flowInfo")
@Tag(name = "标准流程管理", description = "流程信息增删改查+分页查询接口")
public class FlowInfoController {
@Autowired
FlowInfoService flowInfoService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询流程信息", description = "支持流程排序精准查询、流程名称/岛屿ID列表模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "flowIndex", description = "流程排序(可选,精准查询)", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "flowName", description = "流程名称(可选,模糊查询)", required = false, example = "检测流程", in = ParameterIn.QUERY),
@Parameter(name = "islandIdList", description = "岛屿ID列表可选模糊查询", required = false, example = "1,2,3", in = ParameterIn.QUERY)
})
public Result getFlowInfoPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer flowIndex,
@RequestParam(required = false) String flowName,
@RequestParam(required = false) String islandIdList) {
PageInfo<FlowInfo> pageBean = flowInfoService.selectPage(pageNum, pageSize, flowIndex, flowName, islandIdList);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询流程信息", description = "支持流程排序精准查询、流程名称/岛屿ID列表模糊查询")
@Parameters({
@Parameter(name = "flowIndex", description = "流程排序(可选,精准查询)", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "flowName", description = "流程名称(可选,模糊查询)", required = false, example = "检测流程", in = ParameterIn.QUERY),
@Parameter(name = "islandIdList", description = "岛屿ID列表可选模糊查询", required = false, example = "1,2,3", in = ParameterIn.QUERY)
})
public Result getFlowInfoList(
@RequestParam(required = false) Integer flowIndex,
@RequestParam(required = false) String flowName,
@RequestParam(required = false) String islandIdList) {
List<FlowInfo> list = flowInfoService.selectList( flowIndex, flowName, islandIdList);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个流程信息", description = "根据流程信息ID查询详情")
public Result getFlowInfoById(@PathVariable Long id) {
FlowInfo flowInfo = flowInfoService.selectById(id);
return flowInfo != null ? Result.success(flowInfo) : Result.error("流程信息不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增流程信息", description = "流程名称、流程排序为必填项")
public Result addFlowInfo(@RequestBody FlowInfo flowInfo) {
try {
Long flowInfoId = flowInfoService.insert(flowInfo);
//记录操作样品执行SOP操作日志
LocalDateTime loginTime = LocalDateTime.now();
ManageLog info = new ManageLog();
// ========== 修复开始 ==========
Map<String, Object> mapClaims = ThreadLocalUtil.get();
UserBusy userBusy = new UserBusy();
userBusy.setId(Long.valueOf( mapClaims.get("id").toString()));
userBusy.setUserName((String) mapClaims.get("username"));
// ========== 修复结束 ==========
info.setCreateId(userBusy.getId());
info.setLogName("基础数据操作日志");
info.setLogType("基础数据操作日志");//1登录日志、2SOP操作日志、3基础数据操作日志
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("用户名:").append(userBusy.getUserName()).append("SOP配置添加操作时间").append(loginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
info.setLogContent(stringBuilder.toString());
info.setCreateTime(loginTime);
manageLogService.insert(info);
return Result.success(flowInfoId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改流程信息", description = "需传入流程信息ID其他字段可选非空则更新")
public Result updateFlowInfo(@RequestBody FlowInfo flowInfo) {
try {
Boolean success = flowInfoService.update(flowInfo);
return success ? Result.success(true) : Result.error("修改失败(流程信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@Autowired
ManageLogService manageLogService;
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除流程信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteFlowInfo(@PathVariable Long id) {
try {
Boolean success = flowInfoService.deleteById(id);
//记录操作样品执行SOP操作日志
LocalDateTime loginTime = LocalDateTime.now();
ManageLog info = new ManageLog();
// ========== 修复开始 ==========
Map<String, Object> mapClaims = ThreadLocalUtil.get();
UserBusy userBusy = new UserBusy();
userBusy.setId(Long.valueOf( mapClaims.get("id").toString()));
userBusy.setUserName((String) mapClaims.get("username"));
// ========== 修复结束 ==========
info.setCreateId(userBusy.getId());
info.setLogName("基础数据操作日志");
info.setLogType("基础数据操作日志");//1登录日志、2SOP操作日志、3基础数据操作日志
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("用户名:").append(userBusy.getUserName()).append("SOP配置删除操作时间").append(loginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
info.setLogContent(stringBuilder.toString());
info.setCreateTime(loginTime);
manageLogService.insert(info);
return success ? Result.success(true) : Result.error("删除失败(流程信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,98 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.GoodsFlowStatus;
import com.rczn.rcznautoplc.domain.query.GoodsFlowStatusQuery;
import com.rczn.rcznautoplc.service.GoodsFlowStatusService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/goodsFlowStatus")
@Tag(name = "样品流程信息管理", description = "样品流程状态增删改查+分页查询接口")
public class GoodsFlowStatusController {
@Autowired
GoodsFlowStatusService goodsFlowStatusService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询样品流程状态", description = "支持样品ID、流程ID、岛屿ID、状态精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
})
public Result getGoodsFlowStatusPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@ParameterObject
@Schema(description = "样品ID、流程ID、岛屿ID、状态精准查询条件")
GoodsFlowStatusQuery goodsFlowStatus) {
PageInfo<GoodsFlowStatus> pageBean = goodsFlowStatusService.selectPage(pageNum, pageSize, goodsFlowStatus);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询样品流程状态", description = "支持样品ID、流程ID、岛屿ID、状态等精准查询")
@Parameters({
})
public Result getList(
@ParameterObject
@Schema(description = "样品ID、流程ID、岛屿ID、状态等精准查询条件")
GoodsFlowStatusQuery goodsFlowStatus) {
List<GoodsFlowStatus> list = goodsFlowStatusService.selectList( goodsFlowStatus);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个样品流程状态", description = "根据样品流程状态ID查询详情")
public Result getGoodsFlowStatusById(@PathVariable Long id) {
GoodsFlowStatus goodsFlowStatus = goodsFlowStatusService.selectById(id);
return goodsFlowStatus != null ? Result.success(goodsFlowStatus) : Result.error("样品流程状态不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增样品流程状态", description = "样品ID、流程ID、状态为必填项状态0-未执行1-执行10-通过11-失败)")
public Result addGoodsFlowStatus(@RequestBody GoodsFlowStatus goodsFlowStatus) {
try {
Long goodsFlowStatusId = goodsFlowStatusService.insert(goodsFlowStatus);
return Result.success(goodsFlowStatusId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改样品流程状态", description = "需传入样品流程状态ID其他字段可选非空则更新")
public Result updateGoodsFlowStatus(@RequestBody GoodsFlowStatus goodsFlowStatus) {
try {
Boolean success = goodsFlowStatusService.update(goodsFlowStatus);
return success ? Result.success(true) : Result.error("修改失败(样品流程状态不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除样品流程状态", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteGoodsFlowStatus(@PathVariable Long id) {
try {
Boolean success = goodsFlowStatusService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(样品流程状态不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,134 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.GoodsInfo;
import com.rczn.rcznautoplc.domain.query.GoodsInfoQuery;
import com.rczn.rcznautoplc.service.GoodsInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/goodsInfo")
@Tag(name = "样品信息管理", description = "样品信息增删改查+分页查询接口")
public class GoodsInfoController {
@Autowired
GoodsInfoService goodsInfoService;
/**
* 分页查询样品信息
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询样品信息", description = "支持样品名称/类型/来源模糊查询、批次精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY)
// @Parameter(name = "goodsName", description = "样品名称(可选,模糊查询)", required = false, example = "手机", in = ParameterIn.QUERY),
// @Parameter(name = "goodsType", description = "样品类型(可选,模糊查询)", required = false, example = "电子产品", in = ParameterIn.QUERY),
// @Parameter(name = "goodFrom", description = "样品来源(可选,模糊查询)", required = false, example = "深圳", in = ParameterIn.QUERY),
// @Parameter(name = "goodBatch", description = "样品批次(可选,精准查询)", required = false, example = "202501", in = ParameterIn.QUERY)
})
public Result getGoodsInfoPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@ParameterObject
@Schema(description = "样品信息查询条件(可选)", name = "goodsInfo", required = false)
GoodsInfoQuery goodsInfo) {
PageInfo<GoodsInfo> pageBean = goodsInfoService.selectPage(pageNum, pageSize, goodsInfo);
return Result.success(pageBean);
}
/**
* 查询样品信息
*/
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询样品信息", description = "支持样品名称/类型/来源模糊查询、批次精准查询")
@Parameters({
})
public Result getList(
@ParameterObject
@Schema(description = "样品信息查询条件(可选)", name = "goodsInfo", required = false)
GoodsInfoQuery goodsInfo) {
List<GoodsInfo> list = goodsInfoService.selectList( goodsInfo);
return Result.success(list);
}
/**
* 根据ID查询样品信息
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个样品信息", description = "根据样品信息ID查询详情")
public Result getGoodsInfoById(@PathVariable Long id) {
GoodsInfo goodsInfo = goodsInfoService.selectById(id);
return goodsInfo != null ? Result.success(goodsInfo) : Result.error("样品信息不存在");
}
/**
* 新增样品信息
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增样品信息", description = "样品名称、类型、入库时间为必填项")
public Result addGoodsInfo(@RequestBody GoodsInfo goodsInfo) {
try {
Long goodsInfoId = goodsInfoService.insert(goodsInfo);
return Result.success(goodsInfoId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 扫码新增样品信息
* 扫码信息:样品类型、样品编码、样品名称、样品点位
*/
@PostMapping(value = "/scanAdd", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "扫描新增样品", description = "样品名称、类型、编码、点位为必填项")
public Result scanAdd(@RequestBody GoodsInfo goodsInfo) {
try {
GoodsInfo goodInfoResult = goodsInfoService.insertByScan(goodsInfo);
return Result.success(goodInfoResult);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 修改样品信息
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改样品信息", description = "需传入样品信息ID其他字段可选非空则更新")
public Result updateGoodsInfo(@RequestBody GoodsInfo goodsInfo) {
try {
Boolean success = goodsInfoService.update(goodsInfo);
return success ? Result.success(true) : Result.error("修改失败(样品信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 删除样品信息(逻辑删除)
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除样品信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteGoodsInfo(@PathVariable Long id) {
try {
Boolean success = goodsInfoService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(样品信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,81 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.IslandInfo;
import com.rczn.rcznautoplc.service.IslandInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/islandInfo")
@Tag(name = "功能岛信息管理", description = "功能岛信息增删改查+分页查询接口")
public class IslandInfoController {
@Autowired
IslandInfoService islandInfoService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询功能岛信息", description = "支持功能岛名称、编码模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "islandName", description = "功能岛名称(可选,模糊查询)", required = false, example = "一号岛", in = ParameterIn.QUERY),
@Parameter(name = "islandCode", description = "功能岛编码(可选,模糊查询)", required = false, example = "ISLAND001", in = ParameterIn.QUERY)
})
public Result getIslandInfoPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String islandName,
@RequestParam(required = false) String islandCode) {
PageInfo<IslandInfo> pageBean = islandInfoService.selectPage(pageNum, pageSize, islandName, islandCode);
return Result.success(pageBean);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个功能岛信息", description = "根据功能岛信息ID查询详情")
public Result getIslandInfoById(@PathVariable Long id) {
IslandInfo islandInfo = islandInfoService.selectById(id);
return islandInfo != null ? Result.success(islandInfo) : Result.error("功能岛信息不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增功能岛信息", description = "功能岛名称、编码为必填项")
public Result addIslandInfo(@RequestBody IslandInfo islandInfo) {
try {
Long islandInfoId = islandInfoService.insert(islandInfo);
return Result.success(islandInfoId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改功能岛信息", description = "需传入功能岛信息ID其他字段可选非空则更新")
public Result updateIslandInfo(@RequestBody IslandInfo islandInfo) {
try {
Boolean success = islandInfoService.update(islandInfo);
return success ? Result.success(true) : Result.error("修改失败(功能岛信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除功能岛信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteIslandInfo(@PathVariable Long id) {
try {
Boolean success = islandInfoService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(功能岛信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,86 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.IslandParam;
import com.rczn.rcznautoplc.service.IslandParamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/islandParam")
@Tag(name = "功能岛参数管理", description = "功能岛参数增删改查+分页查询接口")
public class IslandParamController {
@Autowired
IslandParamService islandParamService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询功能岛参数", description = "支持功能岛ID、步骤ID精准查询参数名称模糊查询、参数类型精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "islandId", description = "功能岛ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "stepId", description = "步骤ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "paramName", description = "参数名称(可选,模糊查询)", required = false, example = "温度", in = ParameterIn.QUERY),
@Parameter(name = "paramType", description = "参数类型(可选,精准查询)", required = false, example = "数值", in = ParameterIn.QUERY)
})
public Result getIslandParamPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer islandId,
@RequestParam(required = false) Integer stepId,
@RequestParam(required = false) String paramName,
@RequestParam(required = false) String paramType) {
PageInfo<IslandParam> pageBean = islandParamService.selectPage(pageNum, pageSize, islandId, stepId, paramName, paramType);
return Result.success(pageBean);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个功能岛参数", description = "根据功能岛参数ID查询详情")
public Result getIslandParamById(@PathVariable Long id) {
IslandParam islandParam = islandParamService.selectById(id);
return islandParam != null ? Result.success(islandParam) : Result.error("功能岛参数不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增功能岛参数", description = "功能岛ID、步骤ID、参数名称为必填项")
public Result addIslandParam(@RequestBody IslandParam islandParam) {
try {
Long islandParamId = islandParamService.insert(islandParam);
return Result.success(islandParamId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改功能岛参数", description = "需传入功能岛参数ID其他字段可选非空则更新")
public Result updateIslandParam(@RequestBody IslandParam islandParam) {
try {
Boolean success = islandParamService.update(islandParam);
return success ? Result.success(true) : Result.error("修改失败(功能岛参数不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除功能岛参数", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteIslandParam(@PathVariable Long id) {
try {
Boolean success = islandParamService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(功能岛参数不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,120 @@
package com.rczn.rcznautoplc.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.ManageLog;
import com.rczn.rcznautoplc.service.ManageLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/manage-log")
@Tag(name = "操作日志管理", description = "操作日志增删改查+分页查询接口")
public class ManageLogController {
@Autowired
private ManageLogService manageLogService;
/**
* 分页查询日志
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询操作日志", description = "支持多条件筛选,空条件自动忽略")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "logName", description = "日志名称(可选,模糊查询)", required = false, example = "登录操作", in = ParameterIn.QUERY),
@Parameter(name = "logType", description = "日志类型(可选,精准查询)", required = false, example = "LOGIN", in = ParameterIn.QUERY),
@Parameter(name = "createId", description = "创建人ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "logWritetimeStart", description = "日志开始时间可选格式yyyy-MM-dd HH:mm:ss", required = false, example = "2025-01-01 00:00:00", in = ParameterIn.QUERY),
@Parameter(name = "logWritetimeEnd", description = "日志结束时间可选格式yyyy-MM-dd HH:mm:ss", required = false, example = "2025-12-31 23:59:59", in = ParameterIn.QUERY)
})
public Result<PageBean<ManageLog>> getLogPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String logName,
@RequestParam(required = false) String logType,
@RequestParam(required = false) Long createId,
@RequestParam(required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime logWritetimeStart,
@RequestParam(required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime logWritetimeEnd) {
// 构建查询条件(空字段自动忽略)
ManageLog query = new ManageLog();
query.setLogName(logName);
query.setLogType(logType);
query.setCreateId(createId);
// 扩展字段用于时间范围查询实体类无需新增字段MyBatis 支持直接取参)
query.setStartTime(logWritetimeStart); // 实际用 logWritetimeStart这里仅为传递参数
query.setEndTime(logWritetimeEnd);
PageBean<ManageLog> pageBean = manageLogService.selectPage(pageNum, pageSize, query);
return Result.success(pageBean);
}
/**
* 按 ID 查询日志
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个操作日志", description = "按日志ID查询详情")
public Result getLogById(@PathVariable Long id) {
ManageLog log = manageLogService.selectById(id);
return log != null ? Result.success(log) : Result.error("日志不存在或已删除");
}
/**
* 新增操作日志
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增操作日志", description = "日志名称、类型为必填项,其他字段可选")
public Result addLog(@RequestBody ManageLog manageLog) {
try {
Long logId = manageLogService.insert(manageLog);
return Result.success("日志新增成功");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 更新操作日志
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "更新操作日志", description = "需传入日志ID其他字段非空则更新")
public Result updateLog(@RequestBody ManageLog manageLog) {
try {
Boolean success = manageLogService.update(manageLog);
return success ? Result.success( "日志更新成功") : Result.error("更新失败(日志不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 逻辑删除操作日志
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除操作日志", description = "逻辑删除设置delSign=1不物理删除")
public Result deleteLog(
@PathVariable Long id,
@RequestParam(required = false) Long updateId) {
try {
Boolean success = manageLogService.deleteById(id, updateId);
return success ? Result.success("日志删除成功") : Result.error("删除失败(日志不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,337 @@
package com.rczn.rcznautoplc.controller;
import com.rczn.domain.Result;
import com.rczn.modbus.Modbus4jWriteUtils;
import com.rczn.rcznautoplc.cache.PlcRunStatus;
import com.rczn.rcznautoplc.domain.*;
import com.rczn.rcznautoplc.domain.query.StepInfoQuery;
import com.rczn.rcznautoplc.service.*;
import com.rczn.rcznautoplc.utils.PlcConnectMap;
import com.rczn.utils.ThreadLocalUtil;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 设备信息 ControllerRESTful API
*/
@RestController
@RequestMapping("/plc")
@Tag(name = "plc设备控制类", description = "plc设备初始化查询控制方法集合")
public class PlcController {
@Autowired
private PlcService plcService;
/**
* 设备连接
*/
@PostMapping(value = "/connect", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "连接设备", description = "连接设备...")
public Result plcConnect(
@ParameterObject
@Schema(description = "plc设备参数")
ModbusConnectObj connectObj) {
ModbusMaster connectorInit;
if(PlcConnectMap.modbusConnectorMap.containsKey(connectObj.getIpAddr())){
return Result.error("设备连接已经存在!");
}
try {
connectorInit = plcService.connectModbus(connectObj);
if(connectorInit != null){
return Result.success(true);
}else {
return Result.error("设备连接失败!");
}
} catch (Exception e) {
return Result.error("设备连接失败!");
}
}
/**
* 向plc寄存器写数据
*/
@PostMapping(value = "/plcWrite", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "连接设备", description = "连接设备...")
public Result plcWrite(
@ParameterObject
@Schema(description = "plc设备参数")
ModbusConnectObj connectObj,
@Parameter
@Schema(description = "寄存器地址", required = true, example = "10000")
@RequestParam int registerAddress,
@Parameter
@Schema(description = "寄存器值", required = true, example = "12345")
@RequestParam int registerValue) {
ModbusMaster connectorInit;
if(PlcConnectMap.modbusConnectorMap.containsKey(connectObj.getIpAddr())){
connectorInit = PlcConnectMap.modbusConnectorMap.get(connectObj.getIpAddr());
try {
Modbus4jWriteUtils.writeHoldingRegister(connectorInit,1,registerAddress,registerValue, DataType.TWO_BYTE_INT_UNSIGNED);
} catch (ModbusTransportException e) {
throw new RuntimeException(e);
} catch (ErrorResponseException e) {
throw new RuntimeException(e);
} catch (ModbusInitException e) {
throw new RuntimeException(e);
}
return Result.error("设备连接已经存在!");
}
try {
connectorInit = plcService.connectModbus(connectObj);
if(connectorInit != null){
//往地址1000里面写入数据
Modbus4jWriteUtils.writeHoldingRegister(connectorInit,1,registerAddress,registerValue, DataType.TWO_BYTE_INT_UNSIGNED);
return Result.success(true);
}else {
return Result.error("设备连接失败!");
}
} catch (Exception e) {
return Result.error("设备连接失败!");
}
}
/**
* 根据ID删除设备逻辑删除
*/
@PostMapping(value = "/run")
@Operation(summary = "运行plc", description = "plc设备运行停止")
public Result runPlc(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Boolean success = plcService.startPlc(ipAddr);
return Result.success(success);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据ID删除设备逻辑删除
*/
@PostMapping(value = "/pause")
@Operation(summary = "暂停运行plc", description = "暂停运行plc")
public Result pausePlc(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Boolean success = plcService.pausePlc(ipAddr);
return Result.success(success);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据设备ip地址停止执行
*/
@PostMapping(value = "/stop")
@Operation(summary = "停止plc", description = "plc设备运行停止")
public Result stop(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Boolean success = plcService.stopPlc(ipAddr);
return Result.success(success);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据plc ip地址故障复位
*/
@PostMapping(value = "/resetError")
@Operation(summary = "plc设备复位故障", description = "plc设备复位故障")
public Result resetError(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Boolean success = plcService.resetErrorPlc(ipAddr);
return Result.success(success);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据plc ip地址获取plc设备状态
*/
@GetMapping(value = "/plcStatus")
@Operation(summary = "plc设备获取状态值", description = "状态值10-就绪11-执行中12-暂停中19已停止20-故障中")
public Result plcStatus(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Integer resultValue = plcService.getPlcStatus(ipAddr);
return Result.success(resultValue);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据plc ip地址获取plc设备状态
*/
@GetMapping(value = "/mastertPlcStatus")
@Operation(summary = "获取主plc状态对象", description = "goodsScanStatus = 0; //货物扫描:0-准备1-扫描完毕;//系统准备:0-未准备1-空闲2-忙4异常")
public Result mastertPlcStatus() {
try {
PlcRunStatus.PlcRunStatusResponse response = new PlcRunStatus.PlcRunStatusResponse();
response.setGoodsScanStatus(PlcRunStatus.goodsScanStatus);
response.setSystemPlcRunStatus(PlcRunStatus.systemPlcRunStatus);
response.setGoodsCount(PlcRunStatus.goodsCount);
response.setGoodsCurrentIndex(PlcRunStatus.goodsCurrentIndex);
response.setDefaultGoodsName(PlcRunStatus.defaultGoodsName);
response.setDefaultGoodsType(PlcRunStatus.defaultGoodsType);
response.setDefaultGoalDetect(PlcRunStatus.defaultGoalDetect);
return Result.success(response);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据plc ip地址设置plc设备模式
* 0-手动模式1-自动模式
*/
@PostMapping(value = "/setModel")
@Operation(summary = "plc设备设置模式", description = "模式值0-手动模式1-自动模式")
public Result setModel(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123", in = ParameterIn.QUERY)
@RequestParam String ipAddr,
@Parameter(name = "model", description = "设备模式值", required = true, example = "0-1", in = ParameterIn.QUERY)
@RequestParam Integer model) {
try {
Boolean resultValue = plcService.setPlcModel(ipAddr,model);
return Result.success(resultValue);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 根据plc ip地址获取plc设备模式
* 0-手动模式1-自动模式
*/
@GetMapping(value = "/getModel")
@Operation(summary = "plc设备获取模式值", description = "模式值0-手动模式1-自动模式")
public Result getModel(
@Parameter(name = "ipAddr", description = "设备ip地址", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
try {
Integer resultValue = plcService.getPlcModel(ipAddr);
return Result.success(resultValue);
} catch (Exception e) {
return Result.error("停止失败!");
}
}
/**
* 更新设备
*/
@GetMapping(value = "/getAll", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "获取全部plc连接对象", description = "获取全部plc连接对象")
public Result getPlcAll() {
Map<String,ModbusMaster> connectorMap = plcService.modbusALlMap();
return Result.success(connectorMap);
}
/**
* 根据ID查询设备
*/
@GetMapping(value = "/getPlcByIp", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "更加ip地址查询plc连接对象", description = "更加ip地址查询plc连接对象")
public Result getConnectByIpaddr(
@Parameter(name = "ipAddr", description = "设备IP", required = true, example = "192.168.1.123")
@RequestParam String ipAddr) {
ModbusMaster connector = plcService.getModbusConnect(ipAddr);
return Result.success(connector);
}
/**
* 查询所有设备(不分页)
*/
@PostMapping(value = "/doAction", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "调用plc设备执行动作", description = "根据plc设备ip执行动作")
public Result doAction(
@RequestParam String ip,
@RequestParam String action
) {
Boolean aBoolean = plcService.doAction(ip, action);
return Result.success(aBoolean);
}
@Autowired
StepInfoService stepInfoService;
@Autowired
GoodsInfoService goodsInfoService;
@Autowired
ManageLogService manageLogService;
@PostMapping(value = "/runFlow")
@Operation(summary = "为样品执行国标" ,description = "为样品执行国标")
public Result doStandGoods(
@RequestParam String plcIp,
@RequestParam Integer flowId,
@RequestParam List<Integer> goodsIds
){
//根据flowId获取步骤信息表
StepInfoQuery stepInfo = new StepInfoQuery();
stepInfo.setFlowId(flowId);
List<StepInfo> stepInfoList = stepInfoService.selectList(stepInfo);
//stepInfoList根据StepInfo里面的stepOrderint排序
stepInfoList.sort(Comparator.comparing(StepInfo::getStepOrder));
//根据goodsIds获取样品信息的 bar_code编码列表
List<GoodsInfo> goodsInfoList = goodsInfoService.selectByIdList(goodsIds);
List<String> barCodeList = goodsInfoList.stream().map(GoodsInfo::getBarCode).collect(Collectors.toList());
Boolean aBoolean = plcService.runSopInfoForGoodsList(plcIp,flowId, barCodeList, stepInfoList);
//记录操作样品执行SOP操作日志
LocalDateTime loginTime = LocalDateTime.now();
ManageLog info = new ManageLog();
// ========== 修复开始 ==========
Map<String, Object> mapClaims = ThreadLocalUtil.get();
UserBusy userBusy = new UserBusy();
userBusy.setId(Long.valueOf( mapClaims.get("id").toString()));
userBusy.setUserName((String) mapClaims.get("username"));
// ========== 修复结束 ==========
info.setCreateId(userBusy.getId());
info.setLogName("SOP操作日志");
info.setLogType("SOP操作日志");//1登录日志、2SOP操作日志、3基础数据操作日志
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("用户名:").append(userBusy.getUserName()).append("SOP执行操作时间").append(loginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
info.setLogContent(stringBuilder.toString());
info.setCreateTime(loginTime);
manageLogService.insert(info);
return Result.success(aBoolean);
}
}

View File

@@ -0,0 +1,84 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.RecordInfo;
import com.rczn.rcznautoplc.service.RecordInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/recordInfo")
@Tag(name = "记录信息管理", description = "记录信息增删改查+分页查询接口")
public class RecordInfoController {
@Autowired
RecordInfoService recordInfoService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询记录信息", description = "支持记录名称模糊查询,记录类型、状态精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "recordName", description = "记录名称(可选,模糊查询)", required = false, example = "设备故障", in = ParameterIn.QUERY),
@Parameter(name = "recordType", description = "记录类型可选精准查询1-设备异常2-样品异常3-操作异常)", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "recordStatus", description = "记录状态可选精准查询false-未处理true-已处理)", required = false, example = "false", in = ParameterIn.QUERY)
})
public Result getRecordInfoPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String recordName,
@RequestParam(required = false) Integer recordType,
@RequestParam(required = false) Boolean recordStatus) {
PageInfo<RecordInfo> pageBean = recordInfoService.selectPage(pageNum, pageSize, recordName, recordType, recordStatus);
return Result.success(pageBean);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个记录信息", description = "根据记录信息ID查询详情")
public Result getRecordInfoById(@PathVariable Long id) {
RecordInfo recordInfo = recordInfoService.selectById(id);
return recordInfo != null ? Result.success(recordInfo) : Result.error("记录信息不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增记录信息", description = "记录名称、类型、内容为必填项类型1-设备异常2-样品异常3-操作异常)")
public Result addRecordInfo(@RequestBody RecordInfo recordInfo) {
try {
Long recordInfoId = recordInfoService.insert(recordInfo);
return Result.success(recordInfoId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改记录信息", description = "需传入记录信息ID其他字段可选非空则更新")
public Result updateRecordInfo(@RequestBody RecordInfo recordInfo) {
try {
Boolean success = recordInfoService.update(recordInfo);
return success ? Result.success(true) : Result.error("修改失败(记录信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除记录信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteRecordInfo(@PathVariable Long id) {
try {
Boolean success = recordInfoService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(记录信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,133 @@
package com.rczn.rcznautoplc.controller;
import com.github.pagehelper.PageInfo;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.rcznautoplc.domain.StepInfo;
import com.rczn.rcznautoplc.domain.query.StepInfoQuery;
import com.rczn.rcznautoplc.service.StepInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/stepInfo")
@Tag(name = "步骤信息管理", description = "步骤信息增删改查+分页查询接口")
public class StepInfoController {
@Autowired
StepInfoService stepInfoService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询步骤信息", description = "支持岛屿ID精准查询、步骤名称模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY)
})
public Result getStepInfoPage(
@ParameterObject // 核心注解:标记该实体类从查询参数取值
@Schema(description = "设备查询条件(可选)") // 补充描述
StepInfoQuery stepInfo,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize
) {
PageInfo<StepInfo> pageBean = stepInfoService.selectPage(pageNum, pageSize, stepInfo);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询步骤信息", description = "支持岛屿ID精准查询、步骤名称模糊查询")
public Result getStepInfoList(
@ParameterObject // 核心注解:标记该实体类从查询参数取值
@Schema(description = "设备查询条件(可选)") // 补充描述
StepInfoQuery stepInfo) {
List<StepInfo> list = stepInfoService.selectList( stepInfo);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个步骤信息", description = "根据步骤信息ID查询详情")
public Result getStepInfoById(@PathVariable Long id) {
StepInfo stepInfo = stepInfoService.selectById(id);
return stepInfo != null ? Result.success(stepInfo) : Result.error("步骤信息不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增步骤信息", description = "岛屿ID、步骤名称为必填项")
public Result addStepInfo(@RequestBody StepInfo stepInfo) {
try {
Long stepInfoId = stepInfoService.insert(stepInfo);
return Result.success(stepInfoId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PostMapping(value = "/batchAdd", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "批量新增步骤信息", description = "岛屿ID、步骤名称为必填项")
public Result batchAddStepInfo(@RequestBody List<StepInfo> stepInfoList) {
try {
stepInfoService.insertBatch(stepInfoList);
return Result.success(true);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
//批量更新步骤信息
@PostMapping(value = "/batchUpdate", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "批量更新步骤信息", description = "岛屿ID、步骤名称为必填项")
public Result batchUpdateStepInfo(@RequestBody List<StepInfo> stepInfoList) {
try {
stepInfoService.updateBatch(stepInfoList);
return Result.success(true);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改步骤信息", description = "需传入步骤信息ID其他字段可选非空则更新")
public Result updateStepInfo(@RequestBody StepInfo stepInfo) {
try {
Boolean success = stepInfoService.update(stepInfo);
return success ? Result.success(true) : Result.error("修改失败(步骤信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除步骤信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteStepInfo(@PathVariable Long id) {
try {
Boolean success = stepInfoService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(步骤信息不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
//批量删除步骤信息
@DeleteMapping(value = "/batchDel", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "批量删除步骤信息", description = "逻辑删除设置delSign=1不物理删除数据")
public Result batchDeleteStepInfo(@RequestBody List<Long> ids) {
try {
stepInfoService.deleteBatchByIds(ids);
return Result.success(true);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,23 @@
package com.rczn.rcznautoplc.controller;
import com.rczn.websocket.WebSocketServer;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/websocket")
@Tag(name = "websocket", description = "websocket接口")
public class WebSocketController {
@Autowired
private WebSocketServer webSocketServer;
@RequestMapping("/send/{message}")
public String send(@PathVariable("message") String message){
webSocketServer.onMessage(message,null);
return "success";
}
}

View File

@@ -0,0 +1,132 @@
package com.rczn.rcznautoplc.domain;
import com.rczn.domain.BaseBean;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
public class DevInfo extends BaseBean {
//功能岛外键
private Integer islandId;
//设备名称
private String devName;
//设备型号
private String devModel;
//plc映射地址
private Integer plcAddr;
//设备IP地址
private String ipAddr;
private Integer port;
private String protocolType;
private String company;
private Integer status; // 0-空闲1-运行4-故障
private Integer runModel;//0-手动模式1-自动模式
private String devDesc;
public DevInfo() {
}
public DevInfo(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public Integer getIslandId() {
return islandId;
}
public void setIslandId(Integer islandId) {
this.islandId = islandId;
}
public String getDevName() {
return devName;
}
public void setDevName(String devName) {
this.devName = devName;
}
public String getDevModel() {
return devModel;
}
public void setDevModel(String devModel) {
this.devModel = devModel;
}
public Integer getPlcAddr() {
return plcAddr;
}
public void setPlcAddr(Integer plcAddr) {
this.plcAddr = plcAddr;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getProtocolType() {
return protocolType;
}
public void setProtocolType(String protocolType) {
this.protocolType = protocolType;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getRunModel() {
return runModel;
}
public void setRunModel(Integer runModel) {
this.runModel = runModel;
}
public String getDevDesc() {
return devDesc;
}
public void setDevDesc(String devDesc) {
this.devDesc = devDesc;
}
}

View File

@@ -0,0 +1,119 @@
package com.rczn.rcznautoplc.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.rczn.domain.BaseBean;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
public class DevParam extends BaseBean {
private String devIds;
//字典类型-参数分类id
private Integer dicDataId;
private String paramName;
//plc映射地址
private Integer plcAddr;
private String paramValue;
private String paramType;
private String paramUnit;
private String formType;
private String paramDesc;
@JsonIgnore
private DevInfo devInfo;
public DevParam() {
}
public DevParam(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public String getDevIds() {
return devIds;
}
public void setDevIds(String devIds) {
this.devIds = devIds;
}
public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public String getParamValue() {
return paramValue;
}
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}
public String getParamType() {
return paramType;
}
public void setParamType(String paramType) {
this.paramType = paramType;
}
public Integer getPlcAddr() {
return plcAddr;
}
public void setPlcAddr(Integer plcAddr) {
this.plcAddr = plcAddr;
}
public Integer getDicDataId() {
return dicDataId;
}
public void setDicDataId(Integer dicDataId) {
this.dicDataId = dicDataId;
}
public String getParamUnit() {
return paramUnit;
}
public void setParamUnit(String paramUnit) {
this.paramUnit = paramUnit;
}
public String getFormType() {
return formType;
}
public void setFormType(String formType) {
this.formType = formType;
}
public String getParamDesc() {
return paramDesc;
}
public void setParamDesc(String paramDesc) {
this.paramDesc = paramDesc;
}
public DevInfo getDevInfo() {
return devInfo;
}
public void setDevInfo(DevInfo devInfo) {
this.devInfo = devInfo;
}
}

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