换成maven构建工具

This commit is contained in:
liwen
2020-12-29 21:48:00 +08:00
parent df481557b6
commit 4110bc5d20
301 changed files with 668 additions and 749 deletions

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

201
falsework-client/pom.xml Normal file
View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>fx-falsework</artifactId>
<groupId>org.epri</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>falsework-client</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<feign.version>10.9</feign.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.epri</groupId>
<artifactId>falsework-sever</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>jfoenix</groupId>
<artifactId>jfoenix</artifactId>
<version>${jfoenix.version}</version>
<scope>system</scope>
<systemPath>${basedir}/libs/jfoenix-8.0.10.jar</systemPath>
</dependency>
<dependency>
<groupId>datafx-flow</groupId>
<artifactId>datafx-flow</artifactId>
<version>${datafx.version}</version>
<scope>system</scope>
<systemPath>${basedir}/libs/datafx-flow-8.0.2-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>tilesfx</groupId>
<artifactId>tilesfx</artifactId>
<version>1.6.8</version>
<scope>system</scope>
<systemPath>${basedir}/libs/tilesfx-1.6.8.jar</systemPath>
</dependency>
<dependency>
<groupId>datafx-injection</groupId>
<artifactId>datafx-injection</artifactId>
<version>${datafx.version}</version>
<scope>system</scope>
<systemPath>${basedir}/libs/datafx-injection-8.0.2-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>datafx-eventsystem</groupId>
<artifactId>datafx-eventsystem</artifactId>
<version>${datafx.version}</version>
<scope>system</scope>
<systemPath>${basedir}/libs/datafx-eventsystem-8.0.2-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>datafx-core</groupId>
<artifactId>datafx-core</artifactId>
<version>${datafx.version}</version>
<scope>system</scope>
<systemPath>${basedir}/libs/datafx-core-8.0.2-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hystrix</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-ribbon</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx</artifactId>
<version>8.9</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-fontawesome5-pack</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.1-GA</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -0,0 +1,56 @@
Manifest-Version: 1.0
Main-Class: com.epri.fx.client.AppStartup
Class-Path: . libs/javax.inject-1.jar libs/tilesfx-1.6.8.jar libs/netfli
x-statistics-0.1.1.jar libs/jackson-core-2.11.0.jar libs/spring-boot-st
arter-security-2.3.0.RELEASE.jar libs/spring-boot-starter-logging-2.3.0
.RELEASE.jar libs/spring-web-5.2.6.RELEASE.jar libs/jackson-module-para
meter-names-2.11.0.jar libs/datafx-injection-8.0.2-SNAPSHOT.jar libs/pi
nyin4j-2.5.0.jar libs/okhttp-3.14.8.jar libs/spring-context-support-5.2
.6.RELEASE.jar libs/spring-boot-starter-json-2.3.0.RELEASE.jar libs/myb
atis-spring-2.0.5.jar libs/druid-spring-boot-starter-1.1.14.jar libs/Hi
kariCP-3.4.5.jar libs/xml-apis-1.0.b2.jar libs/datafx-core-8.0.2-SNAPSH
OT.jar libs/controlsfx-8.40.17.jar libs/pagehelper-spring-boot-autoconf
igure-1.2.5.jar libs/archaius-core-0.7.6.jar libs/commons-collections-3
.2.1.jar libs/servo-core-0.10.1.jar libs/feign-jackson-10.9.jar libs/ja
karta.annotation-api-1.3.5.jar libs/jsr305-3.0.1.jar libs/ribbon-loadba
lancer-2.3.0.jar libs/tomcat-embed-websocket-9.0.35.jar libs/spring-con
text-5.2.6.RELEASE.jar libs/slf4j-api-1.7.30.jar libs/mybatis-spring-bo
ot-autoconfigure-2.1.3.jar libs/spring-boot-starter-jdbc-2.3.0.RELEASE.
jar libs/okio-1.17.2.jar libs/spring-tx-5.2.6.RELEASE.jar libs/jackson-
datatype-jsr310-2.11.0.jar libs/commons-lang3-3.10.jar libs/spring-boot
-starter-cache-2.3.0.RELEASE.jar libs/jsr311-api-1.1.1.jar libs/hystrix
-core-1.5.18.jar libs/httpcore-4.4.13.jar libs/datafx-flow-8.0.2-SNAPSH
OT.jar libs/ribbon-core-2.3.0.jar libs/log4j-api-2.13.2.jar libs/lucene
-queryparser-7.4.0.jar libs/joda-time-2.10.1.jar libs/servo-internal-0.
10.1.jar libs/pagehelper-5.1.4.jar libs/annotations-2.0.0.jar libs/spri
ng-boot-starter-2.3.0.RELEASE.jar libs/lucene-core-7.4.0.jar libs/dom4j
-1.6.1.jar libs/feign-hystrix-10.9.jar libs/javassist-3.18.1-GA.jar lib
s/logback-classic-1.2.3.jar libs/observable-toogles-0.1.jar libs/DmJdbc
Driver-1.0.0.jar libs/jfoenix-8.0.10.jar libs/tomcat-embed-core-9.0.35.
jar libs/ikonli-javafx-2.4.0.jar libs/spring-security-config-5.3.2.RELE
ASE.jar libs/spring-boot-autoconfigure-2.3.0.RELEASE.jar libs/jakarta.e
l-3.0.3.jar libs/rxjava-1.3.8.jar libs/snakeyaml-1.26.jar libs/spring-s
ecurity-core-5.3.2.RELEASE.jar libs/spring-jdbc-5.2.6.RELEASE.jar libs/
lucene-sandbox-7.4.0.jar libs/pagehelper-spring-boot-starter-1.2.5.jar
libs/log4j-to-slf4j-2.13.2.jar libs/HdrHistogram-2.1.9.jar libs/jjwt-0.
7.0.jar libs/jersey-apache-client4-1.19.1.jar libs/spring-expression-5.
2.6.RELEASE.jar libs/lucene-queries-7.4.0.jar libs/spring-security-web-
5.3.2.RELEASE.jar libs/commons-logging-1.1.1.jar libs/feign-ribbon-10.9
.jar libs/feign-okhttp-10.9.jar libs/ikonli-fontawesome5-pack-2.4.0.jar
libs/feign-core-10.9.jar libs/druid-1.1.14.jar libs/spring-core-5.2.6.
RELEASE.jar libs/commons-configuration-1.8.jar libs/spring-boot-starter
-tomcat-2.3.0.RELEASE.jar libs/logback-core-1.2.3.jar libs/lucene-group
ing-7.4.0.jar libs/spring-beans-5.2.6.RELEASE.jar libs/datafx-eventsyst
em-8.0.2-SNAPSHOT.jar libs/spring-boot-starter-web-2.3.0.RELEASE.jar li
bs/jackson-datatype-jdk8-2.11.0.jar libs/togglz-core-2.0.1.Final.jar li
bs/mysql-connector-java-8.0.20.jar libs/spring-webmvc-5.2.6.RELEASE.jar
libs/jul-to-slf4j-1.7.30.jar libs/spring-jcl-5.2.6.RELEASE.jar libs/ne
tflix-commons-util-0.1.1.jar libs/spring-boot-2.3.0.RELEASE.jar libs/co
mmons-lang-2.6.jar libs/jackson-annotations-2.11.0.jar libs/jackson-dat
abind-2.11.0.jar libs/jersey-client-1.19.1.jar libs/fontawesomefx-8.9.j
ar libs/ribbon-httpclient-2.2.0.jar libs/ikonli-core-2.4.0.jar libs/myb
atis-3.5.5.jar libs/jersey-core-1.19.1.jar libs/guava-16.0.1.jar libs/s
pring-aop-5.2.6.RELEASE.jar libs/commons-codec-1.14.jar libs/mybatis-sp
ring-boot-starter-2.1.3.jar libs/httpclient-4.5.12.jar libs/feign-slf4j
-10.9.jar libs/jsqlparser-1.0.jar

View 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-light.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, 750);
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/login.css").toExternalForm(),AppStartup.class.getResource("/css/app-light.css").toExternalForm());
}
@Override
public void stop() throws Exception {
}
}

View File

@@ -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();
}
}

View 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;
}
}

View File

@@ -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();
// }
}
}

View File

@@ -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();
}

View File

@@ -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));
}
}

View File

@@ -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());
}
}
}
}
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,96 @@
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.JFXSpinner;
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;
@FXML
private JFXSpinner viewSpinner;
@PostConstruct
private void init() {
TextField textField = new TextField();
textField.setStyle("");
viewSpinner.visibleProperty().bind(tabPane.disableProperty());
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
@Override
public void changed(ObservableValue<? extends Tab> observable, Tab oldValue, Tab newValue) {
// groupDataModel.setSelectedGroupType(newValue.);
}
});
initData();
}
private void initData() {
ProcessChain.create().addRunnableInPlatformThread(() -> {
tabPane.getTabs().clear();
tabPane.setDisable(true);
})
.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()).withFinal(() -> {
tabPane.setDisable(false);
})
.run();
}
@OnEvent("refresh")
private void onRefresh(Event<String> e) {
System.err.println(this.getClass() + "\t" + e.getContent());
initData();
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,332 @@
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 io.datafx.eventsystem.Event;
import io.datafx.eventsystem.OnEvent;
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.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.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 VBox contentPane;
@FXML
private StackPane rootPane;
@FXML
private JFXSpinner viewSpinner;
@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());
saveButton.managedProperty().bind(saveButton.visibleProperty());
cancelButton.disableProperty().bind(saveButton.disableProperty().or(updateButton.disableProperty()));
viewSpinner.visibleProperty().bind(contentPane.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().addRunnableInPlatformThread(() -> {
contentPane.setDisable(true);
})
.addSupplierInExecutor(() -> Request.connector(GroupTypeFeign.class).getAllGroupTypes())
.addConsumerInPlatformThread(rel -> {
groupTypeDataModel.getGroupTypes().clear();
groupTypeDataModel.getGroupTypes().addAll(rel);
}).withFinal(() -> {
contentPane.setDisable(false);
})
.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);
}
@OnEvent("refresh")
private void onRefresh(Event<String> e) {
System.err.println(this.getClass() + "\t" + e.getContent());
initData();
}
}

View File

@@ -0,0 +1,269 @@
package com.epri.fx.client.gui.uicomponents.admin.log;
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.LogDataModel;
import com.epri.fx.client.model.UserDataModel;
import com.epri.fx.client.request.Request;
import com.epri.fx.client.request.feign.admin.LogFeign;
import com.epri.fx.client.request.feign.admin.UserFeign;
import com.epri.fx.client.request.feign.login.LoginFeign;
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.entity.log.GateLog;
import com.epri.fx.server.entity.log.LogInfo;
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.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 io.datafx.eventsystem.Event;
import io.datafx.eventsystem.OnEvent;
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/log/log_management.fxml", title = "操作日志")
public class LogManagementController {
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("search")
private Button searchBut;
@FXML
private Pagination pagination;
@FXML
private TableView<GateLog> tableView;
@FXML
private TableColumn<GateLog, String> serialNumberColumn;
@FXML
private TableColumn<GateLog, String> idColumn;
@FXML
private TableColumn<GateLog, String> menuColumn;
@FXML
private TableColumn<GateLog, String> optColumn;
@FXML
private TableColumn<GateLog, String> urlColumn;
@FXML
private TableColumn<GateLog, String> optTimeColumn;
@FXML
private TableColumn<GateLog, String> optUserIdColumn;
@FXML
private TableColumn<GateLog, String> optUserColumn;
@FXML
private TableColumn<GateLog, String> optIpColumn;
@FXML
private TableColumn<GateLog, String> requetDataColumn;
@ActionHandler
private FlowActionHandler actionHandler;
@Inject
private LogDataModel logDataModel;
@Inject
private FeatureResourceConsumer featureResourceConsumer;
@PostConstruct
public void init() {
featureResourceConsumer.consumeResource(this);
spinnerPane.setVisible(false);
serialNumberColumn.setCellFactory((col) -> {
TableCell<GateLog, String> cell = new TableCell<GateLog, 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;
});
idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
menuColumn.setCellValueFactory(new PropertyValueFactory<>("menu"));
optColumn.setCellValueFactory(new PropertyValueFactory<>("opt"));
urlColumn.setCellValueFactory(new PropertyValueFactory<>("uri"));
optTimeColumn.setCellValueFactory(new PropertyValueFactory<>("crtTime"));
optUserIdColumn.setCellValueFactory(new PropertyValueFactory<>("crtUser"));
optUserColumn.setCellValueFactory(new PropertyValueFactory<>("crtName"));
optIpColumn.setCellValueFactory(new PropertyValueFactory<>("crtHost"));
requetDataColumn.setCellValueFactory(new PropertyValueFactory<>("body"));
FilteredList<GateLog> filteredData = new FilteredList<>(logDataModel.getGateLogs(), 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.getMenu()).contains(val)
|| Pinyin4jUtil.toPinYinLowercase(elementProp.getCrtName()).contains(val)
|| elementProp.getCrtHost().toLowerCase().contains(val);
});
});
logDataModel.selectedPersonIndexProperty().bind(tableView.getSelectionModel().selectedIndexProperty());
pagination.pageCountProperty().bind(logDataModel.pageCountProperty());
pagination.setPageFactory(new Callback<Integer, Node>() {
@Override
public Node call(Integer param) {
showPage(param + 1);
return tableView;
}
});
}
private void delete() {
GateLog gateLog = logDataModel.getGateLogs().get(logDataModel.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("确实删除【" + gateLog.getId() + "】吗?"));
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(gateLog.getId()))
.addConsumerInPlatformThread(result -> {
if (result.isRel()) {
logDataModel.getGateLogs().remove(logDataModel.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(LogFeign.class).getPageList(queryMap)
)
.addConsumerInPlatformThread(result -> {
logDataModel.getGateLogs().clear();
List<GateLog> gateLogs = result.getDatas();
logDataModel.setPageCount((int) result.getTotal());
for (GateLog gateLog : gateLogs) {
logDataModel.getGateLogs().add(gateLog);
}
})
.withFinal(() -> {
spinnerPane.setVisible(false);
centPane.setDisable(false);
})
.onException(e -> e.printStackTrace())
.run();
}
@PreDestroy
private void destroy() {
System.err.println("destroy " + this);
}
@OnEvent("refresh")
private void onRefresh(Event<String> e) {
System.err.println(this.getClass() + "\t" + e.getContent());
search();
}
}

View File

@@ -0,0 +1,696 @@
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("refresh")
private void onRefresh(Event<String> e) {
System.err.println(this.getClass() + "\t" + e.getContent());
initTreeData();
}
}

View File

@@ -0,0 +1,390 @@
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 io.datafx.eventsystem.Event;
import io.datafx.eventsystem.OnEvent;
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();
}
@OnEvent("refresh")
private void onRefresh(Event<String> e) {
System.err.println(this.getClass() + "\t" + e.getContent());
search();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,487 @@
package com.epri.fx.client.gui.uicomponents.home;
import com.epri.fx.client.bean.CountryPath;
import com.epri.fx.client.store.ApplicatonStore;
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_DARK = Color.rgb(39, 49, 66); // #2a2a2a
public static final Color BACKGROUND_LIGHT = Color.rgb(255, 255, 255); // #2a2a2a
public static final Color FOREGROUND_DARK = Color.rgb(223, 223, 223); // #2a2a2a
public static final Color FOREGROUND_LIGHT = Color.rgb(52, 52, 52); // #2a2a2a
public static final Color BORDERCOLOR_DARK = Color.rgb(49, 61, 79); // #2a2a2a
public static final Color BORDERCOLOR_LIGHT = Color.rgb(185, 185, 185, 0.3f); // #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);
chartData1.setTextColor(FOREGROUND_LIGHT);
chartData2.setTextColor(FOREGROUND_LIGHT);
chartData3.setTextColor(FOREGROUND_LIGHT);
chartData4.setTextColor(FOREGROUND_LIGHT);
chartData5.setTextColor(FOREGROUND_LIGHT);
chartData6.setTextColor(FOREGROUND_LIGHT);
chartData7.setTextColor(FOREGROUND_LIGHT);
chartData8.setTextColor(FOREGROUND_LIGHT);
//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).foregroundBaseColor(FOREGROUND_LIGHT)
.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_LIGHT).borderColor(BORDERCOLOR_LIGHT).borderWidth(0.8d)
//.smoothing(true)
.build();
areaChartTile = TileBuilder.create()
.skinType(Tile.SkinType.SMOOTHED_CHART).foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).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).foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).borderWidth(0.8d)
.title("SmoothedChart Tile")
.animated(true)
.smoothing(false)
.series(series2, series3)
.build();
worldTile = TileBuilder.create()
.skinType(Tile.SkinType.WORLDMAP).foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).borderWidth(0.8d)
.title("WorldMap Tile")
.text("Whatever text")
.textVisible(false).shadowsEnabled(true)
.build();
radialChartTile = TileBuilder.create()
.skinType(Tile.SkinType.RADIAL_CHART).foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).borderWidth(0.8d)
.title("RadialChart")
.text("Some text")
.textVisible(false)
.chartData(chartData1, chartData2, chartData3, chartData4).shadowsEnabled(true)
.build();
donutChartTile = TileBuilder.create()
.skinType(Tile.SkinType.DONUT_CHART)
.title("DonutChart").foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).borderWidth(0.8d)
.text("Some text")
.textVisible(false)
.chartData(chartData1, chartData2, chartData3, chartData4)
.build();
circularProgressTile = TileBuilder.create()
.skinType(Tile.SkinType.CIRCULAR_PROGRESS)
.title("CircularProgress").foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).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).foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).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").foregroundBaseColor(FOREGROUND_LIGHT).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).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").foregroundBaseColor(FOREGROUND_LIGHT).borderWidth(0.8d).backgroundColor(BACKGROUND_LIGHT).borderRadius(14).borderColor(BORDERCOLOR_LIGHT).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;
}
}
};
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);
ApplicatonStore.styleProperty().addListener((observable, oldValue, newValue) -> {
centerPane.getChildren().forEach(node -> {
if (node instanceof Tile) {
if (newValue) {
((Tile) node).setBackgroundColor(BACKGROUND_DARK);
((Tile) node).setBorderColor(BORDERCOLOR_DARK);
((Tile) node).setForegroundBaseColor(FOREGROUND_DARK);
((Tile) node).setShadowsEnabled(true);
((Tile) node).getChartData().forEach(chartData -> {
chartData.setTextColor(FOREGROUND_DARK);
});
} else {
((Tile) node).setBackgroundColor(BACKGROUND_LIGHT);
((Tile) node).setBorderColor(BORDERCOLOR_LIGHT);
((Tile) node).setForegroundBaseColor(FOREGROUND_LIGHT);
((Tile) node).setShadowsEnabled(true);
((Tile) node).getChartData().forEach(chartData -> {
chartData.setTextColor(FOREGROUND_LIGHT);
});
}
}
});
});
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);
}
}
}
}
}

View File

@@ -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 {
}

View File

@@ -0,0 +1,535 @@
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.Request;
import com.epri.fx.client.request.feign.admin.MenuFeign;
import com.epri.fx.client.request.feign.login.LoginFeign;
import com.epri.fx.client.store.ApplicatonStore;
import com.epri.fx.client.utils.AlertUtil;
import com.epri.fx.client.websocket.Session;
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 com.jfoenix.svg.SVGGlyph;
import com.jfoenix.svg.SVGGlyphLoader;
import com.jfoenix.validation.RegexValidator;
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.binding.BooleanBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
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 StackPane rootPane;
@FXML
private Pane imagePane;
@FXML
private StackPane centerPane;
//正面视图
@FXML
public HBox loginPane;
//反面视图
@FXML
public HBox registeredPane;
@FXML
public Hyperlink registeredLink;
@FXML
public Hyperlink loginLink;
@FXML
private Label errorLabel;
@FXML
private Label userIcon;
@FXML
private Label pwdIcon;
@FXML
private Label reuserIcon;
@FXML
private Label repwdIcon;
@FXML
private Label repwd2Icon;
@FXML
private JFXProgressBar lodingBar;
@FXML
private JFXTextField userNameTextField;
@FXML
private JFXPasswordField passWordTextField;
@FXML
private JFXTextField reUserNameTextField;
@FXML
private JFXPasswordField rePwdTextField;
@FXML
private JFXPasswordField rePwd2TextField;
@FXML
private RegexValidator regexValidatorPwd2;
//翻转角度
private DoubleProperty angleProperty = new SimpleDoubleProperty(Math.PI / 2);
//正面翻转特效
private PerspectiveTransform frontEffect = new PerspectiveTransform();
//反面翻转特效
private PerspectiveTransform backEffect = new PerspectiveTransform();
private Timeline frontTimeLine = new Timeline();
private Timeline backTimeLine = new Timeline();
@ActionHandler
private FlowActionHandler actionHandler;
private SequentialTransition sequentialTransition = new SequentialTransition();
private DoubleProperty imageWidth = new SimpleDoubleProperty();
private DoubleProperty imageHeiht = new SimpleDoubleProperty();
@Inject
private Session session;
@FXML
@ActionTrigger("login")
private JFXButton loginBut;
@FXML
private JFXButton registeredBut;
@FXMLViewFlowContext
private ViewFlowContext flowContext;
@PostConstruct
public void init() {
try {
SVGGlyph userSvg = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".user-name");
SVGGlyph pwdSvg = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".password");
SVGGlyph reuserSvg = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".user-name");
SVGGlyph repwdSvg = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".password");
SVGGlyph repwd2Svg = SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".querenmima");
userSvg.setId("login-svg-glyph");
pwdSvg.setId("login-svg-glyph");
reuserSvg.setId("login-svg-glyph");
repwdSvg.setId("login-svg-glyph");
repwd2Svg.setId("login-svg-glyph");
userIcon.setGraphic(userSvg);
pwdIcon.setGraphic(pwdSvg);
reuserIcon.setGraphic(reuserSvg);
repwdIcon.setGraphic(repwdSvg);
repwd2Icon.setGraphic(repwd2Svg);
} catch (Exception e) {
e.printStackTrace();
}
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);
}
});
registeredPane.visibleProperty().bind(
Bindings.when(angleProperty.lessThan(0)).then(true).otherwise(false));
loginPane.visibleProperty().bind(registeredPane.visibleProperty().not());
loginPane.managedProperty().bind(loginPane.visibleProperty());
registeredPane.managedProperty().bind(registeredPane.visibleProperty());
initAnimation();
loadingImage();
initAction();
}
private void initAnimation() {
FadeTransition fadeTransition = new FadeTransition(Duration.millis(500), centerPane);
fadeTransition.setFromValue(0f);
fadeTransition.setToValue(1f);
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(500), centerPane);
translateTransition.setInterpolator(Interpolator.EASE_BOTH);
translateTransition.setFromY(400);
translateTransition.setToY(centerPane.getLayoutY());
ParallelTransition parallelTransition = new ParallelTransition();
parallelTransition.setDelay(Duration.millis(1500));
parallelTransition.getChildren().addAll(
fadeTransition,
translateTransition
);
parallelTransition.setCycleCount(1);
parallelTransition.play();
KeyFrame frame1 = new KeyFrame(Duration.ZERO, new KeyValue(angleProperty,
Math.PI / 2, Interpolator.LINEAR));
KeyFrame frame2 = new KeyFrame(Duration.seconds(0.7),
new EventHandler() {
@Override
public void handle(Event event) {
loginPane.setEffect(null);
registeredPane.setEffect(null);
}
}, new KeyValue(angleProperty, -Math.PI / 2, Interpolator.LINEAR));
KeyFrame frame3 = new KeyFrame(Duration.seconds(.7), new EventHandler() {
@Override
public void handle(Event event) {
loginPane.setEffect(null);
registeredPane.setEffect(null);
}
}, new KeyValue(angleProperty,
Math.PI / 2, Interpolator.LINEAR));
KeyFrame frame4 = new KeyFrame(Duration.ZERO, new KeyValue(angleProperty, -Math.PI / 2, Interpolator.LINEAR));
frontTimeLine.getKeyFrames().addAll(frame1, frame2);
backTimeLine.getKeyFrames().addAll(frame4, frame3);
}
private void setPT(PerspectiveTransform pt, double t) {
double width = 650;
double height = 450;
double radius = width / 2;
double back = height / 10;
pt.setUlx(radius - Math.sin(t) * radius);
pt.setUly(0 - Math.cos(t) * back);
pt.setUrx(radius + Math.sin(t) * radius);
pt.setUry(0 + Math.cos(t) * back);
pt.setLrx(radius + Math.sin(t) * radius);
pt.setLry(height - Math.cos(t) * back);
pt.setLlx(radius - Math.sin(t) * radius);
pt.setLly(height + Math.cos(t) * back);
}
private void loadingImage() {
ImageView logBack = new ImageView("/images/login.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();
}
private void initAction() {
errorLabel.visibleProperty().bind(errorLabel.textProperty().isNotEmpty());
errorLabel.managedProperty().bind(errorLabel.visibleProperty());
lodingBar.visibleProperty().bind(centerPane.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();
}
});
reUserNameTextField.focusedProperty().addListener((o, oldVal, newVal) -> {
if (!newVal) {
reUserNameTextField.validate();
}
});
rePwdTextField.focusedProperty().addListener((o, oldVal, newVal) -> {
if (!newVal) {
rePwdTextField.validate();
}
});
rePwd2TextField.focusedProperty().addListener((o, oldVal, newVal) -> {
if (!newVal) {
regexValidatorPwd2.setRegexPattern("^" + rePwdTextField.getText() + "$");
rePwd2TextField.validate();
}
});
reUserNameTextField.textProperty().addListener((observable, oldValue, newValue) -> {
reUserNameTextField.validate();
});
rePwdTextField.textProperty().addListener((o, oldVal, newVal) -> {
rePwdTextField.validate();
});
rePwd2TextField.textProperty().addListener((o, oldVal, newVal) -> {
regexValidatorPwd2.setRegexPattern("^" + rePwdTextField.getText() + "$");
rePwd2TextField.validate();
});
loginBut.disableProperty().bind(Bindings.or(
userNameTextField.textProperty().isEqualTo(""),
passWordTextField.textProperty().isEqualTo("")));
BooleanBinding b1 = Bindings.or(
reUserNameTextField.textProperty().isEqualTo(""),
rePwdTextField.textProperty().isEqualTo(""));
BooleanBinding b2 = Bindings.or(b1,
rePwd2TextField.textProperty().isEqualTo(""));
BooleanBinding b3 = Bindings.or(reUserNameTextField.activeValidatorProperty().isNotNull(), rePwdTextField.activeValidatorProperty().isNotNull());
BooleanBinding b4 = Bindings.or(b3, rePwd2TextField.activeValidatorProperty().isNotNull());
registeredBut.disableProperty().bind(Bindings.or(b2, b4));
rootPane.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.ENTER) {
if (loginBut.isDisable() == false) {
login();
}
}
});
angleProperty.addListener((observable, oldValue, newValue) -> {
setPT(frontEffect, angleProperty.get());
setPT(backEffect, angleProperty.get() - Math.PI);
});
registeredLink.setOnAction(event -> {
loginPane.setEffect(frontEffect);
registeredPane.setEffect(backEffect);
frontTimeLine.play();
});
loginLink.setOnAction(event -> {
loginPane.setEffect(frontEffect);
registeredPane.setEffect(backEffect);
backTimeLine.play();
});
}
/**
* @Description:登录
* @param: []
* @return: void
* @auther: liwen
* @date: 2020/11/6 9:56 上午
*/
@ActionMethod("login")
private void login() {
JwtAuthenticationRequest jwtAuthenticationRequest = new JwtAuthenticationRequest();
jwtAuthenticationRequest.setUsername(userNameTextField.getText());
jwtAuthenticationRequest.setPassword(EncryptUtil.getInstance().Base64Encode(passWordTextField.getText()));
ProcessChain.create()
.addRunnableInPlatformThread(() -> {
centerPane.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(() -> {
centerPane.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();
}
}

View File

@@ -0,0 +1,427 @@
package com.epri.fx.client.gui.uicomponents.main;
import com.epri.fx.client.AppStartup;
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.assets.JFoenixResources;
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.core.concurrent.ProcessChain;
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.time.format.DateTimeFormatter;
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 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 JFXToggleButton styleBut;
//刷新按钮
@FXML
@EventTrigger("refresh")
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
@EventTrigger("refresh")
private JFXDatePicker datePicker;
@Inject
private FeatureResourceConsumer featureResourceConsumer;
private final HashMap<String, Tab> tabsMap = new HashMap<>();
@PostConstruct
public void init() throws FlowException {
rootPane.getChildren().removeAll(navigationList);
rootPane.getChildren().removeAll(leftDrawer);
rootPane.getChildren().removeAll(tabPane);
userLabel.textProperty().bind(ApplicatonStore.nameProperty());
roleLabel.textProperty().bind(ApplicatonStore.getRoles().asString());
userButton.textProperty().bind(ApplicatonStore.nameProperty());
try {
homeButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".home-outline"));
refreshButton.setGraphic(SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".shuaxin1"));
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);
datePicker.valueProperty().addListener((observable, oldValue, newValue) ->{
refreshButton.fire();
});
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);
drawersStack.setEffect(null);
try {
addTab("主页", SVGGlyphLoader.getIcoMoonGlyph(ApplicatonStore.ICON_FONT_KEY + ".home-outline"), HomeController.class);
} catch (Exception e) {
e.printStackTrace();
}
styleBut.selectedProperty().bindBidirectional(ApplicatonStore.styleProperty());
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(0);
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("refresh")
private String refresh() {
return datePicker.getValue().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
}
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);
}
listView.setExpanded(true);
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 {
ProcessChain.create().addRunnableInPlatformThread(() -> {
String style1 = AppStartup.class.getResource("/css/app-light.css").toExternalForm();
String style2 = AppStartup.class.getResource("/css/app-dark.css").toExternalForm();
if (styleBut.isSelected()) {
styleBut.setText("明亮");
styleBut.getScene().getStylesheets().removeAll(style1);
styleBut.getScene().getStylesheets().addAll(style2);
} else {
styleBut.setText("黑暗");
styleBut.getScene().getStylesheets().removeAll(style2);
styleBut.getScene().getStylesheets().addAll(style1);
}
}).run();
}
@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();
}
}
}

View File

@@ -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() {
}
}

View File

@@ -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 "退出";
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,58 @@
package com.epri.fx.client.model;
import com.epri.fx.server.entity.log.GateLog;
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 LogDataModel {
private int counter = 0;
private ListProperty<GateLog> gateLogs;
private IntegerProperty pageCount;
private IntegerProperty selectedPersonIndex;
public ListProperty<GateLog> getGateLogs() {
if (gateLogs == null) {
ObservableList<GateLog> innerList = FXCollections.observableArrayList();
gateLogs = new SimpleListProperty<>(innerList);
}
return gateLogs;
}
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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View 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();
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,9 @@
package com.epri.fx.client.request.feign;
import feign.Headers;
@Headers("Content-Type: application/json")
public interface FeignAPI {
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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.User;
import com.epri.fx.server.entity.log.GateLog;
import com.epri.fx.server.entity.log.LogInfo;
import com.epri.fx.server.msg.ObjectRestResponse;
import com.epri.fx.server.msg.TableResultResponse;
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 LogFeign extends FeignAPI {
@RequestLine("GET /log/page")
TableResultResponse<GateLog> getPageList(@QueryMap Map<String, Object> map);
@RequestLine("DELETE /log/{id}")
ObjectRestResponse<Integer> delete(@Param("id") Integer id);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,200 @@
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 SimpleBooleanProperty style = new SimpleBooleanProperty();
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 boolean isStyle() {
return style.get();
}
public static SimpleBooleanProperty styleProperty() {
return style;
}
public static void setStyle(boolean style) {
ApplicatonStore.style.set(style);
}
public static void clearPermissionInfo() {
setName("");
getAllMenu().clear();
getMenuVoCells().clear();
getMenus().clear();
ApplicatonStore.getElements().clear();
getPermissionMenus().clear();
getRoles().clear();
getFeatureMap().clear();
}
}

View 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();
}
}

View 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";
}

View 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();
}
}

View File

@@ -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++);
}
}

View 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>

View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 87 KiB

View File

File diff suppressed because one or more lines are too long

View 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");
}

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,62 @@
/*******************************************************************************
* *
* login *
* *
******************************************************************************/
#login-title {
-fx-font-family: "Microsoft YaHei";
-fx-text-fill: #3e3e3e;
-fx-font-size: 30px;
}
#login-error-label {
-fx-font-family: "Microsoft YaHei";
-fx-text-fill: #f56363;
-fx-font-size: 14px;
}
#login-welcome-title {
-fx-font-family: "Microsoft YaHei";
-fx-font-weight: 100;
-fx-text-fill: #ffffff;
-fx-font-size: 45px;
}
#login-prompt {
-fx-font-family: "Microsoft YaHei";
-fx-font-weight: 100;
-fx-text-fill: #7a7a7a;
-fx-font-size: 12px;
}
#login-welcome-text {
-fx-font-family: "Microsoft YaHei";
-fx-font-weight: 100;
-fx-text-fill: #ffffff;
-fx-font-size: 20px;
}
#login-text-field {
-fx-background-color: transparent;
-fx-font-family: "Microsoft YaHei";
-fx-font-weight: 100;
-fx-font-size: 18px;
-fx-text-fill: -fx-light-text-color;
-fx-prompt-text-fill: #70665e;
-fx-alignment: top-left;
-jfx-focus-color: #0355a7;
-jfx-unfocus-color: -fx-light-text-color;
}
#login-text-field:error {
-jfx-focus-color: #D34336;
-jfx-unfocus-color: #D34336;
}
#login-svg-glyph{
-jfx-size: 20px;
-fx-background-color: #70665e;
}

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 426 KiB

View File

@@ -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;
}

View File

@@ -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">&#xe86b;</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">&#xe9b0;</span>
<div class="name">home-outline</div>
<div class="code-name">&amp;#xe9b0;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe752;</span>
<div class="name">history</div>
<div class="code-name">&amp;#xe752;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9ac;</span>
<div class="name">exit-outline</div>
<div class="code-name">&amp;#xe9ac;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9ad;</span>
<div class="name">create-outline</div>
<div class="code-name">&amp;#xe9ad;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9ae;</span>
<div class="name">power-outline</div>
<div class="code-name">&amp;#xe9ae;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9af;</span>
<div class="name">add-circle-outline</div>
<div class="code-name">&amp;#xe9af;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe65f;</span>
<div class="name">操作日志</div>
<div class="code-name">&amp;#xe65f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6a4;</span>
<div class="name">菜单管理</div>
<div class="code-name">&amp;#xe6a4;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe666;</span>
<div class="name">角色类型</div>
<div class="code-name">&amp;#xe666;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe642;</span>
<div class="name">功能角色权限管理</div>
<div class="code-name">&amp;#xe642;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe62d;</span>
<div class="name">用户管理</div>
<div class="code-name">&amp;#xe62d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe62e;</span>
<div class="name">基础配置</div>
<div class="code-name">&amp;#xe62e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xea8d;</span>
<div class="name">trash-outline</div>
<div class="code-name">&amp;#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"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</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">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
</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">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</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>

View File

@@ -0,0 +1,69 @@
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1600418906476'); /* IE9 */
src: url('iconfont.eot?t=1600418906476#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAt8AAsAAAAAFnwAAAssAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCEUAqdDJc8ATYCJAM4Cx4ABCAFhG0HggQbxhJFRoaNAyLgfTSy/8sEbgwBazyfESpePnvWFaq9JoDICGPC5EVuWee3DmvMC+JMx3AKICEEE4T+tNtUkeCafp5Off//i+9f7lqnSsVRV6ypmBqzMsjpxE6+Qc4ghudp5/vVZdglkEGQwQTGNJhMdqhLTy1LCcvvAuOGZCgByKu9CoJgvwpTGMbnMICDyX2ap6svuhXbvclqHRZ0vPVt1/WxtA0Fwqcp1tTW1Tz/mvu0yA4UsTrhTrhzbl/4ZffDJkf5OaYSoGVdoZIDQFVX1amsRlTC1mC4xTEroC3esQzro1YGCICauxBovSdkgBKD6Qh7HawqAaVjYmKSEaVX7pmxAbpARlnG43MAptr3jz6NowTAZBXYqlIqO5aD+Dz0ycRkNcknDEzlWQAwmw2AAAgBwAB0e+0lyBFDLFX7DmT0BAAbfPCn8TtEKFJpxYu06l9Ptlp5HnodtuFk7HnEhh3/DzxXABosNQUVJYxgyMghFKAOoGwQvoFTYyzJYqABz8M4sJRFgIMarAgcFGCV4KACW4FioAQv0ooBBq82cCCWbQQHBmwTOMjANoODHKwexQCB15MDQDHK6RlcAbQHzANkP3g6Wyq7x0iCDIaCPMAid3ziaQ85etQQyIb10dp6UZYVh3E6RijlP8tSvexseWrndlE2wIedbMwp23W7UY6zuK/Yj6PpnsTY54BZiHFL/wLMqoMIMEG1A3tJW99iIPNNlPV+8+Oe+VgTFKx/KFjoxx7hB/wxfliChTCswDZ5mpCU4Ez4PHs7w8I5BzAigMnOZGrKzeWE+KemgIDRX+e1p5aQ2vRe2pZcnH3aiviavKZw3rTyaHV+q16Iqk6DqoRruY50DzRswajF3YLlMZoUBhELX5YiOBfg3HLjCV7Gd9lC13FmrBeBuVFVWg843caNgJxW5mPlxTZI/27b3LwpVzVHZTQBmg/tncbLXZIVutXIHrg2XmJhBguTQqTYS7y1lNI+kOtGAtPNa6HYph2+X3Auq46m11RRxHZ07AeUU9mLGmm6wq+UbsRSelPXfHCsw4+lTx9w1k6hYZD0h/vgSzTTUwYBIQKFkP0uAcBlVNGPMfKkzymQYBkEC/B7gSnvW13YOrBw+gVgsVt54Ew0E9UToSHmATdcWbdxSzeS15Jm82XBOaTwar7xnf94zPzXRqUwynh27ALCIM0fZBIZ86aYSdaOZN1TidtAraEIcg15r4WDKitwnquU4dPQyR7j8dwK1Dh1nIxll0PdXTogpMAiQoIH6BEyjmfFBYOxmjxg8MD5XtNRgq6+vwDsT29nvJq/4WaevI8XWudIX3ceYLNSvwC6RW2lg+n5dmjTez21dAAWJZvKyo22JEvsWkGBU2qAEM/YsLZoNkylY7nu9aSBcbGqs/t1L4+atTlsKJokxUN7oTuu5syR8V77Ei3xVCt2FACM4ztuBCrPOYU436O7sCG2CP9HDbljo5bVZY9eBU5xy78FTvcBq6ndTFxRu/Z8w8pzLTUL3cqO1XbPQeI4QEhz33y7a7/b2kY2Wl61KlzHbOy4jrWm/9QaB1urJufjWPa8MjZ/PqlxbRtUvKI7FkrdGhk3G/+F+YE2b6vW5nLIr0rcfpUp/iCRPpbkzwTlw+hGFr5akCoQu+YVtsmrLKQEyzi6rnRzBP4xe9aapiBKnMDxinEKs0T+vErJ3ER9ixNcBe6W+SM6x5v5c+ij+cpd3aTRlqXU23n+2rngwonZb57OVjdvzRwsdpi3vQ7rFbntE/raGU44Y7EMer4/WB8Kcvw4mc2J3uBsQsap01MM4tkdYkFUxki1oq9scR3uhwcsWzYAg4AoXUy0hNqFotksWqCBh+nje61F+/6jpSkFH5lC1jU0NVxHLJA9Ltr3S5dQL9348eO4pjs0zlu6dLxDVMu8GUu9YkXdBps9LKXRZI8nuZRgS2j3oO5umpHN5pvWjI+iUZnyFfUb5zy8Q3VVE4LkaQTzDb2rq6O4jk0yOLB61JPXr0l9YeJKQ9u50xnnuUfDJ6aQWSdOzCKc6G2QWSkRE4/MCyQz5sa0TVpZSOpfv6ofyAmcqRaAmh3C8bU67sz+ZD6hIJGiS9ZQEXT19KUngjcE2nk+rZg9q/wcXldaNEG/HwCeH50zo7KkSaNwQPta9dgT0GYX8IyBj2r/tHg9t75Y+Tk/zymhynDKi23sZBupGaNp7DhdrbopAPTQKXYoP7BXpoU7y/fydxTOJdOycv6heC03uNxAMzwSGihO86flDXLI5ksayPfwtxUNxIDe7u/pdkuSJYOSigucZVCvMsUi7UIF3Z1bpACA8ceWsuJF1N0frlmZfD+ffjzdZazP2HkAOxF3eT94neDNKyPq0QMZUSZSjDgTg9KMeLsyz4uFfrGxfoVNIdbQZ2uXgHF70WDqjtT/HN7pkDsVG/TKze3VQDxSyg6fjCpxlxkz3Z/xJFy1z3afio8xZAr7hYrOnSps9qZE6kkEPX6MCrGGCWs5ZUWXzpk26yB9veQZHmEjCZER/DE9IgJJNkv4dEMwaiWhUpAEI0iFRqE8gS6EE6TpIyOx8flmZBRfaUKm7LVfLQkRxQzWS051gs5JHxDMb7lZIBj5jVqQS45HngTOQPMovYE1XeAwQ3WYWgeJ91mBFUFKCCKLLMOIzqaCde+JoSxPwzdIAf5XtbqJDIpIzw9XSB2Cvlwe1TK9ZR+hG7IlbMNYZ63PlQ0ZqMxlPSS9hKkyp3JsC63ON4Gi1M6dU5WGpgQadRegK/IeslRVQ/Eyvaump3lmT8xJ4KTpqeEpOYypqiZmcPYeB0NMcbGscLC3bpBepxyvwIr5ikUI9q5cOP8gvsmQjyteODbcSwj2+x6Yjwb2R7mcaDsf5Z0d/I6kh/vrkpO2HJZRavVmDytEL+1Ho2mcio96NDnatfbt9ey5xw8lnk9NPZ948ASW93ZgtMvkx6o450a6rdP0zuq4K5MNLkkWvGNzwc7jnsiYBbPzo5PGdArhns2K1vZcLCaKHvXMvVNw0uj86GYJbROamYUnjyluMC9D6BeFb8OuDt27Rwb4D6N4i56SHbWI684hrZvSoP4z1xMYMeyg9DKLuu89J3ApH87yJ5z8kQxO3eQOXBJBDzWFCqz2EMVmPZ12X7KiBD426s2Iww6sAMP+AtvJKk1/RETaQoqxxYZIJayW6XXEM1QfaibafkyMaZLX4/UZh8gM0qFnJXlK8nzDHcZPrX+sjAFiKjvYJP3vHAnkX74PLdK2/abU/D1tv+vPzrXHpRf/pzHYSP8pWxmw/vn7eLLA5hjwnS1pWP9ALKWOg0P/foIxZqj5dQD/KRtsPKjLY59a+tfssT/nYApuSHzhPsggPCRHRqMpyhHeIUctmGF2DVs9gUBNBQBBRiMH4W2muKUSkATh55FB+P0cGQfvNDniQ3LUbmnM/QI1/IJnLwyVQKvqTWFDoxZVcnbY+xNM6CumymSsX2CPNKo8yfb9HzAClzGJn00hopVmGtQ7mQD6ntTE1EEjiUXfdExTvZg0aWiIzkRioCK6YEupbaVRg4z0w8XZ1bv/BIygV+GYk25K/wLMwxdXcoksRfAHHVOdtC0HejOjINTSlDySkYHyTi3Q8x6iTP7hOqAhEjZH1+QopRfTaWlSv2d41Ck8fKdkr41LlGRF1XTDtGzH9QK7aYCYgvQ4wsGiF+LtAlaUEPOqudfK5V6XEy3Ak3HuqraNG+Smj1z6eVPRHohxt3jeYUUbrqFHuNw4eugBVxzNgyHlH0FKnkH/oRpXBBrb1OP9FlFhw4X/zxqrrsZiuhsbJihyr0vhytvKjCgCAAAA') format('woff2'),
url('iconfont.woff?t=1600418906476') format('woff'),
url('iconfont.ttf?t=1600418906476') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1600418906476#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-home-outline:before {
content: "\e9b0";
}
.icon-history:before {
content: "\e752";
}
.icon-exit-outline:before {
content: "\e9ac";
}
.icon-create-outline:before {
content: "\e9ad";
}
.icon-power-outline:before {
content: "\e9ae";
}
.icon-add-circle-outline:before {
content: "\e9af";
}
.icon-caozuorizhi:before {
content: "\e65f";
}
.icon-jiaoyixulie:before {
content: "\e6a4";
}
.icon-jiaoseleixing:before {
content: "\e666";
}
.icon-gongnengjiaosequanxianguanli:before {
content: "\e642";
}
.icon-yonghuguanli_huaban:before {
content: "\e62d";
}
.icon-jichupeizhi:before {
content: "\e62e";
}
.icon-trash-outline:before {
content: "\ea8d";
}

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,100 @@
{
"id": "2077973",
"name": "icon-font",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "17288958",
"name": "home-outline",
"font_class": "home-outline",
"unicode": "e9b0",
"unicode_decimal": 59824
},
{
"icon_id": "11488047",
"name": "history",
"font_class": "history",
"unicode": "e752",
"unicode_decimal": 59218
},
{
"icon_id": "17287306",
"name": "exit-outline",
"font_class": "exit-outline",
"unicode": "e9ac",
"unicode_decimal": 59820
},
{
"icon_id": "17287307",
"name": "create-outline",
"font_class": "create-outline",
"unicode": "e9ad",
"unicode_decimal": 59821
},
{
"icon_id": "17287308",
"name": "power-outline",
"font_class": "power-outline",
"unicode": "e9ae",
"unicode_decimal": 59822
},
{
"icon_id": "17287309",
"name": "add-circle-outline",
"font_class": "add-circle-outline",
"unicode": "e9af",
"unicode_decimal": 59823
},
{
"icon_id": "774447",
"name": "操作日志",
"font_class": "caozuorizhi",
"unicode": "e65f",
"unicode_decimal": 58975
},
{
"icon_id": "7133436",
"name": "菜单管理",
"font_class": "jiaoyixulie",
"unicode": "e6a4",
"unicode_decimal": 59044
},
{
"icon_id": "8605742",
"name": "角色类型",
"font_class": "jiaoseleixing",
"unicode": "e666",
"unicode_decimal": 58982
},
{
"icon_id": "11121526",
"name": "功能角色权限管理",
"font_class": "gongnengjiaosequanxianguanli",
"unicode": "e642",
"unicode_decimal": 58946
},
{
"icon_id": "12753449",
"name": "用户管理",
"font_class": "yonghuguanli_huaban",
"unicode": "e62d",
"unicode_decimal": 58925
},
{
"icon_id": "12820167",
"name": "基础配置",
"font_class": "jichupeizhi",
"unicode": "e62e",
"unicode_decimal": 58926
},
{
"icon_id": "17287082",
"name": "trash-outline",
"font_class": "trash-outline",
"unicode": "ea8d",
"unicode_decimal": 60045
}
]
}

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="home-outline" unicode="&#59824;" d="M832-64h-192c-17.6 0-32 14.4-32 32V240c0 8.8-7.2 16-16 16h-160c-8.8 0-16-7.2-16-16v-272c0-17.6-14.4-32-32-32H192c-35.2 0-64 28.8-64 64V472c0 17.6 14.4 32 32 32s32-14.4 32-32v-472h160V240c0 44.2 35.8 80 80 80h160c44.2 0 80-35.8 80-80v-240h160V472c0 17.6 14.4 32 32 32s32-14.4 32-32v-472c0-35.2-28.8-64-64-64zM64 352c-8.4 0-16.8 3.4-23.2 9.8-12.2 12.8-11.8 33 1 45.2L467.6 814.8c10.8 11 27 17.2 44.4 17.2h0.2c17.4 0 33.4-6.4 44.2-17.2l425.8-407.6c12.8-12.2 13.2-32.4 1-45.2-12.2-12.8-32.4-13.2-45.2-1L512.6 768h-1.2L86.2 360.8C80 355 72 352 64 352zM513.4 770z m-2.8 0zM800 506c-17.6 0-32 14.4-32 32V736h-32v-106c0-17.6-14.4-32-32-32s-32 14.4-32 32V768c0 17.6 14.4 32 32 32h96c17.6 0 32-14.4 32-32v-230c0-17.6-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="history" unicode="&#59218;" d="M512 736c194.410667 0 352-157.589333 352-352S706.410667 32 512 32l-2.538667 0.106667c-91.477333 7.274667-165.738667 38.08-221.44 91.989333L288 53.333333h-64V256H405.333333v-64h-92.842666c46.250667-56.917333 112.490667-88.725333 200.768-96l6.677333 0.106667C675.328 100.309333 800 227.605333 800 384c0 159.061333-128.938667 288-288 288S224 543.061333 224 384h-64c0 194.410667 157.589333 352 352 352zM469.333333 576h64v-160h160v-64H469.333333V576z" horiz-adv-x="1024" />
<glyph glyph-name="exit-outline" unicode="&#59820;" d="M560 32H176c-61.8 0-112 50.2-112 112V624c0 61.8 50.2 112 112 112h384c61.8 0 112-50.2 112-112v-80c0-17.6-14.4-32-32-32s-32 14.4-32 32v80c0 26.4-21.6 48-48 48H176c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h384c26.4 0 48 21.6 48 48v80c0 17.6 14.4 32 32 32s32-14.4 32-32v-80c0-61.8-50.2-112-112-112zM768 192c-8.2 0-16.4 3.2-22.6 9.4-12.4 12.4-12.4 32.8 0 45.2l137.4 137.4-137.4 137.4c-12.4 12.4-12.4 32.8 0 45.2 12.4 12.4 32.8 12.4 45.2 0l160-160c12.4-12.4 12.4-32.8 0-45.2l-160-160c-6.2-6.2-14.4-9.4-22.6-9.4zM928 352H382c-17.6 0-32 14.4-32 32s14.4 32 32 32h546c17.6 0 32-14.4 32-32s-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="create-outline" unicode="&#59821;" d="M688-32H208c-61.8 0-112 50.2-112 112V560c0 61.8 50.2 112 112 112h335c17.6 0 32-14.4 32-32s-14.4-32-32-32H208c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h480c26.4 0 48 21.6 48 48V448c0 17.6 14.4 32 32 32s32-14.4 32-32v-368c0-61.8-50.2-112-112-112zM919.8 789.6c-12 13.2-32.2 14-45.4 2.2-0.4-0.4-0.8-0.6-1-1L848.8 766c-6.2-6.2-6.2-16.4 0-22.6l22.6-22.6c6.2-6.2 16.4-6.2 22.6 0l24.2 24c12.2 12.2 13.4 32 1.6 44.8zM798.6 716L437.6 355.6c-2.2-2.2-3.8-4.8-4.6-7.8l-16.8-49.8c-1.2-4.2 1.2-8.4 5.2-9.8 1.4-0.4 3-0.4 4.4 0l49.8 16.8c3 0.8 5.6 2.4 7.8 4.6L844 670.6c7 7 7 18.4 0 25.4l-20 20c-7 7-18.2 7-25.4 0z" horiz-adv-x="1024" />
<glyph glyph-name="power-outline" unicode="&#59822;" d="M512-32c-229.4 0-416 186.6-416 416-0.4 124.2 54.2 241 149.6 320.6 13.6 11.4 33.8 9.4 45-4 11.4-13.6 9.4-33.8-4-45C205.8 588 159.6 489.2 160 384c0-194.2 158-352 352-352s352 158 352 352c0 105.4-46.8 204.4-128.2 271.2-13.6 11.2-15.6 31.4-4.4 45 11.2 13.6 31.4 15.6 45 4.4 96.4-79.2 151.8-196 151.8-320.8C928 154.6 741.4-32 512-32zM512 352c-17.6 0-32 14.4-32 32V768c0 17.6 14.4 32 32 32s32-14.4 32-32v-384c0-17.6-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="add-circle-outline" unicode="&#59823;" d="M512-32c-229.4 0-416 186.6-416 416S282.6 800 512 800s416-186.6 416-416-186.6-416-416-416z m0 768c-194 0-352-158-352-352s158-352 352-352 352 158 352 352S706 736 512 736zM512 192c-17.6 0-32 14.4-32 32V544c0 17.6 14.4 32 32 32s32-14.4 32-32v-320c0-17.6-14.4-32-32-32zM672 352H352c-17.6 0-32 14.4-32 32s14.4 32 32 32h320c17.6 0 32-14.4 32-32s-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="caozuorizhi" unicode="&#58975;" d="M977.668 483.9l-54.674-53.471-149.736 148.526 54.679 53.474c16.622 16.627 42.773 19.012 57.022 4.76l98.638-96.263c13.087-14.239 10.697-40.386-5.93-57.025l0 0 0 0 0 0 0 0zM747.134 554.015l150.917-147.345-358.875-354.122c-1.191-1.186-5.967-5.948-13.078-7.13-1.177 0-1.177 0-2.386-1.186l-187.751-58.246c-4.755-1.191-10.699-1.191-14.271 2.386-3.556 3.553-4.747 8.316-2.391 14.269l59.432 184.197c0 1.167 0 1.167 1.192 2.372 1.179 5.958 5.941 13.069 8.292 14.269l68.933 62.98-228.129 0c-9.517 0-17.833 10.72-17.833 19.003 0 9.534 8.316 20.213 17.833 20.213l263.802 0 254.31 248.341zM492.824 64.431l-92.704 91.49-24.958-77.249 39.217-39.211 78.444 24.97zM742.373 495.783c-4.758 4.744-14.273 4.744-19.013 0l-281.657-275.692c-5.939-4.744-5.939-14.255 0-19.008 4.76-4.753 14.275-4.753 19.019 0l280.449 275.685c5.963 4.757 5.963 13.075 1.201 19.014l0 0 0 0 0 0 0 0zM116.112-42.528c-9.494 0-18.996 3.572-18.996 13.069l0 751.022c-1.186 17.828 10.699 14.252 23.756 14.252l65.357 0 0-24.953c0-9.513 10.688-17.828 21.389-17.828 9.517 0 21.405 8.316 21.405 17.828l0 24.953 97.44 0 0-24.953c0-9.513 10.685-17.828 21.389-17.828 9.517 0 21.405 8.316 21.405 17.828l0 24.953 89.123 0 0-24.953c0-9.513 10.688-17.828 21.394-17.828 9.527 0 21.4 8.316 21.4 17.828l0 24.953 89.129 0 0-24.953c0-9.513 10.702-17.828 21.398-17.828 9.511 0 21.398 8.316 21.398 17.828l0 24.953 74.849 0c9.516 0 15.459-4.739 15.459-14.252l0-123.59 54.679 53.469 0 70.119c0 39.216-29.714 67.729-70.138 67.729l-76.044 0 0 46.361c0 9.517-10.697 17.828-21.403 17.828-9.502 0-21.384-8.311-21.384-17.828l0-46.345-89.129 0 0 46.345c0 9.517-10.688 17.828-21.408 17.828-9.513 0-21.38-8.311-21.38-17.828l0-46.345-89.132 0 0 46.345c0 9.517-10.699 17.828-21.4 17.828-9.518 0-21.389-8.311-21.389-17.828l0-46.345-97.447 0 0 46.345c0 9.517-10.697 17.828-21.4 17.828-9.516 0-21.386-8.311-21.386-17.828l0-46.345-64.174 0c-53.471 0-79.613-28.511-79.613-67.729l0-749.833c0-39.197 35.641-67.733 76.06-67.733l589.416 0c40.402 0 70.115 28.537 70.115 67.733l0 259.061-54.669-53.469 0-206.753c0-9.525-5.944-13.083-15.445-13.083M583.125 586.087l-355.294 0c-9.516 0-16.627-11.871-16.627-20.184 0-9.513 7.13-20.203 16.627-20.203l355.294 0c9.53 0 16.641 11.889 16.641 20.203 0 8.313-7.125 20.184-16.641 20.184l0 0 0 0 0 0 0 0zM583.125 449.439l-355.294 0c-9.516 0-16.627-11.871-16.627-20.198 0-9.516 7.13-20.184 16.627-20.184l355.294 0c9.53 0 16.641 11.885 16.641 20.184 0 8.328-7.125 20.198-16.641 20.198l0 0 0 0 0 0 0 0z" horiz-adv-x="1024" />
<glyph glyph-name="jiaoyixulie" unicode="&#59044;" d="M213.333333 597.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 597.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334zM213.333333 341.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 341.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334zM213.333333 85.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 85.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334z" horiz-adv-x="1024" />
<glyph glyph-name="jiaoseleixing" unicode="&#58982;" d="M491.6 366.8c-112 0-202.9 90.8-202.9 202.9s90.8 202.9 202.9 202.9c112 0 202.9-90.8 202.9-202.9s-90.9-202.9-202.9-202.9m0 463.7c-69.2 0-135.5-27.4-184.5-76.4-48.9-48.9-76.4-115.3-76.4-184.5 0-97.5 54.2-181.7 133.6-226.4C219.3 291.1 115 153.4 115-9.7c0-10 2.2-19.2 2.9-29.1h0.6c1.5-14.4 13.7-25.3 28.2-25.3s26.6 10.9 28.2 25.3h0.9c-0.8 9.8-2.9 19.1-2.9 29.1 0 84.5 33.5 165.6 93.3 225.4C325.9 275.4 407 309 491.5 309l29 2.9c130.1 14.6 231.7 123.8 231.7 257.8 0 143.9-116.6 260.6-260.6 260.8M889.3 86c-1.7 0.5-3.4 1-5.2 1H563.3c-11.9 0-21.6-9.7-21.6-21.6 0-11.9 9.7-21.6 21.6-21.6h271.5l-73.1-71.6c-4-3.9-6.2-9.3-6.2-14.9s2.3-11 6.2-14.9c8.4-8.3 21.9-8.3 30.3 0l109.5 107.8c4 4 6.3 9.4 6.3 15.1 0 5.7-2.3 11.1-6.3 15.1-3.4 3.1-7.7 5.1-12.2 5.6m-330.1 67.1c1.8-0.5 3.7-0.7 5.5-0.7h322.5c8-0.7 15.6 3.2 19.8 10 4.2 6.8 4.2 15.4 0 22.2-4.2 6.8-11.9 10.7-19.8 10h-273l73.4 72.7c6.2 6.2 8.1 15.5 4.7 23.5-3.3 8.1-11.2 13.4-19.9 13.4-5.7 0-11.1-2.3-15.2-6.3L547.3 189c-4-4-6.3-9.5-6.3-15.2 0-5.7 2.3-11.1 6.3-15.2 3.3-3 7.5-5 11.9-5.5" horiz-adv-x="1024" />
<glyph glyph-name="gongnengjiaosequanxianguanli" unicode="&#58946;" d="M339.84 428.16h-192A119.68 119.68 0 0 0 29.44 547.84v192A119.68 119.68 0 0 0 149.12 858.24h192a120.32 120.32 0 0 0 119.04-119.68v-192a120.32 120.32 0 0 0-120.32-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a40.32 40.32 0 0 1 40.32 39.68v192a40.32 40.32 0 0 1-40.32 39.68zM339.84-90.24h-192a119.68 119.68 0 0 0-118.4 119.68v192a119.68 119.68 0 0 0 119.68 118.4h192a120.32 120.32 0 0 0 120.32-119.68v-192a120.32 120.32 0 0 0-121.6-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a40.32 40.32 0 0 1 40.32 39.68v192a40.32 40.32 0 0 1-40.32 39.68zM874.24 428.16h-192A120.32 120.32 0 0 0 563.2 547.84v192A120.32 120.32 0 0 0 683.52 858.24h192a119.68 119.68 0 0 0 119.68-119.68v-192a119.68 119.68 0 0 0-120.96-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a39.68 39.68 0 0 1 39.68 39.68v192a39.68 39.68 0 0 1-39.68 39.68zM964.48 234.24H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM964.48 106.24H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM964.48-21.12H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM899.2 200.96a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 1 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08zM687.36 72.96a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 0 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08zM899.2-54.4a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 1 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08z" horiz-adv-x="1024" />
<glyph glyph-name="yonghuguanli_huaban" unicode="&#58925;" d="M767.23 413.39c35.1 31.02 57.35 75.93 57.35 126 0 86.84-65.08 158.94-151.38 167.72-17.47 1.77-33.28-11.03-35.08-28.61-1.78-17.58 11.03-33.28 28.61-35.06 53.5-5.45 93.84-50.17 93.84-104.05 0-53.31-39.88-97.98-92.75-103.92-11.64-1.3-20.63-8.96-25.12-18.91-0.04-0.08-0.08-0.15-0.12-0.22-1.24-2.8-1.94-5.7-2.33-8.82-0.2-1.16-0.82-2.15-0.88-3.35-0.05-0.89 0.35-1.66 0.37-2.53 0.03-0.53-0.19-1-0.13-1.53 0.09-0.8 0.53-1.44 0.68-2.21 2.18-14.73 13.84-26.58 29.28-27.44 119.3-6.59 216.69-101.45 226.55-220.66 1.38-16.72 15.38-29.36 31.86-29.36 0.88 0 1.77 0.03 2.67 0.11 17.61 1.45 30.7 16.91 29.25 34.53-9.75 117.84-87.27 216.63-192.67 258.31zM536.12 396.89c44.15 35.34 72.55 89.57 72.55 150.39 0 106.25-86.44 192.69-192.67 192.69s-192.67-86.44-192.67-192.69c0-60.81 28.4-115.05 72.55-150.39C170 350.63 75.68 234.45 64.11 94.67c-1.45-17.61 11.64-33.08 29.25-34.53 18.06-1.56 33.08 11.66 34.53 29.25C140.19 238.11 266.75 354.61 416 354.61s275.81-116.5 288.11-265.22c1.38-16.72 15.38-29.36 31.86-29.36 0.88 0 1.77 0.03 2.67 0.11 17.61 1.45 30.7 16.92 29.25 34.53C756.32 234.45 662 350.63 536.12 396.89zM287.33 547.28c0 70.95 57.72 128.69 128.67 128.69s128.67-57.73 128.67-128.69S486.95 418.61 416 418.61s-128.67 57.72-128.67 128.67z" horiz-adv-x="1024" />
<glyph glyph-name="jichupeizhi" unicode="&#58926;" d="M595.590747 162.166596a17.049549 17.049549 0 0 0-17.083683 16.725283l-0.494931 35.106028a16.895949 16.895949 0 0 0 17.083682 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283v-35.123094a16.861816 16.861816 0 0 0-16.964216-16.725283c-6.195181 0.1024-143.342503 0.1024-411.441965 0z m-0.819198-153.855538a17.049549 17.049549 0 0 0-17.083682 16.725283l0.341332 35.071895a16.895949 16.895949 0 0 0 17.066616 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283l-0.341332-34.952429a17.049549 17.049549 0 0 0-16.947149-16.844749H594.771549zM595.112881-128a17.049549 17.049549 0 0 0-17.100748 16.725283v34.59403a16.895949 16.895949 0 0 0 17.083682 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283v-34.474564c-0.119466-9.284239-7.679977-16.725283-16.964216-16.844749H595.112881z m-91.391725 297.91484c-119.978307 0-217.667614 96.085045-217.667614 214.20309s97.569841 214.203091 217.667614 214.203091c119.978307 0 217.667614-96.085045 217.667613-214.203091 0-25.002592-4.33492-49.783317-12.987694-73.181647h-83.711749a136.959589 136.959589 0 0 1 21.299136 73.181647c0 77.021636-63.880342 139.792647-142.267306 139.792648-78.250432 0-142.130774-62.771012-142.130774-139.792648 0-77.141102 63.760875-139.912114 142.130774-139.912113v-74.290977zM511.998464-76.800154v-34.474563c-0.119466-9.796237-7.321578-16.605817-17.220215-16.605817h-85.281877c-33.791899-0.375466-49.441985 34.474563-51.302247 68.164062l-17.407947 68.266462c-31.044174 12.987694-60.415819 28.023383-87.551738 47.95719l-71.04832-28.620714c-30.207909-15.359954-67.105932-4.710386-84.445613 24.40526L8.584508 203.689672a62.105414 62.105414 0 0 0 20.684738 84.20668l60.927817 46.421194a371.318353 371.318353 0 0 0 0 99.430102l-60.808351 46.438261a62.003014 62.003014 0 0 0-20.804204 83.831215l89.036532 151.671012a64.34114 64.34114 0 0 0 84.309081 24.524726l71.20192-28.603647a409.649971 409.649971 0 0 0 87.53467 49.527318l10.410636 75.024841A63.044078 63.044078 0 0 0 414.684623 895.996928h177.919466c34.184431 0 62.037147-26.128988 63.658476-59.681954l10.393568-75.161375a419.019543 419.019543 0 0 0 87.654137-49.527318l71.20192 28.467115a64.528873 64.528873 0 0 0 84.309081-24.388194l88.780533-151.551545a62.088347 62.088347 0 0 0-20.565271-84.206681 1143.036571 1143.036571 0 0 0-56.541697-45.055865c0-21.964734 0.409599-61.781148 1.211729-119.500441h-86.596007l-0.95573 149.844884 92.876521 70.689921-79.359762 135.457727-107.485544-45.448397-17.578614 14.745556a338.123786 338.123786 0 0 1-104.259954 58.931023l-21.418602 7.679977-15.837819 114.397523h-156.87633l-15.854885-114.397523-21.418603-7.679977a343.056037 343.056037 0 0 1-104.37942-59.05049l-17.459148-14.506623-108.338875 43.588136-78.489364-133.460933 92.859455-70.706988-4.095988-22.169533a325.801689 325.801689 0 0 1-5.683183-59.05049c0.119466-19.831407 1.979727-39.765214 5.563717-59.204089l3.976521-22.152467-92.739988-70.706988 79.615761-135.457727 97.689307 47.80359 153.019274-84.906412L426.665387-59.716472c43.946535 0.085333 66.6622 0.085333 68.112862 0C496.962776-59.904204 511.998464-68.198579 511.998464-76.800154z" horiz-adv-x="1024" />
<glyph glyph-name="trash-outline" unicode="&#60045;" d="M696-64H328c-51.8 0-93 40.4-96 94.2L192 670c-1.2 17.6 12.4 32.8 30 34 17.6 1.2 32.8-12.4 34-30l40-640v-0.4c1-20.2 14-33.6 32-33.6h368c18 0 30.8 13.6 32 34l40 640c1.2 17.6 16.4 31 34 30 17.6-1.2 31-16.2 30-34l-40-640c-3.4-54.4-43.8-94-96-94zM864 640H160c-17.6 0-32 14.4-32 32s14.4 32 32 32h704c17.6 0 32-14.4 32-32s-14.4-32-32-32zM640 640c-17.6 0-32 14.4-32 32V752.2c0 8.6-7.2 15.8-15.8 15.8h-160.4c-8.6 0-15.8-7.2-15.8-16v-80c0-17.6-14.4-32-32-32s-32 14.4-32 32V752c-0.2 44 35.6 79.8 79.6 80h160.6c43.8 0 79.6-35.6 79.8-79.6V672c0-17.6-14.4-32-32-32zM512 64c-17.6 0-32 14.4-32 32V544c0 17.6 14.4 32 32 32s32-14.4 32-32v-448c0-17.6-14.4-32-32-32zM384 64c-17.2 0-31.4 13.6-32 30.8l-16 448c-0.6 17.6 13.2 32.4 30.8 33.2 17.8 0.6 32.4-13.2 33.2-30.8l16-448c0.6-17.6-13.2-32.4-30.8-33.2h-1.2zM640 64h-1.2c-17.6 0.6-31.4 15.4-30.8 33.2l16 448c0.6 17.6 15.4 31.4 33.2 30.8 17.6-0.6 31.4-15.4 30.8-33.2l-16-448c-0.6-17.2-14.8-30.8-32-30.8z" horiz-adv-x="1024" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="chakan-copy" unicode="&#58884;" d="M512.852 119.731c-55.321 0-112.681 11.325-170.487 33.663-45.814 17.703-92.023 42.333-137.344 73.207-76.95 52.421-124.384 104.293-126.366 106.476l-12.49 13.757 12.49 13.758c1.982 2.183 49.416 54.055 126.365 106.476 45.321 30.874 91.53 55.505 137.343 73.208 57.807 22.338 115.167 33.663 170.488 33.663 55.322 0 112.681-11.326 170.487-33.663 45.814-17.703 92.023-42.333 137.344-73.208 76.949-52.421 124.384-104.293 126.365-106.476l12.49-13.757-12.49-13.757c-1.982-2.183-49.416-54.055-126.365-106.476-45.321-30.874-91.53-55.504-137.344-73.207-57.805-22.339-115.165-33.664-170.486-33.664zM122.429 346.836c18.801-18.469 56.324-52.908 106.476-86.975 66.62-45.254 169.961-99.197 283.947-99.197 114.335 0 217.976 54.255 284.786 99.767 49.879 33.979 86.998 68.061 105.646 86.396-18.802 18.471-56.328 52.914-106.485 86.984-66.621 45.254-169.962 99.197-283.947 99.197-113.986 0-217.327-53.944-283.947-99.197-50.149-34.064-87.671-68.503-106.476-86.975zM512.852 198.312c-81.724 0-148.212 66.626-148.212 148.524s66.487 148.524 148.212 148.524c81.724 0 148.212-66.627 148.212-148.524s-66.487-148.524-148.212-148.524zM512.852 454.427c-59.154 0-107.279-48.265-107.279-107.591s48.125-107.591 107.279-107.591 107.279 48.265 107.279 107.591c0 59.326-48.126 107.591-107.279 107.591z" horiz-adv-x="1024" />
<glyph glyph-name="shuaxin1" unicode="&#58887;" d="M512 52.48a322.987 322.987 0 0 0-269.653 146.347h-85.334A395.947 395.947 0 0 1 512-21.333a400.213 400.213 0 0 1 395.52 368.64h73.813l-108.373 147.2-108.373-147.2h70.4A327.253 327.253 0 0 0 512 52.48z m0 736.853a399.36 399.36 0 0 1-390.4-331.52H42.667L151.04 310.187l108.373 147.626h-64.426a326.827 326.827 0 0 0 317.013 256A322.133 322.133 0 0 0 756.907 600.32l14.08 3.413h73.386A393.813 393.813 0 0 1 512 789.333z" horiz-adv-x="1024" />
<glyph glyph-name="user-name" unicode="&#58882;" d="M652.3 333.29999999999995C741.6 382.70000000000005 802 477.8 802 587c0 160.2-129.8 290-290 290-160.2 0-290-129.8-290-290 0-109.2 60.4-204.3 149.7-253.7C184 273.79999999999995 48 98.29999999999995 48-109l58 0c0 224.2 181.8 406 406 406 224.2 0 406-181.8 406-406l58 0C976 98.29999999999995 840 273.79999999999995 652.3 333.29999999999995zM280 587c0 128.1 103.9 232 232 232 128.1 0 232-103.9 232-232 0-128.1-103.9-232-232-232C383.9 355 280 458.9 280 587z" horiz-adv-x="1024" />
<glyph glyph-name="querenmima" unicode="&#58890;" d="M236.002113 497.084103c0 51.11072-4.088858 102.22144 0 151.287731C248.268686 795.570707 370.934413 901.881004 520.177715 895.747717 661.243302 889.614431 775.731314 771.037561 777.775743 625.883117v-130.843443c10.222144 0 20.444288-2.044429 28.622003-2.044428 83.82158-2.044429 149.243302-69.510579 149.243302-153.33216v-306.664319c0-87.910438-67.46615-157.421017-157.421017-159.465445-190.131878-2.044429-380.263755-2.044429-572.440062 0-89.954867 0-157.421017 71.555008-157.421017 161.509874 0 91.999296 4.088858 183.998591-2.044429 273.953458-4.088858 96.088153 49.066291 179.909734 169.68759 188.087449zM512-56.956099h257.598028c75.643865 0 118.57687 42.933005 118.57687 118.576869V304.907797c0 79.732723-40.888576 120.621299-120.621299 122.665727h-511.107198c-77.688294 0-118.57687-42.933005-120.621299-118.57687v-247.375884c0-71.555008 44.977433-114.488012 116.532441-114.488012 87.910438-4.088858 173.776447-4.088858 259.642457-4.088857z m-212.620594 551.995773h412.974616v126.754585c0 104.265868-77.688294 190.131878-179.909734 202.398451-104.265868 12.266573-204.442879-55.199577-222.842738-157.421017-12.266573-55.199577-8.177715-112.443584-10.222144-171.732019z m0 0M352.534554 229.263931c14.311002 14.311002 36.799718 14.311002 51.11072 0l96.088153-96.088153c14.311002-14.311002 14.311002-36.799718 0-51.11072s-36.799718-14.311002-51.11072 0l-96.088153 96.088154c-14.311002 14.311002-14.311002 36.799718 0 51.110719z m0 0M671.465446 304.907797c14.311002-14.311002 14.311002-36.799718 0-51.11072l-171.732019-171.732019c-14.311002-14.311002-36.799718-14.311002-51.11072 0s-14.311002 36.799718 0 51.11072l171.732019 171.732019c14.311002 12.266573 36.799718 12.266573 51.11072 0z m0 0" horiz-adv-x="1024" />
<glyph glyph-name="password" unicode="&#58883;" d="M780.8 458.479c41.13 0 74.479-33.348 74.479-74.479v-347.546a74.479 74.479 0 0 0-74.479-74.479H234.667a74.479 74.479 0 0 0-74.48 74.48V384c0 41.13 33.349 74.479 74.48 74.479H780.8m0 74.479H234.667A148.958 148.958 0 0 1 85.709 384v-347.546a148.958 148.958 0 0 1 148.958-148.923H780.8a148.958 148.958 0 0 1 148.958 148.923V384A148.958 148.958 0 0 1 780.8 532.9580000000001zM507.733 806.025a173.739 173.739 0 0 0 173.739-173.773v-99.328H334.029v99.328A173.739 173.739 0 0 0 507.767 805.99m0 74.48a248.252 248.252 0 0 1-248.251-248.218v-173.773h496.503V632.2180000000001A248.252 248.252 0 0 1 507.733 880.503z m0-781.961a37.205 37.205 0 0 0-37.205 37.24V284.70500000000004a37.205 37.205 0 0 0 74.41 0v-148.958a37.205 37.205 0 0 0-37.205-37.205z" horiz-adv-x="1024" />
<glyph glyph-name="skin" unicode="&#59039;" d="M694 743.2a59.72 59.72 0 0 0 45.37-20.87L900.7 534 841 414.63l-38.62 38.62a29.87 29.87 0 0 1-51-21.12v-375.94a29.87 29.87 0 0 0-29.87-29.87H333.17a29.87 29.87 0 0 0-29.87 29.87V432.13a29.86 29.86 0 0 1-51 21.12l-38.63-38.62-89.59 119.48 161.33 188.23a59.71 59.71 0 0 0 45.36 20.86h6.08a89.58 89.58 0 0 0 46.79-13.2q76-46.55 128.74-46.55T641.13 730a89.59 89.59 0 0 0 46.8 13.19H694m0 59.74h-6.07a149.24 149.24 0 0 1-78-22c-50.95-31.2-81.16-37.75-97.54-37.75s-46.59 6.58-97.55 37.82a149.25 149.25 0 0 1-78 22h-6.08a119.31 119.31 0 0 1-90.72-41.73L78.72 573a59.75 59.75 0 0 1-2.43-74.72L165.9 378.8a59.74 59.74 0 0 1 77.66-15.89v-306.7a89.71 89.71 0 0 1 89.61-89.61h388.3a89.71 89.71 0 0 1 89.61 89.61V362.9a59.74 59.74 0 0 1 83.3 25l59.74 119.35a59.74 59.74 0 0 1-8.06 65.6L784.73 761.19A119.31 119.31 0 0 1 694 802.94z m0 0" horiz-adv-x="1024" />
<glyph glyph-name="shuaxin" unicode="&#59056;" d="M936.3 779c-0.6 24-18.8 39.1-45 38.5-26.1-0.5-39.6-16.5-43.9-40.5-2.2-12.4-1.5-25.4-1.6-38.2-0.2-21.8-0.1-43.5-0.1-65.3-3.4-1.5-6.8-3.1-10.2-4.6-11.4 11-22.6 22.2-34.3 32.9C696.4 798.6 571.9 834.7 432.6 813.2 235.8 783 90 618.9 72.9 414c-16-192.2 107.7-377.8 293.5-440.3 187.9-63.2 397 10.3 502.7 177 6.8 10.7 13.9 21.8 18 33.6 8.1 23 4 44.5-18.7 56.8-21.9 11.9-42.6 7.1-58.2-13-7.8-10.1-13.7-21.6-20.9-32-65.5-94.8-155.5-146.5-270.7-152.1C364.4 36.5 223 136.7 178 284.4 131.6 437 195.8 601.3 333.1 681.5c133.5 77.9 304.9 55.6 413-54.3 7.9-8 13.2-18.6 26.1-37.1-42.2 0-74.7 1.7-106.9-0.5-29.7-2.1-45.5-19.8-45.2-44.7 0.2-24.2 17.1-44.3 45.7-45 74.7-1.8 149.5-1.2 224.2-0.4 24.6 0.3 45 14.4 45.8 38.7 2.3 80.3 2.5 160.6 0.5 240.8z" horiz-adv-x="1024" />
<glyph glyph-name="admin" unicode="&#58880;" d="M512-119.68A501.12 501.12 0 1 0 1016.32 384 501.76 501.76 0 0 0 512-119.68zM512 818.56A437.12 437.12 0 1 1 952.32 384 437.76 437.76 0 0 1 512 818.56zM739.2 83.84h-448a57.6 57.6 0 0 0-55.68 59.52v30.72a144 144 0 0 0 75.52 128l147.84 51.84a171.52 171.52 0 0 0 113.28 0l144-50.56a144 144 0 0 0 79.36-131.84v-30.72a57.6 57.6 0 0 0-56.32-56.96z m-440.32 64h431.36v26.24a80.64 80.64 0 0 1-39.68 72.96L550.4 295.68a108.16 108.16 0 0 1-71.04 0l-144-50.56a81.28 81.28 0 0 1-36.48-71.68zM512 304.64a186.88 186.88 0 1 0 192 186.88 186.88 186.88 0 0 0-192-186.88zM512 614.4a122.88 122.88 0 1 1 128-122.88A122.88 122.88 0 0 1 512 614.4z" horiz-adv-x="1024" />
<glyph glyph-name="ChevronDownCircle" unicode="&#58881;" d="M512 810.666667c235.648 0 426.666667-191.018667 426.666667-426.666667s-191.018667-426.666667-426.666667-426.666667S85.333333 148.352 85.333333 384 276.352 810.666667 512 810.666667z m0-64a362.666667 362.666667 0 1 1 0-725.333334 362.666667 362.666667 0 0 1 0 725.333334zM318.72 470.613333a32 32 0 0 0 45.226667 0L512 322.56l148.053333 148.053333a32 32 0 1 0 45.226667-45.226666l-170.666667-170.666667a32 32 0 0 0-45.226666 0l-170.666667 170.666667a32 32 0 0 0 0 45.226666z" horiz-adv-x="1024" />
<glyph glyph-name="Energy-" unicode="&#58930;" d="M680 632c-9.6 0-18.4-1.6-27.2-3.2C625.6 678.4 572.8 712 512 712c-74.4 0-137.6-51.2-155.2-120.8-4 0.8-8 0.8-12.8 0.8-66.4 0-120-45.6-120-112h572c3.2 10.4 4 20.8 4 32 0 66.4-53.6 120-120 120zM790.4 534.4c-9.6 0-18.4 5.6-22.4 14.4-14.4 36-49.6 59.2-88 59.2-7.2 0-14.4-0.8-22.4-2.4-10.4-2.4-21.6 2.4-26.4 12-24 44-69.6 71.2-119.2 71.2-31.2 0-60.8-10.4-84.8-30.4-10.4-8-25.6-6.4-33.6 4s-6.4 25.6 4 33.6c32 25.6 72.8 40 114.4 40 61.6 0 118.4-30.4 152.8-80.8 5.6 0.8 10.4 0.8 16 0.8 57.6 0 110.4-34.4 132.8-88 4.8-12-0.8-26.4-12.8-31.2-4-1.6-7.2-2.4-10.4-2.4zM344 328c-79.2 0-144 64.8-144 144 0 40.8 16.8 79.2 47.2 106.4 9.6 8.8 24.8 8 33.6-1.6s8-24.8-1.6-33.6C259.2 524.8 248 499.2 248 472c0-52.8 43.2-96 96-96 32.8 0 62.4 16.8 80.8 44 6.4 10.4 19.2 13.6 30.4 8.8 18.4-8.8 37.6-12.8 56.8-12.8 28 0 54.4 8 76.8 24 8.8 6.4 20.8 5.6 28.8-1.6 17.6-14.4 40-22.4 62.4-22.4 13.6 0 24-10.4 24-24s-10.4-24-24-24c-28 0-55.2 8-78.4 23.2C574.4 376 544 368 512 368c-20 0-40 3.2-59.2 9.6C425.6 346.4 386.4 328 344 328zM768.8 13.6H256c-44 0-80 36-80 80V480h672.8v-386.4c0-44-36-80-80-80zM768.8-10.4H256c-57.6 0-104 46.4-104 104V480c0 6.4 2.4 12.8 7.2 16.8 4.8 4.8 10.4 7.2 16.8 7.2h672.8c13.6 0 24-10.4 24-24v-386.4c0-57.6-47.2-104-104-104zM200 456l0.8-362.4c0-31.2 24.8-56 56-56h512c31.2 0 56 24.8 56 56V456H200zM259.2-19.2a76.8 76.8 0 1 1 153.6 0 76.8 76.8 0 1 1-153.6 0ZM611.2-19.2a76.8 76.8 0 1 1 153.6 0 76.8 76.8 0 1 1-153.6 0ZM336-120c-56 0-100.8 45.6-100.8 100.8S280 81.6 336 81.6s100.8-45.6 100.8-100.8S391.2-120 336-120z m0 153.6c-29.6 0-52.8-24-52.8-52.8s24-52.8 52.8-52.8c29.6 0 52.8 24 52.8 52.8s-24 52.8-52.8 52.8zM688-120c-56 0-100.8 45.6-100.8 100.8S632 81.6 688 81.6s100.8-45.6 100.8-100.8S743.2-120 688-120z m0 153.6c-29.6 0-52.8-24-52.8-52.8s24-52.8 52.8-52.8 52.8 24 52.8 52.8-24 52.8-52.8 52.8zM344 568c-1.6 0-3.2 0-4.8 0.8-1.6 0-3.2 0.8-4.8 1.6-1.6 0.8-3.2 1.6-4 2.4-1.6 0.8-2.4 1.6-4 3.2-4 3.2-6.4 9.6-6.4 16 0 1.6 0 3.2 0.8 4.8 0 1.6 0.8 3.2 1.6 4.8 0.8 1.6 1.6 2.4 2.4 4 0.8 1.6 1.6 2.4 3.2 4 8.8 8.8 24.8 8.8 33.6 0 4.8-4.8 7.2-10.4 7.2-16.8 0-1.6 0-3.2-0.8-4.8 0-1.6-0.8-3.2-1.6-4.8-0.8-1.6-1.6-3.2-2.4-4-0.8-1.6-1.6-2.4-3.2-4-0.8-0.8-2.4-2.4-4-3.2-1.6-0.8-2.4-1.6-4-2.4-1.6-0.8-3.2-0.8-4.8-1.6H344zM688-120H152c-13.6 0-24 10.4-24 24s10.4 24 24 24h536c13.6 0 24-10.4 24-24s-11.2-24-24-24zM32-120c-6.4 0-12.8 2.4-16.8 7.2-0.8 0.8-2.4 2.4-3.2 4-0.8 1.6-1.6 2.4-2.4 4-0.8 0.8-1.6 2.4-1.6 4s-0.8 3.2-0.8 4.8c0 6.4 2.4 12.8 7.2 16.8 5.6 5.6 13.6 8 21.6 6.4 1.6 0 3.2-0.8 4.8-1.6 1.6-0.8 3.2-1.6 4-2.4 1.6-0.8 2.4-1.6 4-3.2 4.8-4.8 7.2-10.4 7.2-16.8v-4.8c0-1.6-0.8-3.2-1.6-4.8-0.8-1.6-1.6-3.2-2.4-4-0.8-1.6-1.6-2.4-3.2-4-4.8-3.2-11.2-5.6-16.8-5.6z" horiz-adv-x="1024" />
<glyph glyph-name="hangzheng" unicode="&#58952;" d="M508 295.33333333999997L48 520.8333333400001c-9.9 4.9-14 16.8-9.2 26.8 4.9 9.9 16.8 14 26.8 9.2l442.3-216.8 432.3 216.7c9.9 5 21.9 1 26.8-8.9 5-9.9 1-21.9-8.9-26.8L508 295.33333333999997zM56.8 518.63333334c-7.4 0-14.5 4.1-18 11.2-4.9 9.9-0.8 21.9 9.2 26.8L508 782.13333334l450-225.6c9.9-5 13.9-17 8.9-26.8s-17-13.9-26.8-8.9L507.8 737.43333334 65.6 520.63333334c-2.9-1.4-5.9-2-8.8-2zM508 115.33333333999997L48 340.83333333999997c-9.9 4.9-14 16.8-9.2 26.8 4.9 9.9 16.8 14 26.8 9.2l442.3-216.8 432.3 216.7c9.9 5 21.9 1 26.8-8.9 5-9.9 1-21.9-8.9-26.8L508 115.33333333999997zM508-64.66666666000003L48 160.83333333999997c-9.9 4.9-14 16.8-9.2 26.8 4.9 9.9 16.8 14 26.8 9.2l442.3-216.8 432.3 216.7c9.9 5 21.9 1 26.8-8.9 5-9.9 1-21.9-8.9-26.8L508-64.66666666000003z" horiz-adv-x="1024" />
<glyph glyph-name="jichucanshu" unicode="&#58927;" d="M809.3 708.3H214.7c-14.9 0-27-12.1-27-27v-594.6c0-14.9 12.1-27 27-27h594.6c14.9 0 27 12.1 27 27V681.3c0 14.9-12.1 27-27 27zM364.6 107c0 81.5 66.1 147.6 147.6 147.6S659.8 188.5 659.8 107H364.6z m424.4 0h-44.4c0 8.6-0.5 17.1-1.5 25.4l45.9 32.1-19.7 60-56.1-1.3c-8.3 14.3-18 27.6-29.1 39.7l18.4 53.1-51.1 37-44.6-33.9c-14.9 6.7-30.6 11.9-47 15.4L543.7 388h-63.1l-16.2-53.5c-16.9-3.5-33-9-48.3-16l-44.8 33.7-50.9-37.4 18.7-53c-11-12.2-20.7-25.6-28.9-39.9l-56.1 0.9-19.1-60.1 46-31.7c-0.8-7.9-1.2-15.9-1.2-24H235V507.8h554V107zM440.9 660.5c15.9 0 28.7-12.9 28.7-28.7S456.8 603 440.9 603c-15.9 0-28.7 12.9-28.7 28.7s12.8 28.8 28.7 28.8z m-90.6 0c15.9 0 28.7-12.9 28.7-28.7S366.2 603 350.3 603c-15.9 0-28.7 12.9-28.7 28.7s12.8 28.8 28.7 28.8z m-90.6 0c15.9 0 28.7-12.9 28.7-28.7S275.5 603 259.7 603c-15.9 0-28.7 12.9-28.7 28.7s12.8 28.8 28.7 28.8z" horiz-adv-x="1024" />
<glyph glyph-name="jichuxinxi" unicode="&#58908;" d="M512 480.6c53.3 0 96.6-43.3 96.6-96.6s-43.3-96.6-96.6-96.6-96.6 43.3-96.6 96.6 43.3 96.6 96.6 96.6m0 64c-88.7 0-160.6-71.9-160.6-160.6S423.3 223.4 512 223.4 672.6 295.3 672.6 384 600.7 544.6 512 544.6zM531.8-64.3h-39.6c-55.5 0-104.6 35.4-122 88.1l-5.6 16.9c-5 15.1-15.5 27.8-29.5 35.9l-0.6 0.3c-14.2 8.2-30.5 10.9-46 7.7L271 81c-8.7-1.8-17.5-2.7-26.1-2.7-45.3 0-87.9 23.9-111.2 64.3L113.8 177C86 225.1 92.2 285.2 129.1 326.7l11.4 12.8c10.6 11.9 16.4 27.3 16.3 43.5v1.9c0 16.2-5.8 31.7-16.3 43.5L129 441.3C92.2 482.8 86 542.9 113.8 591l19.8 34.3c27.8 48.1 83 72.9 137.3 61.6l16-3.3c15.6-3.2 31.9-0.5 45.9 7.7 0.9 0.5 1.8 1.1 2.7 1.6 13.9 8 24.3 20.7 29.4 35.8l5.2 15.6c17.5 52.7 66.5 88.1 122 88.1h39.6c55.5 0 104.6-35.4 122-88.1l5.2-15.6c5-15.1 15.4-27.8 29.4-35.8 0.9-0.5 1.8-1.1 2.7-1.6 14-8.2 30.3-10.9 45.9-7.7l16 3.3c54.4 11.2 109.6-13.5 137.3-61.6L910 591c27.8-48.1 21.6-108.3-15.3-149.7l-11.5-12.9c-10.5-11.8-16.3-27.2-16.3-43.4v-1.9c-0.1-16.1 5.7-31.6 16.3-43.5l11.4-12.8c36.9-41.5 43.1-101.7 15.3-149.7l-19.8-34.3c-27.8-48.1-83-72.8-137.3-61.6l-17.5 3.6c-15.5 3.2-31.8 0.5-45.9-7.7l-0.7-0.4c-14-8.1-24.5-20.8-29.5-35.9l-5.6-16.9c-17.2-52.8-66.3-88.2-121.8-88.2zM301.3 150c22.6 0 45-6 65.1-17.6l0.5-0.3c27.7-16 48.4-41.3 58.4-71.3l5.6-16.9c8.8-26.5 33.4-44.3 61.3-44.3h39.6c27.9 0 52.5 17.8 61.3 44.3l5.6 16.9c9.9 30 30.7 55.3 58.3 71.2l0.6 0.3c27.7 16 60 21.3 90.9 14.9l17.5-3.6c27.3-5.6 55 6.8 69 30.9l19.8 34.3c13.9 24.1 10.9 54.4-7.7 75.2l-11.4 13c-21.1 23.7-32.7 54.4-32.5 86.3v1.6c0 31.9 11.5 62.5 32.5 86l11.5 12.9c18.5 20.8 21.6 51 7.7 75.2L835 593.3c-13.9 24.1-41.7 36.6-69 30.9l-16-3.3c-31.1-6.4-63.5-1.1-91.2 15.1-0.7 0.4-1.5 0.9-2.2 1.3-27.6 15.8-48.3 41.1-58.3 71.2l-5.2 15.6c-8.8 26.5-33.4 44.3-61.3 44.3h-39.6c-27.9 0-52.5-17.8-61.3-44.3l-5.2-15.6c-10-30.1-30.7-55.4-58.3-71.2-0.7-0.4-1.5-0.9-2.2-1.3-27.7-16.2-60-21.5-91.2-15.1l-16 3.3c-27.3 5.6-55-6.8-69-30.9L169.2 559c-13.9-24.1-10.9-54.4 7.7-75.2l11.5-12.9c21-23.6 32.5-54.1 32.5-86.1v-1.6c0.1-31.9-11.4-62.6-32.5-86.3L177 284.1c-18.5-20.8-21.6-51-7.7-75.2l19.8-34.3c13.9-24.1 41.7-36.6 69-30.9l17.5 3.6c8.4 1.8 17.1 2.7 25.7 2.7z" horiz-adv-x="1024" />
<glyph glyph-name="tieluyunshu" unicode="&#59031;" d="M995.555556 365.79555600000003C878.364444 355.555556 554.382222 327.11111100000005 554.382222 327.11111100000005a581.404444 581.404444 0 0 0 5.404445 113.777778 2994.062222 2994.062222 0 0 1 433.208889-47.217778v88.177778c-218.453333 13.368889-405.617778 160.426667-405.617778 160.426667a286.435556 286.435556 0 0 1-222.72 74.524444 205.653333 205.653333 0 0 1-133.973334-59.164444 977.92 977.92 0 0 1-137.102222-181.191112c-46.933333-76.515556-67.128889-159.573333-26.453333-247.751111a398.222222 398.222222 0 0 1 48.071111-77.653333c4.266667-5.12 19.057778-28.444444 25.884444-28.444444a1339.733333 1339.733333 0 0 1-116.337777-84.195556h91.022222s59.448889 44.657778 119.182222 81.351111l122.026667-2.56c-25.884444-19.342222-80.782222-60.871111-121.742222-98.986667h91.022222s170.666667 126.293333 312.888889 155.022223l-14.506667-2.56c282.168889 80.213333 369.777778 85.333333 369.777778 85.333333zM83.057778 384c0 20.48 25.315556 36.977778 56.888889 36.977778s56.888889-16.497778 56.888889-36.977778-25.315556-36.977778-56.888889-36.977778-56.888889 16.497778-56.888889 36.977778z m217.315555 161.28l-113.777777 5.973333s50.915556 79.075556 67.128888 84.195556l70.257778-1.422222z m51.484445 85.333333l98.702222-3.128889v-89.031111l-118.613333 4.835556z m53.191111-210.204444c31.288889 0 56.888889-16.497778 56.888889-36.977778s-25.315556-36.977778-56.888889-36.977778-56.888889 16.497778-56.888889 36.977778 25.315556 36.977778 56.888889 36.977778z m0 0" horiz-adv-x="1024" />
<glyph glyph-name="yonghugl" unicode="&#58899;" d="M519.893333 358.82666700000004a229.333333 229.333333 0 1 0 229.333334 229.333333 229.546667 229.546667 0 0 0-229.333334-229.333333z m0 437.333333a208 208 0 1 1 208-208 208.213333 208.213333 0 0 1-208 208zM659.413333 21.33333300000004H146.133333v13.013334 4.48c0 188.586667 169.386667 341.333333 377.813334 341.333333v-21.333333c-194.986667 0-353.92-141.866667-356.266667-317.013334h491.733333zM738.346667 15.360000000000014l-15.146667 15.146667L841.386667 149.33333300000004H519.893333v21.333334h347.093334a10.666667 10.666667 0 0 0 7.466666-18.133334zM866.986667 202.66666699999996H519.893333a10.666667 10.666667 0 0 0-7.466666 18.133333l136.32 136.32 15.146666-15.146667-118.186666-117.973333h321.28z" horiz-adv-x="1024" />
<glyph glyph-name="quanxianfenpei" unicode="&#58891;" d="M576 871.104l343.168-198.144a64 64 0 0 0 31.616-62.464l-36.48-328a384 384 0 0 0-208.256-300.16l-165.12-83.648a64 64 0 0 0-57.856 0l-165.12 83.584a384 384 0 0 0-208.32 300.224L73.216 610.56a64 64 0 0 0 31.616 62.464L448 871.104a128 128 0 0 0 128 0z m-88.32-51.648l-7.68-3.776L136.832 617.6l36.48-327.936a320 320 0 0 1 160-242.944l13.504-7.232L512-44.224l165.12 83.648a320 320 0 0 1 171.52 234.88l2.112 15.296 36.48 327.936L544 815.68a64 64 0 0 1-56.32 3.776zM512 704a192 192 0 0 0 32-381.312V256h64a32 32 0 1 0 0-64h-64v-34.048h62.592a32 32 0 0 0 31.488-26.304l0.512-5.76a32 32 0 0 0-26.24-31.488l-5.76-0.512H512a32 32 0 0 0-31.488 26.24l-0.512 5.76V322.624A192 192 0 0 0 512 704z m0-64a128 128 0 1 1 0-256 128 128 0 0 1 0 256z" horiz-adv-x="1024" />
<glyph glyph-name="home-outline" unicode="&#59824;" d="M832-64h-192c-17.6 0-32 14.4-32 32V240c0 8.8-7.2 16-16 16h-160c-8.8 0-16-7.2-16-16v-272c0-17.6-14.4-32-32-32H192c-35.2 0-64 28.8-64 64V472c0 17.6 14.4 32 32 32s32-14.4 32-32v-472h160V240c0 44.2 35.8 80 80 80h160c44.2 0 80-35.8 80-80v-240h160V472c0 17.6 14.4 32 32 32s32-14.4 32-32v-472c0-35.2-28.8-64-64-64zM64 352c-8.4 0-16.8 3.4-23.2 9.8-12.2 12.8-11.8 33 1 45.2L467.6 814.8c10.8 11 27 17.2 44.4 17.2h0.2c17.4 0 33.4-6.4 44.2-17.2l425.8-407.6c12.8-12.2 13.2-32.4 1-45.2-12.2-12.8-32.4-13.2-45.2-1L512.6 768h-1.2L86.2 360.8C80 355 72 352 64 352zM513.4 770z m-2.8 0zM800 506c-17.6 0-32 14.4-32 32V736h-32v-106c0-17.6-14.4-32-32-32s-32 14.4-32 32V768c0 17.6 14.4 32 32 32h96c17.6 0 32-14.4 32-32v-230c0-17.6-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="history" unicode="&#59218;" d="M512 736c194.410667 0 352-157.589333 352-352S706.410667 32 512 32l-2.538667 0.106667c-91.477333 7.274667-165.738667 38.08-221.44 91.989333L288 53.333333h-64V256H405.333333v-64h-92.842666c46.250667-56.917333 112.490667-88.725333 200.768-96l6.677333 0.106667C675.328 100.309333 800 227.605333 800 384c0 159.061333-128.938667 288-288 288S224 543.061333 224 384h-64c0 194.410667 157.589333 352 352 352zM469.333333 576h64v-160h160v-64H469.333333V576z" horiz-adv-x="1024" />
<glyph glyph-name="exit-outline" unicode="&#59820;" d="M560 32H176c-61.8 0-112 50.2-112 112V624c0 61.8 50.2 112 112 112h384c61.8 0 112-50.2 112-112v-80c0-17.6-14.4-32-32-32s-32 14.4-32 32v80c0 26.4-21.6 48-48 48H176c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h384c26.4 0 48 21.6 48 48v80c0 17.6 14.4 32 32 32s32-14.4 32-32v-80c0-61.8-50.2-112-112-112zM768 192c-8.2 0-16.4 3.2-22.6 9.4-12.4 12.4-12.4 32.8 0 45.2l137.4 137.4-137.4 137.4c-12.4 12.4-12.4 32.8 0 45.2 12.4 12.4 32.8 12.4 45.2 0l160-160c12.4-12.4 12.4-32.8 0-45.2l-160-160c-6.2-6.2-14.4-9.4-22.6-9.4zM928 352H382c-17.6 0-32 14.4-32 32s14.4 32 32 32h546c17.6 0 32-14.4 32-32s-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="create-outline" unicode="&#59821;" d="M688-32H208c-61.8 0-112 50.2-112 112V560c0 61.8 50.2 112 112 112h335c17.6 0 32-14.4 32-32s-14.4-32-32-32H208c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h480c26.4 0 48 21.6 48 48V448c0 17.6 14.4 32 32 32s32-14.4 32-32v-368c0-61.8-50.2-112-112-112zM919.8 789.6c-12 13.2-32.2 14-45.4 2.2-0.4-0.4-0.8-0.6-1-1L848.8 766c-6.2-6.2-6.2-16.4 0-22.6l22.6-22.6c6.2-6.2 16.4-6.2 22.6 0l24.2 24c12.2 12.2 13.4 32 1.6 44.8zM798.6 716L437.6 355.6c-2.2-2.2-3.8-4.8-4.6-7.8l-16.8-49.8c-1.2-4.2 1.2-8.4 5.2-9.8 1.4-0.4 3-0.4 4.4 0l49.8 16.8c3 0.8 5.6 2.4 7.8 4.6L844 670.6c7 7 7 18.4 0 25.4l-20 20c-7 7-18.2 7-25.4 0z" horiz-adv-x="1024" />
<glyph glyph-name="power-outline" unicode="&#59822;" d="M512-32c-229.4 0-416 186.6-416 416-0.4 124.2 54.2 241 149.6 320.6 13.6 11.4 33.8 9.4 45-4 11.4-13.6 9.4-33.8-4-45C205.8 588 159.6 489.2 160 384c0-194.2 158-352 352-352s352 158 352 352c0 105.4-46.8 204.4-128.2 271.2-13.6 11.2-15.6 31.4-4.4 45 11.2 13.6 31.4 15.6 45 4.4 96.4-79.2 151.8-196 151.8-320.8C928 154.6 741.4-32 512-32zM512 352c-17.6 0-32 14.4-32 32V768c0 17.6 14.4 32 32 32s32-14.4 32-32v-384c0-17.6-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="add-circle-outline" unicode="&#59823;" d="M512-32c-229.4 0-416 186.6-416 416S282.6 800 512 800s416-186.6 416-416-186.6-416-416-416z m0 768c-194 0-352-158-352-352s158-352 352-352 352 158 352 352S706 736 512 736zM512 192c-17.6 0-32 14.4-32 32V544c0 17.6 14.4 32 32 32s32-14.4 32-32v-320c0-17.6-14.4-32-32-32zM672 352H352c-17.6 0-32 14.4-32 32s14.4 32 32 32h320c17.6 0 32-14.4 32-32s-14.4-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="caozuorizhi" unicode="&#58975;" d="M977.668 483.9l-54.674-53.471-149.736 148.526 54.679 53.474c16.622 16.627 42.773 19.012 57.022 4.76l98.638-96.263c13.087-14.239 10.697-40.386-5.93-57.025l0 0 0 0 0 0 0 0zM747.134 554.015l150.917-147.345-358.875-354.122c-1.191-1.186-5.967-5.948-13.078-7.13-1.177 0-1.177 0-2.386-1.186l-187.751-58.246c-4.755-1.191-10.699-1.191-14.271 2.386-3.556 3.553-4.747 8.316-2.391 14.269l59.432 184.197c0 1.167 0 1.167 1.192 2.372 1.179 5.958 5.941 13.069 8.292 14.269l68.933 62.98-228.129 0c-9.517 0-17.833 10.72-17.833 19.003 0 9.534 8.316 20.213 17.833 20.213l263.802 0 254.31 248.341zM492.824 64.431l-92.704 91.49-24.958-77.249 39.217-39.211 78.444 24.97zM742.373 495.783c-4.758 4.744-14.273 4.744-19.013 0l-281.657-275.692c-5.939-4.744-5.939-14.255 0-19.008 4.76-4.753 14.275-4.753 19.019 0l280.449 275.685c5.963 4.757 5.963 13.075 1.201 19.014l0 0 0 0 0 0 0 0zM116.112-42.528c-9.494 0-18.996 3.572-18.996 13.069l0 751.022c-1.186 17.828 10.699 14.252 23.756 14.252l65.357 0 0-24.953c0-9.513 10.688-17.828 21.389-17.828 9.517 0 21.405 8.316 21.405 17.828l0 24.953 97.44 0 0-24.953c0-9.513 10.685-17.828 21.389-17.828 9.517 0 21.405 8.316 21.405 17.828l0 24.953 89.123 0 0-24.953c0-9.513 10.688-17.828 21.394-17.828 9.527 0 21.4 8.316 21.4 17.828l0 24.953 89.129 0 0-24.953c0-9.513 10.702-17.828 21.398-17.828 9.511 0 21.398 8.316 21.398 17.828l0 24.953 74.849 0c9.516 0 15.459-4.739 15.459-14.252l0-123.59 54.679 53.469 0 70.119c0 39.216-29.714 67.729-70.138 67.729l-76.044 0 0 46.361c0 9.517-10.697 17.828-21.403 17.828-9.502 0-21.384-8.311-21.384-17.828l0-46.345-89.129 0 0 46.345c0 9.517-10.688 17.828-21.408 17.828-9.513 0-21.38-8.311-21.38-17.828l0-46.345-89.132 0 0 46.345c0 9.517-10.699 17.828-21.4 17.828-9.518 0-21.389-8.311-21.389-17.828l0-46.345-97.447 0 0 46.345c0 9.517-10.697 17.828-21.4 17.828-9.516 0-21.386-8.311-21.386-17.828l0-46.345-64.174 0c-53.471 0-79.613-28.511-79.613-67.729l0-749.833c0-39.197 35.641-67.733 76.06-67.733l589.416 0c40.402 0 70.115 28.537 70.115 67.733l0 259.061-54.669-53.469 0-206.753c0-9.525-5.944-13.083-15.445-13.083M583.125 586.087l-355.294 0c-9.516 0-16.627-11.871-16.627-20.184 0-9.513 7.13-20.203 16.627-20.203l355.294 0c9.53 0 16.641 11.889 16.641 20.203 0 8.313-7.125 20.184-16.641 20.184l0 0 0 0 0 0 0 0zM583.125 449.439l-355.294 0c-9.516 0-16.627-11.871-16.627-20.198 0-9.516 7.13-20.184 16.627-20.184l355.294 0c9.53 0 16.641 11.885 16.641 20.184 0 8.328-7.125 20.198-16.641 20.198l0 0 0 0 0 0 0 0z" horiz-adv-x="1024" />
<glyph glyph-name="jiaoyixulie" unicode="&#59044;" d="M213.333333 597.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 597.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334zM213.333333 341.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 341.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334zM213.333333 85.333333H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM896 85.333333H384a42.666667 42.666667 0 0 0 0 85.333334h512a42.666667 42.666667 0 0 0 0-85.333334z" horiz-adv-x="1024" />
<glyph glyph-name="jiaoseleixing" unicode="&#58982;" d="M491.6 366.8c-112 0-202.9 90.8-202.9 202.9s90.8 202.9 202.9 202.9c112 0 202.9-90.8 202.9-202.9s-90.9-202.9-202.9-202.9m0 463.7c-69.2 0-135.5-27.4-184.5-76.4-48.9-48.9-76.4-115.3-76.4-184.5 0-97.5 54.2-181.7 133.6-226.4C219.3 291.1 115 153.4 115-9.7c0-10 2.2-19.2 2.9-29.1h0.6c1.5-14.4 13.7-25.3 28.2-25.3s26.6 10.9 28.2 25.3h0.9c-0.8 9.8-2.9 19.1-2.9 29.1 0 84.5 33.5 165.6 93.3 225.4C325.9 275.4 407 309 491.5 309l29 2.9c130.1 14.6 231.7 123.8 231.7 257.8 0 143.9-116.6 260.6-260.6 260.8M889.3 86c-1.7 0.5-3.4 1-5.2 1H563.3c-11.9 0-21.6-9.7-21.6-21.6 0-11.9 9.7-21.6 21.6-21.6h271.5l-73.1-71.6c-4-3.9-6.2-9.3-6.2-14.9s2.3-11 6.2-14.9c8.4-8.3 21.9-8.3 30.3 0l109.5 107.8c4 4 6.3 9.4 6.3 15.1 0 5.7-2.3 11.1-6.3 15.1-3.4 3.1-7.7 5.1-12.2 5.6m-330.1 67.1c1.8-0.5 3.7-0.7 5.5-0.7h322.5c8-0.7 15.6 3.2 19.8 10 4.2 6.8 4.2 15.4 0 22.2-4.2 6.8-11.9 10.7-19.8 10h-273l73.4 72.7c6.2 6.2 8.1 15.5 4.7 23.5-3.3 8.1-11.2 13.4-19.9 13.4-5.7 0-11.1-2.3-15.2-6.3L547.3 189c-4-4-6.3-9.5-6.3-15.2 0-5.7 2.3-11.1 6.3-15.2 3.3-3 7.5-5 11.9-5.5" horiz-adv-x="1024" />
<glyph glyph-name="gongnengjiaosequanxianguanli" unicode="&#58946;" d="M339.84 428.16h-192A119.68 119.68 0 0 0 29.44 547.84v192A119.68 119.68 0 0 0 149.12 858.24h192a120.32 120.32 0 0 0 119.04-119.68v-192a120.32 120.32 0 0 0-120.32-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a40.32 40.32 0 0 1 40.32 39.68v192a40.32 40.32 0 0 1-40.32 39.68zM339.84-90.24h-192a119.68 119.68 0 0 0-118.4 119.68v192a119.68 119.68 0 0 0 119.68 118.4h192a120.32 120.32 0 0 0 120.32-119.68v-192a120.32 120.32 0 0 0-121.6-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a40.32 40.32 0 0 1 40.32 39.68v192a40.32 40.32 0 0 1-40.32 39.68zM874.24 428.16h-192A120.32 120.32 0 0 0 563.2 547.84v192A120.32 120.32 0 0 0 683.52 858.24h192a119.68 119.68 0 0 0 119.68-119.68v-192a119.68 119.68 0 0 0-120.96-118.4z m-192 350.08a39.68 39.68 0 0 1-39.68-39.68v-192a39.68 39.68 0 0 1 39.68-39.68h192a39.68 39.68 0 0 1 39.68 39.68v192a39.68 39.68 0 0 1-39.68 39.68zM964.48 234.24H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM964.48 106.24H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM964.48-21.12H616.96a30.08 30.08 0 0 0 0 60.16h347.52a30.08 30.08 0 0 0 0-60.16zM899.2 200.96a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 1 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08zM687.36 72.96a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 0 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08zM899.2-54.4a30.08 30.08 0 0 0-30.08 30.08v64a30.08 30.08 0 1 0 60.16 0v-64a30.08 30.08 0 0 0-30.08-30.08z" horiz-adv-x="1024" />
<glyph glyph-name="yonghuguanli_huaban" unicode="&#58925;" d="M767.23 413.39c35.1 31.02 57.35 75.93 57.35 126 0 86.84-65.08 158.94-151.38 167.72-17.47 1.77-33.28-11.03-35.08-28.61-1.78-17.58 11.03-33.28 28.61-35.06 53.5-5.45 93.84-50.17 93.84-104.05 0-53.31-39.88-97.98-92.75-103.92-11.64-1.3-20.63-8.96-25.12-18.91-0.04-0.08-0.08-0.15-0.12-0.22-1.24-2.8-1.94-5.7-2.33-8.82-0.2-1.16-0.82-2.15-0.88-3.35-0.05-0.89 0.35-1.66 0.37-2.53 0.03-0.53-0.19-1-0.13-1.53 0.09-0.8 0.53-1.44 0.68-2.21 2.18-14.73 13.84-26.58 29.28-27.44 119.3-6.59 216.69-101.45 226.55-220.66 1.38-16.72 15.38-29.36 31.86-29.36 0.88 0 1.77 0.03 2.67 0.11 17.61 1.45 30.7 16.91 29.25 34.53-9.75 117.84-87.27 216.63-192.67 258.31zM536.12 396.89c44.15 35.34 72.55 89.57 72.55 150.39 0 106.25-86.44 192.69-192.67 192.69s-192.67-86.44-192.67-192.69c0-60.81 28.4-115.05 72.55-150.39C170 350.63 75.68 234.45 64.11 94.67c-1.45-17.61 11.64-33.08 29.25-34.53 18.06-1.56 33.08 11.66 34.53 29.25C140.19 238.11 266.75 354.61 416 354.61s275.81-116.5 288.11-265.22c1.38-16.72 15.38-29.36 31.86-29.36 0.88 0 1.77 0.03 2.67 0.11 17.61 1.45 30.7 16.92 29.25 34.53C756.32 234.45 662 350.63 536.12 396.89zM287.33 547.28c0 70.95 57.72 128.69 128.67 128.69s128.67-57.73 128.67-128.69S486.95 418.61 416 418.61s-128.67 57.72-128.67 128.67z" horiz-adv-x="1024" />
<glyph glyph-name="jichupeizhi" unicode="&#58926;" d="M595.590747 162.166596a17.049549 17.049549 0 0 0-17.083683 16.725283l-0.494931 35.106028a16.895949 16.895949 0 0 0 17.083682 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283v-35.123094a16.861816 16.861816 0 0 0-16.964216-16.725283c-6.195181 0.1024-143.342503 0.1024-411.441965 0z m-0.819198-153.855538a17.049549 17.049549 0 0 0-17.083682 16.725283l0.341332 35.071895a16.895949 16.895949 0 0 0 17.066616 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283l-0.341332-34.952429a17.049549 17.049549 0 0 0-16.947149-16.844749H594.771549zM595.112881-128a17.049549 17.049549 0 0 0-17.100748 16.725283v34.59403a16.895949 16.895949 0 0 0 17.083682 16.725283h411.936897c9.284239 0 16.844749-7.441044 16.964216-16.725283v-34.474564c-0.119466-9.284239-7.679977-16.725283-16.964216-16.844749H595.112881z m-91.391725 297.91484c-119.978307 0-217.667614 96.085045-217.667614 214.20309s97.569841 214.203091 217.667614 214.203091c119.978307 0 217.667614-96.085045 217.667613-214.203091 0-25.002592-4.33492-49.783317-12.987694-73.181647h-83.711749a136.959589 136.959589 0 0 1 21.299136 73.181647c0 77.021636-63.880342 139.792647-142.267306 139.792648-78.250432 0-142.130774-62.771012-142.130774-139.792648 0-77.141102 63.760875-139.912114 142.130774-139.912113v-74.290977zM511.998464-76.800154v-34.474563c-0.119466-9.796237-7.321578-16.605817-17.220215-16.605817h-85.281877c-33.791899-0.375466-49.441985 34.474563-51.302247 68.164062l-17.407947 68.266462c-31.044174 12.987694-60.415819 28.023383-87.551738 47.95719l-71.04832-28.620714c-30.207909-15.359954-67.105932-4.710386-84.445613 24.40526L8.584508 203.689672a62.105414 62.105414 0 0 0 20.684738 84.20668l60.927817 46.421194a371.318353 371.318353 0 0 0 0 99.430102l-60.808351 46.438261a62.003014 62.003014 0 0 0-20.804204 83.831215l89.036532 151.671012a64.34114 64.34114 0 0 0 84.309081 24.524726l71.20192-28.603647a409.649971 409.649971 0 0 0 87.53467 49.527318l10.410636 75.024841A63.044078 63.044078 0 0 0 414.684623 895.996928h177.919466c34.184431 0 62.037147-26.128988 63.658476-59.681954l10.393568-75.161375a419.019543 419.019543 0 0 0 87.654137-49.527318l71.20192 28.467115a64.528873 64.528873 0 0 0 84.309081-24.388194l88.780533-151.551545a62.088347 62.088347 0 0 0-20.565271-84.206681 1143.036571 1143.036571 0 0 0-56.541697-45.055865c0-21.964734 0.409599-61.781148 1.211729-119.500441h-86.596007l-0.95573 149.844884 92.876521 70.689921-79.359762 135.457727-107.485544-45.448397-17.578614 14.745556a338.123786 338.123786 0 0 1-104.259954 58.931023l-21.418602 7.679977-15.837819 114.397523h-156.87633l-15.854885-114.397523-21.418603-7.679977a343.056037 343.056037 0 0 1-104.37942-59.05049l-17.459148-14.506623-108.338875 43.588136-78.489364-133.460933 92.859455-70.706988-4.095988-22.169533a325.801689 325.801689 0 0 1-5.683183-59.05049c0.119466-19.831407 1.979727-39.765214 5.563717-59.204089l3.976521-22.152467-92.739988-70.706988 79.615761-135.457727 97.689307 47.80359 153.019274-84.906412L426.665387-59.716472c43.946535 0.085333 66.6622 0.085333 68.112862 0C496.962776-59.904204 511.998464-68.198579 511.998464-76.800154z" horiz-adv-x="1024" />
<glyph glyph-name="trash-outline" unicode="&#60045;" d="M696-64H328c-51.8 0-93 40.4-96 94.2L192 670c-1.2 17.6 12.4 32.8 30 34 17.6 1.2 32.8-12.4 34-30l40-640v-0.4c1-20.2 14-33.6 32-33.6h368c18 0 30.8 13.6 32 34l40 640c1.2 17.6 16.4 31 34 30 17.6-1.2 31-16.2 30-34l-40-640c-3.4-54.4-43.8-94-96-94zM864 640H160c-17.6 0-32 14.4-32 32s14.4 32 32 32h704c17.6 0 32-14.4 32-32s-14.4-32-32-32zM640 640c-17.6 0-32 14.4-32 32V752.2c0 8.6-7.2 15.8-15.8 15.8h-160.4c-8.6 0-15.8-7.2-15.8-16v-80c0-17.6-14.4-32-32-32s-32 14.4-32 32V752c-0.2 44 35.6 79.8 79.6 80h160.6c43.8 0 79.6-35.6 79.8-79.6V672c0-17.6-14.4-32-32-32zM512 64c-17.6 0-32 14.4-32 32V544c0 17.6 14.4 32 32 32s32-14.4 32-32v-448c0-17.6-14.4-32-32-32zM384 64c-17.2 0-31.4 13.6-32 30.8l-16 448c-0.6 17.6 13.2 32.4 30.8 33.2 17.8 0.6 32.4-13.2 33.2-30.8l16-448c0.6-17.6-13.2-32.4-30.8-33.2h-1.2zM640 64h-1.2c-17.6 0.6-31.4 15.4-30.8 33.2l16 448c0.6 17.6 15.4 31.4 33.2 30.8 17.6-0.6 31.4-15.4 30.8-33.2l-16-448c-0.6-17.2-14.8-30.8-32-30.8z" horiz-adv-x="1024" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXCheckBox?>
<?import com.jfoenix.controls.JFXDialog?>
<?import com.jfoenix.controls.JFXDialogLayout?>
<?import com.jfoenix.controls.JFXProgressBar?>
<?import com.jfoenix.controls.JFXTextArea?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXTreeView?>
<?import com.jfoenix.validation.RequiredFieldValidator?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import org.kordamp.ikonli.javafx.FontIcon?>
<StackPane fx:id="root" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox>
<children>
<HBox alignment="CENTER_LEFT" prefHeight="40.0" spacing="0">
<children>
<ToggleButton fx:id="addButton" maxHeight="40.0" minHeight="40.0" prefHeight="40.0" styleClass="left-pill" text="添加" />
<ToggleButton fx:id="editButton" maxHeight="40.0" minHeight="40.0" prefHeight="40.0" styleClass="center-pill" text="编辑" />
<ToggleButton fx:id="deleteButton" maxHeight="40.0" minHeight="40.0" prefHeight="40.0" styleClass="center-pill" text="删除" />
<ToggleButton fx:id="handlerAuthorityButton" maxHeight="40.0" minHeight="40.0" prefHeight="40.0" styleClass="center-pill" text="权限分配" />
<ToggleButton fx:id="handlerUserButton" maxHeight="40.0" minHeight="40.0" prefHeight="40.0" styleClass="right-pill" text="关联用户" />
</children>
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
</HBox>
<SplitPane dividerPositions="0.29797979797979796" VBox.vgrow="ALWAYS">
<items>
<VBox maxHeight="1.7976931348623157E308" maxWidth="-Infinity" minWidth="250.0" prefWidth="250.0" scaleX="0.95" scaleY="0.95" spacing="7.0" styleClass="card-pane">
<children>
<JFXTextField fx:id="treeSearchTextField" promptText="输入关键字过滤" />
<JFXTreeView fx:id="treeView" VBox.vgrow="ALWAYS" />
</children>
</VBox>
<StackPane scaleX="0.95" scaleY="0.95" styleClass="card-pane">
<children>
<VBox fx:id="contentPane" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="367.0" prefWidth="380.0" StackPane.alignment="CENTER">
<children>
<GridPane alignment="CENTER" nodeOrientation="LEFT_TO_RIGHT" vgap="15.0" VBox.vgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints />
</rowConstraints>
<children>
<JFXTextField fx:id="nameTextField" labelFloat="true" promptText="名称">
<validators>
<RequiredFieldValidator message="Input Required!">
<FontIcon iconLiteral="fas-exclamation-triangle" />
</RequiredFieldValidator>
</validators>
<GridPane.margin>
<Insets />
</GridPane.margin>
</JFXTextField>
<JFXTextField fx:id="codeTextField" labelFloat="true" promptText="编码" GridPane.rowIndex="1">
<validators>
<RequiredFieldValidator message="Input Required!">
<FontIcon iconLiteral="fas-exclamation-triangle" />
</RequiredFieldValidator>
</validators>
</JFXTextField>
<JFXTextArea fx:id="descTextArea" labelFloat="true" promptText="描述" GridPane.columnSpan="2" GridPane.rowIndex="2" GridPane.rowSpan="2" />
</children>
<padding>
<Insets left="10.0" right="10.0" top="15.0" />
</padding>
</GridPane>
<ButtonBar fx:id="buttonBar">
<buttons>
<JFXButton fx:id="cancelButton" text="取消" />
<JFXButton fx:id="defineButton" text="确定" />
<JFXButton fx:id="updateButton" text="保存" />
</buttons>
</ButtonBar>
<JFXProgressBar fx:id="progressBar" maxWidth="1.7976931348623157E308" visible="false" />
</children>
</VBox>
</children>
</StackPane>
</items>
</SplitPane>
</children>
</VBox>
<JFXDialog fx:id="groupAuthorityDialog" transitionType="TOP">
<JFXDialogLayout minWidth="700">
<heading>
<Label fx:id="authorityTitle" text="关联资源" />
</heading>
<body>
<HBox>
<children>
<VBox minWidth="200.0" prefWidth="200.0" spacing="10.0">
<children>
<JFXTextField fx:id="menuTreeSearchTextField" promptText="输入关键字过滤" />
<JFXTreeView fx:id="menuTreeView" VBox.vgrow="ALWAYS" />
</children>
</VBox>
<TableView fx:id="elementTableView" HBox.hgrow="ALWAYS">
<columns>
<TableColumn fx:id="selColumn" maxWidth="45.0" minWidth="45.0" prefWidth="45.0">
<graphic>
<JFXCheckBox fx:id="selectAllCheckBox" alignment="CENTER" contentDisplay="GRAPHIC_ONLY" graphicTextGap="0.0" maxHeight="20.0" maxWidth="20.0" minHeight="20.0" minWidth="20.0" prefHeight="20.0" prefWidth="20.0" />
</graphic>
</TableColumn>
<TableColumn fx:id="serialNumberColumn" prefWidth="128.0" text="序号" />
<TableColumn fx:id="codeColumn" prefWidth="90.0" text="资源编码" />
<TableColumn fx:id="typeColumn" prefWidth="75.0" text="资源类型" />
<TableColumn fx:id="nameColumn" prefWidth="75.0" text="资源名称" />
<TableColumn fx:id="addressColumn" prefWidth="75.0" text="资源地址" />
<TableColumn fx:id="requestTypeColumn" prefWidth="75.0" text="资源请求类型" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</HBox>
</body>
<actions>
<JFXButton fx:id="cancelAuthorityButton">取消</JFXButton>
<JFXButton fx:id="saveAuthorityButton">保存</JFXButton>
</actions>
</JFXDialogLayout>
</JFXDialog>
<JFXDialog fx:id="groupUserDialog" transitionType="TOP">
<JFXDialogLayout>
<heading>
<Label fx:id="userTitle" text="关联用户" />
</heading>
<body>
<fx:include source="group_user.fxml" />
</body>
<actions>
<JFXButton fx:id="cancelUserButton">取消</JFXButton>
<JFXButton fx:id="saveUserButton">保存</JFXButton>
</actions>
</JFXDialogLayout>
</JFXDialog>
</children>
</StackPane>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXChipView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="326.0" prefWidth="470.0" spacing="10.0" xmlns="http://javafx.com/javafx/8.0.171"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<HBox prefHeight="100.0" prefWidth="200.0" spacing="10.0">
<children>
<Label text="群主|领导"/>
<JFXChipView fx:id="leaderChipView" promptText="请输入关键词" style="-fx-border-color: #000000;"
HBox.hgrow="ALWAYS"/>
</children>
</HBox>
<HBox prefHeight="100.0" prefWidth="200.0" spacing="10.0" VBox.vgrow="ALWAYS">
<children>
<Label text="组员|下属"/>
<JFXChipView fx:id="memberChipView" prefWidth="1578.0" promptText="请输入关键词"
style="-fx-border-color: #000000;" HBox.hgrow="ALWAYS"/>
</children>
</HBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</VBox>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXTabPane?>
<?import javafx.scene.layout.StackPane?>
<?import com.jfoenix.controls.JFXSpinner?>
<StackPane fx:id="rootPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<JFXTabPane fx:id="tabPane"/>
<JFXSpinner fx:id="viewSpinner" radius="18" startingAngle="90" styleClass="blue-spinner" visible="false" />
</children>
</StackPane>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXProgressBar?>
<?import com.jfoenix.controls.JFXTextArea?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="315.0" prefWidth="342.0" spacing="20.0">
<children>
<JFXTextField fx:id="codeTextField" labelFloat="true" promptText="编码" />
<JFXTextField fx:id="nameTextField" labelFloat="true" promptText="类型名称" />
<JFXTextArea fx:id="descriptionTextArea" labelFloat="true" promptText="描述" VBox.vgrow="ALWAYS" />
</children>
<padding>
<Insets bottom="3.0" top="20.0" />
</padding>
</VBox>
<JFXProgressBar fx:id="progressBar" maxWidth="1.7976931348623157E308" />
</children>
</VBox>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXDialog?>
<?import com.jfoenix.controls.JFXDialogLayout?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import com.jfoenix.controls.JFXSpinner?>
<StackPane fx:id="rootPane" prefHeight="384.0" prefWidth="585.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox fx:id="contentPane" spacing="7.0">
<children>
<HBox alignment="CENTER_RIGHT" spacing="10.0" styleClass="card-pane">
<children>
<JFXTextField fx:id="searchField" prefHeight="27.0" prefWidth="235.0" promptText="姓名或账户" />
<JFXButton fx:id="searchButton" buttonType="RAISED" text="搜索" />
<JFXButton fx:id="addButton" buttonType="RAISED" text="添加" />
</children>
</HBox>
<TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="serialNumberColumn" maxWidth="45.0" minWidth="45.0" prefWidth="45.0" text="序号" />
<TableColumn fx:id="codeColumn" prefWidth="75.0" text="编码" />
<TableColumn fx:id="nameColumn" prefWidth="75.0" text="类型名称" />
<TableColumn fx:id="descriptionColumn" prefWidth="75.0" text="描述" />
<TableColumn fx:id="updTimeColumn" prefWidth="75.0" text="最后更新时间" />
<TableColumn fx:id="updHostColumn" prefWidth="93.0" text="最后更新主机" />
<TableColumn fx:id="operatingColumn" maxWidth="120.0" minWidth="120.0" prefWidth="120.0" text="操作" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</VBox>
<JFXSpinner fx:id="viewSpinner" radius="18" startingAngle="90" styleClass="blue-spinner" visible="false" />
<JFXDialog fx:id="dialog" transitionType="TOP">
<JFXDialogLayout>
<heading>
<Label fx:id="title" text="关联用户" />
</heading>
<body>
<fx:include source="components/group_type_detailed.fxml" />
</body>
<actions>
<JFXButton fx:id="cancelButton">取消</JFXButton>
<JFXButton fx:id="saveButton">保存</JFXButton>
<JFXButton fx:id="updateButton">确定</JFXButton>
</actions>
</JFXDialogLayout>
</JFXDialog>
</children>
</StackPane>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXSpinner?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<StackPane fx:id="root" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox fx:id="centPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="10.0">
<children>
<HBox alignment="CENTER_RIGHT" maxHeight="-Infinity" prefHeight="45.0" prefWidth="200.0" spacing="10.0" styleClass="card-pane">
<children>
<JFXTextField fx:id="searchField" promptText="菜单,操作人或操作主机" />
<JFXButton fx:id="searchBut" buttonType="RAISED" text="搜索" />
</children>
</HBox>
<AnchorPane VBox.vgrow="ALWAYS">
<children>
<Pagination fx:id="pagination" cache="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<TableView fx:id="tableView" editable="true" tableMenuButtonVisible="false" AnchorPane.bottomAnchor="60.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
<columns>
<TableColumn fx:id="serialNumberColumn" maxWidth="50.0" minWidth="50.0" prefWidth="50.0" text="序号" />
<TableColumn fx:id="idColumn" maxWidth="50.0" minWidth="50.0" prefWidth="50.0" text="id" />
<TableColumn fx:id="menuColumn" text="菜单" />
<TableColumn fx:id="optColumn" text="操作" />
<TableColumn fx:id="urlColumn" text="资源路径" />
<TableColumn fx:id="optTimeColumn" text="操作时间" />
<TableColumn fx:id="optUserIdColumn" text="操作人id" />
<TableColumn fx:id="optUserColumn" maxWidth="120.0" minWidth="120.0" prefWidth="120" text="操作人" />
<TableColumn fx:id="optIpColumn" maxWidth="120.0" minWidth="120.0" prefWidth="120" text="操作主机" />
<TableColumn fx:id="requetDataColumn" maxWidth="120.0" minWidth="120.0" prefWidth="120" text="请求数据" />
</columns>
</TableView>
</children>
</AnchorPane>
</children>
</VBox>
<StackPane fx:id="spinnerPane" visible="false">
<JFXSpinner startingAngle="-40" styleClass="materialDesign-purple, first-spinner" />
<JFXSpinner startingAngle="-90" styleClass="materialDesign-blue, second-spinner" />
<JFXSpinner startingAngle="-120" styleClass="materialDesign-cyan, third-spinner" />
<JFXSpinner startingAngle="-150" styleClass="materialDesign-green, fourth-spinner" />
<JFXSpinner startingAngle="-180" styleClass="materialDesign-yellow, fifth-spinner" />
<JFXSpinner startingAngle="-210" styleClass="materialDesign-orange, sixth-spinner" />
<JFXSpinner startingAngle="-240" styleClass="materialDesign-red, seventh-spinner" />
</StackPane>
</children>
</StackPane>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="356.0"
prefWidth="435.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<GridPane alignment="CENTER" vgap="15.0" VBox.vgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints/>
</rowConstraints>
<children>
<JFXTextField fx:id="elementCodeTextField" labelFloat="true" promptText="资源编码"/>
<JFXComboBox fx:id="elementTypeComboBox" labelFloat="true" maxWidth="1.7976931348623157E308"
promptText="资源类型" GridPane.rowIndex="3"/>
<JFXTextField fx:id="elementNameTextField" labelFloat="true" promptText="资源名称" GridPane.rowIndex="1"/>
<JFXTextField fx:id="elementUriTextField" labelFloat="true" promptText="资源地址" GridPane.rowIndex="2"/>
<JFXComboBox fx:id="elementMethodComBox" labelFloat="true" maxWidth="1.7976931348623157E308"
promptText="资源请求类型" GridPane.rowIndex="4"/>
<JFXTextArea fx:id="elementDesTextAre" labelFloat="true" prefWidth="470.0" promptText="描述"
GridPane.rowIndex="5" GridPane.rowSpan="2">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</JFXTextArea>
</children>
</GridPane>
</children>
</VBox>

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