init
This commit is contained in:
65
.gitignore
vendored
Normal file
65
.gitignore
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store*
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Editor Files #
|
||||
################
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# Build output directies
|
||||
/target
|
||||
**/test-output
|
||||
**/target
|
||||
**/bin
|
||||
build
|
||||
*/build
|
||||
.m2
|
||||
|
||||
# IntelliJ specific files/directories
|
||||
out
|
||||
.idea
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Eclipse specific files/directories
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.metadata
|
||||
.factorypath
|
||||
.generated
|
||||
|
||||
#font
|
||||
*.ttc
|
||||
|
||||
|
||||
BIN
.gradle/6.4.1/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/6.4.1/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/6.4.1/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/fileChanges/last-build.bin
Normal file
BIN
.gradle/6.4.1/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/fileContent/fileContent.lock
Normal file
BIN
.gradle/6.4.1/fileContent/fileContent.lock
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/6.4.1/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/6.4.1/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/6.4.1/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/6.4.1/gc.properties
Normal file
0
.gradle/6.4.1/gc.properties
Normal file
BIN
.gradle/6.4.1/javaCompile/classAnalysis.bin
Normal file
BIN
.gradle/6.4.1/javaCompile/classAnalysis.bin
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/javaCompile/jarAnalysis.bin
Normal file
BIN
.gradle/6.4.1/javaCompile/jarAnalysis.bin
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/javaCompile/javaCompile.lock
Normal file
BIN
.gradle/6.4.1/javaCompile/javaCompile.lock
Normal file
Binary file not shown.
BIN
.gradle/6.4.1/javaCompile/taskHistory.bin
Normal file
BIN
.gradle/6.4.1/javaCompile/taskHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
#Sat Jul 11 23:56:44 CST 2020
|
||||
gradle.version=6.4.1
|
||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
BIN
.gradle/checksums/checksums.lock
Normal file
BIN
.gradle/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/checksums/md5-checksums.bin
Normal file
BIN
.gradle/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
<<<<<<< HEAD
|
||||
#ipsm-sced
|
||||
=======
|
||||
# fx-falsework
|
||||
基于javafx、spring boot 开发的客户端与服务端系统开发脚手架
|
||||
>>>>>>> 81a2173cfca6f001994b84cf6f6997432fea415d
|
||||
16
build.gradle
Normal file
16
build.gradle
Normal file
@@ -0,0 +1,16 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group 'org.example'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
|
||||
|
||||
}
|
||||
50
client/build.gradle
Normal file
50
client/build.gradle
Normal file
@@ -0,0 +1,50 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group 'org.epri.fx.client'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':server')
|
||||
// implementation 'com.jfoenix:jfoenix:8.0.10'
|
||||
// compile 'com.airhacks:afterburner.fx:1.7.0'
|
||||
compile 'de.jensd:fontawesomefx:8.9'
|
||||
compile 'org.apache.lucene:lucene-core:7.4.0'
|
||||
compile 'org.apache.lucene:lucene-grouping:7.4.0'
|
||||
compile 'org.apache.lucene:lucene-queryparser:7.4.0'
|
||||
compile 'dom4j:dom4j:1.6.1'
|
||||
|
||||
|
||||
compile 'org.controlsfx:controlsfx:8.40.17'
|
||||
compile group: 'org.javassist', name: 'javassist', version: '3.18.1-GA'
|
||||
compile group: 'com.guigarage', name: 'observable-toogles', version: '0.1'
|
||||
compile group: 'javax.inject', name: 'javax.inject', version: '1'
|
||||
compile files('libs/datafx-injection-8.0.2-SNAPSHOT.jar')
|
||||
compile files('libs/datafx-eventsystem-8.0.2-SNAPSHOT.jar')
|
||||
compile files('libs/datafx-core-8.0.2-SNAPSHOT.jar')
|
||||
compile files('libs/datafx-flow-8.0.2-SNAPSHOT.jar')
|
||||
compile files('libs/jfoenix-8.0.10.jar')
|
||||
compile files('libs/pinyin4j-2.5.0.jar')
|
||||
compile files('libs/tilesfx-1.6.8.jar')
|
||||
|
||||
|
||||
compile 'org.kordamp.ikonli:ikonli-javafx:2.4.0'
|
||||
compile 'org.kordamp.ikonli:ikonli-fontawesome5-pack:2.4.0'
|
||||
compile 'io.github.openfeign:feign-core:10.9'
|
||||
compile 'io.github.openfeign:feign-okhttp:10.9'
|
||||
compile 'io.github.openfeign:feign-jackson:10.9'
|
||||
compile 'io.github.openfeign:feign-hystrix:10.9'
|
||||
compile 'io.github.openfeign:feign-ribbon:10.9'
|
||||
compile 'io.github.openfeign:feign-slf4j:10.9'
|
||||
compile 'com.netflix.ribbon:ribbon-httpclient:2.2.0'
|
||||
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
implementation 'org.apache.commons:commons-lang3:3.4'
|
||||
|
||||
|
||||
}
|
||||
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT-javadoc.jar
Normal file
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT-sources.jar
Normal file
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT.jar
Normal file
BIN
client/libs/datafx-core-8.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT-javadoc.jar
Normal file
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT-sources.jar
Normal file
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT.jar
Normal file
BIN
client/libs/datafx-eventsystem-8.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-featuretoggle-8.0.2-SNAPSHOT.jar
Normal file
BIN
client/libs/datafx-featuretoggle-8.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT-javadoc.jar
Normal file
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT-sources.jar
Normal file
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT.jar
Normal file
BIN
client/libs/datafx-flow-8.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT-javadoc.jar
Normal file
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT-sources.jar
Normal file
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT.jar
Normal file
BIN
client/libs/datafx-injection-8.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
client/libs/jfoenix-8.0.10.jar
Normal file
BIN
client/libs/jfoenix-8.0.10.jar
Normal file
Binary file not shown.
BIN
client/libs/pinyin4j-2.5.0.jar
Normal file
BIN
client/libs/pinyin4j-2.5.0.jar
Normal file
Binary file not shown.
BIN
client/libs/tilesfx-1.6.8.jar
Normal file
BIN
client/libs/tilesfx-1.6.8.jar
Normal file
Binary file not shown.
99
client/src/main/java/com/epri/fx/client/AppStartup.java
Normal file
99
client/src/main/java/com/epri/fx/client/AppStartup.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package com.epri.fx.client;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.control.LFXDecorator;
|
||||
import com.epri.fx.client.gui.uicomponents.login.LoginController;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.jfoenix.assets.JFoenixResources;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import io.datafx.controller.context.ApplicationContext;
|
||||
import io.datafx.controller.flow.Flow;
|
||||
import io.datafx.controller.flow.FlowHandler;
|
||||
import io.datafx.controller.flow.container.AnimatedFlowContainer;
|
||||
import io.datafx.controller.flow.container.ContainerAnimations;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: AppStartup
|
||||
* @author: liwen
|
||||
* @date: 2019-08-26 16:24
|
||||
*/
|
||||
public class AppStartup extends Application {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
|
||||
InputStream in = AppStartup.class.getClassLoader().getResourceAsStream("fonts/msyh.ttf");
|
||||
Font font1 = Font.loadFont(in, 12);
|
||||
|
||||
System.err.println(font1.getName()+"\t"+font1.getFamily());
|
||||
ConfigurationManager.loadPropertiesFromResources("sample-client.properties");
|
||||
//
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
|
||||
String keyPrefix = "";
|
||||
// //全局样式
|
||||
// setUserAgentStylesheet(null);
|
||||
// StyleManager.getInstance().addUserAgentStylesheet("css/app.css");
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
SVGGlyphLoader.loadGlyphsFont(AppStartup.class.getResourceAsStream("/fonts/icon_font/iconfont.svg"),
|
||||
ApplicatonStore.ICON_FONT_KEY);
|
||||
// SVGGlyphLoader.loadGlyphsFont(AppStartup.class.getResourceAsStream("/fonts/icon_font/icon-font-solid.svg"),
|
||||
// "IconFontSolid.svg");
|
||||
} catch (IOException ioExc) {
|
||||
ioExc.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
ApplicationContext.getInstance().register(stage, Stage.class);
|
||||
|
||||
Flow flow = new Flow(LoginController.class);
|
||||
FlowHandler flowHandler = flow.createHandler();
|
||||
StackPane rootPane = flowHandler.start(new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.SWIPE_LEFT));
|
||||
|
||||
ApplicationContext.getInstance().register("mainFlowHandler", flowHandler);
|
||||
ApplicationContext.getInstance().register(rootPane, StackPane.class);
|
||||
|
||||
LFXDecorator wfxDecorator = new LFXDecorator(stage, rootPane, false, true, true);
|
||||
wfxDecorator.setCustomMaximize(true);
|
||||
wfxDecorator.setGraphic(new SVGGlyph(""));
|
||||
|
||||
Scene scene = new Scene(wfxDecorator, 1000, 700);
|
||||
stage.setTitle("JavaFX Welcome");
|
||||
scene.setFill(Color.TRANSPARENT);
|
||||
stage.setScene(scene);
|
||||
stage.show();
|
||||
|
||||
|
||||
scene.getStylesheets().addAll(JFoenixResources.load("/css/app-fonts.css").toExternalForm(),AppStartup.class.getResource("/css/app.css").toExternalForm());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
|
||||
System.err.println(Font.getFontNames());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2017 by Gerrit Grunwald
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.epri.fx.client.bean;
|
||||
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hansolo on 21.12.16.
|
||||
*/
|
||||
public class CountryPath extends SVGPath {
|
||||
private String name;
|
||||
private Locale locale;
|
||||
private Tooltip tooltip;
|
||||
|
||||
|
||||
// ******************** Constructors **************************************
|
||||
public CountryPath() {
|
||||
this("", null);
|
||||
}
|
||||
|
||||
public CountryPath(final String NAME) {
|
||||
this(NAME, null);
|
||||
}
|
||||
|
||||
public CountryPath(final String NAME, final String CONTENT) {
|
||||
super();
|
||||
name = NAME;
|
||||
locale = new Locale("", NAME);
|
||||
tooltip = new Tooltip(locale.getDisplayCountry());
|
||||
|
||||
Tooltip.install(this, tooltip);
|
||||
if (null == CONTENT) return;
|
||||
setContent(CONTENT);
|
||||
}
|
||||
|
||||
|
||||
// ******************** Methods *******************************************
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String NAME) {
|
||||
this.name = NAME;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(final Locale LOCALE) {
|
||||
locale = LOCALE;
|
||||
}
|
||||
|
||||
public Tooltip getTooltip() {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
public void setTooltip(final Tooltip TOOLTIP) {
|
||||
tooltip = TOOLTIP;
|
||||
Tooltip.install(this, tooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("{\n").append(" name :\"").append(name).append("\"\n")
|
||||
.append(" locale :\"").append(locale).append("\"\n")
|
||||
.append(" tooltip:\"").append(tooltip.getText()).append("\"\n")
|
||||
.append(" content:\"").append(getContent()).append("\"\n")
|
||||
.append("}\n")
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
50
client/src/main/java/com/epri/fx/client/bean/MenuVoCell.java
Normal file
50
client/src/main/java/com/epri/fx/client/bean/MenuVoCell.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.epri.fx.client.bean;
|
||||
|
||||
import com.epri.fx.server.entity.Menu;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: MenuVoCell
|
||||
* @author: liwen
|
||||
* @date: 2020/8/17 20:08
|
||||
*/
|
||||
|
||||
public class MenuVoCell {
|
||||
private ObjectProperty<MenuVO> menuVO;
|
||||
private ObservableList<MenuVO> childrenMenus;
|
||||
|
||||
public MenuVoCell(MenuVO menuVO, List<MenuVO> childrenMenus) {
|
||||
this.menuVO = new SimpleObjectProperty<>(menuVO);
|
||||
if (childrenMenus != null) {
|
||||
getChildrenMenus().addAll(childrenMenus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public MenuVO getMenuVO() {
|
||||
return menuVO.get();
|
||||
}
|
||||
|
||||
public ObjectProperty<MenuVO> menuVOProperty() {
|
||||
return menuVO;
|
||||
}
|
||||
|
||||
public ObservableList<MenuVO> getChildrenMenus() {
|
||||
if (childrenMenus == null) {
|
||||
ObservableList<MenuVO> innerList = FXCollections.observableArrayList();
|
||||
childrenMenus = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
|
||||
return childrenMenus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.epri.fx.client.exception;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: AppRunException
|
||||
* @author: liwen
|
||||
* @date: 2020/8/5 23:58
|
||||
*/
|
||||
public class AppRunException {
|
||||
|
||||
public static void showError(Thread t, Throwable e) {
|
||||
System.err.println("***Default exception handler***");
|
||||
if (Platform.isFxApplicationThread()) {
|
||||
showErrorDialog(e);
|
||||
} else {
|
||||
System.err.println("An unexpected error occurred in " + t);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void showErrorDialog(Throwable e) {
|
||||
StringWriter errorMsg = new StringWriter();
|
||||
e.printStackTrace();
|
||||
// e.printStackTrace(new PrintWriter(errorMsg));
|
||||
|
||||
// Stage dialog = new Stage();
|
||||
// dialog.initModality(Modality.APPLICATION_MODAL);
|
||||
// FXMLLoader loader = new FXMLLoader(Main.class.getResource("Error.fxml"));
|
||||
// try {
|
||||
// Parent root = loader.load();
|
||||
// ((ErrorController)loader.getController()).setErrorText(errorMsg.toString());
|
||||
// dialog.setScene(new Scene(root, 250, 400));
|
||||
// dialog.show();
|
||||
// } catch (IOException exc) {
|
||||
// exc.printStackTrace();
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.epri.fx.client.gui.feature;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DisabledByFeature {
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.epri.fx.client.gui.feature;
|
||||
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.Node;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class FeatureHandler {
|
||||
|
||||
private static FeatureHandler instance;
|
||||
|
||||
private Map<String, String> permissionInfoMap;
|
||||
|
||||
private FeatureHandler() {
|
||||
}
|
||||
|
||||
public static synchronized FeatureHandler getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FeatureHandler();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void hideByFeature(Node node, String featureName) {
|
||||
node.visibleProperty().bind(new SimpleBooleanProperty(ApplicatonStore.getFeatureMap().get(featureName)!=null));
|
||||
node.managedProperty().bind(node.visibleProperty());
|
||||
}
|
||||
|
||||
public void disableByFeature(Node node, String featureName) {
|
||||
node.disableProperty().bind(new SimpleBooleanProperty(ApplicatonStore.getFeatureMap().get(featureName)!=null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.epri.fx.client.gui.feature;
|
||||
|
||||
import io.datafx.controller.ViewNode;
|
||||
import io.datafx.controller.injection.scopes.ApplicationScoped;
|
||||
import io.datafx.core.DataFXUtils;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ApplicationScoped
|
||||
public class FeatureResourceConsumer {
|
||||
|
||||
public void consumeResource(Object object) {
|
||||
|
||||
Class<? extends Object> cls = object.getClass();
|
||||
for (final Field field : DataFXUtils.getInheritedDeclaredFields(cls)) {
|
||||
|
||||
if (field.getAnnotation(FXML.class) != null || field.getAnnotation(ViewNode.class) != null) {
|
||||
|
||||
List<Annotation> fieldAnnotations = Arrays.asList(field.getAnnotations());
|
||||
|
||||
for (Annotation annotation : fieldAnnotations) {
|
||||
if (annotation instanceof DisabledByFeature) {
|
||||
FeatureHandler.getInstance().disableByFeature(DataFXUtils.getPrivileged(field, object), ((DisabledByFeature) annotation).value());
|
||||
} else if (annotation instanceof HideByFeature) {
|
||||
FeatureHandler.getInstance().hideByFeature(DataFXUtils.getPrivileged(field, object), ((HideByFeature) annotation).value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.epri.fx.client.gui.feature;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface HideByFeature {
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.group;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.admin.group.components.GroupDetailController;
|
||||
import com.epri.fx.client.model.GroupDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.GroupTypeFeign;
|
||||
import com.epri.fx.server.vo.GroupTypeVO;
|
||||
import com.jfoenix.controls.JFXTabPane;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.Flow;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.context.ViewFlowContext;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import io.datafx.eventsystem.Event;
|
||||
import io.datafx.eventsystem.OnEvent;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.StackPane;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: GroupManagementController
|
||||
* @author: liwen
|
||||
* @date: 2020/7/22 15:09
|
||||
*/
|
||||
@ViewController(value = "/fxml/admin/group/group_management.fxml", title = "角色权限管理")
|
||||
public class GroupManagementController {
|
||||
|
||||
|
||||
@FXML
|
||||
private JFXTabPane tabPane;
|
||||
|
||||
@FXML
|
||||
private StackPane rootPane;
|
||||
@Inject
|
||||
private GroupDataModel groupDataModel;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
||||
TextField textField = new TextField();
|
||||
textField.setStyle("");
|
||||
|
||||
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Tab> observable, Tab oldValue, Tab newValue) {
|
||||
// groupDataModel.setSelectedGroupType(newValue.);
|
||||
}
|
||||
});
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).getAllGroupTypes())
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
for (GroupTypeVO groupType : rel) {
|
||||
|
||||
Tab tab = new Tab(groupType.getName());
|
||||
Flow flow = new Flow(GroupDetailController.class);
|
||||
ViewFlowContext viewFlowContext = new ViewFlowContext();
|
||||
viewFlowContext.register("groupType", groupType.getId());
|
||||
viewFlowContext.register("rootPane", rootPane);
|
||||
try {
|
||||
tab.setContent(flow.createHandler(viewFlowContext).start());
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
tabPane.getTabs().add(tab);
|
||||
}
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
@OnEvent("test-message")
|
||||
private void onNewChatMessage(Event<String> e) {
|
||||
System.err.println(this.getClass() + "\t" + e.getContent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,703 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.group.components;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.control.FilterableCheckBoxTreeItem;
|
||||
import com.epri.fx.client.gui.uicomponents.control.FilterableTreeItem;
|
||||
import com.epri.fx.client.gui.uicomponents.control.TreeItemPredicate;
|
||||
import com.epri.fx.client.model.GroupDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.GroupFeign;
|
||||
import com.epri.fx.client.request.feign.admin.MenuFeign;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.utils.Pinyin4jUtil;
|
||||
import com.epri.fx.server.entity.User;
|
||||
import com.epri.fx.server.vo.ElementVO;
|
||||
import com.epri.fx.server.vo.GroupVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import com.jfoenix.controls.*;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.context.FXMLViewFlowContext;
|
||||
import io.datafx.controller.flow.context.ViewFlowContext;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import io.datafx.eventsystem.Event;
|
||||
import io.datafx.eventsystem.OnEvent;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.CheckBoxTableCell;
|
||||
import javafx.scene.control.cell.CheckBoxTreeCell;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: GroupDetail
|
||||
* @author: liwen
|
||||
* @date: 2020/7/22 16:17
|
||||
*/
|
||||
@ViewController(value = "/fxml/admin/group/components/group_detail.fxml", title = "test")
|
||||
public class GroupDetailController {
|
||||
|
||||
|
||||
@FXML
|
||||
private VBox contentPane;
|
||||
@FXML
|
||||
private JFXChipView<User> leaderChipView;
|
||||
@FXML
|
||||
private JFXChipView<User> memberChipView;
|
||||
@FXML
|
||||
private JFXDialog groupAuthorityDialog;
|
||||
@FXML
|
||||
private JFXDialog groupUserDialog;
|
||||
@FXML
|
||||
private JFXProgressBar progressBar;
|
||||
@FXML
|
||||
@ActionTrigger("saveAuthority")
|
||||
private JFXButton saveAuthorityButton;
|
||||
@FXML
|
||||
@ActionTrigger("selectAllElement")
|
||||
private JFXCheckBox selectAllCheckBox;
|
||||
@FXML
|
||||
@ActionTrigger("handlerAuthority")
|
||||
private ToggleButton handlerAuthorityButton;
|
||||
@FXML
|
||||
@ActionTrigger("handlerUser")
|
||||
private ToggleButton handlerUserButton;
|
||||
@FXML
|
||||
@ActionTrigger("addGroup")
|
||||
private ToggleButton addButton;
|
||||
@FXML
|
||||
@ActionTrigger("editGroup")
|
||||
private ToggleButton editButton;
|
||||
@FXML
|
||||
@ActionTrigger("deleteGroup")
|
||||
private ToggleButton deleteButton;
|
||||
@FXML
|
||||
@ActionTrigger("cancelGroup")
|
||||
private JFXButton cancelButton;
|
||||
@FXML
|
||||
@ActionTrigger("createGroup")
|
||||
private JFXButton defineButton;
|
||||
@FXML
|
||||
@ActionTrigger("updateGroup")
|
||||
private JFXButton updateButton;
|
||||
@FXML
|
||||
@ActionTrigger("cancelAuthority")
|
||||
private JFXButton cancelAuthorityButton;
|
||||
@FXML
|
||||
@ActionTrigger("cancelUser")
|
||||
private JFXButton cancelUserButton;
|
||||
@FXML
|
||||
@ActionTrigger("modifiyUsers")
|
||||
private JFXButton saveUserButton;
|
||||
@FXML
|
||||
private JFXTextField treeSearchTextField;
|
||||
@FXML
|
||||
private JFXTextField nameTextField;
|
||||
@FXML
|
||||
private JFXTextField codeTextField;
|
||||
@FXML
|
||||
private JFXTextArea descTextArea;
|
||||
@FXML
|
||||
private ButtonBar buttonBar;
|
||||
@FXML
|
||||
private JFXTreeView treeView;
|
||||
@Inject
|
||||
private GroupDataModel groupDataModel;
|
||||
|
||||
@FXMLViewFlowContext
|
||||
private ViewFlowContext viewFlowContext;
|
||||
|
||||
|
||||
@FXML
|
||||
private JFXTextField menuTreeSearchTextField;
|
||||
@FXML
|
||||
private JFXTreeView menuTreeView;
|
||||
@FXML
|
||||
private TableView elementTableView;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, Boolean> selColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> serialNumberColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> codeColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> typeColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> nameColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> addressColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> requestTypeColumn;
|
||||
|
||||
private Integer groupType;
|
||||
private Integer groupId = -1;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
final ToggleGroup group = new ToggleGroup();
|
||||
|
||||
addButton.setToggleGroup(group);
|
||||
editButton.setToggleGroup(group);
|
||||
deleteButton.setToggleGroup(group);
|
||||
handlerAuthorityButton.setToggleGroup(group);
|
||||
handlerUserButton.setToggleGroup(group);
|
||||
try {
|
||||
addButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".add-circle-outline"));
|
||||
editButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".create-outline"));
|
||||
deleteButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".trash-outline"));
|
||||
handlerAuthorityButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".quanxianfenpei"));
|
||||
handlerUserButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".yonghugl"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
buttonBar.managedProperty().bind(buttonBar.visibleProperty());
|
||||
contentPane.disableProperty().bind(buttonBar.visibleProperty().not());
|
||||
defineButton.managedProperty().bind(defineButton.visibleProperty());
|
||||
updateButton.visibleProperty().bind(defineButton.visibleProperty().not());
|
||||
updateButton.managedProperty().bind(updateButton.visibleProperty());
|
||||
progressBar.visibleProperty().bind(buttonBar.disableProperty().and(buttonBar.visibleProperty()));
|
||||
progressBar.managedProperty().bind(progressBar.visibleProperty());
|
||||
groupType = (Integer) viewFlowContext.getRegisteredObject("groupType");
|
||||
|
||||
serialNumberColumn.setCellFactory((col) -> {
|
||||
TableCell<ElementVO, String> cell = new TableCell<ElementVO, String>() {
|
||||
@Override
|
||||
public void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
this.setText(null);
|
||||
this.setGraphic(null);
|
||||
|
||||
if (!empty) {
|
||||
int rowIndex = this.getIndex() + 1;
|
||||
this.setText(String.valueOf(rowIndex));
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
});
|
||||
selColumn.setCellValueFactory(new PropertyValueFactory<>("sel"));
|
||||
selColumn.setCellFactory(new Callback<TableColumn<ElementVO, Boolean>, //
|
||||
TableCell<ElementVO, Boolean>>() {
|
||||
@Override
|
||||
public TableCell<ElementVO, Boolean> call(TableColumn<ElementVO, Boolean> p) {
|
||||
CheckBoxTableCell<ElementVO, Boolean> cell = new CheckBoxTableCell<ElementVO, Boolean>() {
|
||||
@Override
|
||||
public void updateItem(Boolean item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
CheckBox cb = (CheckBox) getGraphic();
|
||||
JFXCheckBox checkBox = new JFXCheckBox();
|
||||
checkBox.indeterminateProperty().bindBidirectional(cb.indeterminateProperty());
|
||||
checkBox.selectedProperty().bindBidirectional(cb.selectedProperty());
|
||||
setGraphic(checkBox);
|
||||
}
|
||||
}
|
||||
};
|
||||
cell.setAlignment(Pos.CENTER);
|
||||
return cell;
|
||||
}
|
||||
|
||||
});
|
||||
codeColumn.setCellValueFactory(cellData -> cellData.getValue().codeProperty());
|
||||
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
|
||||
typeColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
|
||||
addressColumn.setCellValueFactory(new PropertyValueFactory<>("uri"));
|
||||
requestTypeColumn.setCellValueFactory(new PropertyValueFactory<>("method"));
|
||||
|
||||
treeView.setCellFactory(new Callback<TreeView, TreeCell>() {
|
||||
@Override
|
||||
public TreeCell<GroupVO> call(TreeView param) {
|
||||
return new TreeCell<GroupVO>() {
|
||||
@Override
|
||||
protected void updateItem(GroupVO menu, boolean empty) {
|
||||
super.updateItem(menu, empty);
|
||||
if (!empty && menu != null) {
|
||||
setText(menu.getName());
|
||||
} else {
|
||||
setText(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
menuTreeView.setCellFactory(new Callback<TreeView, CheckBoxTreeCell>() {
|
||||
@Override
|
||||
public CheckBoxTreeCell<MenuVO> call(TreeView param) {
|
||||
return new CheckBoxTreeCell<MenuVO>() {
|
||||
@Override
|
||||
public void updateItem(MenuVO item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (!empty && item != null) {
|
||||
|
||||
setText(item.getTitle());
|
||||
CheckBox cb = (CheckBox) getGraphic();
|
||||
JFXCheckBox checkBox = new JFXCheckBox();
|
||||
checkBox.indeterminateProperty().bindBidirectional(cb.indeterminateProperty());
|
||||
checkBox.selectedProperty().bindBidirectional(cb.selectedProperty());
|
||||
setGraphic(checkBox);
|
||||
} else {
|
||||
setText(null);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
});
|
||||
menuTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<MenuVO>>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends TreeItem<MenuVO>> observable, TreeItem<MenuVO> oldValue, TreeItem<MenuVO> newValue) {
|
||||
|
||||
if (newValue.isLeaf()) {
|
||||
MenuVO menuVO = newValue.getValue();
|
||||
groupDataModel.setSelectedMenuVO(menuVO);
|
||||
elementTableView.setItems(groupDataModel.getElementVOS());
|
||||
} else {
|
||||
groupDataModel.getElementVOS().clear();
|
||||
}
|
||||
|
||||
int sel = 0;
|
||||
if (groupDataModel.getElementVOS().isEmpty()) {
|
||||
sel=-1;
|
||||
}
|
||||
for (ElementVO elementVO : groupDataModel.getElementVOS()) {
|
||||
|
||||
if (elementVO.isSel() == false) {
|
||||
sel = -1;
|
||||
break;
|
||||
} else {
|
||||
sel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selectAllCheckBox.setSelected(sel==groupDataModel.getElementVOS().size());
|
||||
|
||||
}
|
||||
});
|
||||
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<GroupVO>>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends TreeItem<GroupVO>> observable, TreeItem<GroupVO> oldValue, TreeItem<GroupVO> newValue) {
|
||||
|
||||
updateMenuInfo(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
leaderChipView.setChipFactory((emailJFXChipView, email) -> new JFXDefaultChip<User>(emailJFXChipView, email) {
|
||||
{
|
||||
if (getItem() != null) {
|
||||
try {
|
||||
Node image = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".user-tie");
|
||||
image.getStyleClass().add("chip-icon");
|
||||
root.getChildren().add(0, image);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
leaderChipView.setPredicate((user, val) -> {
|
||||
|
||||
val = Pinyin4jUtil.toPinYinLowercase(val);
|
||||
return Pinyin4jUtil.toPinYinLowercase(user.getName()).contains(val);
|
||||
});
|
||||
|
||||
memberChipView.setPredicate((user, val) -> {
|
||||
|
||||
val = Pinyin4jUtil.toPinYinLowercase(val);
|
||||
return Pinyin4jUtil.toPinYinLowercase(user.getName()).contains(val);
|
||||
});
|
||||
|
||||
|
||||
memberChipView.setChipFactory((emailJFXChipView, email) -> new JFXDefaultChip<User>(emailJFXChipView, email) {
|
||||
{
|
||||
if (getItem() != null) {
|
||||
try {
|
||||
Node image = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".user");
|
||||
image.getStyleClass().add("chip-icon");
|
||||
root.getChildren().add(0, image);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
leaderChipView.setSuggestionsCellFactory(param -> new JFXListCell<>());
|
||||
memberChipView.setSuggestionsCellFactory(param -> new JFXListCell<>());
|
||||
|
||||
initLoadData();
|
||||
|
||||
}
|
||||
|
||||
private void initLoadData() {
|
||||
|
||||
loadingTreeData();
|
||||
|
||||
}
|
||||
|
||||
private void loadingTreeData() {
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).getGroupList(groupType))
|
||||
.addConsumerInPlatformThread(rel -> buildGroupTree(rel)).onException(e -> e.printStackTrace()).run();
|
||||
}
|
||||
|
||||
private void updateMenuInfo(TreeItem<GroupVO> newValue) {
|
||||
buttonBar.setVisible(false);
|
||||
if (newValue == null) {
|
||||
groupId = -1;
|
||||
groupDataModel.setSelectedGroup(null);
|
||||
return;
|
||||
}
|
||||
|
||||
GroupVO groupVO = newValue.getValue();
|
||||
groupDataModel.setSelectedGroup(groupVO);
|
||||
groupId = groupVO.getId();
|
||||
codeTextField.textProperty().unbind();
|
||||
codeTextField.textProperty().bind(groupVO.codeProperty());
|
||||
nameTextField.textProperty().unbind();
|
||||
nameTextField.textProperty().bind(groupVO.nameProperty());
|
||||
descTextArea.textProperty().unbind();
|
||||
descTextArea.textProperty().bind(groupVO.descriptionProperty());
|
||||
|
||||
}
|
||||
|
||||
private void buildMenuTree(List<MenuVO> menuVOList) {
|
||||
|
||||
|
||||
if (menuVOList.isEmpty()) {
|
||||
menuTreeView.setRoot(null);
|
||||
return;
|
||||
}
|
||||
groupDataModel.getMenuVOS().clear();
|
||||
for (MenuVO menuVO : menuVOList) {
|
||||
groupDataModel.getMenuVOS().add(menuVO);
|
||||
}
|
||||
|
||||
MenuVO root = menuVOList.stream().min(Comparator.comparing(MenuVO::getParentId)).get();
|
||||
Map<Integer, List<MenuVO>> map = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId));
|
||||
map.remove(root.getParentId());
|
||||
|
||||
FilterableCheckBoxTreeItem<MenuVO> rootNode = new FilterableCheckBoxTreeItem<MenuVO>(root);
|
||||
groupDataModel.setSelectedMenuVO(root);
|
||||
menuTreeView.setRoot(rootNode);
|
||||
menuTreeView.setShowRoot(false);
|
||||
addMenuChildrenNode(rootNode, map);
|
||||
rootNode.predicateProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
if (menuTreeSearchTextField.getText() == null || menuTreeSearchTextField.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return TreeItemPredicate.create(actor -> {
|
||||
String searchText = Pinyin4jUtil.toPinYinLowercase(menuTreeSearchTextField.getText());
|
||||
String itemText = Pinyin4jUtil.toPinYinLowercase(actor.getTitle());
|
||||
return itemText.contains(searchText);
|
||||
});
|
||||
}, menuTreeSearchTextField.textProperty()));
|
||||
menuTreeView.getSelectionModel().select(1);
|
||||
|
||||
rootNode.setExpanded(true);
|
||||
}
|
||||
|
||||
private void addMenuChildrenNode(FilterableCheckBoxTreeItem<MenuVO> parentNode, Map<Integer, List<MenuVO>> map) {
|
||||
|
||||
List<MenuVO> childrenList = map.get(parentNode.getValue().getId());
|
||||
|
||||
if (childrenList != null) {
|
||||
|
||||
for (MenuVO menu : childrenList) {
|
||||
|
||||
FilterableCheckBoxTreeItem<MenuVO> clildrenNode = new FilterableCheckBoxTreeItem<>(menu);
|
||||
clildrenNode.selectedProperty().bindBidirectional(menu.selProperty());
|
||||
parentNode.getInternalChildren().add(clildrenNode);
|
||||
addMenuChildrenNode(clildrenNode, map);
|
||||
}
|
||||
parentNode.setExpanded(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void buildGroupTree(List<GroupVO> groupVOList) {
|
||||
|
||||
if (groupVOList.isEmpty()) {
|
||||
treeView.setRoot(null);
|
||||
return;
|
||||
}
|
||||
Map<Integer, List<GroupVO>> map = groupVOList.stream().collect(Collectors.groupingBy(GroupVO::getParentId));
|
||||
GroupVO root = new GroupVO();
|
||||
root.setId(-1);
|
||||
|
||||
FilterableTreeItem<GroupVO> rootNode = new FilterableTreeItem<GroupVO>(root);
|
||||
treeView.setRoot(rootNode);
|
||||
treeView.setShowRoot(false);
|
||||
addChildrenNode(rootNode, map);
|
||||
rootNode.predicateProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
if (treeSearchTextField.getText() == null || treeSearchTextField.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return TreeItemPredicate.create(actor -> {
|
||||
String searchText = Pinyin4jUtil.toPinYinLowercase(treeSearchTextField.getText());
|
||||
String itemText = Pinyin4jUtil.toPinYinLowercase(actor.getName());
|
||||
return itemText.contains(searchText);
|
||||
});
|
||||
}, treeSearchTextField.textProperty()));
|
||||
rootNode.setExpanded(true);
|
||||
treeView.getSelectionModel().select(rootNode);
|
||||
}
|
||||
|
||||
private void addChildrenNode(FilterableTreeItem<GroupVO> parentNode, Map<Integer, List<GroupVO>> map) {
|
||||
|
||||
List<GroupVO> childrenList = map.get(parentNode.getValue().getId());
|
||||
|
||||
if (childrenList != null) {
|
||||
|
||||
for (GroupVO menu : childrenList) {
|
||||
|
||||
FilterableTreeItem<GroupVO> clildrenNode = new FilterableTreeItem<>(menu);
|
||||
parentNode.getInternalChildren().add(clildrenNode);
|
||||
parentNode.setExpanded(true);
|
||||
addChildrenNode(clildrenNode, map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("addGroup")
|
||||
private void addGroup() {
|
||||
codeTextField.textProperty().unbind();
|
||||
codeTextField.setText("");
|
||||
nameTextField.textProperty().unbind();
|
||||
nameTextField.setText("");
|
||||
descTextArea.textProperty().unbind();
|
||||
descTextArea.setText("");
|
||||
buttonBar.setVisible(true);
|
||||
defineButton.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("editGroup")
|
||||
private void editGroup() {
|
||||
codeTextField.textProperty().unbind();
|
||||
nameTextField.textProperty().unbind();
|
||||
descTextArea.textProperty().unbind();
|
||||
buttonBar.setVisible(true);
|
||||
defineButton.setVisible(false);
|
||||
}
|
||||
|
||||
@ActionMethod("cancelGroup")
|
||||
private void cancelGroup() {
|
||||
buttonBar.setVisible(false);
|
||||
}
|
||||
|
||||
@ActionMethod("createGroup")
|
||||
private void createGroup() {
|
||||
GroupVO groupVO = new GroupVO();
|
||||
groupVO.setParentId(groupId);
|
||||
groupVO.setGroupType(groupType);
|
||||
groupVO.setCode(codeTextField.getText());
|
||||
groupVO.setName(nameTextField.getText());
|
||||
groupVO.setDescription(descTextArea.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> buttonBar.setDisable(true)).addSupplierInExecutor(() -> Request.connector(GroupFeign.class).addGroup(groupVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
loadingTreeData();
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
buttonBar.setDisable(false);
|
||||
buttonBar.setVisible(false);
|
||||
})
|
||||
.run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("updateGroup")
|
||||
private void updateGroup() {
|
||||
GroupVO groupVO = new GroupVO();
|
||||
groupVO.setId(groupDataModel.getSelectedGroup().getId());
|
||||
groupVO.setParentId(groupDataModel.getSelectedGroup().getParentId());
|
||||
groupVO.setGroupType(groupType);
|
||||
groupVO.setCode(codeTextField.getText());
|
||||
groupVO.setName(nameTextField.getText());
|
||||
groupVO.setDescription(descTextArea.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> buttonBar.setDisable(true)).addSupplierInExecutor(() -> Request.connector(GroupFeign.class).updateGroup(groupVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
loadingTreeData();
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
buttonBar.setDisable(false);
|
||||
buttonBar.setVisible(false);
|
||||
})
|
||||
.run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("deleteGroup")
|
||||
private void deleteGroup() {
|
||||
GroupVO groupVO = groupDataModel.getSelectedGroup();
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) contentPane.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("消息提示"));
|
||||
layout.setBody(new Label("确实删除【" + groupVO.getName() + "】吗?"));
|
||||
JFXButton closeButton = new JFXButton("取消");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
JFXButton determineButton = new JFXButton("确定");
|
||||
determineButton.setOnAction(event -> {
|
||||
alert.hideWithAnimation();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).deleteGroup(groupVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
loadingTreeData();
|
||||
}
|
||||
}).onException(e -> e.printStackTrace())
|
||||
|
||||
.run();
|
||||
});
|
||||
layout.setActions(closeButton, determineButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("saveAuthority")
|
||||
private void saveAuthority() {
|
||||
|
||||
List<MenuVO> saveMenuList = new ArrayList<>();
|
||||
|
||||
for (MenuVO menuVO : groupDataModel.getMenuVOS()) {
|
||||
if (menuVO.isSel()) {
|
||||
saveMenuList.add(menuVO);
|
||||
List<ElementVO> elementList = menuVO.getElementVOS().stream().filter(elementVO -> elementVO.isSel()).collect(Collectors.toList());
|
||||
menuVO.getElementVOS().clear();
|
||||
menuVO.getElementVOS().addAll(elementList);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).modifyMenuAuthority(groupId, saveMenuList))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
groupDataModel.setSelectedMenuVO(new MenuVO());
|
||||
}
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.withFinal(() -> groupAuthorityDialog.close())
|
||||
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("cancelAuthority")
|
||||
private void cancelAuthorityButton() {
|
||||
groupAuthorityDialog.close();
|
||||
}
|
||||
|
||||
@ActionMethod("selectAllElement")
|
||||
private void selectAllElement() {
|
||||
|
||||
List<ElementVO> elementVOS = groupDataModel.getElementVOS();
|
||||
for (ElementVO elementVO : elementVOS) {
|
||||
elementVO.setSel(selectAllCheckBox.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
@ActionMethod("handlerAuthority")
|
||||
private void handlerAuthority() throws FlowException {
|
||||
groupAuthorityDialog.show((StackPane) viewFlowContext.getRegisteredObject("rootPane"));
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).getAuthorityMenuElementAll(groupId))
|
||||
.addConsumerInPlatformThread(rel -> buildMenuTree(rel)).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("cancelUser")
|
||||
private void cancelUser() throws FlowException {
|
||||
groupUserDialog.close();
|
||||
}
|
||||
|
||||
@ActionMethod("modifiyUsers")
|
||||
private void modifiyUsers() throws FlowException {
|
||||
|
||||
Set<Integer> ls = new HashSet<>();
|
||||
Set<Integer> ms = new HashSet<>();
|
||||
|
||||
for (User user : memberChipView.getChips()) {
|
||||
ms.add(user.getId());
|
||||
}
|
||||
for (User user : leaderChipView.getChips()) {
|
||||
ls.add(user.getId());
|
||||
}
|
||||
|
||||
Map<String, String> parmMap = new HashMap<>();
|
||||
parmMap.put("members", ms.toString());
|
||||
parmMap.put("leaders", ls.toString());
|
||||
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).modifiyUsers(groupId, parmMap))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
groupUserDialog.close();
|
||||
}
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("handlerUser")
|
||||
private void handlerUser() {
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
leaderChipView.getChips().clear();
|
||||
leaderChipView.getSuggestions().clear();
|
||||
memberChipView.getChips().clear();
|
||||
memberChipView.getSuggestions().clear();
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupFeign.class).getUsers(groupId))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
leaderChipView.getChips().addAll(rel.getLeaders());
|
||||
leaderChipView.getSuggestions().addAll(rel.getUsers());
|
||||
memberChipView.getChips().addAll(rel.getMembers());
|
||||
memberChipView.getSuggestions().addAll(rel.getUsers());
|
||||
}).withFinal(() -> groupUserDialog.show((StackPane) viewFlowContext.getRegisteredObject("rootPane")))
|
||||
.onException(e -> e.printStackTrace()).run();
|
||||
|
||||
}
|
||||
@OnEvent("test-message")
|
||||
private void onNewChatMessage(Event<String> e) {
|
||||
System.err.println(this.getClass() + "\t" + e.getContent());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.grouptype;
|
||||
|
||||
import com.epri.fx.client.model.GroupTypeDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.GroupTypeFeign;
|
||||
import com.epri.fx.client.request.feign.admin.UserFeign;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.utils.Pinyin4jUtil;
|
||||
import com.epri.fx.server.vo.GroupTypeVO;
|
||||
import com.jfoenix.controls.*;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.context.FXMLViewFlowContext;
|
||||
import io.datafx.controller.flow.context.ViewFlowContext;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: RoleRightsManagement
|
||||
* @author: liwen
|
||||
* @date: 2020/7/12 01:23
|
||||
*/
|
||||
@ViewController(value = "/fxml/admin/groupType/group_type_management.fxml", title = "角色类型管理")
|
||||
public class GroupTypeManagementController {
|
||||
|
||||
|
||||
@FXMLViewFlowContext
|
||||
private ViewFlowContext viewFlowContext;
|
||||
|
||||
@FXML
|
||||
private StackPane rootPane;
|
||||
@FXML
|
||||
private JFXProgressBar progressBar;
|
||||
@FXML
|
||||
private JFXDialog dialog;
|
||||
@FXML
|
||||
private Label title;
|
||||
@FXML
|
||||
private JFXButton searchButton;
|
||||
@FXML
|
||||
@ActionTrigger("createDialog")
|
||||
private JFXButton addButton;
|
||||
@FXML
|
||||
@ActionTrigger("closeDialog")
|
||||
private JFXButton cancelButton;
|
||||
@FXML
|
||||
@ActionTrigger("createGroupType")
|
||||
private JFXButton saveButton;
|
||||
@FXML
|
||||
@ActionTrigger("updateGroupType")
|
||||
private JFXButton updateButton;
|
||||
@FXML
|
||||
private JFXTextField searchField;
|
||||
@FXML
|
||||
private JFXTextField nameTextField;
|
||||
@FXML
|
||||
private JFXTextField codeTextField;
|
||||
@FXML
|
||||
private JFXTextArea descriptionTextArea;
|
||||
@FXML
|
||||
private TableView<GroupTypeVO> tableView;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> serialNumberColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> codeColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> nameColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> descriptionColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, Date> updTimeColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> updHostColumn;
|
||||
@FXML
|
||||
private TableColumn<GroupTypeVO, String> operatingColumn;
|
||||
@Inject
|
||||
private GroupTypeDataModel groupTypeDataModel;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
||||
progressBar.visibleProperty().bind(dialog.disableProperty());
|
||||
progressBar.managedProperty().bind(progressBar.visibleProperty());
|
||||
updateButton.visibleProperty().bind(saveButton.visibleProperty().not());
|
||||
updateButton.managedProperty().bind(updateButton.visibleProperty());
|
||||
cancelButton.disableProperty().bind(saveButton.disableProperty().or(updateButton.disableProperty()));
|
||||
|
||||
serialNumberColumn.setCellFactory((col) -> {
|
||||
TableCell<GroupTypeVO, String> cell = new TableCell<GroupTypeVO, String>() {
|
||||
@Override
|
||||
public void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
this.setText(null);
|
||||
this.setGraphic(null);
|
||||
|
||||
if (!empty) {
|
||||
int rowIndex = this.getIndex() + 1;
|
||||
this.setText(String.valueOf(rowIndex));
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
});
|
||||
|
||||
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
|
||||
codeColumn.setCellValueFactory(new PropertyValueFactory<>("code"));
|
||||
descriptionColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
|
||||
updTimeColumn.setCellValueFactory(new PropertyValueFactory<>("updTime"));
|
||||
updHostColumn.setCellValueFactory(new PropertyValueFactory<>("updHost"));
|
||||
|
||||
Callback<TableColumn<GroupTypeVO, String>, TableCell<GroupTypeVO, String>> cellFactory = new Callback<TableColumn<GroupTypeVO, String>, TableCell<GroupTypeVO, String>>() {
|
||||
@Override
|
||||
public TableCell<GroupTypeVO, String> call(TableColumn param) {
|
||||
|
||||
final TableCell<GroupTypeVO, String> cell = new TableCell<GroupTypeVO, String>() {
|
||||
|
||||
private final ToggleButton editBut = new ToggleButton();
|
||||
private final ToggleButton delBut = new ToggleButton();
|
||||
|
||||
{
|
||||
|
||||
|
||||
editBut.getStyleClass().add("left-pill");
|
||||
delBut.getStyleClass().add("right-pill");
|
||||
|
||||
try {
|
||||
editBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".create-outline"));
|
||||
delBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".trash-outline"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
editBut.setOnMouseClicked(event -> {
|
||||
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
updateDialog();
|
||||
});
|
||||
delBut.setOnMouseClicked(event -> {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
delete();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
HBox hBox = new HBox(editBut, delBut);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
hBox.setSpacing(0);
|
||||
setGraphic(hBox);
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
}
|
||||
};
|
||||
|
||||
operatingColumn.setCellFactory(cellFactory);
|
||||
|
||||
FilteredList<GroupTypeVO> filteredData = new FilteredList<>(groupTypeDataModel.getGroupTypes(), p -> true);
|
||||
tableView.setItems(filteredData);
|
||||
searchField.textProperty().addListener((o, oldVal, newVal) -> {
|
||||
filteredData.setPredicate(elementProp -> {
|
||||
if (newVal == null || newVal.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
String val = Pinyin4jUtil.toPinYinLowercase(newVal);
|
||||
return Pinyin4jUtil.toPinYinLowercase(elementProp.getName()).contains(val)
|
||||
|| Pinyin4jUtil.toPinYinLowercase(elementProp.getCode()).contains(val);
|
||||
});
|
||||
});
|
||||
|
||||
groupTypeDataModel.selectedIndexProperty().bind(tableView.getSelectionModel().selectedIndexProperty());
|
||||
|
||||
initData();
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
loadingTableData();
|
||||
}
|
||||
|
||||
private void loadingTableData() {
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).getAllGroupTypes())
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
groupTypeDataModel.getGroupTypes().clear();
|
||||
groupTypeDataModel.getGroupTypes().addAll(rel);})
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("closeDialog")
|
||||
private void closeDialog() {
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
@ActionMethod("createDialog")
|
||||
private void createDialog() {
|
||||
title.setText("新建");
|
||||
codeTextField.setText("");
|
||||
nameTextField.setText("");
|
||||
descriptionTextArea.setText("");
|
||||
saveButton.setVisible(true);
|
||||
dialog.show(rootPane);
|
||||
}
|
||||
|
||||
@ActionMethod("createGroupType")
|
||||
private void createGroupType() {
|
||||
|
||||
GroupTypeVO groupTypeVO = new GroupTypeVO();
|
||||
groupTypeVO.setCode(codeTextField.getText());
|
||||
groupTypeVO.setName(nameTextField.getText());
|
||||
groupTypeVO.setDescription(descriptionTextArea.getText());
|
||||
|
||||
ProcessChain.create().addRunnableInPlatformThread(() -> dialog.setDisable(true))
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).addGroupType(groupTypeVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >=0) {
|
||||
loadingTableData();
|
||||
}
|
||||
}).withFinal(() -> {
|
||||
dialog.setDisable(false);
|
||||
dialog.close();
|
||||
})
|
||||
.run();
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("updateGroupType")
|
||||
private void updateGroupType() {
|
||||
GroupTypeVO groupTypeVO = new GroupTypeVO();
|
||||
groupTypeVO.setId((groupTypeDataModel.getGroupTypes().get(groupTypeDataModel.getSelectedIndex())).getId());
|
||||
groupTypeVO.setCode(codeTextField.getText());
|
||||
groupTypeVO.setName(nameTextField.getText());
|
||||
groupTypeVO.setDescription(descriptionTextArea.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> dialog.setDisable(true))
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).updateGroupType(groupTypeVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel > -0) {
|
||||
loadingTableData();
|
||||
}
|
||||
}).withFinal(() -> {
|
||||
dialog.setDisable(false);
|
||||
dialog.close();
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
private void delete() {
|
||||
GroupTypeVO groupTypeVO = groupTypeDataModel.getGroupTypes().get(groupTypeDataModel.getSelectedIndex());
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) rootPane.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("消息提示"));
|
||||
layout.setBody(new Label("确实删除【" + groupTypeVO.getName() + "】吗?"));
|
||||
JFXButton closeButton = new JFXButton("取消");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
JFXButton determineButton = new JFXButton("确定");
|
||||
determineButton.setOnAction(event -> {
|
||||
alert.hideWithAnimation();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).deleteGroupTypes(groupTypeVO.getId()))
|
||||
.addConsumerInPlatformThread(result -> {
|
||||
if (result >= 0) {
|
||||
groupTypeDataModel.getGroupTypes().remove(groupTypeDataModel.getSelectedIndex());
|
||||
}
|
||||
}).onException(e -> e.printStackTrace()).run();
|
||||
});
|
||||
layout.setActions(closeButton, determineButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
|
||||
}
|
||||
|
||||
private void updateDialog() {
|
||||
title.setText("编辑");
|
||||
saveButton.setVisible(false);
|
||||
GroupTypeVO groupTypeVO = groupTypeDataModel.getGroupTypes().get(groupTypeDataModel.getSelectedIndex());
|
||||
codeTextField.setText(groupTypeVO.getCode());
|
||||
nameTextField.setText(groupTypeVO.getName());
|
||||
descriptionTextArea.setText(groupTypeVO.getDescription());
|
||||
dialog.show(rootPane);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,693 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.menu;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.control.FilterableTreeItem;
|
||||
import com.epri.fx.client.gui.uicomponents.control.TreeItemPredicate;
|
||||
import com.epri.fx.client.model.MenuDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.ElementFeign;
|
||||
import com.epri.fx.client.request.feign.admin.MenuFeign;
|
||||
import com.epri.fx.client.request.feign.admin.UserFeign;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.utils.Pinyin4jUtil;
|
||||
import com.epri.fx.server.entity.Element;
|
||||
import com.epri.fx.server.msg.TableResultResponse;
|
||||
import com.epri.fx.server.vo.ElementVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import com.jfoenix.controls.*;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import io.datafx.eventsystem.Event;
|
||||
import io.datafx.eventsystem.OnEvent;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserManagement
|
||||
* @author: liwen
|
||||
* @date: 2020/6/30 22:37
|
||||
*/
|
||||
@ViewController(value = "/fxml/admin/menu/menu_management.fxml", title = "菜单管理")
|
||||
public class MenuManagementController {
|
||||
|
||||
private static final String[] METHOD_OPTIONS = {"GET", "POST", "PUT", "DELETE"};
|
||||
private static final String[] TYPE_OPTIONS = {"uri", "button"};
|
||||
|
||||
@FXML
|
||||
private StackPane rootPane;
|
||||
@FXML
|
||||
private VBox infoPane;
|
||||
@FXML
|
||||
private TableView<ElementVO> tableView;
|
||||
@FXML
|
||||
private TreeView treeView;
|
||||
@FXML
|
||||
private VBox treePane;
|
||||
@FXML
|
||||
private JFXSpinner treeViewSpinner;
|
||||
@FXML
|
||||
private JFXTextField treeSearchTextField;
|
||||
@FXML
|
||||
private JFXProgressBar elementProgressBar;
|
||||
//menu
|
||||
@FXML
|
||||
private JFXTextField titleTextField;
|
||||
@FXML
|
||||
private JFXTextField codeTextField;
|
||||
@FXML
|
||||
private JFXTextField orderNumTextField;
|
||||
@FXML
|
||||
private JFXTextField parentIdTextField;
|
||||
@FXML
|
||||
private JFXTextField iconTextField;
|
||||
@FXML
|
||||
private JFXTextArea descriptionTextAre;
|
||||
@FXML
|
||||
private JFXTextField hrefTextFeild;
|
||||
|
||||
//element
|
||||
@FXML
|
||||
private VBox elementPane;
|
||||
@FXML
|
||||
private JFXTextField elementCodeTextField;
|
||||
@FXML
|
||||
private JFXComboBox<String> elementTypeComboBox;
|
||||
@FXML
|
||||
private JFXTextField elementNameTextField;
|
||||
@FXML
|
||||
private JFXTextField elementUriTextField;
|
||||
@FXML
|
||||
private JFXComboBox<String> elementMethodComBox;
|
||||
@FXML
|
||||
private JFXTextArea elementDesTextAre;
|
||||
|
||||
|
||||
@FXML
|
||||
@ActionTrigger("updateMenu")
|
||||
private JFXButton updateButton;
|
||||
@FXML
|
||||
@ActionTrigger("saveMenu")
|
||||
private JFXButton saveButton;
|
||||
@FXML
|
||||
private JFXButton cancelButton;
|
||||
@FXML
|
||||
@ActionTrigger("addElement")
|
||||
private JFXButton addElement;
|
||||
@FXML
|
||||
@ActionTrigger("addMenu")
|
||||
private ToggleButton addButton;
|
||||
@FXML
|
||||
@ActionTrigger("editMenu")
|
||||
private ToggleButton editButton;
|
||||
@FXML
|
||||
@ActionTrigger("deleteMenu")
|
||||
private ToggleButton deleteButton;
|
||||
@FXML
|
||||
private ButtonBar buttonBar;
|
||||
@FXML
|
||||
private GridPane gridPane;
|
||||
|
||||
@FXML
|
||||
@ActionTrigger("cancelElementDialog")
|
||||
private JFXButton cancelElementButton;
|
||||
@FXML
|
||||
@ActionTrigger("upeateElement")
|
||||
private JFXButton updateElementButton;
|
||||
@FXML
|
||||
@ActionTrigger("createElement")
|
||||
private JFXButton saveElementButton;
|
||||
@FXML
|
||||
private JFXTextField elementfilterField;
|
||||
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> serialNumberColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> codeColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> typeColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> nameColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> addressColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> requestTypeColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> descriptionColumn;
|
||||
@FXML
|
||||
private TableColumn<ElementVO, String> operateColumn;
|
||||
@FXML
|
||||
private JFXDialog dialog;
|
||||
|
||||
|
||||
@Inject
|
||||
private MenuDataModel menuDataModel;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
final ToggleGroup group = new ToggleGroup();
|
||||
addButton.setToggleGroup(group);
|
||||
editButton.setToggleGroup(group);
|
||||
deleteButton.setToggleGroup(group);
|
||||
|
||||
try {
|
||||
addButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".add-circle-outline"));
|
||||
editButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".create-outline"));
|
||||
deleteButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY+".trash-outline"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
elementTypeComboBox.getItems().addAll(TYPE_OPTIONS);
|
||||
elementMethodComBox.getItems().addAll(METHOD_OPTIONS);
|
||||
|
||||
elementProgressBar.visibleProperty().bind(updateElementButton.disableProperty().or(saveElementButton.disableProperty()));
|
||||
elementProgressBar.managedProperty().bind(elementProgressBar.visibleProperty());
|
||||
|
||||
updateElementButton.visibleProperty().bind(saveElementButton.visibleProperty().not());
|
||||
updateElementButton.managedProperty().bind(updateElementButton.visibleProperty());
|
||||
cancelElementButton.disableProperty().bind(saveElementButton.disableProperty().or(updateElementButton.disableProperty()));
|
||||
|
||||
buttonBar.visibleProperty().bind(infoPane.disableProperty().not());
|
||||
buttonBar.managedProperty().bind(buttonBar.visibleProperty());
|
||||
saveButton.managedProperty().bind(saveButton.visibleProperty());
|
||||
updateButton.visibleProperty().bind(saveButton.visibleProperty().not());
|
||||
updateButton.managedProperty().bind(updateButton.visibleProperty());
|
||||
|
||||
serialNumberColumn.setCellFactory((col) -> {
|
||||
TableCell<ElementVO, String> cell = new TableCell<ElementVO, String>() {
|
||||
@Override
|
||||
public void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
this.setText(null);
|
||||
this.setGraphic(null);
|
||||
|
||||
if (!empty) {
|
||||
int rowIndex = this.getIndex() + 1;
|
||||
this.setText(String.valueOf(rowIndex));
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
});
|
||||
codeColumn.setCellValueFactory(new PropertyValueFactory<>("code"));
|
||||
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
|
||||
typeColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
|
||||
addressColumn.setCellValueFactory(new PropertyValueFactory<>("uri"));
|
||||
requestTypeColumn.setCellValueFactory(new PropertyValueFactory<>("method"));
|
||||
descriptionColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
|
||||
addOperateButtonToTable();
|
||||
menuDataModel.selectedElementIndexProperty().bind(tableView.getSelectionModel().selectedIndexProperty());
|
||||
FilteredList<ElementVO> filteredData = new FilteredList<>(menuDataModel.getElementVOS(), p -> true);
|
||||
tableView.setItems(filteredData);
|
||||
elementfilterField.textProperty().addListener((o, oldVal, newVal) -> {
|
||||
filteredData.setPredicate(elementProp -> {
|
||||
if (newVal == null || newVal.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
String val = Pinyin4jUtil.toPinYinLowercase(newVal);
|
||||
return Pinyin4jUtil.toPinYinLowercase(elementProp.getName()).contains(val)
|
||||
|| elementProp.getMethod().toLowerCase().contains(val)
|
||||
|| elementProp.getType().toLowerCase().contains(val);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
treeViewSpinner.visibleProperty().bind(treePane.disableProperty());
|
||||
gridPane.disableProperty().bind(buttonBar.visibleProperty().not());
|
||||
treeView.setCellFactory(new Callback<TreeView, TreeCell>() {
|
||||
@Override
|
||||
public TreeCell<MenuVO> call(TreeView param) {
|
||||
return new TreeCell<MenuVO>() {
|
||||
@Override
|
||||
protected void updateItem(MenuVO menu, boolean empty) {
|
||||
super.updateItem(menu, empty);
|
||||
if (!empty && menu != null) {
|
||||
setText(menu.getTitle());
|
||||
} else {
|
||||
setText(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
parentIdTextField.setDisable(true);
|
||||
|
||||
cancelButton.setOnAction(event -> {
|
||||
infoPane.setDisable(true);
|
||||
});
|
||||
|
||||
|
||||
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<MenuVO>>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends TreeItem<MenuVO>> observable, TreeItem<MenuVO> oldValue, TreeItem<MenuVO> newValue) {
|
||||
|
||||
updateMenuInfo(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
initTreeData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void updateMenuInfo(TreeItem<MenuVO> newValue) {
|
||||
infoPane.setDisable(true);
|
||||
|
||||
if (newValue == null) {
|
||||
return;
|
||||
}
|
||||
MenuVO menuVO = newValue.getValue();
|
||||
menuDataModel.setSelectMenuVO(menuVO);
|
||||
|
||||
if (newValue.isLeaf()) {
|
||||
elementPane.setVisible(true);
|
||||
elementPane.setManaged(true);
|
||||
updateMenuElement();
|
||||
} else {
|
||||
elementPane.setVisible(false);
|
||||
elementPane.setManaged(false);
|
||||
menuDataModel.getElementVOS().clear();
|
||||
}
|
||||
|
||||
codeTextField.setText(menuVO.getCode());
|
||||
orderNumTextField.setText(menuVO.getOrderNum() + "");
|
||||
titleTextField.setText(menuVO.getTitle());
|
||||
parentIdTextField.setText(menuVO.getParentId() + "");
|
||||
iconTextField.setText(menuVO.getIcon());
|
||||
hrefTextFeild.setText(menuVO.getHref());
|
||||
descriptionTextAre.setText(menuVO.getDescription());
|
||||
}
|
||||
|
||||
private void updateMenuElement() {
|
||||
MenuVO menuVO = menuDataModel.getSelectMenuVO();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> {
|
||||
TableResultResponse<Element> tableResultResponse = Request.connector(ElementFeign.class).getMenuElementList(menuVO.getId());
|
||||
List<Element> elementList = tableResultResponse.getDatas();
|
||||
List<ElementVO> elementVOList = new ArrayList<>();
|
||||
|
||||
elementList.forEach(element -> {
|
||||
elementVOList.add(new ElementVO(element.getId(), element.getCode(), element.getType(), element.getName(), element.getUri(), element.getMenuId(), element.getParentId(), element.getPath(), element.getMethod(), element.getDescription()));
|
||||
});
|
||||
return elementVOList;
|
||||
})
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
menuVO.getElementVOS().clear();
|
||||
menuVO.getElementVOS().addAll(rel);
|
||||
menuDataModel.getElementVOS().clear();
|
||||
menuDataModel.getElementVOS().addAll(rel);
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
|
||||
private <T> void setupCellValueFactory(JFXTreeTableColumn<ElementVO, T> column, Function<ElementVO, ObservableValue<T>> mapper) {
|
||||
column.setCellValueFactory((TreeTableColumn.CellDataFeatures<ElementVO, T> param) -> {
|
||||
if (column.validateValue(param)) {
|
||||
return mapper.apply(param.getValue().getValue());
|
||||
} else {
|
||||
return column.getComputedValue(param);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initTreeData() {
|
||||
ProcessChain.create().addRunnableInPlatformThread(() -> treePane.setDisable(true))
|
||||
.addSupplierInExecutor(() -> Request.connector(MenuFeign.class).getMenuAll())
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
buildMenuTree(rel);
|
||||
}).onException(e -> e.printStackTrace()).withFinal(() -> treePane.setDisable(false)).run();
|
||||
}
|
||||
|
||||
|
||||
private void buildMenuTree(List<MenuVO> menuList) {
|
||||
|
||||
MenuVO rootMenu = menuList.stream().min(Comparator.comparing(MenuVO::getParentId)).get();
|
||||
Map<Integer, List<MenuVO>> map = menuList.stream().collect(Collectors.groupingBy(MenuVO::getParentId));
|
||||
map.remove(rootMenu.getParentId());
|
||||
|
||||
FilterableTreeItem<MenuVO> rootNode = new FilterableTreeItem<MenuVO>(rootMenu);
|
||||
treeView.setRoot(rootNode);
|
||||
treeView.setShowRoot(false);
|
||||
addChildrenNode(rootNode, map);
|
||||
rootNode.predicateProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
if (treeSearchTextField.getText() == null || treeSearchTextField.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return TreeItemPredicate.create(actor -> {
|
||||
String searchText = Pinyin4jUtil.toPinYinLowercase(treeSearchTextField.getText());
|
||||
String itemText = Pinyin4jUtil.toPinYinLowercase(actor.toString());
|
||||
return itemText.contains(searchText);
|
||||
});
|
||||
}, treeSearchTextField.textProperty()));
|
||||
rootNode.setExpanded(true);
|
||||
treeView.getSelectionModel().select(rootNode);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void addChildrenNode(FilterableTreeItem<MenuVO> parentNode, Map<Integer, List<MenuVO>> map) {
|
||||
|
||||
List<MenuVO> childrenList = map.get(parentNode.getValue().getId());
|
||||
|
||||
if (childrenList != null) {
|
||||
|
||||
for (MenuVO menu : childrenList) {
|
||||
|
||||
FilterableTreeItem<MenuVO> clildrenNode = new FilterableTreeItem<>(menu);
|
||||
parentNode.getInternalChildren().add(clildrenNode);
|
||||
|
||||
addChildrenNode(clildrenNode, map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void addOperateButtonToTable() {
|
||||
|
||||
Callback<TableColumn<ElementVO, String>, TableCell<ElementVO, String>> cellFactory = new Callback<TableColumn<ElementVO, String>, TableCell<ElementVO, String>>() {
|
||||
@Override
|
||||
public TableCell<ElementVO, String> call(TableColumn param) {
|
||||
|
||||
final TableCell<ElementVO, String> cell = new TableCell<ElementVO, String>() {
|
||||
|
||||
private final ToggleButton editBut = new ToggleButton();
|
||||
private final ToggleButton delBut = new ToggleButton();
|
||||
|
||||
{
|
||||
|
||||
|
||||
editBut.getStyleClass().add("left-pill");
|
||||
delBut.getStyleClass().add("right-pill");
|
||||
|
||||
try {
|
||||
editBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".create-outline"));
|
||||
delBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".trash-outline"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
editBut.setOnMouseClicked(event -> {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
editElement();
|
||||
});
|
||||
delBut.setOnMouseClicked(event -> {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
deleteElement();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
HBox hBox = new HBox(editBut, delBut);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
hBox.setSpacing(0);
|
||||
setGraphic(hBox);
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
}
|
||||
};
|
||||
|
||||
operateColumn.setCellFactory(cellFactory);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("addMenu")
|
||||
private void addMenu() {
|
||||
|
||||
infoPane.setDisable(false);
|
||||
saveButton.setVisible(true);
|
||||
|
||||
codeTextField.setText("");
|
||||
orderNumTextField.setText("");
|
||||
titleTextField.setText("");
|
||||
parentIdTextField.setText(menuDataModel.getSelectMenuVO().getId() + "");
|
||||
iconTextField.setText("");
|
||||
hrefTextFeild.setText("");
|
||||
descriptionTextAre.setText("");
|
||||
}
|
||||
|
||||
@ActionMethod("saveMenu")
|
||||
private void saveMenu() {
|
||||
|
||||
MenuVO menuVO = new MenuVO();
|
||||
menuVO.setTitle(titleTextField.getText());
|
||||
menuVO.setCode(codeTextField.getText());
|
||||
menuVO.setIcon(iconTextField.getText());
|
||||
menuVO.setHref(hrefTextFeild.getText());
|
||||
menuVO.setOrderNum(Integer.parseInt(orderNumTextField.getText()));
|
||||
menuVO.setParentId(Integer.parseInt(parentIdTextField.getText()));
|
||||
menuVO.setDescription(descriptionTextAre.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> infoPane.setDisable(true))
|
||||
.addSupplierInExecutor(() -> Request.connector(MenuFeign.class).addMenu(menuVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel == 1) {
|
||||
initTreeData();
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
infoPane.setDisable(false);
|
||||
treeView.getRoot().setExpanded(true);
|
||||
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("editMenu")
|
||||
private void editMenu() {
|
||||
|
||||
infoPane.setDisable(false);
|
||||
saveButton.setVisible(false);
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("updateMenu")
|
||||
private void updateMenu() {
|
||||
|
||||
MenuVO menuVO = menuDataModel.getSelectMenuVO();
|
||||
menuVO.setTitle(titleTextField.getText());
|
||||
menuVO.setCode(codeTextField.getText());
|
||||
menuVO.setIcon(iconTextField.getText());
|
||||
menuVO.setHref(hrefTextFeild.getText());
|
||||
menuVO.setOrderNum(Integer.parseInt(orderNumTextField.getText()));
|
||||
menuVO.setParentId(Integer.parseInt(parentIdTextField.getText()));
|
||||
menuVO.setDescription(descriptionTextAre.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> infoPane.setDisable(true))
|
||||
.addSupplierInExecutor(() -> Request.connector(MenuFeign.class).updateMenu(menuVO))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
initTreeData();
|
||||
}
|
||||
}).withFinal(() -> {
|
||||
infoPane.setDisable(false);
|
||||
treeView.getRoot().setExpanded(true);
|
||||
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
@ActionMethod("deleteMenu")
|
||||
private void deleteMenu() {
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) rootPane.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("消息提示"));
|
||||
layout.setBody(new Label("确实删除【" + menuDataModel.getSelectMenuVO().getTitle() + "】吗?"));
|
||||
JFXButton closeButton = new JFXButton("取消");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
JFXButton determineButton = new JFXButton("确定");
|
||||
determineButton.setOnAction(event -> {
|
||||
alert.hideWithAnimation();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(MenuFeign.class).deleteMenu(menuDataModel.getSelectMenuVO()))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
initTreeData();
|
||||
}
|
||||
}).withFinal(() -> {
|
||||
treeView.getRoot().setExpanded(true);
|
||||
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
});
|
||||
layout.setActions(closeButton, determineButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("addElement")
|
||||
private void addElement() {
|
||||
|
||||
elementCodeTextField.setText("");
|
||||
elementTypeComboBox.getSelectionModel().select(null);
|
||||
elementMethodComBox.getSelectionModel().select(null);
|
||||
elementNameTextField.setText("");
|
||||
elementUriTextField.setText("");
|
||||
elementCodeTextField.setText("");
|
||||
elementDesTextAre.setText("");
|
||||
|
||||
|
||||
saveElementButton.setManaged(true);
|
||||
saveElementButton.setVisible(true);
|
||||
dialog.setTransitionType(JFXDialog.DialogTransition.TOP);
|
||||
dialog.show(rootPane);
|
||||
}
|
||||
|
||||
@ActionMethod("createElement")
|
||||
private void createElement() {
|
||||
|
||||
MenuVO menuVO = menuDataModel.getSelectMenuVO();
|
||||
Element newElect = new Element();
|
||||
|
||||
newElect.setCode(elementCodeTextField.getText());
|
||||
newElect.setMenuId(menuVO.getId() + "");
|
||||
newElect.setName(elementNameTextField.getText());
|
||||
newElect.setUri(elementUriTextField.getText());
|
||||
newElect.setType(elementTypeComboBox.getSelectionModel().getSelectedItem());
|
||||
newElect.setMethod(elementMethodComBox.getSelectionModel().getSelectedItem());
|
||||
newElect.setDescription(elementDesTextAre.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
saveElementButton.setDisable(true);
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(ElementFeign.class).addElement(newElect))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
updateMenuElement();
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
saveElementButton.setDisable(false);
|
||||
dialog.close();
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("upeateElement")
|
||||
private void updateElement() {
|
||||
|
||||
MenuVO menuVO = menuDataModel.getSelectMenuVO();
|
||||
Element newElect = new Element();
|
||||
newElect.setId(menuDataModel.getElementVOS().get(menuDataModel.getSelectedElementIndex()).getId());
|
||||
newElect.setCode(elementCodeTextField.getText());
|
||||
newElect.setMenuId(menuVO.getId() + "");
|
||||
newElect.setName(elementNameTextField.getText());
|
||||
newElect.setUri(elementUriTextField.getText());
|
||||
newElect.setType(elementTypeComboBox.getSelectionModel().getSelectedItem());
|
||||
newElect.setMethod(elementMethodComBox.getSelectionModel().getSelectedItem());
|
||||
newElect.setDescription(elementDesTextAre.getText());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
updateElementButton.setDisable(true);
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(ElementFeign.class).updateElement(newElect))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel >= 0) {
|
||||
updateMenuElement();
|
||||
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
updateElementButton.setDisable(false);
|
||||
dialog.close();
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void editElement() {
|
||||
|
||||
ElementVO elementVO = menuDataModel.getElementVOS().get(menuDataModel.getSelectedElementIndex());
|
||||
elementCodeTextField.setText(elementVO.getCode());
|
||||
elementTypeComboBox.getSelectionModel().select(elementVO.getType());
|
||||
elementMethodComBox.getSelectionModel().select(elementVO.getMethod());
|
||||
elementNameTextField.setText(elementVO.getName());
|
||||
elementUriTextField.setText(elementVO.getUri());
|
||||
elementDesTextAre.setText(elementVO.getDescription());
|
||||
|
||||
saveElementButton.setManaged(false);
|
||||
saveElementButton.setVisible(false);
|
||||
dialog.setTransitionType(JFXDialog.DialogTransition.TOP);
|
||||
dialog.show(rootPane);
|
||||
}
|
||||
|
||||
private void deleteElement() {
|
||||
|
||||
ElementVO elementVO = menuDataModel.getElementVOS().get(menuDataModel.getSelectedElementIndex());
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(ElementFeign.class).deleteElement(elementVO.getId()))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
|
||||
if (rel >= 0) {
|
||||
updateMenuElement();
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
|
||||
}).onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("cancelElementDialog")
|
||||
private void cancelElementDialog() {
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
@OnEvent("test-message")
|
||||
private void onNewChatMessage(Event<String> e) {
|
||||
System.err.println(this.getClass() + "\t" + e.getContent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.user;
|
||||
|
||||
import com.epri.fx.client.gui.feature.FeatureResourceConsumer;
|
||||
import com.epri.fx.client.gui.feature.HideByFeature;
|
||||
import com.epri.fx.client.gui.uicomponents.admin.user.components.UserAddController;
|
||||
import com.epri.fx.client.gui.uicomponents.admin.user.components.UserEditController;
|
||||
import com.epri.fx.client.model.UserDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.UserFeign;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.utils.Pinyin4jUtil;
|
||||
import com.epri.fx.server.entity.User;
|
||||
import com.epri.fx.server.util.DateUtils;
|
||||
import com.epri.fx.server.vo.UserVO;
|
||||
import com.jfoenix.controls.JFXAlert;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXDialogLayout;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import io.datafx.controller.util.VetoException;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserManagementController
|
||||
* @author: liwen
|
||||
* @date: 2020/3/4 21:05
|
||||
*/
|
||||
@ViewController(value = "/fxml/admin/user/user_management.fxml", title = "用户管理")
|
||||
public class UserManagementController {
|
||||
|
||||
public static final String CONTENT_PANE = "ContentPane";
|
||||
|
||||
|
||||
@FXML
|
||||
private StackPane root;
|
||||
@FXML
|
||||
private VBox centPane;
|
||||
@FXML
|
||||
private StackPane spinnerPane;
|
||||
@FXML
|
||||
private TextField searchField;
|
||||
@FXML
|
||||
private TextField userNameTextField;
|
||||
@FXML
|
||||
private TextField accountTextField;
|
||||
@FXML
|
||||
private TextField pwdTextField;
|
||||
@FXML
|
||||
private TextArea descTextArea;
|
||||
@FXML
|
||||
private ComboBox genderCombobox;
|
||||
@FXML
|
||||
@ActionTrigger("createUser")
|
||||
@HideByFeature("userManager:btn_add")
|
||||
private Button addBut;
|
||||
@FXML
|
||||
@ActionTrigger("accept")
|
||||
private Button acceptButton;
|
||||
@FXML
|
||||
@ActionTrigger("cancel")
|
||||
private Button cancelButton;
|
||||
@FXML
|
||||
@ActionTrigger("search")
|
||||
private Button searchBut;
|
||||
|
||||
|
||||
@FXML
|
||||
private Pagination pagination;
|
||||
|
||||
|
||||
@FXML
|
||||
private TableView<UserVO> tableView;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> serialNumberColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> nameColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> accountColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> remarksColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> lastUpdateTimeColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> lastUpdatedByColumn;
|
||||
@FXML
|
||||
private TableColumn<UserVO, String> operateColumn;
|
||||
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
@Inject
|
||||
private UserDataModel dataModel;
|
||||
|
||||
@Inject
|
||||
private FeatureResourceConsumer featureResourceConsumer;
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
featureResourceConsumer.consumeResource(this);
|
||||
spinnerPane.setVisible(false);
|
||||
serialNumberColumn.setCellFactory((col) -> {
|
||||
TableCell<UserVO, String> cell = new TableCell<UserVO, String>() {
|
||||
@Override
|
||||
public void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
this.setText(null);
|
||||
this.setGraphic(null);
|
||||
|
||||
if (!empty) {
|
||||
int rowIndex = this.getIndex() + 1;
|
||||
this.setText(String.valueOf(rowIndex));
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
});
|
||||
|
||||
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
|
||||
accountColumn.setCellValueFactory(new PropertyValueFactory<>("userName"));
|
||||
remarksColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
|
||||
lastUpdateTimeColumn.setCellValueFactory(new PropertyValueFactory<>("updTime"));
|
||||
lastUpdatedByColumn.setCellValueFactory(new PropertyValueFactory<>("updUser"));
|
||||
Callback<TableColumn<UserVO, String>, TableCell<UserVO, String>> cellFactory = new Callback<TableColumn<UserVO, String>, TableCell<UserVO, String>>() {
|
||||
@Override
|
||||
public TableCell<UserVO, String> call(TableColumn param) {
|
||||
|
||||
final TableCell<UserVO, String> cell = new TableCell<UserVO, String>() {
|
||||
|
||||
private final ToggleButton resetBut = new ToggleButton();
|
||||
private final ToggleButton editBut = new ToggleButton();
|
||||
private final ToggleButton delBut = new ToggleButton();
|
||||
|
||||
{
|
||||
|
||||
|
||||
resetBut.setTooltip(new Tooltip("重置密码"));
|
||||
resetBut.getStyleClass().add("left-pill");
|
||||
editBut.getStyleClass().add("center-pill");
|
||||
delBut.getStyleClass().add("right-pill");
|
||||
|
||||
try {
|
||||
editBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".create-outline"));
|
||||
resetBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".history"));
|
||||
delBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".trash-outline"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
editBut.setOnMouseClicked(event -> {
|
||||
|
||||
try {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
actionHandler.navigate(UserEditController.class);
|
||||
} catch (VetoException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
delBut.setOnMouseClicked(event -> {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
delete();
|
||||
});
|
||||
resetBut.setOnMouseClicked(event -> {
|
||||
tableView.getSelectionModel().select(getIndex());
|
||||
restPassword();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
HBox hBox = new HBox(resetBut, editBut, delBut);
|
||||
hBox.setSpacing(0);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
setGraphic(hBox);
|
||||
}
|
||||
}
|
||||
};
|
||||
return cell;
|
||||
}
|
||||
};
|
||||
|
||||
operateColumn.setCellFactory(cellFactory);
|
||||
|
||||
FilteredList<UserVO> filteredData = new FilteredList<>(dataModel.getUsers(), p -> true);
|
||||
tableView.setItems(filteredData);
|
||||
searchField.textProperty().addListener((o, oldVal, newVal) -> {
|
||||
filteredData.setPredicate(elementProp -> {
|
||||
if (newVal == null || newVal.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
String val = Pinyin4jUtil.toPinYinLowercase(newVal);
|
||||
return Pinyin4jUtil.toPinYinLowercase(elementProp.getName()).contains(val)
|
||||
|| elementProp.getName().toLowerCase().contains(val)
|
||||
|| elementProp.getUserName().toLowerCase().contains(val);
|
||||
});
|
||||
});
|
||||
|
||||
dataModel.selectedPersonIndexProperty().bind(tableView.getSelectionModel().selectedIndexProperty());
|
||||
pagination.pageCountProperty().bind(dataModel.pageCountProperty());
|
||||
pagination.setPageFactory(new Callback<Integer, Node>() {
|
||||
@Override
|
||||
public Node call(Integer param) {
|
||||
showPage(param + 1);
|
||||
return tableView;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("createUser")
|
||||
private void createUser() {
|
||||
|
||||
try {
|
||||
actionHandler.navigate(UserAddController.class);
|
||||
} catch (VetoException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ActionMethod("cancel")
|
||||
private void cancel() {
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("accept")
|
||||
private void accept() {
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) root.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
|
||||
layout.setBody(new Label(userNameTextField.getText() + "\t" + accountTextField.getText() + "\t" + genderCombobox.getSelectionModel().getSelectedItem() + "\t" + descTextArea.getText()));
|
||||
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void restPassword() {
|
||||
UserVO userVO = dataModel.getUsers().get(dataModel.getSelectedPersonIndex());
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) root.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("消息提示"));
|
||||
layout.setBody(new Label("确定要重置【" + userVO.getUserName() + "】登录密码吗?"));
|
||||
JFXButton closeButton = new JFXButton("取消");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
JFXButton determineButton = new JFXButton("确定");
|
||||
determineButton.setOnAction(event -> {
|
||||
alert.hideWithAnimation();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(UserFeign.class).restPassword(userVO.getId()))
|
||||
.addConsumerInPlatformThread(result -> {
|
||||
|
||||
}).onException(e -> e.printStackTrace()).run();
|
||||
});
|
||||
layout.setActions(closeButton, determineButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void delete() {
|
||||
UserVO userVO = dataModel.getUsers().get(dataModel.getSelectedPersonIndex());
|
||||
|
||||
JFXAlert alert = new JFXAlert((Stage) root.getScene().getWindow());
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("消息提示"));
|
||||
layout.setBody(new Label("确实删除【" + userVO.getUserName() + "】吗?"));
|
||||
JFXButton closeButton = new JFXButton("取消");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
JFXButton determineButton = new JFXButton("确定");
|
||||
determineButton.setOnAction(event -> {
|
||||
alert.hideWithAnimation();
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(UserFeign.class).delete(userVO.getId()))
|
||||
.addConsumerInPlatformThread(result -> {
|
||||
if (result.isRel()) {
|
||||
dataModel.getUsers().remove(dataModel.getSelectedPersonIndex());
|
||||
}
|
||||
}).onException(e -> e.printStackTrace()).run();
|
||||
});
|
||||
layout.setActions(closeButton, determineButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void showPage(Integer page) {
|
||||
Map<String, Object> queryMap = new HashMap<>();
|
||||
queryMap.put("keyId", searchField.getText());
|
||||
queryMap.put("page", page);
|
||||
query(queryMap);
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("search")
|
||||
private void search() {
|
||||
Map<String, Object> queryMap = new HashMap<>();
|
||||
queryMap.put("keyId", searchField.getText());
|
||||
query(queryMap);
|
||||
|
||||
}
|
||||
|
||||
private void query(Map<String, Object> queryMap) {
|
||||
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
spinnerPane.setVisible(true);
|
||||
centPane.setDisable(true);
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(UserFeign.class).getPageList(queryMap)
|
||||
)
|
||||
.addConsumerInPlatformThread(result -> {
|
||||
dataModel.getUsers().clear();
|
||||
List<User> userList = result.getDatas();
|
||||
dataModel.setPageCount((int) result.getTotal());
|
||||
|
||||
for (User user : userList) {
|
||||
dataModel.getUsers().add(new UserVO(user.getId(), user.getName(), user.getUsername(), DateUtils.format(user.getUpdTime(), DateUtils.DATE_TIME_PATTERN), user.getUpdUser(), user.getSex(), user.getDescription()));
|
||||
}
|
||||
})
|
||||
.withFinal(() -> {
|
||||
spinnerPane.setVisible(false);
|
||||
centPane.setDisable(false);
|
||||
})
|
||||
.onException(e -> e.printStackTrace())
|
||||
.run();
|
||||
}
|
||||
|
||||
|
||||
@PreDestroy
|
||||
private void destroy() {
|
||||
System.err.println("destroy " + this);
|
||||
}
|
||||
|
||||
|
||||
@FXML
|
||||
private void test() {
|
||||
System.err.println();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.user.components;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.admin.user.UserManagementController;
|
||||
import com.epri.fx.client.model.UserDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.UserFeign;
|
||||
import com.epri.fx.server.entity.User;
|
||||
import com.jfoenix.controls.*;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.action.BackAction;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import io.datafx.controller.util.VetoException;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserAddController
|
||||
* @author: liwen
|
||||
* @date: 2020/7/3 17:04
|
||||
*/
|
||||
|
||||
@ViewController(value = "/fxml/admin/user/user_detailed.fxml", title = "添加用户")
|
||||
public class UserAddController {
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
@FXML
|
||||
@BackAction
|
||||
private JFXButton cancelBut;
|
||||
@FXML
|
||||
private Label title;
|
||||
@FXML
|
||||
@ActionTrigger("save")
|
||||
private JFXButton saveBut;
|
||||
@FXML
|
||||
@ActionTrigger("update")
|
||||
private JFXButton updateBut;
|
||||
@FXML
|
||||
private JFXTextField nameTextField;
|
||||
@FXML
|
||||
private JFXTextField userNameTextField;
|
||||
@FXML
|
||||
private JFXPasswordField pwdTextField;
|
||||
@FXML
|
||||
private JFXTextArea descTextArea;
|
||||
@FXML
|
||||
private JFXComboBox genderCombobox;
|
||||
|
||||
@Inject
|
||||
private UserDataModel dataModel;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
||||
|
||||
title.setText("添加用户");
|
||||
updateBut.setVisible(false);
|
||||
updateBut.managedProperty().bind(updateBut.visibleProperty());
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("save")
|
||||
private void save() {
|
||||
|
||||
User user = new User();
|
||||
user.setName(nameTextField.getText());
|
||||
user.setDescription(descTextArea.getText());
|
||||
user.setUsername(userNameTextField.getText());
|
||||
user.setPassword(pwdTextField.getText());
|
||||
user.setSex(genderCombobox.getSelectionModel().getSelectedIndex() == 0 ? "男" : "女");
|
||||
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(UserFeign.class).add(user))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel.isRel()) {
|
||||
try {
|
||||
actionHandler.navigate(UserManagementController.class);
|
||||
} catch (VetoException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).run();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.epri.fx.client.gui.uicomponents.admin.user.components;
|
||||
|
||||
import com.epri.fx.client.gui.uicomponents.admin.user.UserManagementController;
|
||||
import com.epri.fx.client.model.UserDataModel;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.request.feign.admin.UserFeign;
|
||||
import com.epri.fx.server.entity.User;
|
||||
import com.epri.fx.server.vo.UserVO;
|
||||
import com.jfoenix.controls.*;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.action.BackAction;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import io.datafx.controller.util.VetoException;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserAddController
|
||||
* @author: liwen
|
||||
* @date: 2020/7/3 17:04
|
||||
*/
|
||||
|
||||
@ViewController(value = "/fxml/admin/user/user_detailed.fxml", title = "编辑用户")
|
||||
public class UserEditController {
|
||||
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
@FXML
|
||||
@BackAction
|
||||
private JFXButton cancelBut;
|
||||
|
||||
@FXML
|
||||
private Label title;
|
||||
@FXML
|
||||
private JFXButton saveBut;
|
||||
@FXML
|
||||
@ActionTrigger("update")
|
||||
private JFXButton updateBut;
|
||||
@FXML
|
||||
private JFXTextField nameTextField;
|
||||
@FXML
|
||||
private JFXTextField userNameTextField;
|
||||
@FXML
|
||||
private JFXPasswordField pwdTextField;
|
||||
@FXML
|
||||
private JFXTextArea descTextArea;
|
||||
@FXML
|
||||
private JFXComboBox genderCombobox;
|
||||
|
||||
@Inject
|
||||
private UserDataModel dataModel;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
title.setText("编辑用户");
|
||||
saveBut.managedProperty().bind(saveBut.visibleProperty());
|
||||
pwdTextField.setDisable(true);
|
||||
saveBut.setVisible(false);
|
||||
genderCombobox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
|
||||
UserVO userVO = dataModel.getUsers().get(dataModel.getSelectedPersonIndex());
|
||||
userVO.setSex(newValue.intValue() == 0 ? "男" : "女");
|
||||
}
|
||||
});
|
||||
UserVO userVO = dataModel.getUsers().get(dataModel.getSelectedPersonIndex());
|
||||
|
||||
nameTextField.textProperty().bindBidirectional(userVO.nameProperty());
|
||||
userNameTextField.textProperty().bindBidirectional(userVO.userNameProperty());
|
||||
pwdTextField.textProperty().bindBidirectional(userVO.userNameProperty());
|
||||
descTextArea.textProperty().bindBidirectional(userVO.descriptionProperty());
|
||||
String sex = userVO.sexProperty().getValue();
|
||||
genderCombobox.getSelectionModel().select("男".equals(sex) ? 0 : 1);
|
||||
}
|
||||
|
||||
@ActionMethod("update")
|
||||
private void update() {
|
||||
|
||||
UserVO userVO = dataModel.getUsers().get(dataModel.getSelectedPersonIndex());
|
||||
|
||||
User user = new User();
|
||||
user.setId(userVO.getId());
|
||||
user.setName(userVO.getName());
|
||||
user.setDescription(userVO.getDescription());
|
||||
user.setUsername(userVO.getUserName());
|
||||
user.setSex(userVO.getSex());
|
||||
ProcessChain.create()
|
||||
.addSupplierInExecutor(() -> Request.connector(UserFeign.class).update(user.getId(), user))
|
||||
.addConsumerInPlatformThread((rel) -> {
|
||||
if (rel.isRel()) {
|
||||
try {
|
||||
actionHandler.navigate(UserManagementController.class);
|
||||
} catch (VetoException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})
|
||||
.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.epri.fx.client.gui.uicomponents.basicInfo;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: BasicDataSetController
|
||||
* @author: liwen
|
||||
* @date: 2020/10/14 16:55
|
||||
*/
|
||||
@ViewController(value = "/fxml/basicInfo/basic_data_set.fxml", title = "基础数据", iconPath = "")
|
||||
public class BasicDataSetController {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.epri.fx.client.gui.uicomponents.basicInfo;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: BasicDataSetController
|
||||
* @author: liwen
|
||||
* @date: 2020/10/14 16:55
|
||||
*/
|
||||
@ViewController(value = "/fxml/basicInfo/coal_price_difference.fxml", title = "煤价差", iconPath = "")
|
||||
public class CoalPriceDiffController {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.epri.fx.client.gui.uicomponents.basicInfo;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: BasicDataSetController
|
||||
* @author: liwen
|
||||
* @date: 2020/10/14 16:55
|
||||
*/
|
||||
@ViewController(value = "/fxml/basicInfo/current_freight.fxml", title = "现行运价", iconPath = "")
|
||||
public class CurrentFreightController {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.epri.fx.client.gui.uicomponents.basicInfo;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: BasicDataSetController
|
||||
* @author: liwen
|
||||
* @date: 2020/10/14 16:55
|
||||
*/
|
||||
@ViewController(value = "/fxml/basicInfo/main_conclusion.fxml", title = "主要结论", iconPath = "")
|
||||
public class MainConclusionController {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.epri.fx.client.gui.uicomponents.basicInfo;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: BasicDataSetController
|
||||
* @author: liwen
|
||||
* @date: 2020/10/14 16:55
|
||||
*/
|
||||
@ViewController(value = "/fxml/basicInfo/railway_cost.fxml", title = "铁路成本", iconPath = "")
|
||||
public class RailwayCostController {
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.epri.fx.client.gui.uicomponents.container;
|
||||
|
||||
import com.jfoenix.controls.JFXTabPane;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
|
||||
import io.datafx.controller.context.ViewContext;
|
||||
import io.datafx.controller.flow.FlowContainer;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: TabPaneFlowContainer
|
||||
* @author: liwen
|
||||
* @date: 2020/6/24 18:09
|
||||
*/
|
||||
public class TabPaneFlowContainer implements FlowContainer<JFXTabPane> {
|
||||
|
||||
private final JFXTabPane tabPane;
|
||||
private final HashMap<String, Tab> tabsMap = new HashMap<>();
|
||||
|
||||
|
||||
public TabPaneFlowContainer() {
|
||||
this(new JFXTabPane());
|
||||
}
|
||||
|
||||
public TabPaneFlowContainer(JFXTabPane tabPane) {
|
||||
this.tabPane = tabPane;
|
||||
this.tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> void setViewContext(ViewContext<U> context) {
|
||||
|
||||
String title = context.getMetadata().getTitle();
|
||||
Class controller = context.getController().getClass();
|
||||
Tab tab = tabsMap.get(controller.getName());
|
||||
if (tab == null ) {
|
||||
tab = new Tab(title);
|
||||
tab.setUserData(context.getController());
|
||||
tab.setContent(context.getRootNode());
|
||||
tabPane.getTabs().add(tab);
|
||||
tabsMap.put(controller.getName(), tab);
|
||||
tab.setGraphic(new MaterialDesignIconView(MaterialDesignIcon.HOME));
|
||||
tab.setOnClosed(event -> {
|
||||
tabsMap.remove(controller.getName());
|
||||
try {
|
||||
context.destroy();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
tabPane.getSelectionModel().select(tab);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public JFXTabPane getView() {
|
||||
return tabPane;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.epri.fx.client.gui.uicomponents.control;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.scene.control.CheckBoxTreeItem;
|
||||
import javafx.scene.control.TreeItem;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class FilterableCheckBoxTreeItem<T> extends CheckBoxTreeItem<T> {
|
||||
final private ObservableList<TreeItem<T>> sourceList;
|
||||
private FilteredList<TreeItem<T>> filteredList;
|
||||
private ObjectProperty<TreeItemPredicate<T>> predicate = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
public FilterableCheckBoxTreeItem(T value) {
|
||||
super(value);
|
||||
this.sourceList = FXCollections.observableArrayList();
|
||||
this.filteredList = new FilteredList<>(this.sourceList);
|
||||
this.filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
return child -> {
|
||||
// Set the predicate of child items to force filtering
|
||||
if (child instanceof FilterableCheckBoxTreeItem) {
|
||||
FilterableCheckBoxTreeItem<T> filterableChild = (FilterableCheckBoxTreeItem<T>) child;
|
||||
filterableChild.setPredicate(this.predicate.get());
|
||||
}
|
||||
// If there is no predicate, keep this tree item
|
||||
if (this.predicate.get() == null) {
|
||||
return true;
|
||||
}
|
||||
// If there are children, keep this tree item
|
||||
if (child.getChildren().size() > 0) {
|
||||
return true;
|
||||
}
|
||||
// Otherwise ask the TreeItemPredicate
|
||||
return this.predicate.get().test(this, child.getValue());
|
||||
};
|
||||
}, this.predicate));
|
||||
setHiddenFieldChildren(this.filteredList);
|
||||
}
|
||||
|
||||
protected void setHiddenFieldChildren(ObservableList<TreeItem<T>> list) {
|
||||
try {
|
||||
Field childrenField = TreeItem.class.getDeclaredField("children"); //$NON-NLS-1$
|
||||
childrenField.setAccessible(true);
|
||||
childrenField.set(this, list);
|
||||
|
||||
Field declaredField = TreeItem.class.getDeclaredField("childrenListener"); //$NON-NLS-1$
|
||||
declaredField.setAccessible(true);
|
||||
list.addListener((ListChangeListener<? super TreeItem<T>>) declaredField.get(this));
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Could not set TreeItem.children", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableList<TreeItem<T>> getInternalChildren() {
|
||||
return this.sourceList;
|
||||
}
|
||||
|
||||
public void setPredicate(TreeItemPredicate<T> predicate) {
|
||||
this.predicate.set(predicate);
|
||||
}
|
||||
|
||||
public TreeItemPredicate getPredicate() {
|
||||
return predicate.get();
|
||||
}
|
||||
|
||||
public ObjectProperty<TreeItemPredicate<T>> predicateProperty() {
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.epri.fx.client.gui.uicomponents.control;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.scene.control.TreeItem;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class FilterableTreeItem<T> extends TreeItem<T> {
|
||||
final private ObservableList<TreeItem<T>> sourceList;
|
||||
private FilteredList<TreeItem<T>> filteredList;
|
||||
private ObjectProperty<TreeItemPredicate<T>> predicate = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
public FilterableTreeItem(T value) {
|
||||
super(value);
|
||||
this.sourceList = FXCollections.observableArrayList();
|
||||
this.filteredList = new FilteredList<>(this.sourceList);
|
||||
this.filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
return child -> {
|
||||
// Set the predicate of child items to force filtering
|
||||
if (child instanceof FilterableTreeItem) {
|
||||
FilterableTreeItem<T> filterableChild = (FilterableTreeItem<T>) child;
|
||||
filterableChild.setPredicate(this.predicate.get());
|
||||
}
|
||||
// If there is no predicate, keep this tree item
|
||||
if (this.predicate.get() == null) {
|
||||
return true;
|
||||
}
|
||||
// If there are children, keep this tree item
|
||||
if (child.getChildren().size() > 0) {
|
||||
return true;
|
||||
}
|
||||
// Otherwise ask the TreeItemPredicate
|
||||
return this.predicate.get().test(this, child.getValue());
|
||||
};
|
||||
}, this.predicate));
|
||||
setHiddenFieldChildren(this.filteredList);
|
||||
}
|
||||
|
||||
protected void setHiddenFieldChildren(ObservableList<TreeItem<T>> list) {
|
||||
try {
|
||||
Field childrenField = TreeItem.class.getDeclaredField("children"); //$NON-NLS-1$
|
||||
childrenField.setAccessible(true);
|
||||
childrenField.set(this, list);
|
||||
|
||||
Field declaredField = TreeItem.class.getDeclaredField("childrenListener"); //$NON-NLS-1$
|
||||
declaredField.setAccessible(true);
|
||||
list.addListener((ListChangeListener<? super TreeItem<T>>) declaredField.get(this));
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Could not set TreeItem.children", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableList<TreeItem<T>> getInternalChildren() {
|
||||
return this.sourceList;
|
||||
}
|
||||
|
||||
public void setPredicate(TreeItemPredicate<T> predicate) {
|
||||
this.predicate.set(predicate);
|
||||
}
|
||||
|
||||
public TreeItemPredicate getPredicate() {
|
||||
return predicate.get();
|
||||
}
|
||||
|
||||
public ObjectProperty<TreeItemPredicate<T>> predicateProperty() {
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,653 @@
|
||||
package com.epri.fx.client.gui.uicomponents.control;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.Interpolator;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.geometry.BoundingBox;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.effect.Shadow;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.Border;
|
||||
import javafx.scene.layout.BorderStroke;
|
||||
import javafx.scene.layout.BorderStrokeStyle;
|
||||
import javafx.scene.layout.BorderWidths;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import javafx.stage.WindowEvent;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Window Decorator allow to resize/move its content Note: the default close button will call stage.close() which will
|
||||
* only close the current stage. it will not close the java application, however it can be customized by calling {@link
|
||||
* #setOnCloseButtonAction(Runnable)}
|
||||
*
|
||||
* @author Shadi Shaheen
|
||||
* @version 1.0
|
||||
* @since 2016-03-09
|
||||
*/
|
||||
public class LFXDecorator extends StackPane {
|
||||
|
||||
private Stage primaryStage;
|
||||
private VBox contentPane = new VBox();
|
||||
|
||||
private double snapped_inset = 6;
|
||||
private double xOffset = 0;
|
||||
private double yOffset = 0;
|
||||
private double newX, newY, initX, initY, initWidth = -1, initHeight = -1,
|
||||
initStageX = -1, initStageY = -1;
|
||||
|
||||
private boolean allowMove = false;
|
||||
private boolean isDragging = false;
|
||||
private Timeline windowDecoratorAnimation;
|
||||
private StackPane contentPlaceHolder = new StackPane();
|
||||
private HBox buttonsContainer;
|
||||
|
||||
private ObjectProperty<Runnable> onCloseButtonAction = new SimpleObjectProperty<>(() ->
|
||||
primaryStage.fireEvent(new WindowEvent(primaryStage, WindowEvent.WINDOW_CLOSE_REQUEST)));
|
||||
|
||||
private BooleanProperty customMaximize = new SimpleBooleanProperty(false);
|
||||
private boolean maximized = false;
|
||||
private BoundingBox originalBox;
|
||||
private BoundingBox maximizedBox;
|
||||
|
||||
protected JFXButton btnMax;
|
||||
protected JFXButton btnFull;
|
||||
protected JFXButton btnClose;
|
||||
protected JFXButton btnMin;
|
||||
|
||||
protected StringProperty title = new SimpleStringProperty();
|
||||
protected Text text;
|
||||
protected Node graphic;
|
||||
protected HBox graphicContainer;
|
||||
|
||||
/**
|
||||
* Create a window decorator for the specified node with the options:
|
||||
* - full screen
|
||||
* - maximize
|
||||
* - minimize
|
||||
*
|
||||
* @param stage the primary stage used by the application
|
||||
* @param node the node to be decorated
|
||||
*/
|
||||
public LFXDecorator(Stage stage, Node node) {
|
||||
this(stage, node, true, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a window decorator for the specified node with the options:
|
||||
* - full screen
|
||||
* - maximize
|
||||
* - minimize
|
||||
*
|
||||
* @param stage the primary stage used by the application
|
||||
* @param node the node to be decorated
|
||||
* @param fullScreen indicates whether to show full screen option or not
|
||||
* @param max indicates whether to show maximize option or not
|
||||
* @param min indicates whether to show minimize option or not
|
||||
*/
|
||||
public LFXDecorator(Stage stage, Node node, boolean fullScreen, boolean max, boolean min) {
|
||||
primaryStage = stage;
|
||||
// Note that setting the style to TRANSPARENT is causing performance
|
||||
// degradation, as an alternative we set it to UNDECORATED instead.
|
||||
primaryStage.initStyle(StageStyle.TRANSPARENT);
|
||||
|
||||
setPickOnBounds(false);
|
||||
getStyleClass().add("lfx-decorator");
|
||||
|
||||
initializeButtons();
|
||||
initializeContainers(node, fullScreen, max, min);
|
||||
|
||||
primaryStage.fullScreenProperty().addListener((o, oldVal, newVal) -> {
|
||||
if (newVal) {
|
||||
// remove border
|
||||
contentPlaceHolder.getStyleClass().remove("resize-border");
|
||||
/*
|
||||
* note the border property MUST NOT be bound to another property
|
||||
* when going full screen mode, thus the binding will be lost if exisited
|
||||
*/
|
||||
contentPlaceHolder.borderProperty().unbind();
|
||||
contentPlaceHolder.setBorder(Border.EMPTY);
|
||||
if (windowDecoratorAnimation != null) {
|
||||
windowDecoratorAnimation.stop();
|
||||
}
|
||||
windowDecoratorAnimation = new Timeline(new KeyFrame(Duration.millis(320),
|
||||
new KeyValue(this.translateYProperty(),
|
||||
-buttonsContainer.getHeight(),
|
||||
Interpolator.EASE_BOTH)));
|
||||
windowDecoratorAnimation.setOnFinished((finish) -> {
|
||||
this.getChildren().remove(buttonsContainer);
|
||||
this.setTranslateY(0);
|
||||
});
|
||||
windowDecoratorAnimation.play();
|
||||
} else {
|
||||
// add border
|
||||
if (windowDecoratorAnimation != null) {
|
||||
if (windowDecoratorAnimation.getStatus() == Animation.Status.RUNNING) {
|
||||
windowDecoratorAnimation.stop();
|
||||
} else {
|
||||
this.getChildren().add(0, buttonsContainer);
|
||||
}
|
||||
}
|
||||
this.setTranslateY(-buttonsContainer.getHeight());
|
||||
windowDecoratorAnimation = new Timeline(new KeyFrame(Duration.millis(320),
|
||||
new KeyValue(this.translateYProperty(),
|
||||
0,
|
||||
Interpolator.EASE_BOTH)));
|
||||
windowDecoratorAnimation.setOnFinished((finish) -> {
|
||||
contentPlaceHolder.setBorder(new Border(new BorderStroke(Color.BLACK,
|
||||
BorderStrokeStyle.SOLID,
|
||||
CornerRadii.EMPTY,
|
||||
new BorderWidths(0, 4, 4, 4))));
|
||||
contentPlaceHolder.getStyleClass().add("resize-border");
|
||||
});
|
||||
windowDecoratorAnimation.play();
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventHandler(MouseEvent.MOUSE_PRESSED, (mouseEvent) ->
|
||||
updateInitMouseValues(mouseEvent));
|
||||
this.addEventHandler(MouseEvent.MOUSE_PRESSED, (mouseEvent) ->
|
||||
updateInitMouseValues(mouseEvent));
|
||||
|
||||
// show the drag cursor on the borders
|
||||
addEventFilter(MouseEvent.MOUSE_MOVED, (mouseEvent) -> showDragCursorOnBorders(mouseEvent));
|
||||
|
||||
|
||||
// handle drag events on the decorator pane
|
||||
addEventFilter(MouseEvent.MOUSE_RELEASED, (mouseEvent) -> isDragging = false);
|
||||
this.setOnMouseDragged((mouseEvent) -> handleDragEventOnDecoratorPane(mouseEvent));
|
||||
}
|
||||
|
||||
private void initializeButtons() {
|
||||
|
||||
SVGGlyph full = new SVGGlyph(0,
|
||||
"FULLSCREEN",
|
||||
"M598 214h212v212h-84v-128h-128v-84zM726 726v-128h84v212h-212v-84h128zM214 426v-212h212v84h-128v128h-84zM298 598v128h128v84h-212v-212h84z",
|
||||
Color.WHITE);
|
||||
full.setSize(16, 16);
|
||||
SVGGlyph minus = new SVGGlyph(0,
|
||||
"MINUS",
|
||||
"M804.571 420.571v109.714q0 22.857-16 38.857t-38.857 16h-694.857q-22.857 0-38.857-16t-16-38.857v-109.714q0-22.857 16-38.857t38.857-16h694.857q22.857 0 38.857 16t16 38.857z",
|
||||
Color.WHITE);
|
||||
minus.setSize(12, 2);
|
||||
minus.setTranslateY(4);
|
||||
SVGGlyph resizeMax = new SVGGlyph(0,
|
||||
"RESIZE_MAX",
|
||||
"M726 810v-596h-428v596h428zM726 44q34 0 59 25t25 59v768q0 34-25 60t-59 26h-428q-34 0-59-26t-25-60v-768q0-34 25-60t59-26z",
|
||||
Color.WHITE);
|
||||
resizeMax.setSize(12, 12);
|
||||
SVGGlyph resizeMin = new SVGGlyph(0,
|
||||
"RESIZE_MIN",
|
||||
"M80.842 943.158v-377.264h565.894v377.264h-565.894zM0 404.21v619.79h727.578v-619.79h-727.578zM377.264 161.684h565.894v377.264h-134.736v80.842h215.578v-619.79h-727.578v323.37h80.842v-161.686z",
|
||||
Color.WHITE);
|
||||
resizeMin.setSize(12, 12);
|
||||
SVGGlyph close = new SVGGlyph(0,
|
||||
"CLOSE",
|
||||
"M810 274l-238 238 238 238-60 60-238-238-238 238-60-60 238-238-238-238 60-60 238 238 238-238z",
|
||||
Color.WHITE);
|
||||
close.setSize(12, 12);
|
||||
btnFull = new JFXButton();
|
||||
btnFull.getStyleClass().add("lfx-decorator-button");
|
||||
btnFull.setCursor(Cursor.HAND);
|
||||
btnFull.setOnAction((action) -> primaryStage.setFullScreen(!primaryStage.isFullScreen()));
|
||||
btnFull.setGraphic(full);
|
||||
btnFull.setTranslateX(-30);
|
||||
btnFull.setRipplerFill(Color.WHITE);
|
||||
|
||||
btnClose = new JFXButton();
|
||||
btnClose.getStyleClass().add("lfx-decorator-button");
|
||||
btnClose.setCursor(Cursor.HAND);
|
||||
btnClose.setOnAction((action) -> onCloseButtonAction.get().run());
|
||||
btnClose.setGraphic(close);
|
||||
btnClose.setRipplerFill(Color.WHITE);
|
||||
|
||||
btnMin = new JFXButton();
|
||||
btnMin.getStyleClass().add("lfx-decorator-button");
|
||||
btnMin.setCursor(Cursor.HAND);
|
||||
btnMin.setOnAction((action) -> primaryStage.setIconified(true));
|
||||
btnMin.setGraphic(minus);
|
||||
btnMin.setRipplerFill(Color.WHITE);
|
||||
|
||||
btnMax = new JFXButton();
|
||||
btnMax.getStyleClass().add("lfx-decorator-button");
|
||||
btnMax.setCursor(Cursor.HAND);
|
||||
btnMax.setRipplerFill(Color.WHITE);
|
||||
btnMax.setOnAction((action) -> maximize(resizeMin, resizeMax));
|
||||
btnMax.setGraphic(resizeMax);
|
||||
}
|
||||
|
||||
private void maximize(SVGGlyph resizeMin, SVGGlyph resizeMax) {
|
||||
if (!isCustomMaximize()) {
|
||||
primaryStage.setMaximized(!primaryStage.isMaximized());
|
||||
maximized = primaryStage.isMaximized();
|
||||
if (primaryStage.isMaximized()) {
|
||||
btnMax.setGraphic(resizeMin);
|
||||
btnMax.setTooltip(new Tooltip("Restore Down"));
|
||||
} else {
|
||||
btnMax.setGraphic(resizeMax);
|
||||
btnMax.setTooltip(new Tooltip("Maximize"));
|
||||
}
|
||||
} else {
|
||||
if (!maximized) {
|
||||
// store original bounds
|
||||
originalBox = new BoundingBox(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight());
|
||||
// get the max stage bounds
|
||||
Screen screen = Screen.getScreensForRectangle(primaryStage.getX(),
|
||||
primaryStage.getY(),
|
||||
primaryStage.getWidth(),
|
||||
primaryStage.getHeight()).get(0);
|
||||
Rectangle2D bounds = screen.getVisualBounds();
|
||||
maximizedBox = new BoundingBox(bounds.getMinX(),
|
||||
bounds.getMinY(),
|
||||
bounds.getWidth(),
|
||||
bounds.getHeight());
|
||||
// maximized the stage
|
||||
primaryStage.setX(maximizedBox.getMinX());
|
||||
primaryStage.setY(maximizedBox.getMinY());
|
||||
primaryStage.setWidth(maximizedBox.getWidth());
|
||||
primaryStage.setHeight(maximizedBox.getHeight());
|
||||
btnMax.setGraphic(resizeMin);
|
||||
btnMax.setTooltip(new Tooltip("Restore Down"));
|
||||
this.setPadding(new Insets(0,0,0,0));
|
||||
} else {
|
||||
// restore stage to its original size
|
||||
primaryStage.setX(originalBox.getMinX());
|
||||
primaryStage.setY(originalBox.getMinY());
|
||||
primaryStage.setWidth(originalBox.getWidth());
|
||||
primaryStage.setHeight(originalBox.getHeight());
|
||||
originalBox = null;
|
||||
btnMax.setGraphic(resizeMax);
|
||||
btnMax.setTooltip(new Tooltip("Maximize"));
|
||||
this.setPadding(new Insets(3,3,3,3));
|
||||
}
|
||||
maximized = !maximized;
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeContainers(Node node, boolean fullScreen, boolean max, boolean min) {
|
||||
buttonsContainer = new HBox();
|
||||
buttonsContainer.getStyleClass().add("lfx-decorator-buttons-container");
|
||||
buttonsContainer.setBackground(new Background(new BackgroundFill(Color.BLACK,
|
||||
CornerRadii.EMPTY,
|
||||
Insets.EMPTY)));
|
||||
// BINDING
|
||||
buttonsContainer.setPadding(new Insets(4));
|
||||
buttonsContainer.setAlignment(Pos.CENTER_RIGHT);
|
||||
|
||||
// customize decorator buttons
|
||||
List<JFXButton> btns = new ArrayList<>();
|
||||
if (fullScreen) {
|
||||
btns.add(btnFull);
|
||||
}
|
||||
if (min) {
|
||||
btns.add(btnMin);
|
||||
}
|
||||
if (max) {
|
||||
btns.add(btnMax);
|
||||
// maximize/restore the window on header double click
|
||||
buttonsContainer.addEventHandler(MouseEvent.MOUSE_CLICKED, (mouseEvent) -> {
|
||||
if (mouseEvent.getClickCount() == 2) {
|
||||
btnMax.fire();
|
||||
}
|
||||
});
|
||||
}
|
||||
btns.add(btnClose);
|
||||
|
||||
text = new Text();
|
||||
text.getStyleClass().addAll("lfx-decorator-text", "title", "lfx-decorator-title");
|
||||
text.setFill(Color.WHITE);
|
||||
text.textProperty().bind(title); //binds the Text's text to title
|
||||
title.bind(primaryStage.titleProperty()); //binds title to the primaryStage's title
|
||||
|
||||
graphicContainer = new HBox();
|
||||
graphicContainer.setPickOnBounds(false);
|
||||
graphicContainer.setAlignment(Pos.CENTER_LEFT);
|
||||
graphicContainer.getChildren().setAll(text);
|
||||
|
||||
HBox graphicTextContainer = new HBox(graphicContainer, text);
|
||||
graphicTextContainer.getStyleClass().add("lfx-decorator-title-container");
|
||||
graphicTextContainer.setAlignment(Pos.CENTER_LEFT);
|
||||
graphicTextContainer.setPickOnBounds(false);
|
||||
HBox.setHgrow(graphicTextContainer, Priority.ALWAYS);
|
||||
HBox.setMargin(graphicContainer, new Insets(0, 8, 0, 8));
|
||||
|
||||
buttonsContainer.getChildren().setAll(graphicTextContainer);
|
||||
buttonsContainer.getChildren().addAll(btns);
|
||||
buttonsContainer.addEventHandler(MouseEvent.MOUSE_ENTERED, (enter) -> allowMove = true);
|
||||
buttonsContainer.addEventHandler(MouseEvent.MOUSE_EXITED, (enter) -> {
|
||||
if (!isDragging) {
|
||||
allowMove = false;
|
||||
}
|
||||
});
|
||||
buttonsContainer.setMinWidth(180);
|
||||
contentPlaceHolder.getStyleClass().add("lfx-decorator-content-container");
|
||||
contentPlaceHolder.setMinSize(0, 0);
|
||||
StackPane clippedContainer = new StackPane(node);
|
||||
contentPlaceHolder.getChildren().add(clippedContainer);
|
||||
((Region) node).setMinSize(0, 0);
|
||||
|
||||
contentPlaceHolder.getStyleClass().add("resize-border");
|
||||
|
||||
// BINDING
|
||||
|
||||
Rectangle clip = new Rectangle();
|
||||
clip.setArcWidth(20);
|
||||
clip.setArcHeight(20);
|
||||
clip.widthProperty().bind(contentPane.widthProperty());
|
||||
clip.heightProperty().bind(contentPane.heightProperty());
|
||||
|
||||
VBox.setVgrow(contentPlaceHolder, Priority.ALWAYS);
|
||||
contentPane.getChildren().addAll(buttonsContainer, contentPlaceHolder);
|
||||
contentPane.setClip(clip);
|
||||
|
||||
this.setPadding(new Insets(3,3,3,3));
|
||||
this.getChildren().addAll(contentPane);
|
||||
}
|
||||
|
||||
private void showDragCursorOnBorders(MouseEvent mouseEvent) {
|
||||
if (primaryStage.isFullScreen() || maximized) {
|
||||
this.setCursor(Cursor.DEFAULT);
|
||||
return; // maximized mode does not support resize
|
||||
}
|
||||
if (!primaryStage.isResizable()) {
|
||||
return;
|
||||
}
|
||||
double x = mouseEvent.getX();
|
||||
double y = mouseEvent.getY();
|
||||
double borderWidth = 20;
|
||||
if (isRightEdge(x)) {
|
||||
if (y < borderWidth) {
|
||||
this.setCursor(Cursor.NE_RESIZE);
|
||||
} else if (y > this.getHeight() - borderWidth) {
|
||||
this.setCursor(Cursor.SE_RESIZE);
|
||||
} else {
|
||||
this.setCursor(Cursor.E_RESIZE);
|
||||
}
|
||||
} else if (isLeftEdge(x)) {
|
||||
if (y < borderWidth) {
|
||||
this.setCursor(Cursor.NW_RESIZE);
|
||||
} else if (y > this.getHeight() - borderWidth) {
|
||||
this.setCursor(Cursor.SW_RESIZE);
|
||||
} else {
|
||||
this.setCursor(Cursor.W_RESIZE);
|
||||
}
|
||||
} else if (isTopEdge(y)) {
|
||||
this.setCursor(Cursor.N_RESIZE);
|
||||
} else if (isBottomEdge(y)) {
|
||||
this.setCursor(Cursor.S_RESIZE);
|
||||
} else {
|
||||
this.setCursor(Cursor.DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void handleDragEventOnDecoratorPane(MouseEvent mouseEvent) {
|
||||
isDragging = true;
|
||||
if (!mouseEvent.isPrimaryButtonDown() || (xOffset == -1 && yOffset == -1)) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Long press generates drag event!
|
||||
*/
|
||||
if (primaryStage.isFullScreen() || maximized) {
|
||||
return;
|
||||
}
|
||||
|
||||
newX = mouseEvent.getScreenX();
|
||||
newY = mouseEvent.getScreenY();
|
||||
|
||||
|
||||
double deltax = newX - initX;
|
||||
double deltay = newY - initY;
|
||||
Cursor cursor = this.getCursor();
|
||||
|
||||
if (Cursor.E_RESIZE.equals(cursor)) {
|
||||
setStageWidth(initWidth + deltax);
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.NE_RESIZE.equals(cursor)) {
|
||||
if (setStageHeight(initHeight - deltay)) {
|
||||
primaryStage.setY(initStageY + deltay);
|
||||
}
|
||||
setStageWidth(initWidth + deltax);
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.SE_RESIZE.equals(cursor)) {
|
||||
setStageWidth(initWidth + deltax);
|
||||
setStageHeight(initHeight + deltay);
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.S_RESIZE.equals(cursor)) {
|
||||
setStageHeight(initHeight + deltay);
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.W_RESIZE.equals(cursor)) {
|
||||
if (setStageWidth(initWidth - deltax)) {
|
||||
primaryStage.setX(initStageX + deltax);
|
||||
}
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.SW_RESIZE.equals(cursor)) {
|
||||
if (setStageWidth(initWidth - deltax)) {
|
||||
primaryStage.setX(initStageX + deltax);
|
||||
}
|
||||
setStageHeight(initHeight + deltay);
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.NW_RESIZE.equals(cursor)) {
|
||||
if (setStageWidth(initWidth - deltax)) {
|
||||
primaryStage.setX(initStageX + deltax);
|
||||
}
|
||||
if (setStageHeight(initHeight - deltay)) {
|
||||
primaryStage.setY(initStageY + deltay);
|
||||
}
|
||||
mouseEvent.consume();
|
||||
} else if (Cursor.N_RESIZE.equals(cursor)) {
|
||||
if (setStageHeight(initHeight - deltay)) {
|
||||
primaryStage.setY(initStageY + deltay);
|
||||
}
|
||||
mouseEvent.consume();
|
||||
} else if (allowMove) {
|
||||
primaryStage.setX(mouseEvent.getScreenX() - xOffset);
|
||||
primaryStage.setY(mouseEvent.getScreenY() - yOffset);
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInitMouseValues(MouseEvent mouseEvent) {
|
||||
initStageX = primaryStage.getX();
|
||||
initStageY = primaryStage.getY();
|
||||
initWidth = primaryStage.getWidth();
|
||||
initHeight = primaryStage.getHeight();
|
||||
initX = mouseEvent.getScreenX();
|
||||
initY = mouseEvent.getScreenY();
|
||||
xOffset = mouseEvent.getSceneX();
|
||||
yOffset = mouseEvent.getSceneY();
|
||||
}
|
||||
|
||||
|
||||
private boolean isRightEdge(double x) {
|
||||
final double width = this.getWidth();
|
||||
return x < width && x > width - snapped_inset;
|
||||
}
|
||||
|
||||
private boolean isTopEdge(double y) {
|
||||
return y >= 0 && y < snapped_inset;
|
||||
}
|
||||
|
||||
private boolean isBottomEdge(double y) {
|
||||
final double height = this.getHeight();
|
||||
return y < height && y > height - snapped_inset;
|
||||
}
|
||||
|
||||
private boolean isLeftEdge(double x) {
|
||||
return x >= 0 && x < snapped_inset;
|
||||
}
|
||||
|
||||
boolean setStageWidth(double width) {
|
||||
if (width >= primaryStage.getMinWidth() && width >= buttonsContainer.getMinWidth()) {
|
||||
primaryStage.setWidth(width);
|
||||
// initX = newX;
|
||||
return true;
|
||||
} else if (width >= primaryStage.getMinWidth() && width <= buttonsContainer.getMinWidth()) {
|
||||
width = buttonsContainer.getMinWidth();
|
||||
primaryStage.setWidth(width);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean setStageHeight(double height) {
|
||||
if (height >= primaryStage.getMinHeight() && height >= buttonsContainer.getHeight()) {
|
||||
primaryStage.setHeight(height);
|
||||
// initY = newY;
|
||||
return true;
|
||||
} else if (height >= primaryStage.getMinHeight() && height <= buttonsContainer.getHeight()) {
|
||||
height = buttonsContainer.getHeight();
|
||||
primaryStage.setHeight(height);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a speficed runnable when clicking on the close button
|
||||
*
|
||||
* @param onCloseButtonAction runnable to be executed
|
||||
*/
|
||||
public void setOnCloseButtonAction(Runnable onCloseButtonAction) {
|
||||
this.onCloseButtonAction.set(onCloseButtonAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* this property is used to replace JavaFX maximization
|
||||
* with a custom one that prevents hiding windows taskbar when
|
||||
* the JFXDecorator is maximized.
|
||||
*
|
||||
* @return customMaximizeProperty whether to use custom maximization or not.
|
||||
*/
|
||||
public final BooleanProperty customMaximizeProperty() {
|
||||
return this.customMaximize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether customMaximizeProperty is active or not
|
||||
*/
|
||||
public final boolean isCustomMaximize() {
|
||||
return this.customMaximizeProperty().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* set customMaximize property
|
||||
*
|
||||
* @param customMaximize
|
||||
*/
|
||||
public final void setCustomMaximize(final boolean customMaximize) {
|
||||
this.customMaximizeProperty().set(customMaximize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maximized
|
||||
*/
|
||||
public void setMaximized(boolean maximized) {
|
||||
if (this.maximized != maximized) {
|
||||
Platform.runLater(() -> {
|
||||
btnMax.fire();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* will change the decorator content
|
||||
*
|
||||
* @param content
|
||||
*/
|
||||
public void setContent(Node content) {
|
||||
this.contentPlaceHolder.getChildren().setAll(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* will set the title
|
||||
*
|
||||
* @param text
|
||||
* @deprecated Use {@link LFXDecorator#setTitle(String)} instead.
|
||||
*/
|
||||
public void setText(String text) {
|
||||
setTitle(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* will get the title
|
||||
*
|
||||
* @deprecated Use {@link LFXDecorator#setTitle(String)} instead.
|
||||
*/
|
||||
public String getText() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* By default this title property is bound to the primaryStage's title property.
|
||||
* <p>
|
||||
* To change it to something else, use <pre>
|
||||
* {@code jfxDecorator.titleProperty().unbind();}</pre> first.
|
||||
*/
|
||||
public StringProperty titleProperty() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you want the {@code primaryStage}'s title and the {@code JFXDecorator}'s title to be different, then
|
||||
* go ahead and use this method.
|
||||
* <p>
|
||||
* By default, this title property is bound to the {@code primaryStage}'s title property-so merely setting the
|
||||
* {@code primaryStage}'s title, will set the {@code JFXDecorator}'s title.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title.unbind();
|
||||
this.title.set(title);
|
||||
}
|
||||
|
||||
public void setGraphic(Node node) {
|
||||
if (graphic != null) {
|
||||
graphicContainer.getChildren().remove(graphic);
|
||||
}
|
||||
if (node != null) {
|
||||
graphicContainer.getChildren().add(0, node);
|
||||
}
|
||||
graphic = node;
|
||||
}
|
||||
|
||||
public Node getGraphic() {
|
||||
return graphic;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.epri.fx.client.gui.uicomponents.control;
|
||||
|
||||
import javafx.scene.control.TreeItem;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TreeItemPredicate<T> {
|
||||
|
||||
boolean test(TreeItem<T> parent, T value);
|
||||
|
||||
static <T> TreeItemPredicate<T> create(Predicate<T> predicate) {
|
||||
return (parent, value) -> predicate.test(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
package com.epri.fx.client.gui.uicomponents.home;
|
||||
|
||||
import com.epri.fx.client.bean.CountryPath;
|
||||
import eu.hansolo.tilesfx.Tile;
|
||||
import eu.hansolo.tilesfx.TileBuilder;
|
||||
import eu.hansolo.tilesfx.TimeSection;
|
||||
import eu.hansolo.tilesfx.TimeSectionBuilder;
|
||||
import eu.hansolo.tilesfx.addons.Indicator;
|
||||
import eu.hansolo.tilesfx.chart.ChartData;
|
||||
import eu.hansolo.tilesfx.chart.RadarChart;
|
||||
import eu.hansolo.tilesfx.chart.TilesFXSeries;
|
||||
import eu.hansolo.tilesfx.colors.Bright;
|
||||
import eu.hansolo.tilesfx.colors.Dark;
|
||||
import eu.hansolo.tilesfx.skins.BarChartItem;
|
||||
import eu.hansolo.tilesfx.skins.LeaderBoardItem;
|
||||
import eu.hansolo.tilesfx.tools.Country;
|
||||
import eu.hansolo.tilesfx.tools.FlowGridPane;
|
||||
import eu.hansolo.tilesfx.tools.Helper;
|
||||
import eu.hansolo.tilesfx.tools.Location;
|
||||
import eu.hansolo.tilesfx.weather.DarkSky;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.CycleMethod;
|
||||
import javafx.scene.paint.LinearGradient;
|
||||
import javafx.scene.paint.Stop;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static javafx.scene.layout.Region.USE_COMPUTED_SIZE;
|
||||
import static javafx.scene.layout.Region.USE_PREF_SIZE;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: HomeController
|
||||
* @author: liwen
|
||||
* @date: 2020/6/24 18:16
|
||||
*/
|
||||
@ViewController(value = "/fxml/home/home.fxml", title = "主页", iconPath = "")
|
||||
public class HomeController {
|
||||
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
public static final Color BACKGROUND = Color.rgb(39, 49, 66); // #2a2a2a
|
||||
public static final Color BORDERCOLOR = Color.rgb(49, 61, 79); // #2a2a2a
|
||||
|
||||
|
||||
private static final Random RND = new Random();
|
||||
private int noOfNodes = 0;
|
||||
|
||||
private BarChartItem barChartItem1;
|
||||
private BarChartItem barChartItem2;
|
||||
private BarChartItem barChartItem3;
|
||||
private BarChartItem barChartItem4;
|
||||
|
||||
private LeaderBoardItem leaderBoardItem1;
|
||||
private LeaderBoardItem leaderBoardItem2;
|
||||
private LeaderBoardItem leaderBoardItem3;
|
||||
private LeaderBoardItem leaderBoardItem4;
|
||||
|
||||
private ChartData chartData1;
|
||||
private ChartData chartData2;
|
||||
private ChartData chartData3;
|
||||
private ChartData chartData4;
|
||||
private ChartData chartData5;
|
||||
private ChartData chartData6;
|
||||
private ChartData chartData7;
|
||||
private ChartData chartData8;
|
||||
|
||||
private ChartData smoothChartData1;
|
||||
private ChartData smoothChartData2;
|
||||
private ChartData smoothChartData3;
|
||||
private ChartData smoothChartData4;
|
||||
|
||||
private Tile radialChartTile;
|
||||
private Tile donutChartTile;
|
||||
private Tile circularProgressTile;
|
||||
private Tile radarChartTile1;
|
||||
|
||||
private Tile worldTile;
|
||||
private Tile ephemerisTile;
|
||||
private Tile statusTile;
|
||||
|
||||
private Tile sparkLineTile;
|
||||
private Tile areaChartTile;
|
||||
private Tile lineChartTile;
|
||||
|
||||
|
||||
private long lastTimerCall;
|
||||
private AnimationTimer timer;
|
||||
private DoubleProperty value;
|
||||
|
||||
|
||||
private Map<String, List<CountryPath>> hiresCountryPaths = new ConcurrentHashMap<>();
|
||||
|
||||
@FXML
|
||||
private GridPane centerPane;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
|
||||
value = new SimpleDoubleProperty(0);
|
||||
|
||||
// AreaChart Data
|
||||
XYChart.Series<String, Number> series1 = new XYChart.Series();
|
||||
series1.setName("Whatever");
|
||||
series1.getData().add(new XYChart.Data("MO", 23));
|
||||
series1.getData().add(new XYChart.Data("TU", 21));
|
||||
series1.getData().add(new XYChart.Data("WE", 20));
|
||||
series1.getData().add(new XYChart.Data("TH", 22));
|
||||
series1.getData().add(new XYChart.Data("FR", 24));
|
||||
series1.getData().add(new XYChart.Data("SA", 22));
|
||||
series1.getData().add(new XYChart.Data("SU", 20));
|
||||
|
||||
// LineChart Data
|
||||
XYChart.Series<String, Number> series2 = new XYChart.Series();
|
||||
series2.setName("Inside");
|
||||
series2.getData().add(new XYChart.Data("MO", 8));
|
||||
series2.getData().add(new XYChart.Data("TU", 5));
|
||||
series2.getData().add(new XYChart.Data("WE", 0));
|
||||
series2.getData().add(new XYChart.Data("TH", 2));
|
||||
series2.getData().add(new XYChart.Data("FR", 4));
|
||||
series2.getData().add(new XYChart.Data("SA", 3));
|
||||
series2.getData().add(new XYChart.Data("SU", 5));
|
||||
|
||||
XYChart.Series<String, Number> series3 = new XYChart.Series();
|
||||
series3.setName("Outside");
|
||||
series3.getData().add(new XYChart.Data("MO", 8));
|
||||
series3.getData().add(new XYChart.Data("TU", 5));
|
||||
series3.getData().add(new XYChart.Data("WE", 0));
|
||||
series3.getData().add(new XYChart.Data("TH", 2));
|
||||
series3.getData().add(new XYChart.Data("FR", 4));
|
||||
series3.getData().add(new XYChart.Data("SA", 3));
|
||||
series3.getData().add(new XYChart.Data("SU", 5));
|
||||
|
||||
// WorldMap Data
|
||||
for (int i = 0; i < Country.values().length; i++) {
|
||||
double value = RND.nextInt(10);
|
||||
Color color;
|
||||
if (value > 8) {
|
||||
color = Tile.RED;
|
||||
} else if (value > 6) {
|
||||
color = Tile.ORANGE;
|
||||
} else if (value > 4) {
|
||||
color = Tile.YELLOW_ORANGE;
|
||||
} else if (value > 2) {
|
||||
color = Tile.GREEN;
|
||||
} else {
|
||||
color = Tile.BLUE;
|
||||
}
|
||||
Country.values()[i].setColor(color);
|
||||
}
|
||||
|
||||
// TimeControl Data
|
||||
TimeSection timeSection = TimeSectionBuilder.create()
|
||||
.start(LocalTime.now().plusSeconds(20))
|
||||
.stop(LocalTime.now().plusHours(1))
|
||||
//.days(DayOfWeek.MONDAY, DayOfWeek.FRIDAY)
|
||||
.color(Tile.GRAY)
|
||||
.highlightColor(Tile.RED)
|
||||
.build();
|
||||
|
||||
timeSection.setOnTimeSectionEntered(e -> System.out.println("Section ACTIVE"));
|
||||
timeSection.setOnTimeSectionLeft(e -> System.out.println("Section INACTIVE"));
|
||||
|
||||
// Weather (You can get a DarkSky API key here: https://darksky.net/dev/ )
|
||||
DarkSky darkSky = new DarkSky("YOUR DARKSKY API KEY", DarkSky.Unit.CA, DarkSky.Language.ENGLISH, 51.911858, 7.632815);
|
||||
//darkSky.update();
|
||||
|
||||
// BarChart Items
|
||||
barChartItem1 = new BarChartItem("Gerrit", 47, Tile.BLUE);
|
||||
barChartItem2 = new BarChartItem("Sandra", 43, Tile.RED);
|
||||
barChartItem3 = new BarChartItem("Lilli", 12, Tile.GREEN);
|
||||
barChartItem4 = new BarChartItem("Anton", 8, Tile.ORANGE);
|
||||
|
||||
barChartItem1.setFormatString("%.1f kWh");
|
||||
|
||||
// LeaderBoard Items
|
||||
leaderBoardItem1 = new LeaderBoardItem("Gerrit", 47);
|
||||
leaderBoardItem2 = new LeaderBoardItem("Sandra", 43);
|
||||
leaderBoardItem3 = new LeaderBoardItem("Lilli", 12);
|
||||
leaderBoardItem4 = new LeaderBoardItem("Anton", 8);
|
||||
|
||||
// Chart Data
|
||||
chartData1 = new ChartData("Item 1", 24.0, Tile.GREEN);
|
||||
chartData2 = new ChartData("Item 2", 10.0, Tile.BLUE);
|
||||
chartData3 = new ChartData("Item 3", 12.0, Tile.RED);
|
||||
chartData4 = new ChartData("Item 4", 13.0, Tile.YELLOW_ORANGE);
|
||||
chartData5 = new ChartData("Item 5", 13.0, Tile.BLUE);
|
||||
chartData6 = new ChartData("Item 6", 13.0, Tile.BLUE);
|
||||
chartData7 = new ChartData("Item 7", 13.0, Tile.BLUE);
|
||||
chartData8 = new ChartData("Item 8", 13.0, Tile.BLUE);
|
||||
//ChartData.animated = false;
|
||||
|
||||
smoothChartData1 = new ChartData("Item 1", RND.nextDouble() * 25, Tile.BLUE);
|
||||
smoothChartData2 = new ChartData("Item 2", RND.nextDouble() * 25, Tile.BLUE);
|
||||
smoothChartData3 = new ChartData("Item 3", RND.nextDouble() * 25, Tile.BLUE);
|
||||
smoothChartData4 = new ChartData("Item 4", RND.nextDouble() * 25, Tile.BLUE);
|
||||
|
||||
|
||||
sparkLineTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.SPARK_LINE)
|
||||
.title("SparkLine Tile")
|
||||
.unit("mb").borderRadius(14)
|
||||
.gradientStops(new Stop(0, Tile.GREEN),
|
||||
new Stop(0.5, Tile.YELLOW),
|
||||
new Stop(1.0, Tile.RED))
|
||||
.strokeWithGradient(true)
|
||||
.backgroundColor(BACKGROUND).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
//.smoothing(true)
|
||||
.build();
|
||||
|
||||
|
||||
areaChartTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.SMOOTHED_CHART).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.title("SmoothedChart Tile")
|
||||
.chartType(Tile.ChartType.AREA)
|
||||
//.animated(true)
|
||||
.smoothing(true)
|
||||
.tooltipTimeout(1000)
|
||||
.tilesFxSeries(new TilesFXSeries<>(series1,
|
||||
Tile.BLUE,
|
||||
new LinearGradient(0, 0, 0, 1,
|
||||
true, CycleMethod.NO_CYCLE,
|
||||
new Stop(0, Tile.BLUE),
|
||||
new Stop(1, Color.TRANSPARENT))))
|
||||
.build();
|
||||
|
||||
lineChartTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.SMOOTHED_CHART).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.title("SmoothedChart Tile")
|
||||
//.animated(true)
|
||||
.smoothing(false)
|
||||
.series(series2, series3)
|
||||
.build();
|
||||
|
||||
|
||||
worldTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.WORLDMAP).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.title("WorldMap Tile")
|
||||
.text("Whatever text")
|
||||
.textVisible(false)
|
||||
.build();
|
||||
|
||||
|
||||
radialChartTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.RADIAL_CHART).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.title("RadialChart")
|
||||
.text("Some text")
|
||||
.textVisible(false)
|
||||
.chartData(chartData1, chartData2, chartData3, chartData4)
|
||||
.build();
|
||||
|
||||
donutChartTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.DONUT_CHART)
|
||||
.title("DonutChart").backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.text("Some text")
|
||||
.textVisible(false)
|
||||
.chartData(chartData1, chartData2, chartData3, chartData4)
|
||||
.build();
|
||||
|
||||
circularProgressTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.CIRCULAR_PROGRESS)
|
||||
.title("CircularProgress").backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.text("Some text")
|
||||
.unit("\u0025")
|
||||
//.graphic(new WeatherSymbol(ConditionAndIcon.CLEAR_DAY, 48, Color.WHITE))
|
||||
.build();
|
||||
|
||||
|
||||
radarChartTile1 = TileBuilder.create().skinType(Tile.SkinType.RADAR_CHART)
|
||||
.minValue(0)
|
||||
.maxValue(50).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.title("RadarChart Sector")
|
||||
.unit("Unit")
|
||||
.radarChartMode(RadarChart.Mode.SECTOR)
|
||||
.gradientStops(new Stop(0.00000, Color.TRANSPARENT),
|
||||
new Stop(0.00001, Color.web("#3552a0")),
|
||||
new Stop(0.09090, Color.web("#456acf")),
|
||||
new Stop(0.27272, Color.web("#45a1cf")),
|
||||
new Stop(0.36363, Color.web("#30c8c9")),
|
||||
new Stop(0.45454, Color.web("#30c9af")),
|
||||
new Stop(0.50909, Color.web("#56d483")),
|
||||
new Stop(0.72727, Color.web("#9adb49")),
|
||||
new Stop(0.81818, Color.web("#efd750")),
|
||||
new Stop(0.90909, Color.web("#ef9850")),
|
||||
new Stop(1.00000, Color.web("#ef6050")))
|
||||
.text("Test")
|
||||
.chartData(chartData1, chartData2, chartData3, chartData4,
|
||||
chartData5, chartData6, chartData7, chartData8)
|
||||
.tooltipText("")
|
||||
.animated(true)
|
||||
.build();
|
||||
|
||||
|
||||
ephemerisTile = TileBuilder.create().skinType(Tile.SkinType.EPHEMERIS)
|
||||
.title("Ephemeris").backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.currentLocation(new Location(51.911515, 7.6340026, "Hiltrup"))
|
||||
.text("Hiltrup")
|
||||
.build();
|
||||
|
||||
|
||||
Indicator leftGraphics = new Indicator(Tile.RED);
|
||||
leftGraphics.setOn(true);
|
||||
|
||||
Indicator middleGraphics = new Indicator(Tile.YELLOW);
|
||||
middleGraphics.setOn(true);
|
||||
|
||||
Indicator rightGraphics = new Indicator(Tile.GREEN);
|
||||
rightGraphics.setOn(true);
|
||||
|
||||
statusTile = TileBuilder.create()
|
||||
.skinType(Tile.SkinType.STATUS)
|
||||
.title("Status Tile").borderWidth(0.8d).backgroundColor(BACKGROUND).borderRadius(14).borderColor(BORDERCOLOR).borderWidth(0.8d)
|
||||
.description("Notifications")
|
||||
.leftText("CRITICAL")
|
||||
.middleText("WARNING")
|
||||
.rightText("INFORMATION")
|
||||
.leftGraphics(leftGraphics)
|
||||
.middleGraphics(middleGraphics)
|
||||
.rightGraphics(rightGraphics)
|
||||
.text("Text")
|
||||
.build();
|
||||
|
||||
|
||||
lastTimerCall = System.nanoTime();
|
||||
timer = new AnimationTimer() {
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
if (now > lastTimerCall + 3_500_000_000L) {
|
||||
|
||||
sparkLineTile.setValue(RND.nextDouble() * sparkLineTile.getRange() * 1.5 + sparkLineTile.getMinValue());
|
||||
//value.set(RND.nextDouble() * sparkLineTile.getRange() * 1.5 + sparkLineTile.getMinValue());
|
||||
//sparkLineTile.setValue(20);
|
||||
|
||||
for (XYChart.Data<String, Number> stringNumberData : series1.getData()) {
|
||||
stringNumberData.setYValue(RND.nextInt(100));
|
||||
}
|
||||
for (XYChart.Data<String, Number> stringNumberData : series2.getData()) {
|
||||
stringNumberData.setYValue(RND.nextInt(30));
|
||||
}
|
||||
for (XYChart.Data<String, Number> data : series3.getData()) {
|
||||
data.setYValue(RND.nextInt(10));
|
||||
}
|
||||
|
||||
chartData1.setValue(RND.nextDouble() * 50);
|
||||
chartData2.setValue(RND.nextDouble() * 50);
|
||||
chartData3.setValue(RND.nextDouble() * 50);
|
||||
chartData4.setValue(RND.nextDouble() * 50);
|
||||
chartData5.setValue(RND.nextDouble() * 50);
|
||||
chartData6.setValue(RND.nextDouble() * 50);
|
||||
chartData7.setValue(RND.nextDouble() * 50);
|
||||
chartData8.setValue(RND.nextDouble() * 50);
|
||||
|
||||
|
||||
circularProgressTile.setValue(RND.nextDouble() * 120);
|
||||
|
||||
|
||||
smoothChartData1.setValue(smoothChartData2.getValue());
|
||||
smoothChartData2.setValue(smoothChartData3.getValue());
|
||||
smoothChartData3.setValue(smoothChartData4.getValue());
|
||||
smoothChartData4.setValue(RND.nextDouble() * 25);
|
||||
|
||||
|
||||
if (statusTile.getLeftValue() > 1000) {
|
||||
statusTile.setLeftValue(0);
|
||||
}
|
||||
if (statusTile.getMiddleValue() > 1000) {
|
||||
statusTile.setMiddleValue(0);
|
||||
}
|
||||
if (statusTile.getRightValue() > 1000) {
|
||||
statusTile.setRightValue(0);
|
||||
}
|
||||
statusTile.setLeftValue(statusTile.getLeftValue() + RND.nextInt(4));
|
||||
statusTile.setMiddleValue(statusTile.getMiddleValue() + RND.nextInt(3));
|
||||
statusTile.setRightValue(statusTile.getRightValue() + RND.nextInt(3));
|
||||
|
||||
|
||||
lastTimerCall = now;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
System.out.println("Initialization: " + (System.currentTimeMillis() - start) + "ms");
|
||||
|
||||
|
||||
centerPane.add(radialChartTile, 0, 0);
|
||||
centerPane.add(donutChartTile, 1, 0);
|
||||
centerPane.add(circularProgressTile, 2, 0);
|
||||
centerPane.add(radarChartTile1, 3, 0);
|
||||
|
||||
centerPane.add(worldTile, 0, 1, 2, 1);
|
||||
centerPane.add(ephemerisTile, 2, 1);
|
||||
centerPane.add(statusTile, 3, 1);
|
||||
|
||||
centerPane.add(sparkLineTile, 0, 2);
|
||||
centerPane.add(areaChartTile, 1, 2);
|
||||
centerPane.add(lineChartTile, 2, 2, 2, 1);
|
||||
|
||||
System.out.println("Nodes in Scene: " + noOfNodes);
|
||||
|
||||
timer.start();
|
||||
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void destroy() {
|
||||
// useful for jpro
|
||||
timer.stop();
|
||||
System.err.println("destroy " + this + actionHandler.getExceptionHandler());
|
||||
}
|
||||
|
||||
// ******************** Misc **********************************************
|
||||
private void calcNoOfNodes(Node node) {
|
||||
if (node instanceof Parent) {
|
||||
if (((Parent) node).getChildrenUnmodifiable().size() != 0) {
|
||||
ObservableList<Node> tempChildren = ((Parent) node).getChildrenUnmodifiable();
|
||||
noOfNodes += tempChildren.size();
|
||||
for (Node n : tempChildren) {
|
||||
calcNoOfNodes(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.epri.fx.client.gui.uicomponents.login;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: ConversationItemPresenter
|
||||
* @author: liwen
|
||||
* @date: 2019-09-25 16:51
|
||||
*/
|
||||
@ViewController("/fxml/login/loading.fxml")
|
||||
public class LoadingController {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
package com.epri.fx.client.gui.uicomponents.login;
|
||||
|
||||
import com.epri.fx.client.bean.MenuVoCell;
|
||||
import com.epri.fx.client.gui.uicomponents.main.MainController;
|
||||
import com.epri.fx.client.request.feign.admin.MenuFeign;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.request.feign.login.LoginFeign;
|
||||
import com.epri.fx.client.request.Request;
|
||||
import com.epri.fx.client.utils.AlertUtil;
|
||||
import com.epri.fx.client.websocket.Session;
|
||||
import com.epri.fx.server.util.DynamicEnumUtils;
|
||||
import com.epri.fx.server.util.EncryptUtil;
|
||||
import com.epri.fx.server.util.user.JwtAuthenticationRequest;
|
||||
import com.epri.fx.server.vo.FrontUser;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import com.epri.fx.server.vo.PermissionInfo;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXPasswordField;
|
||||
import com.jfoenix.controls.JFXProgressBar;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FXMLViewFlowContext;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import io.datafx.controller.flow.context.ViewFlowContext;
|
||||
import io.datafx.controller.util.VetoException;
|
||||
import io.datafx.core.concurrent.ProcessChain;
|
||||
import javafx.animation.*;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.EventType;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: ConversationItemPresenter
|
||||
* @author: liwen
|
||||
* @date: 2019-09-25 16:51
|
||||
*/
|
||||
@ViewController("/fxml/login/login.fxml")
|
||||
public class LoginController {
|
||||
|
||||
|
||||
@FXML
|
||||
|
||||
private Pane imagePane;
|
||||
@FXML
|
||||
private GridPane enterPane;
|
||||
@FXML
|
||||
private StackPane rootPane;
|
||||
@FXML
|
||||
private JFXTextField userNameTextField;
|
||||
@FXML
|
||||
private JFXPasswordField passWordTextField;
|
||||
@FXML
|
||||
private Label errorLabel;
|
||||
@FXML
|
||||
@ActionTrigger("login")
|
||||
private JFXButton loginBut;
|
||||
@FXML
|
||||
private VBox signCredsPane;
|
||||
|
||||
@FXML
|
||||
private JFXProgressBar lodingBar;
|
||||
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
private SequentialTransition sequentialTransition = new SequentialTransition();
|
||||
|
||||
private DoubleProperty imageWidth = new SimpleDoubleProperty();
|
||||
private DoubleProperty imageHeiht = new SimpleDoubleProperty();
|
||||
private Stage stage;
|
||||
|
||||
|
||||
@Inject
|
||||
private Session session;
|
||||
|
||||
|
||||
@FXMLViewFlowContext
|
||||
private ViewFlowContext flowContext;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
errorLabel.visibleProperty().bind(errorLabel.textProperty().isNotEmpty());
|
||||
errorLabel.managedProperty().bind(errorLabel.visibleProperty());
|
||||
|
||||
lodingBar.visibleProperty().bind(enterPane.disableProperty());
|
||||
lodingBar.managedProperty().bind(lodingBar.visibleProperty());
|
||||
|
||||
userNameTextField.focusedProperty().addListener((o, oldVal, newVal) -> {
|
||||
if (!newVal) {
|
||||
userNameTextField.validate();
|
||||
}
|
||||
});
|
||||
passWordTextField.focusedProperty().addListener((o, oldVal, newVal) -> {
|
||||
if (!newVal) {
|
||||
passWordTextField.validate();
|
||||
}
|
||||
});
|
||||
|
||||
loginBut.disableProperty().bind(Bindings.or(
|
||||
userNameTextField.textProperty().isEqualTo(""),
|
||||
passWordTextField.textProperty().isEqualTo("")));
|
||||
|
||||
rootPane.setOnKeyPressed(event -> {
|
||||
if (event.getCode() == KeyCode.ENTER) {
|
||||
if (loginBut.isDisable() == false) {
|
||||
login();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
imagePane.widthProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
|
||||
imageWidth.setValue(newValue);
|
||||
}
|
||||
});
|
||||
imagePane.heightProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
|
||||
imageHeiht.setValue(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
FadeTransition fadeTransition = new FadeTransition(Duration.millis(500), signCredsPane);
|
||||
fadeTransition.setFromValue(0f);
|
||||
fadeTransition.setToValue(1f);
|
||||
|
||||
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(500), signCredsPane);
|
||||
translateTransition.setInterpolator(Interpolator.EASE_BOTH);
|
||||
translateTransition.setFromY(400);
|
||||
translateTransition.setToY(signCredsPane.getLayoutY());
|
||||
|
||||
ParallelTransition parallelTransition = new ParallelTransition();
|
||||
parallelTransition.setDelay(Duration.millis(1500));
|
||||
parallelTransition.getChildren().addAll(
|
||||
fadeTransition,
|
||||
translateTransition
|
||||
);
|
||||
parallelTransition.setCycleCount(1);
|
||||
parallelTransition.play();
|
||||
|
||||
ImageView logBack = new ImageView("/images/loginBack.jpg");
|
||||
logBack.fitHeightProperty().bind(imageHeiht);
|
||||
logBack.fitWidthProperty().bind(imageWidth);
|
||||
imagePane.getChildren().add(new Label("", logBack));
|
||||
|
||||
List<File> files = Arrays.asList(new File(this.getClass().getResource("/images/login/").getPath()).listFiles());
|
||||
|
||||
sequentialTransition.setAutoReverse(true);
|
||||
sequentialTransition.setCycleCount(Timeline.INDEFINITE);
|
||||
|
||||
ProcessChain.create().addPublishingTask(() -> imagePane.getChildren(), p -> {
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
|
||||
File file = files.get(i);
|
||||
if (!file.isDirectory()) {
|
||||
String url = "/images/login/" + file.getName();
|
||||
ImageView imageView = new ImageView(url);
|
||||
imageView.fitHeightProperty().bind(imageHeiht);
|
||||
imageView.fitWidthProperty().bind(imageWidth);
|
||||
Label label = new Label("", imageView);
|
||||
|
||||
label.setOpacity(0d);
|
||||
FadeTransition fadeT = new FadeTransition(Duration.millis(500), label);
|
||||
fadeT.setDelay(Duration.millis(1500));
|
||||
fadeT.setFromValue(0f);
|
||||
fadeT.setToValue(1f);
|
||||
fadeT.setCycleCount(1);
|
||||
sequentialTransition.getChildren().add(fadeT);
|
||||
|
||||
p.publish(label);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}).withFinal(() -> sequentialTransition.play()).run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("login")
|
||||
private void login() {
|
||||
|
||||
JwtAuthenticationRequest jwtAuthenticationRequest = new JwtAuthenticationRequest();
|
||||
jwtAuthenticationRequest.setUsername(userNameTextField.getText());
|
||||
jwtAuthenticationRequest.setPassword(EncryptUtil.getInstance().Base64Encode(passWordTextField.getText()));
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
enterPane.setDisable(true);
|
||||
loginBut.setText("正在登录...");
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(LoginFeign.class).login(jwtAuthenticationRequest))
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
|
||||
if (rel.getStatus() == 200) {
|
||||
errorLabel.setText("");
|
||||
ApplicatonStore.setToken(rel.getData());
|
||||
loadApplicatonStore();
|
||||
} else {
|
||||
lodingBar.requestFocus();
|
||||
errorLabel.setText(rel.getMessage());
|
||||
}
|
||||
|
||||
})
|
||||
.onException(e -> {
|
||||
e.printStackTrace();
|
||||
errorLabel.setText("无法连接服务器,请检查服务器是否启动。");
|
||||
lodingBar.requestFocus();
|
||||
})
|
||||
.withFinal(() -> {
|
||||
enterPane.setDisable(false);
|
||||
loginBut.setText("登录");
|
||||
}).run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void loadApplicatonStore() {
|
||||
ProcessChain.create()
|
||||
.addRunnableInPlatformThread(() -> {
|
||||
try {
|
||||
actionHandler.navigate(LoadingController.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ApplicatonStore.setName("");
|
||||
ApplicatonStore.getAllMenu().clear();
|
||||
ApplicatonStore.getMenus().clear();
|
||||
ApplicatonStore.getElements().clear();
|
||||
ApplicatonStore.getPermissionMenus().clear();
|
||||
ApplicatonStore.getRoles().clear();
|
||||
})
|
||||
.addSupplierInExecutor(() -> Request.connector(MenuFeign.class).getMenuAll())
|
||||
.addConsumerInPlatformThread(rel -> ApplicatonStore.getAllMenu().addAll(rel))
|
||||
.addSupplierInExecutor(() ->
|
||||
Request.connector(LoginFeign.class).getInfo(ApplicatonStore.getToken())
|
||||
)
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
if (rel.getStatus() == 200) {
|
||||
FrontUser frontUser = rel.getData();
|
||||
ApplicatonStore.setName(frontUser.name);
|
||||
ApplicatonStore.getMenus().addAll(frontUser.getMenus());
|
||||
ApplicatonStore.getRoles().addAll(frontUser.getRoles());
|
||||
ApplicatonStore.getElements().addAll(frontUser.getElements());
|
||||
ApplicatonStore.setIntroduction(frontUser.getDescription());
|
||||
|
||||
for (PermissionInfo permissionInfo : frontUser.getElements()) {
|
||||
ApplicatonStore.getFeatureMap().put(permissionInfo.getCode(), permissionInfo.getName());
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
AlertUtil.show(rel);
|
||||
}
|
||||
})
|
||||
.addSupplierInExecutor(() ->
|
||||
Request.connector(LoginFeign.class).getMenus(ApplicatonStore.getToken())
|
||||
)
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
ApplicatonStore.getPermissionMenus().addAll(rel);
|
||||
|
||||
})
|
||||
.addSupplierInExecutor(() -> {
|
||||
|
||||
List<MenuVO> allMenuList = ApplicatonStore.getAllMenu();
|
||||
Map<Integer, List<MenuVO>> allMap = allMenuList.stream().collect(Collectors.groupingBy(MenuVO::getParentId));
|
||||
MenuVO rootMenu = allMenuList.stream().min(Comparator.comparing(MenuVO::getParentId)).get();
|
||||
|
||||
|
||||
List<MenuVO> permissionInfoList = ApplicatonStore.getPermissionMenus();
|
||||
Map<Integer, List<MenuVO>> permissionInfoMap = permissionInfoList.stream().collect(Collectors.groupingBy(MenuVO::getParentId));
|
||||
Map<String, List<MenuVO>> permissonTitleMap = permissionInfoList.stream().collect(Collectors.groupingBy(MenuVO::getTitle));
|
||||
|
||||
for (MenuVO menu : allMap.get(rootMenu.getId())) {
|
||||
|
||||
List<MenuVO> childrenMenus = permissionInfoMap.get(menu.getId());
|
||||
|
||||
List<MenuVO> partMenus = permissonTitleMap.get(menu.getTitle());
|
||||
if (childrenMenus == null && partMenus == null) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
MenuVoCell menuVoCell=new MenuVoCell(menu,childrenMenus);
|
||||
|
||||
ApplicatonStore.getMenuVoCells().add(menuVoCell);
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
})
|
||||
.addConsumerInPlatformThread(rel -> {
|
||||
|
||||
try {
|
||||
actionHandler.navigate(MainController.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.onException(e -> {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
actionHandler.navigate(LoginController.class);
|
||||
} catch (VetoException vetoException) {
|
||||
vetoException.printStackTrace();
|
||||
} catch (FlowException flowException) {
|
||||
flowException.printStackTrace();
|
||||
}
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void destroy() {
|
||||
sequentialTransition.stop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
package com.epri.fx.client.gui.uicomponents.main;
|
||||
|
||||
import com.epri.fx.client.bean.MenuVoCell;
|
||||
import com.epri.fx.client.gui.feature.FeatureResourceConsumer;
|
||||
import com.epri.fx.client.gui.uicomponents.home.HomeController;
|
||||
import com.epri.fx.client.gui.uicomponents.login.LoginController;
|
||||
import com.epri.fx.client.gui.uicomponents.main.components.UserInfoController;
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import com.jfoenix.controls.*;
|
||||
import com.jfoenix.svg.SVGGlyphLoader;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.controller.context.ApplicationContext;
|
||||
import io.datafx.controller.context.FXMLApplicationContext;
|
||||
import io.datafx.controller.flow.Flow;
|
||||
import io.datafx.controller.flow.FlowException;
|
||||
import io.datafx.controller.flow.FlowHandler;
|
||||
import io.datafx.controller.flow.action.ActionMethod;
|
||||
import io.datafx.controller.flow.action.ActionTrigger;
|
||||
import io.datafx.controller.flow.container.AnimatedFlowContainer;
|
||||
import io.datafx.controller.flow.container.ContainerAnimations;
|
||||
import io.datafx.controller.flow.context.ActionHandler;
|
||||
import io.datafx.controller.flow.context.FlowActionHandler;
|
||||
import io.datafx.controller.util.VetoException;
|
||||
import io.datafx.eventsystem.Event;
|
||||
import io.datafx.eventsystem.EventProducer;
|
||||
import io.datafx.eventsystem.EventTrigger;
|
||||
import io.datafx.eventsystem.OnEvent;
|
||||
import javafx.animation.Transition;
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: MainPresenter
|
||||
* @author: liwen
|
||||
* @date: 2019-09-02 15:33
|
||||
*/
|
||||
|
||||
@ViewController("/fxml/main/main.fxml")
|
||||
public class MainController {
|
||||
|
||||
@FXMLApplicationContext
|
||||
private ApplicationContext context;
|
||||
|
||||
@ActionHandler
|
||||
private FlowActionHandler actionHandler;
|
||||
|
||||
@FXML
|
||||
private JFXToolbar toolBar; //工具栏
|
||||
@FXML
|
||||
private StackPane rootPane;
|
||||
@FXML
|
||||
private JFXListView<Object> navigationList;
|
||||
@FXML
|
||||
private Pane backgroundPicturePane;
|
||||
@FXML
|
||||
private HBox leftHbox;
|
||||
@FXML
|
||||
private HBox rightHbox;
|
||||
//导航按钮
|
||||
@FXML
|
||||
private JFXHamburger navigationButton;
|
||||
//主页按钮
|
||||
@FXML
|
||||
@ActionTrigger("goHome")
|
||||
private JFXButton homeButton;
|
||||
@FXML
|
||||
@ActionTrigger("showSkinPane")
|
||||
private JFXButton skinButton;
|
||||
//刷新按钮
|
||||
@FXML
|
||||
@EventTrigger("test-message1")
|
||||
private JFXButton refreshButton;
|
||||
|
||||
//内容面板tabPane
|
||||
@FXML
|
||||
private JFXTabPane tabPane;
|
||||
|
||||
|
||||
private JFXPopup popOver;
|
||||
|
||||
@FXML
|
||||
@ActionTrigger("userInfo")
|
||||
private JFXButton userButton;
|
||||
@FXML
|
||||
private JFXButton rolesBut;
|
||||
|
||||
|
||||
@FXML
|
||||
private Label userLabel;
|
||||
|
||||
@FXML
|
||||
private Label roleLabel;
|
||||
|
||||
|
||||
@FXML
|
||||
private JFXDrawersStack drawersStack;
|
||||
|
||||
@FXML
|
||||
private JFXDrawer leftDrawer;
|
||||
|
||||
@FXML
|
||||
private JFXDatePicker datePicker;
|
||||
@Inject
|
||||
private FeatureResourceConsumer featureResourceConsumer;
|
||||
|
||||
|
||||
private final HashMap<String, Tab> tabsMap = new HashMap<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() throws FlowException {
|
||||
userLabel.textProperty().bind(ApplicatonStore.nameProperty());
|
||||
roleLabel.textProperty().bind(ApplicatonStore.getRoles().asString());
|
||||
userButton.textProperty().bind(ApplicatonStore.nameProperty());
|
||||
try {
|
||||
skinButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".skin"));
|
||||
homeButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".home-outline"));
|
||||
refreshButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".shuaxin"));
|
||||
rolesBut.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".admin"));
|
||||
userButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".ChevronDownCircle"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
datePicker.setEditable(false);
|
||||
leftDrawer.setSidePane(navigationList);
|
||||
leftDrawer.setOverLayVisible(false);
|
||||
leftDrawer.setResizeContent(true);
|
||||
leftDrawer.setResizableOnDrag(true);
|
||||
|
||||
// create and setup search popover
|
||||
backgroundPicturePane.setMouseTransparent(true);
|
||||
|
||||
leftDrawer.setOnDrawerOpening(e -> {
|
||||
final Transition animation = navigationButton.getAnimation();
|
||||
animation.setRate(1);
|
||||
animation.play();
|
||||
});
|
||||
leftDrawer.setOnDrawerClosing(e -> {
|
||||
final Transition animation = navigationButton.getAnimation();
|
||||
animation.setRate(-1);
|
||||
animation.play();
|
||||
});
|
||||
navigationButton.setOnMouseClicked(e -> {
|
||||
drawersStack.toggle(leftDrawer);
|
||||
});
|
||||
|
||||
tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
|
||||
drawersStack.setContent(tabPane);
|
||||
drawersStack.toggle(leftDrawer);
|
||||
try {
|
||||
addTab("主页", SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".home-outline"), HomeController.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
featureResourceConsumer.consumeResource(this);
|
||||
|
||||
navigationList.setCellFactory(listView -> new JFXListCell<Object>() {
|
||||
@Override
|
||||
public void updateItem(Object item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null) {
|
||||
if (item instanceof MenuVO) {
|
||||
MenuVO menuVO = (MenuVO) item;
|
||||
try {
|
||||
Label label = new Label(menuVO.getTitle(), SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + "." + menuVO.getIcon()));
|
||||
setGraphic(label);
|
||||
setText("");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
navigationList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue instanceof MenuVO) {
|
||||
try {
|
||||
addTab(((MenuVO) newValue).getTitle(), SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + "." + ((MenuVO) newValue).getIcon()), Class.forName(((MenuVO) newValue).getHref()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
navigationList.depthProperty().setValue(1);
|
||||
navigationList.expandedProperty().set(true);
|
||||
initData();
|
||||
}
|
||||
|
||||
private JFXPopup getPopOver() {
|
||||
if (popOver == null) {
|
||||
try {
|
||||
popOver = new JFXPopup(new Flow(UserInfoController.class).start());
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return popOver;
|
||||
}
|
||||
|
||||
@EventProducer("test-message")
|
||||
private String getMessage() {
|
||||
return "--------=================-----------";
|
||||
}
|
||||
|
||||
@EventProducer("test-message1")
|
||||
private String getMessage1() {
|
||||
return "--------=================-----------";
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
||||
ListProperty<MenuVoCell> listProperty = ApplicatonStore.getMenuVoCells();
|
||||
listProperty.sort((o1, o2) -> o1.getMenuVO().getOrderNum().compareTo(o2.getMenuVO().getOrderNum()));
|
||||
|
||||
for (MenuVoCell menuVoCell : listProperty) {
|
||||
if (menuVoCell.getChildrenMenus().isEmpty()) {
|
||||
navigationList.getItems().add(menuVoCell.getMenuVO());
|
||||
|
||||
} else {
|
||||
JFXListView<MenuVO> listView = new JFXListView<MenuVO>();
|
||||
listView.getStyleClass().add("sublist");
|
||||
Label label = null;
|
||||
try {
|
||||
label = new Label(menuVoCell.getMenuVO().getTitle(), SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + "." + menuVoCell.getMenuVO().getIcon()));
|
||||
label.getStyleClass().add("sublist-label");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
label.setTextAlignment(TextAlignment.LEFT);
|
||||
listView.setGroupnode(label);
|
||||
listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue instanceof MenuVO) {
|
||||
try {
|
||||
addTab(newValue.getTitle(), SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + "." + newValue.getIcon()), Class.forName(newValue.getHref()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
listView.setCellFactory(lv -> new JFXListCell<MenuVO>() {
|
||||
@Override
|
||||
public void updateItem(MenuVO item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null) {
|
||||
if (item instanceof MenuVO) {
|
||||
MenuVO menuVO = (MenuVO) item;
|
||||
try {
|
||||
Label label = new Label(menuVO.getTitle(), SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + "." + menuVO.getIcon()));
|
||||
setText("");
|
||||
setGraphic(label);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
ObservableList<MenuVO> childrenMenus = menuVoCell.getChildrenMenus();
|
||||
childrenMenus.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()));
|
||||
for (MenuVO menuVO : childrenMenus) {
|
||||
listView.getItems().add(menuVO);
|
||||
}
|
||||
navigationList.getItems().add(listView);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @param: [controllerClass]
|
||||
* @return: void
|
||||
* @auther: liwen
|
||||
* @date: 2020/6/28 9:57 上午
|
||||
*/
|
||||
private <T> void addTab(String title, Node icon, Class<T> controllerClass) {
|
||||
addTab(title, icon, new Flow(controllerClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:添加tab页
|
||||
* @param: [flow]
|
||||
* @return: void
|
||||
* @auther: liwen
|
||||
* @date: 2020/6/28 9:57 上午
|
||||
*/
|
||||
private <T> void addTab(String title, Node icon, Flow flow) {
|
||||
FlowHandler flowHandler = flow.createHandler();
|
||||
Tab tab = tabsMap.get(title);
|
||||
|
||||
if (tab == null) {
|
||||
|
||||
tab = new Tab(title);
|
||||
tab.setGraphic(icon);
|
||||
|
||||
try {
|
||||
StackPane node = flowHandler.start(new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.SWIPE_LEFT));
|
||||
node.getStyleClass().addAll("tab-content");
|
||||
node.setPadding(new Insets(15, 20, 15, 20));
|
||||
tab.setContent(node);
|
||||
featureResourceConsumer.consumeResource(flowHandler.getCurrentViewContext().getController());
|
||||
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
tabPane.getTabs().add(tab);
|
||||
tabsMap.put(title, tab);
|
||||
tab.setOnClosed(event -> {
|
||||
tabsMap.remove(title);
|
||||
try {
|
||||
flowHandler.getCurrentViewContext().destroy();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ("主页".equals(title)) {
|
||||
tab.setClosable(false);
|
||||
}
|
||||
tabPane.getSelectionModel().select(tab);
|
||||
|
||||
}
|
||||
|
||||
@ActionMethod("goHome")
|
||||
private void goHome() {
|
||||
try {
|
||||
addTab("主页", SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".home-outline"), HomeController.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ActionMethod("userInfo")
|
||||
private void userInfo() throws VetoException, FlowException {
|
||||
getPopOver().show(userButton, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, userButton.getHeight());
|
||||
}
|
||||
|
||||
@ActionMethod("showSkinPane")
|
||||
private void showSkinPane() throws VetoException, FlowException {
|
||||
|
||||
getPopOver().show(skinButton);
|
||||
}
|
||||
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:退出登录
|
||||
* @param: [event]
|
||||
* @return: void
|
||||
* @auther: liwen
|
||||
* @date: 2020/8/20 6:33 下午
|
||||
*/
|
||||
@OnEvent("dropOut")
|
||||
private void signOut(Event<String> event) {
|
||||
getPopOver().hide();
|
||||
ApplicatonStore.clearPermissionInfo();
|
||||
try {
|
||||
actionHandler.navigate(LoginController.class);
|
||||
} catch (VetoException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FlowException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.epri.fx.client.gui.uicomponents.main.components;
|
||||
|
||||
import io.datafx.controller.ViewController;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserInfoController
|
||||
* @author: liwen
|
||||
* @date: 2020/8/16 10:52
|
||||
*/
|
||||
@ViewController("/fxml/main/components/skin_info.fxml")
|
||||
public class SkinInfoController {
|
||||
|
||||
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.epri.fx.client.gui.uicomponents.main.components;
|
||||
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import io.datafx.controller.ViewController;
|
||||
import io.datafx.eventsystem.EventProducer;
|
||||
import io.datafx.eventsystem.EventTrigger;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: UserInfoController
|
||||
* @author: liwen
|
||||
* @date: 2020/8/16 10:52
|
||||
*/
|
||||
@ViewController("/fxml/main/components/user_info.fxml")
|
||||
public class UserInfoController {
|
||||
|
||||
@FXML
|
||||
private JFXListView listView;
|
||||
|
||||
@FXML
|
||||
private Label userLabel;
|
||||
@FXML
|
||||
private Label personalCenterLabel;
|
||||
@FXML
|
||||
@EventTrigger("dropOut")
|
||||
private Label dropOutLabel;
|
||||
|
||||
@FXML
|
||||
private Label roleLabel;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
userLabel.textProperty().bind(ApplicatonStore.nameProperty());
|
||||
roleLabel.textProperty().bind(ApplicatonStore.getRoles().asString());
|
||||
listView.expandedProperty().bind(listView.visibleProperty());
|
||||
|
||||
}
|
||||
|
||||
@EventProducer("dropOut")
|
||||
private String listViewListener() {
|
||||
|
||||
|
||||
return "退出";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.epri.fx.client.model;
|
||||
|
||||
import com.epri.fx.server.vo.ElementVO;
|
||||
import com.epri.fx.server.vo.GroupVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import io.datafx.controller.FxmlLoadException;
|
||||
import io.datafx.controller.injection.scopes.ViewScoped;
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: GroupDataModel
|
||||
* @author: liwen
|
||||
* @date: 2020/7/22 16:42
|
||||
*/
|
||||
@ViewScoped
|
||||
public class GroupDataModel {
|
||||
|
||||
|
||||
private ListProperty<MenuVO> menuVOS;
|
||||
private SimpleObjectProperty<GroupVO> selectedGroupVO = new SimpleObjectProperty<>(new GroupVO());
|
||||
private SimpleObjectProperty<MenuVO> selectedMenuVO = new SimpleObjectProperty<>(new MenuVO());
|
||||
|
||||
|
||||
public ObservableList<ElementVO> getElementVOS() {
|
||||
return FXCollections.observableArrayList(getSelectedMenuVO().getElementVOS());
|
||||
}
|
||||
|
||||
public ListProperty<MenuVO> getMenuVOS() {
|
||||
if (menuVOS == null) {
|
||||
ObservableList<MenuVO> innerList = FXCollections.observableArrayList();
|
||||
menuVOS = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return menuVOS;
|
||||
}
|
||||
|
||||
public GroupVO getSelectedGroup() {
|
||||
return selectedGroupVO.get();
|
||||
}
|
||||
|
||||
public ObjectProperty<GroupVO> selectedGroupProperty() {
|
||||
return selectedGroupVO;
|
||||
}
|
||||
|
||||
public void setSelectedGroup(GroupVO group) {
|
||||
this.selectedGroupVO.set(group);
|
||||
}
|
||||
|
||||
public MenuVO getSelectedMenuVO() {
|
||||
return selectedMenuVO.get();
|
||||
}
|
||||
|
||||
public SimpleObjectProperty<MenuVO> selectedMenuVOProperty() {
|
||||
return selectedMenuVO;
|
||||
}
|
||||
|
||||
public void setSelectedMenuVO(MenuVO selectedMenuVO) {
|
||||
this.selectedMenuVO.set(selectedMenuVO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.epri.fx.client.model;
|
||||
|
||||
import com.epri.fx.server.vo.GroupTypeVO;
|
||||
import io.datafx.controller.injection.scopes.FlowScoped;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@FlowScoped
|
||||
public class GroupTypeDataModel {
|
||||
private int counter = 0;
|
||||
private ListProperty<GroupTypeVO> groupTypes;
|
||||
private IntegerProperty selectedIndex;
|
||||
|
||||
public ListProperty<GroupTypeVO> getGroupTypes() {
|
||||
if (groupTypes == null) {
|
||||
ObservableList<GroupTypeVO> innerList = FXCollections.observableArrayList();
|
||||
groupTypes = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return groupTypes;
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return selectedIndexProperty().get();
|
||||
}
|
||||
|
||||
public void setSelectedIndex(int selectedPersonIndex) {
|
||||
this.selectedIndex.set(selectedPersonIndex);
|
||||
}
|
||||
|
||||
public IntegerProperty selectedIndexProperty() {
|
||||
if (selectedIndex == null) {
|
||||
selectedIndex = new SimpleIntegerProperty();
|
||||
}
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.epri.fx.client.model;
|
||||
|
||||
import com.epri.fx.server.vo.ElementVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import io.datafx.controller.injection.scopes.ViewScoped;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@ViewScoped
|
||||
public class MenuDataModel {
|
||||
|
||||
private ObjectProperty<MenuVO> selectMenuVOProperty;
|
||||
|
||||
private ListProperty<ElementVO> elementVOS;
|
||||
|
||||
private IntegerProperty selectedElementIndex;
|
||||
|
||||
public ListProperty<ElementVO> getElementVOS() {
|
||||
|
||||
if (elementVOS == null) {
|
||||
ObservableList<ElementVO> innerList = FXCollections.observableArrayList();
|
||||
elementVOS = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return elementVOS;
|
||||
}
|
||||
|
||||
|
||||
public MenuVO getSelectMenuVO() {
|
||||
return selectMenuVOPropertyProperty().get();
|
||||
}
|
||||
|
||||
public ObjectProperty<MenuVO> selectMenuVOPropertyProperty() {
|
||||
if (selectMenuVOProperty == null) {
|
||||
selectMenuVOProperty = new SimpleObjectProperty<>(new MenuVO());
|
||||
}
|
||||
return selectMenuVOProperty;
|
||||
}
|
||||
|
||||
public void setSelectMenuVO(MenuVO selectMenuVOProperty) {
|
||||
this.selectMenuVOPropertyProperty().set(selectMenuVOProperty);
|
||||
}
|
||||
|
||||
|
||||
public int getSelectedElementIndex() {
|
||||
return selectedElementIndexProperty().get();
|
||||
}
|
||||
|
||||
public IntegerProperty selectedElementIndexProperty() {
|
||||
|
||||
if (selectedElementIndex == null) {
|
||||
selectedElementIndex = new SimpleIntegerProperty();
|
||||
}
|
||||
return selectedElementIndex;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.epri.fx.client.model;
|
||||
|
||||
import com.epri.fx.server.vo.UserVO;
|
||||
import io.datafx.controller.injection.scopes.FlowScoped;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@FlowScoped
|
||||
public class UserDataModel {
|
||||
private int counter = 0;
|
||||
private ListProperty<UserVO> users;
|
||||
|
||||
private IntegerProperty pageCount;
|
||||
private IntegerProperty selectedPersonIndex;
|
||||
|
||||
|
||||
public ListProperty<UserVO> getUsers() {
|
||||
if (users == null) {
|
||||
ObservableList<UserVO> innerList = FXCollections.observableArrayList();
|
||||
users = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
public int getSelectedPersonIndex() {
|
||||
return selectedPersonIndexProperty().get();
|
||||
}
|
||||
|
||||
public void setSelectedPersonIndex(int selectedPersonIndex) {
|
||||
this.selectedPersonIndex.set(selectedPersonIndex);
|
||||
}
|
||||
|
||||
public IntegerProperty selectedPersonIndexProperty() {
|
||||
if (selectedPersonIndex == null) {
|
||||
selectedPersonIndex = new SimpleIntegerProperty();
|
||||
}
|
||||
return selectedPersonIndex;
|
||||
}
|
||||
|
||||
public int getPageCount() {
|
||||
return pageCount.get();
|
||||
}
|
||||
|
||||
public IntegerProperty pageCountProperty() {
|
||||
if (pageCount == null) {
|
||||
pageCount = new SimpleIntegerProperty();
|
||||
}
|
||||
return pageCount;
|
||||
}
|
||||
|
||||
public void setPageCount(int pageCount) {
|
||||
this.pageCount.set(pageCount);
|
||||
}
|
||||
}
|
||||
137
client/src/main/java/com/epri/fx/client/request/Request.java
Normal file
137
client/src/main/java/com/epri/fx/client/request/Request.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package com.epri.fx.client.request;
|
||||
|
||||
import com.epri.fx.client.request.feign.AppRequestErrorDecoder;
|
||||
import com.epri.fx.client.request.feign.AppRequestInterceptor;
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.BestAvailableRule;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.Retryer;
|
||||
import feign.jackson.JacksonDecoder;
|
||||
import feign.jackson.JacksonEncoder;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
import feign.ribbon.LBClient;
|
||||
import feign.ribbon.LBClientFactory;
|
||||
import feign.ribbon.LoadBalancingTarget;
|
||||
import feign.ribbon.RibbonClient;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import okhttp3.ConnectionPool;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class Request {
|
||||
|
||||
private static final Map<String, FeignAPI> CONNECTORS = new ConcurrentHashMap<>();
|
||||
private static RibbonClient ribbonClient;
|
||||
|
||||
private static String API_URL = "http://sample-client";
|
||||
private final static int CONNECT_TIME_OUT_MILLIS = 1000;
|
||||
private final static int READ_TIME_OUT_MILLIS = 60000;
|
||||
private static JacksonDecoder jacksonDecoder;
|
||||
private static JacksonEncoder jacksonEncoder;
|
||||
private static AppRequestInterceptor requestInterceptor;
|
||||
private static AppRequestErrorDecoder requestErrorDecoder;
|
||||
private static Slf4jLogger slf4jLogger;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @param: [connectorClass, readTimeOut->设置超时时间]
|
||||
* @return: T
|
||||
* @auther: liwen
|
||||
* @date: 2019-06-05 14:33
|
||||
*/
|
||||
public static <T extends FeignAPI> T connector(Class<T> connectorClass, int readTimeOut) {
|
||||
final String commandConfigKey = connectorClass.getSimpleName() + readTimeOut;
|
||||
|
||||
return (T) CONNECTORS.computeIfAbsent(commandConfigKey, k -> {
|
||||
return Feign.builder()
|
||||
.client(ribbonClient())
|
||||
.decoder(getJacksonDecoder())
|
||||
.encoder(getJacksonEncoder())
|
||||
.errorDecoder(getRequestErrorDecoder())
|
||||
.requestInterceptor(getRequestInterceptor())
|
||||
.logger(getSlf4jLogger())
|
||||
.logLevel(Logger.Level.FULL)
|
||||
.retryer(Retryer.NEVER_RETRY)
|
||||
.options(new feign.Request.Options(CONNECT_TIME_OUT_MILLIS, readTimeOut))
|
||||
.target(connectorClass, API_URL);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <T extends FeignAPI> T connector(Class<T> connectorClass) {
|
||||
return connector(connectorClass, READ_TIME_OUT_MILLIS);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static JacksonDecoder getJacksonDecoder() {
|
||||
if (jacksonDecoder == null) {
|
||||
jacksonDecoder = new JacksonDecoder();
|
||||
}
|
||||
return jacksonDecoder;
|
||||
}
|
||||
|
||||
|
||||
private static JacksonEncoder getJacksonEncoder() {
|
||||
if (jacksonEncoder == null) {
|
||||
jacksonEncoder = new JacksonEncoder();
|
||||
}
|
||||
return jacksonEncoder;
|
||||
}
|
||||
|
||||
private static AppRequestInterceptor getRequestInterceptor() {
|
||||
if (requestInterceptor == null) {
|
||||
requestInterceptor = new AppRequestInterceptor();
|
||||
}
|
||||
return requestInterceptor;
|
||||
}
|
||||
|
||||
private static AppRequestErrorDecoder getRequestErrorDecoder() {
|
||||
if (requestErrorDecoder == null) {
|
||||
requestErrorDecoder = new AppRequestErrorDecoder();
|
||||
}
|
||||
return requestErrorDecoder;
|
||||
}
|
||||
|
||||
private static Slf4jLogger getSlf4jLogger() {
|
||||
if (slf4jLogger == null) {
|
||||
slf4jLogger = new Slf4jLogger();
|
||||
}
|
||||
return slf4jLogger;
|
||||
}
|
||||
|
||||
private static RibbonClient ribbonClient() {
|
||||
|
||||
if (ribbonClient == null) {
|
||||
ribbonClient = RibbonClient.builder().delegate(new OkHttpClient(createOkHttpClient())).lbClientFactory(new LBClientFactory() {
|
||||
|
||||
@Override
|
||||
public LBClient create(String clientName) {
|
||||
IClientConfig config = ClientFactory.getNamedConfig(clientName);
|
||||
ILoadBalancer lb = ClientFactory.getNamedLoadBalancer(clientName);
|
||||
ZoneAwareLoadBalancer zb = (ZoneAwareLoadBalancer) lb;
|
||||
zb.setRule(new BestAvailableRule());
|
||||
LBClient lbClient = LBClient.create(lb, config);
|
||||
return lbClient;
|
||||
}
|
||||
|
||||
|
||||
}).build();
|
||||
}
|
||||
return ribbonClient;
|
||||
}
|
||||
|
||||
private static okhttp3.OkHttpClient createOkHttpClient() {
|
||||
return new okhttp3.OkHttpClient.Builder().connectionPool(new ConnectionPool())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.epri.fx.client.request.feign;
|
||||
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import com.epri.fx.client.utils.AlertUtil;
|
||||
import feign.Response;
|
||||
import feign.codec.ErrorDecoder;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: RequestErrorDecoder
|
||||
* @author: liwen
|
||||
* @date: 2020/8/13 09:36
|
||||
*/
|
||||
public class AppRequestErrorDecoder implements ErrorDecoder {
|
||||
@Override
|
||||
public Exception decode(String methodKey, Response response) {
|
||||
AlertUtil.show(response);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.epri.fx.client.request.feign;
|
||||
|
||||
import com.epri.fx.client.store.ApplicatonStore;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
|
||||
public class AppRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
|
||||
template.header("Authorization", ApplicatonStore.getToken());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.epri.fx.client.request.feign;
|
||||
|
||||
import feign.Headers;
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
public interface FeignAPI {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.epri.fx.client.request.feign.admin;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.entity.Element;
|
||||
import com.epri.fx.server.msg.TableResultResponse;
|
||||
import feign.Param;
|
||||
import feign.RequestLine;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: ElementFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/7/19 18:55
|
||||
*/
|
||||
public interface ElementFeign extends FeignAPI {
|
||||
|
||||
@RequestLine("GET /element/list/{menuId}")
|
||||
TableResultResponse<Element> getMenuElementList(@Param("menuId") Integer menuId);
|
||||
|
||||
@RequestLine("POST /element")
|
||||
Integer addElement(Element element);
|
||||
|
||||
@RequestLine("PUT /element")
|
||||
Integer updateElement(Element element);
|
||||
|
||||
@RequestLine("DELETE /element/{id}")
|
||||
Integer deleteElement(@Param("id") Integer id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.epri.fx.client.request.feign.admin;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.vo.GroupUsers;
|
||||
import com.epri.fx.server.vo.GroupVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import feign.Param;
|
||||
import feign.QueryMap;
|
||||
import feign.RequestLine;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: TestFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/4/1 17:31
|
||||
*/
|
||||
public interface GroupFeign extends FeignAPI {
|
||||
@RequestLine("GET /group/treeList/{groupTypeId}")
|
||||
List<GroupVO> getGroupList(@Param("groupTypeId") Integer groupTypeId);
|
||||
|
||||
@RequestLine("GET /group/{groupId}/authority/menu")
|
||||
List<MenuVO> getAuthorityMenuElementAll(@Param("groupId") Integer groupId);
|
||||
|
||||
@RequestLine("PUT /group/{groupId}/authority/menu")
|
||||
Integer modifyMenuAuthority(@Param("groupId") int id, List<MenuVO> menuVOList);
|
||||
|
||||
@RequestLine("POST /group")
|
||||
Integer addGroup(GroupVO groupVO);
|
||||
|
||||
@RequestLine("PUT /group")
|
||||
Integer updateGroup(GroupVO groupVO);
|
||||
|
||||
@RequestLine("DELETE /group")
|
||||
Integer deleteGroup(GroupVO groupVO);
|
||||
|
||||
|
||||
@RequestLine(value = "GET /group/{id}/user")
|
||||
public GroupUsers getUsers(@Param("id") int id);
|
||||
|
||||
@RequestLine(value = "PUT /group/{id}/user")
|
||||
public Integer modifiyUsers(@Param("id") int id, @QueryMap Map<String,String> map);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.epri.fx.client.request.feign.admin;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.vo.GroupTypeVO;
|
||||
import feign.Param;
|
||||
import feign.RequestLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: TestFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/4/1 17:31
|
||||
*/
|
||||
public interface GroupTypeFeign extends FeignAPI {
|
||||
@RequestLine("GET /groupType/all")
|
||||
List<GroupTypeVO> getAllGroupTypes();
|
||||
|
||||
@RequestLine("POST /groupType")
|
||||
Integer addGroupType(GroupTypeVO groupTypeVO);
|
||||
|
||||
@RequestLine("PUT /groupType")
|
||||
Integer updateGroupType(GroupTypeVO groupTypeVO);
|
||||
|
||||
@RequestLine("DELETE /groupType/{groupTypeId}")
|
||||
Integer deleteGroupTypes(@Param("groupTypeId") int groupTypeId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.epri.fx.client.request.feign.admin;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import feign.Headers;
|
||||
import feign.RequestLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: TestFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/4/1 17:31
|
||||
*/
|
||||
@Headers("Content-Type: application/json")
|
||||
public interface MenuFeign extends FeignAPI {
|
||||
@RequestLine("GET /menu/all")
|
||||
List<MenuVO> getMenuAll();
|
||||
@RequestLine("GET /menu/element/all")
|
||||
List<MenuVO> getMenuElementAll();
|
||||
|
||||
@RequestLine("POST /menu")
|
||||
Integer addMenu(MenuVO menuVO);
|
||||
|
||||
@RequestLine("PUT /menu")
|
||||
Integer updateMenu(MenuVO menuVO);
|
||||
|
||||
@RequestLine("DELETE /menu")
|
||||
Integer deleteMenu(MenuVO menuVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.epri.fx.client.request.feign.admin;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.entity.User;
|
||||
import com.epri.fx.server.msg.ObjectRestResponse;
|
||||
import com.epri.fx.server.msg.TableResultResponse;
|
||||
import com.epri.fx.server.vo.UserVO;
|
||||
import feign.Param;
|
||||
import feign.QueryMap;
|
||||
import feign.RequestLine;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: TestFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/4/1 17:31
|
||||
*/
|
||||
public interface UserFeign extends FeignAPI {
|
||||
@RequestLine("GET /user/page")
|
||||
TableResultResponse<User> getPageList(@QueryMap Map<String, Object> map);
|
||||
|
||||
@RequestLine("PUT /user/{id}")
|
||||
ObjectRestResponse<Integer> update(@Param("id") Integer id, User user);
|
||||
|
||||
@RequestLine("DELETE /user/{id}")
|
||||
ObjectRestResponse<Integer> delete(@Param("id") Integer id);
|
||||
|
||||
@RequestLine("PUT /user/password/{id}")
|
||||
ObjectRestResponse<Integer> restPassword(@Param("id")Integer id);
|
||||
|
||||
@RequestLine("POST /user")
|
||||
ObjectRestResponse<Integer> add(User user);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.epri.fx.client.request.feign.login;
|
||||
|
||||
import com.epri.fx.client.request.feign.FeignAPI;
|
||||
import com.epri.fx.server.msg.ObjectRestResponse;
|
||||
import com.epri.fx.server.util.user.JwtAuthenticationRequest;
|
||||
import com.epri.fx.server.vo.FrontUser;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import feign.Param;
|
||||
import feign.RequestLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: LoginFeign
|
||||
* @author: liwen
|
||||
* @date: 2020/8/2 09:47
|
||||
*/
|
||||
public interface LoginFeign extends FeignAPI {
|
||||
|
||||
@RequestLine("POST /jwt/token")
|
||||
ObjectRestResponse<String> login(JwtAuthenticationRequest request);
|
||||
|
||||
@RequestLine("GET /jwt/invalid")
|
||||
ObjectRestResponse<String> logout(JwtAuthenticationRequest request);
|
||||
|
||||
@RequestLine("GET /user/front/info/{token}")
|
||||
ObjectRestResponse<FrontUser> getInfo(@Param("token") String token);
|
||||
|
||||
@RequestLine("GET /user/front/menus/{token}")
|
||||
List<MenuVO> getMenus(@Param("token") String token);
|
||||
|
||||
@RequestLine("GET /user/front/menus/all/{token}")
|
||||
List<MenuVO> getMenuAll(@Param("token") String token);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package com.epri.fx.client.store;
|
||||
|
||||
import com.epri.fx.client.bean.MenuVoCell;
|
||||
import com.epri.fx.server.vo.GroupVO;
|
||||
import com.epri.fx.server.vo.MenuVO;
|
||||
import com.epri.fx.server.vo.PermissionInfo;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: User
|
||||
* @author: liwen
|
||||
* @date: 2020/8/2 10:17
|
||||
*/
|
||||
|
||||
public class ApplicatonStore {
|
||||
|
||||
public static String ICON_FONT_KEY = "icon.svg";
|
||||
private static SimpleIntegerProperty status = new SimpleIntegerProperty();
|
||||
private static SimpleStringProperty code = new SimpleStringProperty();
|
||||
private static SimpleStringProperty token = new SimpleStringProperty();
|
||||
private static SimpleStringProperty name = new SimpleStringProperty();
|
||||
private static SimpleStringProperty avatar = new SimpleStringProperty();
|
||||
private static SimpleStringProperty introduction = new SimpleStringProperty();
|
||||
private static ListProperty<GroupVO> roles;
|
||||
private static ListProperty<PermissionInfo> menus;
|
||||
private static ListProperty<MenuVO> permissionMenus;
|
||||
private static ListProperty<MenuVO> allMenu;
|
||||
private static ListProperty<MenuVoCell> menuVoCells;
|
||||
private static ListProperty<PermissionInfo> elements;
|
||||
private static MapProperty<String, String> featureMap;
|
||||
|
||||
|
||||
public static int getStatus() {
|
||||
return status.get();
|
||||
}
|
||||
|
||||
public static SimpleIntegerProperty statusProperty() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static void setStatus(int status) {
|
||||
ApplicatonStore.status.set(status);
|
||||
}
|
||||
|
||||
public static String getCode() {
|
||||
return code.get();
|
||||
}
|
||||
|
||||
public static SimpleStringProperty codeProperty() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static void setCode(String code) {
|
||||
ApplicatonStore.code.set(code);
|
||||
}
|
||||
|
||||
public static String getToken() {
|
||||
return token.get();
|
||||
}
|
||||
|
||||
public static SimpleStringProperty tokenProperty() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public static void setToken(String token) {
|
||||
ApplicatonStore.token.set(token);
|
||||
}
|
||||
|
||||
public static String getName() {
|
||||
return name.get();
|
||||
}
|
||||
|
||||
public static SimpleStringProperty nameProperty() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void setName(String name) {
|
||||
ApplicatonStore.name.set(name);
|
||||
}
|
||||
|
||||
public static String getAvatar() {
|
||||
return avatar.get();
|
||||
}
|
||||
|
||||
public static SimpleStringProperty avatarProperty() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public static void setAvatar(String avatar) {
|
||||
ApplicatonStore.avatar.set(avatar);
|
||||
}
|
||||
|
||||
public static String getIntroduction() {
|
||||
return introduction.get();
|
||||
}
|
||||
|
||||
public static SimpleStringProperty introductionProperty() {
|
||||
return introduction;
|
||||
}
|
||||
|
||||
public static void setIntroduction(String introduction) {
|
||||
ApplicatonStore.introduction.set(introduction);
|
||||
}
|
||||
|
||||
|
||||
public static ListProperty<GroupVO> getRoles() {
|
||||
if (roles == null) {
|
||||
ObservableList<GroupVO> innerList = FXCollections.observableArrayList();
|
||||
roles = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
||||
public static ListProperty<PermissionInfo> getMenus() {
|
||||
if (menus == null) {
|
||||
ObservableList<PermissionInfo> innerList = FXCollections.observableArrayList();
|
||||
menus = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return menus;
|
||||
}
|
||||
|
||||
|
||||
public static ListProperty<MenuVO> getAllMenu() {
|
||||
if (allMenu == null) {
|
||||
ObservableList<MenuVO> innerList = FXCollections.observableArrayList();
|
||||
allMenu = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return allMenu;
|
||||
}
|
||||
|
||||
public static ListProperty<MenuVoCell> getMenuVoCells() {
|
||||
if (menuVoCells == null) {
|
||||
ObservableList<MenuVoCell> innerList = FXCollections.observableArrayList();
|
||||
menuVoCells = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
|
||||
return menuVoCells;
|
||||
}
|
||||
|
||||
|
||||
public static ListProperty<PermissionInfo> getElements() {
|
||||
if (elements == null) {
|
||||
ObservableList<PermissionInfo> innerList = FXCollections.observableArrayList();
|
||||
elements = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static MapProperty<String, String> getFeatureMap() {
|
||||
if (featureMap == null) {
|
||||
ObservableMap<String, String> map = FXCollections.observableMap(new HashMap<>());
|
||||
featureMap = new SimpleMapProperty<>(map);
|
||||
}
|
||||
return featureMap;
|
||||
}
|
||||
|
||||
public static ListProperty<MenuVO> getPermissionMenus() {
|
||||
if (permissionMenus == null) {
|
||||
ObservableList<MenuVO> innerList = FXCollections.observableArrayList();
|
||||
permissionMenus = new SimpleListProperty<>(innerList);
|
||||
}
|
||||
return permissionMenus;
|
||||
}
|
||||
|
||||
public static void clearPermissionInfo() {
|
||||
setName("");
|
||||
getAllMenu().clear();
|
||||
getMenuVoCells().clear();
|
||||
getMenus().clear();
|
||||
ApplicatonStore.getElements().clear();
|
||||
getPermissionMenus().clear();
|
||||
getRoles().clear();
|
||||
getFeatureMap().clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
48
client/src/main/java/com/epri/fx/client/utils/AlertUtil.java
Normal file
48
client/src/main/java/com/epri/fx/client/utils/AlertUtil.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.epri.fx.client.utils;
|
||||
|
||||
import com.epri.fx.server.msg.BaseResponse;
|
||||
import com.jfoenix.controls.JFXAlert;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXDialogLayout;
|
||||
import feign.Response;
|
||||
import io.datafx.controller.context.ApplicationContext;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: AlerUtil
|
||||
* @author: liwen
|
||||
* @date: 2020/8/2 13:39
|
||||
*/
|
||||
public class AlertUtil {
|
||||
|
||||
public static void show(BaseResponse response) {
|
||||
JFXAlert alert = new JFXAlert(ApplicationContext.getInstance().getRegisteredObject(Stage.class));
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("提示"));
|
||||
layout.setBody(new Label(response.getStatus() + "\t" + response.getMessage()));
|
||||
JFXButton closeButton = new JFXButton("确定");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
layout.setActions(closeButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
public static void show(Response response) {
|
||||
JFXAlert alert = new JFXAlert(ApplicationContext.getInstance().getRegisteredObject(Stage.class));
|
||||
alert.initModality(Modality.APPLICATION_MODAL);
|
||||
alert.setOverlayClose(false);
|
||||
JFXDialogLayout layout = new JFXDialogLayout();
|
||||
layout.setHeading(new Label("提示"));
|
||||
layout.setBody(new Label(response.status() + "\t" + response.reason()));
|
||||
JFXButton closeButton = new JFXButton("确定");
|
||||
closeButton.setOnAction(event -> alert.hideWithAnimation());
|
||||
layout.setActions(closeButton);
|
||||
alert.setContent(layout);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
12
client/src/main/java/com/epri/fx/client/utils/Helper.java
Normal file
12
client/src/main/java/com/epri/fx/client/utils/Helper.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.epri.fx.client.utils;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: Helper
|
||||
* @author: liwen
|
||||
* @date: 2020/9/22 16:05
|
||||
*/
|
||||
public class Helper {
|
||||
private static final String COUNTRY_PROPERTIES = "resources/country/中国.svg";
|
||||
|
||||
}
|
||||
161
client/src/main/java/com/epri/fx/client/utils/Pinyin4jUtil.java
Normal file
161
client/src/main/java/com/epri/fx/client/utils/Pinyin4jUtil.java
Normal file
@@ -0,0 +1,161 @@
|
||||
package com.epri.fx.client.utils;
|
||||
|
||||
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
|
||||
|
||||
/**
|
||||
* 汉字转换成拼音方法
|
||||
*
|
||||
* @author 蔡龙
|
||||
*/
|
||||
|
||||
public class Pinyin4jUtil {
|
||||
|
||||
static HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
|
||||
|
||||
public static enum Type {
|
||||
UPPERCASE, //全部大写
|
||||
LOWERCASE, //全部小写
|
||||
FIRSTUPPER //首字母大写
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
|
||||
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换全部大写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return str为颐和园 ,return获取到的是YHY
|
||||
*/
|
||||
public static String toPinYinUppercase(String str) {
|
||||
return toPinYin(str, "", Type.UPPERCASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换全部大写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param spera 转换字母间隔加的字符串,如果不需要为""
|
||||
* @return str为颐和园 ,spera为** return获取到的是Y**H**Y
|
||||
*/
|
||||
public static String toPinYinUppercase(String str, String spera) {
|
||||
return toPinYin(str, spera, Type.UPPERCASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换全部小写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return str为颐和园 ,return获取到的是yhy
|
||||
* @
|
||||
*/
|
||||
public static String toPinYinLowercase(String str) {
|
||||
return toPinYin(str, "", Type.LOWERCASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换全部小写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param spera 转换字母间隔加的字符串,如果不需要为""
|
||||
* @return str为颐和园 ,spera为** return获取到的是y**h**y
|
||||
* @
|
||||
*/
|
||||
public static String toPinYinLowercase(String str, String spera) {
|
||||
return toPinYin(str, spera, Type.LOWERCASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼音首字母(大写)
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return str为颐和园 ,return获取到的是Y
|
||||
* @ 异常信息
|
||||
*/
|
||||
public static String toPinYinUppercaseInitials(String str) {
|
||||
String initials = null;
|
||||
String py = toPinYinUppercase(str);
|
||||
if (py.length() > 1) {
|
||||
initials = py.substring(0, 1);
|
||||
}
|
||||
if (py.length() <= 1) {
|
||||
initials = py;
|
||||
}
|
||||
return initials.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼音首字母(小写)
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return str为颐和园 ,return获取到的是y
|
||||
* @ 异常信息
|
||||
*/
|
||||
public static String toPinYinLowercaseInitials(String str) {
|
||||
String initials = null;
|
||||
String py = toPinYinLowercase(str);
|
||||
if (py.length() > 1) {
|
||||
initials = py.substring(0, 1);
|
||||
}
|
||||
if (py.length() <= 1) {
|
||||
initials = py;
|
||||
}
|
||||
return initials.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将str转换成拼音,如果不是汉字或者没有对应的拼音,则不作转换
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param spera 默认,可为""
|
||||
* @param type 转换格式
|
||||
* @return 按照转换格式转换成字符串
|
||||
*/
|
||||
public static String toPinYin(String str, String spera, Type type) {
|
||||
if (str == null || str.trim().length() == 0) {
|
||||
return "";
|
||||
}
|
||||
if (type == Type.UPPERCASE) {
|
||||
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
|
||||
} else {
|
||||
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||
}
|
||||
String py = "";
|
||||
String temp = "";
|
||||
String[] t = null;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
if ((int) c <= 128) {
|
||||
py += c;
|
||||
} else {
|
||||
try {
|
||||
t = PinyinHelper.toHanyuPinyinStringArray(c, format);
|
||||
} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
|
||||
badHanyuPinyinOutputFormatCombination.printStackTrace();
|
||||
}
|
||||
if (t == null) {
|
||||
py += c;
|
||||
} else {
|
||||
temp = t[0];
|
||||
if (type == Type.FIRSTUPPER) {
|
||||
temp = t[0].toUpperCase().charAt(0) + temp.substring(1);
|
||||
}
|
||||
if (temp.length() >= 1) {
|
||||
temp = temp.substring(0, 1);
|
||||
}
|
||||
py += temp + (i == str.length() - 1 ? "" : spera);
|
||||
}
|
||||
}
|
||||
}
|
||||
return py.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.epri.fx.client.websocket;
|
||||
|
||||
import io.datafx.controller.injection.scopes.ApplicationScoped;
|
||||
import io.datafx.controller.injection.scopes.FlowScoped;
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @className: Session
|
||||
* @author: liwen
|
||||
* @date: 2020/6/24 16:17
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class Session {
|
||||
|
||||
private int counter = 0;
|
||||
|
||||
public Session() {
|
||||
|
||||
}
|
||||
|
||||
public void print(String from) {
|
||||
System.out.println(from + ": counter = " + counter++);
|
||||
}
|
||||
}
|
||||
7
client/src/main/resources/META-INF/datafx.xml
Normal file
7
client/src/main/resources/META-INF/datafx.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<datafx version="8.0">
|
||||
<features>
|
||||
<featureEnum>com.epri.fx.client.gui.uicomponents.feature.UserGroupFeatures</featureEnum>
|
||||
|
||||
</features>
|
||||
</datafx>
|
||||
107
client/src/main/resources/country/中国.svg
Normal file
107
client/src/main/resources/country/中国.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 87 KiB |
15
client/src/main/resources/css/app-fonts.css
Normal file
15
client/src/main/resources/css/app-fonts.css
Normal file
@@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'Microsoft YaHei';
|
||||
src: url("../fonts/msyh.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Microsoft YaHei Light';
|
||||
src: url("../fonts/msyhl.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Microsoft YaHei Bold';
|
||||
src: url("../fonts/msyhbd.ttf");
|
||||
}
|
||||
|
||||
918
client/src/main/resources/css/app.css
Normal file
918
client/src/main/resources/css/app.css
Normal file
File diff suppressed because one or more lines are too long
714
client/src/main/resources/css/app.test.css
Normal file
714
client/src/main/resources/css/app.test.css
Normal file
File diff suppressed because one or more lines are too long
0
client/src/main/resources/css/login.css
Normal file
0
client/src/main/resources/css/login.css
Normal file
3427
client/src/main/resources/css/test.css
Normal file
3427
client/src/main/resources/css/test.css
Normal file
File diff suppressed because it is too large
Load Diff
8584
client/src/main/resources/css/页面-1.svg
Normal file
8584
client/src/main/resources/css/页面-1.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 426 KiB |
@@ -0,0 +1,539 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>IconFont Demo</title>
|
||||
<link rel="shortcut icon" href="https://img.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
|
||||
<link rel="stylesheet" href="demo.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="iconfont.js"></script>
|
||||
<!-- jQuery -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
|
||||
<!-- 代码高亮 -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank"></a></h1>
|
||||
<div class="nav-tabs">
|
||||
<ul id="tabs" class="dib-box">
|
||||
<li class="dib active"><span>Unicode</span></li>
|
||||
<li class="dib"><span>Font class</span></li>
|
||||
<li class="dib"><span>Symbol</span></li>
|
||||
</ul>
|
||||
|
||||
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2077973" target="_blank" class="nav-more">查看项目</a>
|
||||
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">home-outline</div>
|
||||
<div class="code-name">&#xe9b0;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">history</div>
|
||||
<div class="code-name">&#xe752;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">exit-outline</div>
|
||||
<div class="code-name">&#xe9ac;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">create-outline</div>
|
||||
<div class="code-name">&#xe9ad;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">power-outline</div>
|
||||
<div class="code-name">&#xe9ae;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">add-circle-outline</div>
|
||||
<div class="code-name">&#xe9af;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">操作日志</div>
|
||||
<div class="code-name">&#xe65f;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">菜单管理</div>
|
||||
<div class="code-name">&#xe6a4;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">角色类型</div>
|
||||
<div class="code-name">&#xe666;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">功能角色权限管理</div>
|
||||
<div class="code-name">&#xe642;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">用户管理</div>
|
||||
<div class="code-name">&#xe62d;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">基础配置</div>
|
||||
<div class="code-name">&#xe62e;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">trash-outline</div>
|
||||
<div class="code-name">&#xea8d;</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="unicode-">Unicode 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
|
||||
<ul>
|
||||
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
|
||||
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
|
||||
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
|
||||
</blockquote>
|
||||
<p>Unicode 使用步骤如下:</p>
|
||||
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.eot');
|
||||
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('iconfont.woff2') format('woff2'),
|
||||
url('iconfont.woff') format('woff'),
|
||||
url('iconfont.ttf') format('truetype'),
|
||||
url('iconfont.svg#iconfont') format('svg');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
<pre><code class="language-css"
|
||||
>.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
|
||||
<pre>
|
||||
<code class="language-html"
|
||||
><span class="iconfont">&#x33;</span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-home-outline"></span>
|
||||
<div class="name">
|
||||
home-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-home-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-history"></span>
|
||||
<div class="name">
|
||||
history
|
||||
</div>
|
||||
<div class="code-name">.icon-history
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-exit-outline"></span>
|
||||
<div class="name">
|
||||
exit-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-exit-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-create-outline"></span>
|
||||
<div class="name">
|
||||
create-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-create-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-power-outline"></span>
|
||||
<div class="name">
|
||||
power-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-power-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-add-circle-outline"></span>
|
||||
<div class="name">
|
||||
add-circle-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-add-circle-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-caozuorizhi"></span>
|
||||
<div class="name">
|
||||
操作日志
|
||||
</div>
|
||||
<div class="code-name">.icon-caozuorizhi
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-jiaoyixulie"></span>
|
||||
<div class="name">
|
||||
菜单管理
|
||||
</div>
|
||||
<div class="code-name">.icon-jiaoyixulie
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-jiaoseleixing"></span>
|
||||
<div class="name">
|
||||
角色类型
|
||||
</div>
|
||||
<div class="code-name">.icon-jiaoseleixing
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-gongnengjiaosequanxianguanli"></span>
|
||||
<div class="name">
|
||||
功能角色权限管理
|
||||
</div>
|
||||
<div class="code-name">.icon-gongnengjiaosequanxianguanli
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-yonghuguanli_huaban"></span>
|
||||
<div class="name">
|
||||
用户管理
|
||||
</div>
|
||||
<div class="code-name">.icon-yonghuguanli_huaban
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-jichupeizhi"></span>
|
||||
<div class="name">
|
||||
基础配置
|
||||
</div>
|
||||
<div class="code-name">.icon-jichupeizhi
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-trash-outline"></span>
|
||||
<div class="name">
|
||||
trash-outline
|
||||
</div>
|
||||
<div class="code-name">.icon-trash-outline
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="font-class-">font-class 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
|
||||
<p>与 Unicode 使用方式相比,具有如下特点:</p>
|
||||
<ul>
|
||||
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
|
||||
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
|
||||
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
|
||||
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
|
||||
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
|
||||
</code></pre>
|
||||
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><span class="iconfont icon-xxx"></span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"
|
||||
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-home-outline"></use>
|
||||
</svg>
|
||||
<div class="name">home-outline</div>
|
||||
<div class="code-name">#icon-home-outline</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-history"></use>
|
||||
</svg>
|
||||
<div class="name">history</div>
|
||||
<div class="code-name">#icon-history</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-exit-outline"></use>
|
||||
</svg>
|
||||
<div class="name">exit-outline</div>
|
||||
<div class="code-name">#icon-exit-outline</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-create-outline"></use>
|
||||
</svg>
|
||||
<div class="name">create-outline</div>
|
||||
<div class="code-name">#icon-create-outline</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-power-outline"></use>
|
||||
</svg>
|
||||
<div class="name">power-outline</div>
|
||||
<div class="code-name">#icon-power-outline</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-add-circle-outline"></use>
|
||||
</svg>
|
||||
<div class="name">add-circle-outline</div>
|
||||
<div class="code-name">#icon-add-circle-outline</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-caozuorizhi"></use>
|
||||
</svg>
|
||||
<div class="name">操作日志</div>
|
||||
<div class="code-name">#icon-caozuorizhi</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-jiaoyixulie"></use>
|
||||
</svg>
|
||||
<div class="name">菜单管理</div>
|
||||
<div class="code-name">#icon-jiaoyixulie</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-jiaoseleixing"></use>
|
||||
</svg>
|
||||
<div class="name">角色类型</div>
|
||||
<div class="code-name">#icon-jiaoseleixing</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-gongnengjiaosequanxianguanli"></use>
|
||||
</svg>
|
||||
<div class="name">功能角色权限管理</div>
|
||||
<div class="code-name">#icon-gongnengjiaosequanxianguanli</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-yonghuguanli_huaban"></use>
|
||||
</svg>
|
||||
<div class="name">用户管理</div>
|
||||
<div class="code-name">#icon-yonghuguanli_huaban</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-jichupeizhi"></use>
|
||||
</svg>
|
||||
<div class="name">基础配置</div>
|
||||
<div class="code-name">#icon-jichupeizhi</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-trash-outline"></use>
|
||||
</svg>
|
||||
<div class="name">trash-outline</div>
|
||||
<div class="code-name">#icon-trash-outline</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="symbol-">Symbol 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
|
||||
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
|
||||
<ul>
|
||||
<li>支持多色图标了,不再受单色限制。</li>
|
||||
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
|
||||
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
|
||||
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
|
||||
<pre><code class="language-html"><script src="./iconfont.js"></script>
|
||||
</code></pre>
|
||||
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
|
||||
<pre><code class="language-html"><style>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xxx"></use>
|
||||
</svg>
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.tab-container .content:first').show()
|
||||
|
||||
$('#tabs li').click(function (e) {
|
||||
var tabContent = $('.tab-container .content')
|
||||
var index = $(this).index()
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
return
|
||||
} else {
|
||||
$('#tabs li').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
|
||||
tabContent.hide().eq(index).fadeIn()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user