cuixubin 4 years ago
commit
a6d1143c75

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+/target/

+ 25 - 0
file-move-tool.iml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.47" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient-cache:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient-win:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: net.java.dev.jna:jna:4.4.0" level="project" />
+    <orderEntry type="library" name="Maven: net.java.dev.jna:jna-platform:4.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+  </component>
+</module>

+ 56 - 0
pom.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>file-move-tool</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <org.apache.httpcomponents.version>4.5.5</org.apache.httpcomponents.version>
+    </properties>
+
+    <dependencies>
+        <!-- json -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.47</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>${org.apache.httpcomponents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient-cache</artifactId>
+            <version>${org.apache.httpcomponents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient-win</artifactId>
+            <version>${org.apache.httpcomponents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>${org.apache.httpcomponents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.9</version>
+        </dependency>
+    </dependencies>
+
+    <repositories>
+        <repository>
+            <id>alimaven</id>
+            <name>aliyun maven</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+        </repository>
+    </repositories>
+</project>

+ 49 - 0
src/main/java/com/persagy/filemove/app/Ex6_ChoiceBox.java

@@ -0,0 +1,49 @@
+package com.persagy.filemove.app;
+
+import javafx.application.Application;
+import javafx.collections.FXCollections;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.scene.Scene;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.Separator;
+import javafx.scene.layout.FlowPane;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+public class Ex6_ChoiceBox extends Application {
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    private void build(FlowPane basePane) {
+        Text tips = new Text();
+
+        ChoiceBox cb = new ChoiceBox();
+        // 设置列表项,分隔符也算列表项的一个元素占用一个位置,但不能被选中
+        cb.setItems(FXCollections.observableArrayList("A", "B", new Separator(), "C"));
+        cb.setPrefSize(100, 30);
+        // 设置默认选择第一项
+        cb.getSelectionModel().selectFirst();
+
+        cb.getSelectionModel().selectedIndexProperty().addListener((obv, ov, nv)->{
+            // 显示选中项的下标,从0开始
+            tips.setText("selectIndex=" + nv.intValue() + cb.getItems().get(nv.intValue()));
+        });
+
+        basePane.getChildren().addAll(cb, tips);
+    }
+
+    @Override
+    public void start(Stage primaryStage) throws Exception {
+        FlowPane root = new FlowPane();
+        build(root);
+        Scene scene = new Scene(root, 350, 150);
+        primaryStage.setScene(scene);
+        primaryStage.setTitle("ChoiceBox");
+        root.setPadding(new Insets(10)); root.setVgap(20);
+        root.setOrientation(Orientation.VERTICAL);
+
+        primaryStage.show();
+    }
+}

+ 407 - 0
src/main/java/com/persagy/filemove/app/SagaFileMoveApp.java

@@ -0,0 +1,407 @@
+package com.persagy.filemove.app;
+
+import com.persagy.filemove.dto.SagaFileMoveDTO;
+import com.persagy.filemove.service.SagaFileMoveService;
+import com.persagy.filemove.util.StringTools;
+import javafx.application.Application;
+import javafx.collections.FXCollections;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.control.Label;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+import javax.sound.midi.Soundbank;
+import java.lang.reflect.Field;
+import java.util.LinkedHashMap;
+
+public class SagaFileMoveApp extends Application {
+    private static int appWidth = 600;
+    private static int appHeight = 500;
+
+    private SagaFileMoveDTO dto = new SagaFileMoveDTO();
+    private SagaFileMoveService service = new SagaFileMoveService(dto);
+
+    /** 文件服务上传下载接口类型 */
+    private static final String[] apiTypes = {"file", "image"};
+
+    /** 对象类型 */
+    private static String[] objTypes;
+    /** 对象类型对应信息点 */
+    private static final LinkedHashMap<String, String[]> objToInfoCode = new LinkedHashMap<>();
+    static {
+        objToInfoCode.put("Fl", new String[]{"FloorMap"});
+        objToInfoCode.put("Eq", new String[]{"EquipQRCode"});
+        objToInfoCode.put("Sp", new String[]{"RoomQRCode"});
+        objToInfoCode.put("Sy", new String[]{"EquipQRCode"});
+        objToInfoCode.put("Ec", new String[]{"EquipQRCode"});
+        objTypes = objToInfoCode.keySet().stream().toArray(n -> new String[n]);
+    }
+
+    /** 数据平台地址 */
+    private TextField tfDPF = new TextField("http://api.sagacloud.cn/data-platform-3");
+
+    /** 项目id */
+    private TextField tfPjId = new TextField("Pj1101010001");
+    /** 项目密码 */
+    private TextField tfPjSecret = new TextField();
+    /** 对象类型 */
+    private ChoiceBox cbObjType = new ChoiceBox();
+    /** 对象信息点 */
+    private ChoiceBox cbObjInfoCodeArray = new ChoiceBox();
+
+    /** 文件服务from地址 */
+    private TextField tfImgFromURL = new TextField("http://127.0.0.1:8080/image-service");
+    /** 文件服务from的systemId */
+    private TextField tfImgFromSysId = new TextField("dataPlatform");
+    /** 文件服务from的secret */
+    private TextField tfImgFromSecret = new TextField("9e0891a7a8c8e885");
+    /** 接口类型 */
+    private ChoiceBox cbImgFromApiType = new ChoiceBox(FXCollections.observableArrayList(apiTypes));
+
+    /** 文件服务To地址 */
+    private TextField tfImgToURL = new TextField("http://127.0.0.1:8080/image-service");
+    /** 文件服务To的systemId */
+    private TextField tfImgToSysId = new TextField("dataPlatform");
+    /** 文件服务To的secret */
+    private TextField tfImgToSecret = new TextField("9e0891a7a8c8e885");
+    /** 接口类型 */
+    private ChoiceBox cbImgToApiType = new ChoiceBox(FXCollections.observableArrayList(apiTypes));
+
+    /** 执行校验按钮 */
+    private Button btnValid = new Button("参数校验");
+    /** 文件传输执行按钮 */
+    private Button btnExecute = new Button("开始传输");
+    /** 执行信息 */
+    private Label lblExecute = new Label();
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    /**
+     * 初始化基础控件
+     */
+    private void initComponents() {
+        bindDTO();
+
+        tfDPF.setPrefWidth(appWidth * .7);
+
+        tfPjId.setPrefWidth(appWidth * .25);
+        tfPjSecret.setPrefWidth(appWidth * .25);
+
+        cbObjType.setItems(FXCollections.observableArrayList(objTypes));
+        cbObjType.setPrefWidth(appWidth * .1);
+        // 设置默认选择第一项
+        cbObjType.getSelectionModel().selectFirst();
+
+        cbObjInfoCodeArray.setItems(FXCollections.observableArrayList(objToInfoCode.get(cbObjType.getSelectionModel().getSelectedItem().toString())));
+        cbObjInfoCodeArray.getSelectionModel().selectFirst();
+        cbObjInfoCodeArray.setPrefWidth(appWidth * .25);
+
+        tfImgFromURL.setPrefWidth(appWidth * .5);
+        tfImgFromSysId.setPrefWidth(appWidth * .25);
+        tfImgFromSecret.setPrefWidth(appWidth * .25);
+        cbImgFromApiType.setPrefWidth(appWidth * .15);
+        cbImgFromApiType.getSelectionModel().selectFirst();
+
+        tfImgToURL.setPrefWidth(appWidth * .5);
+        tfImgToSysId.setPrefWidth(appWidth * .25);
+        tfImgToSecret.setPrefWidth(appWidth * .25);
+        cbImgToApiType.setPrefWidth(appWidth * .15);
+        cbImgToApiType.getSelectionModel().selectFirst();
+
+        btnValid.setOnAction(e -> {
+
+            validParam();
+        });
+
+        btnExecute.setOnAction(e -> {
+            disableSet(true, this);
+            if(validParam()) {
+                // 操作按钮置为不可操作
+            }
+        });
+
+        cbObjType.getSelectionModel().selectedIndexProperty().addListener((obv, ov, nv)->{
+            cbObjInfoCodeArray.setItems(FXCollections.observableArrayList(objToInfoCode.get(cbObjType.getItems().get(nv.intValue()))));
+            cbObjInfoCodeArray.getSelectionModel().selectFirst();
+        });
+    }
+
+    private void disableSet(boolean isAble, SagaFileMoveApp father) {
+        Field[] allFields = SagaFileMoveApp.class.getDeclaredFields();
+        for(Field field : allFields) {
+            if(Node.class.isAssignableFrom(field.getDeclaringClass())) {
+                try {
+                    Node node = (Node) field.get(father);
+                    node.setDisable(isAble);
+                }catch (Exception e) {}
+            }
+        }
+    }
+
+    /**
+     * 校验参数
+     * @return
+     */
+    private boolean validParam() {
+        //
+        if(StringTools.isBlank(dto.dpf.getValue()) || StringTools.isBlank(dto.pjId.getValue()) ||
+                StringTools.isBlank(dto.imgFromUrl.getValue()) || StringTools.isBlank(dto.imgFromSysId.getValue()) ||
+                StringTools.isBlank(dto.imgFromSecret.getValue()) || StringTools.isBlank(dto.imgToUrl.getValue()) ||
+                StringTools.isBlank(dto.imgToSysId.getValue()) || StringTools.isBlank(dto.imgToSecret.getValue())) {
+            showTipsError("必填参数不能为空!");
+            return false;
+        }
+
+        if(!service.validParamDpfAndPj()) {
+            showTipsError("获取不到项目信息!请确保数据平台地址和项目id参数正确。");
+            return false;
+        }
+
+        if(!service.validParamImgFromUrl()) {
+            showTipsError("[文件服务-From]访问不通!请确保URL正确。");
+            return false;
+        }
+
+        if(!service.validParamImgToUrl()) {
+            showTipsError("[文件服务-To]访问不通!请确保URL正确。");
+            return false;
+        }
+
+        if(dto.imgFromUrl.getValue().equals(dto.imgToUrl.getValue())) {
+            showTipsWarn("参数校验通过。警告:两个文件服务的URL相同!");
+        }else {
+            showTipsSuccess("校验通过");
+        }
+
+        return true;
+    }
+
+    private void showTipsSuccess(String info) {
+        lblExecute.setTextFill(Color.DARKGREEN);
+        lblExecute.setText(info);
+    }
+
+    private void showTipsInfo(String info) {
+        lblExecute.setTextFill(Color.BLACK);
+        lblExecute.setText(info);
+    }
+
+    private void showTipsError(String errMsg) {
+        lblExecute.setTextFill(Color.RED);
+        lblExecute.setText(errMsg);
+    }
+
+    private void showTipsWarn(String warnMsg) {
+        lblExecute.setTextFill(Color.DARKORANGE);
+        lblExecute.setText(warnMsg);
+    }
+
+    /**
+     * 将控件的值绑定到DTO对象的属性上
+     */
+    private void bindDTO() {
+        dto.dpf.bind(tfDPF.textProperty());
+        dto.imgFromApiType.bind(cbImgFromApiType.valueProperty());
+        dto.imgFromSecret.bind(tfImgFromSecret.textProperty());
+        dto.imgFromSysId.bind(tfImgFromSysId.textProperty());
+        dto.imgFromUrl.bind(tfImgFromURL.textProperty());
+        dto.imgToApiType.bind(cbImgToApiType.valueProperty());
+        dto.imgToSecret.bind(tfImgToSecret.textProperty());
+        dto.imgToSysId.bind(tfImgToSysId.textProperty());
+        dto.imgToUrl.bind(tfImgToURL.textProperty());
+        dto.objInfoCode.bind(cbObjInfoCodeArray.valueProperty());
+        dto.objType.bind(cbObjType.valueProperty());
+        dto.pjId.bind(tfPjId.textProperty());
+        dto.pjSecret.bind(tfPjSecret.textProperty());
+    }
+
+    @Override
+    public void start(Stage primaryStage) throws Exception {
+        initComponents();
+
+        // 底层border布局
+        BorderPane baseBorderPane = new BorderPane();
+
+        // 菜单栏
+        MenuBar menuBar = new MenuBar();
+        menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
+        menuBar.getMenus().addAll(getHelpMenu());
+
+        // 主视图内容布局
+        Pane centerPane = getCenterPane();
+
+        baseBorderPane.setTop(menuBar);
+        baseBorderPane.setCenter(centerPane);
+
+        primaryStage.setResizable(false);
+        Scene scene = new Scene(baseBorderPane, appWidth, appHeight);
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+
+    /**
+     * 获取主要内容的布局面板实例
+     * @return
+     */
+    private Pane getCenterPane() {
+        Pane centerPane = new VBox();
+        centerPane.setPadding(new Insets(0, 5, 0, 5));
+
+        TitledPane paneObjParam = getObjTitlePane();
+        TitledPane paneImgFrom = getImgTitlePane(true);
+        TitledPane paneImgTo = getImgTitlePane(false);
+
+        Pane paneExe = getExePane();
+
+        centerPane.getChildren().addAll(paneObjParam, paneImgFrom, paneImgTo, paneExe);
+        Insets nodeInsets = new Insets(0, 0, 15, 0);
+        VBox.setMargin(paneObjParam, nodeInsets);
+        VBox.setMargin(paneImgFrom, nodeInsets);
+        return centerPane;
+    }
+
+    /**
+     * 获取执行控制面板
+     * @return
+     */
+    private Pane getExePane() {
+        HBox contentBox = new HBox(btnValid, btnExecute, lblExecute);
+        HBox.setMargin(btnExecute, new Insets(0, 20, 0, 15));
+        contentBox.setPadding(new Insets(15, 0, 0, 0));
+
+        return contentBox;
+    }
+
+    /**
+     * 生成包含数据平台、项目、对象配置参数的带标题的布局实例
+     * @return
+     */
+    private TitledPane getObjTitlePane() {
+
+        String title = "物理对象 - 配置传输哪个项目,哪类对象,哪个信息点对应的文件数据";
+        String titlePaneBack = "-fx-background-color: wheat";
+
+        LinkedHashMap<String, Node> projectMap = new LinkedHashMap<>();
+        projectMap.put("*项目id ", tfPjId);
+        projectMap.put("项目密码 ", tfPjSecret);
+
+        LinkedHashMap<String, Node> objTypeMap = new LinkedHashMap<>();
+        objTypeMap.put("*对象类型 ", cbObjType);
+        objTypeMap.put("*对象信息点 ", cbObjInfoCodeArray);
+
+        VBox contentPane = new VBox(getHBoxPane("*数据平台 ", tfDPF),
+                getHBoxPane(projectMap), getHBoxPane(objTypeMap));
+        contentPane.setPadding(new Insets(5, 0, 5,10));
+        contentPane.setStyle("-fx-background-color: antiquewhite");
+
+        TitledPane titledPane = new TitledPane(title, contentPane);
+        titledPane.setCollapsible(false);
+        return titledPane;
+    }
+
+    /**
+     * 生成包含文件服务参数控件的带标题的布局实例
+     * @param isFrom true-数据来源方的文件服务;false-数据接收方的文件服务
+     * @return
+     */
+    private TitledPane getImgTitlePane(boolean isFrom) {
+        String titleFrom = "From:即获取文件资源数据所访问的image-service服务";
+        String titleTo = "To:即获上传文件资源所访问的image-service服务";
+        String title = "文件服务 - " + (isFrom ? titleFrom : titleTo);
+        String titlePaneBack = "-fx-background-color: wheat";
+
+        Node systemId = null, secret = null, serviceURL = null, apiType;
+        if(isFrom) {
+            systemId = tfImgFromSysId;
+            secret = tfImgFromSecret;
+            serviceURL = tfImgFromURL;
+            apiType = cbImgFromApiType;
+            titlePaneBack = "-fx-background-color: bisque";
+        }else {
+            systemId = tfImgToSysId;
+            secret = tfImgToSecret;
+            serviceURL = tfImgToURL;
+            apiType = cbImgToApiType;
+        }
+
+        LinkedHashMap<String, Node> urlAndApiTypeMap = new LinkedHashMap<>();
+        urlAndApiTypeMap.put("*服务URL ", serviceURL);
+        urlAndApiTypeMap.put("*接口类型 ", apiType);
+
+        LinkedHashMap<String, Node> paramMap = new LinkedHashMap<>();
+        paramMap.put("*systemId ", systemId);
+        paramMap.put("*secret ", secret);
+
+        VBox contentPane = new VBox(getHBoxPane(urlAndApiTypeMap),
+                getHBoxPane(paramMap));
+        contentPane.setPadding(new Insets(5, 0, 5,10));
+        contentPane.setStyle(titlePaneBack);
+
+        TitledPane titledPane = new TitledPane(title, contentPane);
+        titledPane.setCollapsible(false);
+        return titledPane;
+    }
+
+    /**
+     * 获取水平排布的含有Label和Node节点两个控件面板实例
+     * @param label 标签内容
+     * @param node 控件节点
+     * @return
+     */
+    private Pane getHBoxPane(String label, Node node) {
+        LinkedHashMap<String, Node> map = new LinkedHashMap<>();
+        map.put(label, node);
+        return getHBoxPane(map);
+    }
+
+    /**
+     * 获取水平排布的含多对(Label:Node)节点组的面板实例
+     * @param label_textField {标签名:控件节点}
+     * @return
+     */
+    private Pane getHBoxPane(LinkedHashMap<String, Node> label_textField) {
+        HBox pane = new HBox();
+
+        Insets nodeInsets = new Insets(0, 15, 0, 0);
+        for(String name : label_textField.keySet()) {
+            Label label = new Label(name);
+            Node node = label_textField.get(name);
+
+            pane.getChildren().addAll(label, node);
+            HBox.setMargin(node, nodeInsets);
+        }
+
+        pane.setPadding(new Insets(5, 5, 5, 0));
+        pane.setAlignment(Pos.CENTER_LEFT);
+        return pane;
+    }
+
+    /**
+     * 获取帮助菜单按钮
+     * @return
+     */
+    private Menu getHelpMenu() {
+        // 菜单项
+        MenuItem mi_help = new MenuItem("Help");
+        MenuItem mi_about = new MenuItem("About");
+        SeparatorMenuItem seline = new SeparatorMenuItem();
+
+        Menu helpMenu = new Menu("Help");
+        helpMenu.getItems().addAll(mi_help, seline, mi_about);
+        return helpMenu;
+    }
+}

+ 52 - 0
src/main/java/com/persagy/filemove/dto/SagaFileMoveDTO.java

@@ -0,0 +1,52 @@
+package com.persagy.filemove.dto;
+
+import javafx.beans.property.SimpleStringProperty;
+
+public class SagaFileMoveDTO {
+    /** 数据平台地址 */
+    public SimpleStringProperty dpf = new SimpleStringProperty();
+    /** 项目id */
+    public SimpleStringProperty pjId = new SimpleStringProperty();
+    /** 项目密码 */
+    public SimpleStringProperty pjSecret = new SimpleStringProperty();
+    /** 对象类型 */
+    public SimpleStringProperty objType = new SimpleStringProperty();
+    /** 对象信息点编码 */
+    public SimpleStringProperty objInfoCode = new SimpleStringProperty();
+    /** 文件服务from地址 */
+    public SimpleStringProperty imgFromUrl = new SimpleStringProperty();
+    /** 文件服务from的systemId */
+    public SimpleStringProperty imgFromSysId = new SimpleStringProperty();
+    /** 文件服务from的secret */
+    public SimpleStringProperty imgFromSecret = new SimpleStringProperty();
+    /** 文件服务from的接口类型 */
+    public SimpleStringProperty imgFromApiType = new SimpleStringProperty();
+    /** 文件服务to地址 */
+    public SimpleStringProperty imgToUrl = new SimpleStringProperty();
+    /** 文件服务Tom的systemId */
+    public SimpleStringProperty imgToSysId = new SimpleStringProperty();
+    /** 文件服务To的secret */
+    public SimpleStringProperty imgToSecret = new SimpleStringProperty();
+    /** 文件服务To的接口类型 */
+    public SimpleStringProperty imgToApiType = new SimpleStringProperty();
+
+
+    @Override
+    public String toString() {
+        return "SagaFileMoveDTO{" +
+                "dpf=" + dpf.getValue() +
+                ", pjId=" + pjId.getValue() +
+                ", pjSecret=" + pjSecret.getValue() +
+                ", objType=" + objType.getValue() +
+                ", objInfoCode=" + objInfoCode.getValue() +
+                ", imgFromUrl=" + imgFromUrl.getValue() +
+                ", imgFromSysId=" + imgFromSysId.getValue() +
+                ", imgFromSecret=" + imgFromSecret.getValue() +
+                ", imgFromApiType=" + imgFromApiType.getValue() +
+                ", imgToUrl=" + imgToUrl.getValue() +
+                ", imgToSysId=" + imgToSysId.getValue() +
+                ", imgToSecret=" + imgToSecret.getValue() +
+                ", imgToApiType=" + imgToApiType.getValue() +
+                '}';
+    }
+}

+ 65 - 0
src/main/java/com/persagy/filemove/service/SagaFileMoveService.java

@@ -0,0 +1,65 @@
+package com.persagy.filemove.service;
+
+import com.persagy.filemove.dto.SagaFileMoveDTO;
+import com.persagy.filemove.util.HttpTools;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SagaFileMoveService {
+    private SagaFileMoveDTO dto;
+    private static final String resp_success = "success";
+    private static final String testKey = "persagyAndSagaTest2020121130";
+    private static final String url_pj_get = "/mng/project/query";
+    private static final String url_source_get = "BASE/common/TYPE_get?systemId=SYSID&key=KEY";
+
+    public SagaFileMoveService(SagaFileMoveDTO dto) {
+        this.dto = dto;
+    }
+
+    /**
+     * 检查数据平台地址和项目信息
+     * @return
+     */
+    public boolean validParamDpfAndPj() {
+        boolean result = false;
+        Map<Object, Object> param = new HashMap<>();
+        param.put("projectId", dto.pjId.getValue());
+        try {
+            String resp = HttpTools.httpPostJson(dto.dpf.getValue() + url_pj_get, param);
+            if(null != resp && resp.contains(resp_success) && resp.contains(dto.pjId.getValue())) {
+                result = true;
+            }
+        }catch (Exception e) {}
+        return result;
+    }
+
+    /**
+     * 校验文件服务From是否可访问
+     * @return
+     */
+    public boolean validParamImgFromUrl() {
+        return fileGetTest(dto.imgFromUrl.getValue(), dto.imgFromApiType.getValue(), dto.imgFromSysId.getValue(), testKey);
+    }
+
+    /**
+     * 校验文件服务From是否可访问
+     * @return
+     */
+    public boolean validParamImgToUrl() {
+        return fileGetTest(dto.imgToUrl.getValue(), dto.imgToApiType.getValue(), dto.imgToSysId.getValue(), testKey);
+    }
+
+    private boolean fileGetTest(String base, String type, String sysId, String key) {
+        boolean result = false;
+        String url = url_source_get.replace("BASE", base).replace("TYPE", type).replace("SYSID", sysId).replace("KEY", key);
+        try {
+            byte[] byteData = HttpTools.httpGetFile(url);
+            if(byteData != null && byteData.length == 17) {
+                result = true;
+            }
+        }catch (Exception e){}
+
+        return result;
+    }
+}

+ 120 - 0
src/main/java/com/persagy/filemove/util/HttpTools.java

@@ -0,0 +1,120 @@
+package com.persagy.filemove.util;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class HttpTools {
+	private final static PoolingHttpClientConnectionManager CONNECTION_MANAGER = new PoolingHttpClientConnectionManager();
+	private final static CloseableHttpClient HTTP_CLIENT;
+	private static final String UTF8 = "utf-8";
+
+	static {
+		// 设置整个连接池最大连接数 根据自己的场景决定
+		CONNECTION_MANAGER.setMaxTotal(200);
+		// 每个路由(网站)的最大连接数
+		CONNECTION_MANAGER.setDefaultMaxPerRoute(100);
+		RequestConfig requestConfig = RequestConfig.custom()
+				// 与远程主机连接建立时间,三次握手完成时间
+				.setConnectTimeout(5000)
+				// 建立连接后,数据包传输过程中,两个数据包之间间隔的最大时间
+				.setSocketTimeout(5000)
+				// httpClient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间
+				.setConnectionRequestTimeout(6000).build();
+		HTTP_CLIENT = HttpClients.custom().setConnectionManager(CONNECTION_MANAGER)
+				.setDefaultRequestConfig(requestConfig).build();
+	}
+
+	public static String httpGetRequest(String url) throws Exception {
+		HttpGet httpGet = new HttpGet(url);
+		return sendRequest(httpGet);
+	}
+
+	public static String httpPostRequest(String url) throws Exception {
+		HttpPost httpPost = new HttpPost(url);
+		return sendRequest(httpPost);
+	}
+
+	public static String httpPostJson(String url, JSONObject param) throws IOException {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
+		httpPost.setEntity(new StringEntity(param.toJSONString(), UTF8));
+		String respContent = sendRequest(httpPost);
+		return respContent;
+	}
+	
+	public static String httpPostJson(String url, Map<Object, Object> params) throws IOException {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
+		httpPost.setEntity(new StringEntity(JsonTools.beanToJson(params), UTF8));
+		String respContent = sendRequest(httpPost);
+		return respContent;
+	}
+	
+	/**
+	 * 
+	 * @param url http地址
+	 * @param params 表单参数{"key":"jsonString"}
+	 * @return
+	 * @throws IOException
+	 */
+	public static String httpPostForm(String url, Map<String, Object> params) throws IOException {
+		HttpEntity reqEntity = null;
+		List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
+		for(Map.Entry<String,Object> entry : params.entrySet()){
+			pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue().toString()));
+		}
+        reqEntity = new UrlEncodedFormEntity(pairs,"UTF-8");
+        HttpPost httpPost = new HttpPost(url);
+    	if(reqEntity!=null){
+    		httpPost.setEntity(reqEntity);
+    	}
+        
+		String respContent = sendRequest(httpPost);
+		return respContent;
+	}
+
+	private static String sendRequest(HttpUriRequest request) throws IOException {
+		CloseableHttpResponse response = HTTP_CLIENT.execute(request);
+		return EntityUtils.toString(response.getEntity(), UTF8);
+	}
+
+	public static String httpPostRequest(String url, InputStream is) throws Exception {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.setEntity(new InputStreamEntity(is));
+		return sendRequest(httpPost);
+	}
+
+	public static String httpPostRequest(String url, File file) throws Exception {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.setEntity(new FileEntity(file));
+		return sendRequest(httpPost);
+	}
+
+	public static byte[] httpGetFile(String url) throws Exception {
+		HttpGet httpGet = new HttpGet(url);
+		CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet);
+		return EntityUtils.toByteArray(response.getEntity());
+	}
+}

+ 53 - 0
src/main/java/com/persagy/filemove/util/JsonTools.java

@@ -0,0 +1,53 @@
+package com.persagy.filemove.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.*;
+
+public class JsonTools {
+	/**
+	 * 对象转jsonz字符串
+	 * @param obj
+	 * @return
+	 */
+	public static String beanToJson(Object obj) {
+		return JSON.toJSONString(obj);
+	}
+	
+	/**
+     * 读取json文件,返回json串
+     * @param fileName
+     * @return
+     */
+    public static String readJsonFile(String fileName) {
+        String jsonStr = "";
+        try {
+            File jsonFile = new File(fileName);
+            FileReader fileReader = new FileReader(jsonFile);
+
+            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
+            int ch = 0;
+            StringBuffer sb = new StringBuffer();
+            while ((ch = reader.read()) != -1) {
+                sb.append((char) ch);
+            }
+            fileReader.close();
+            reader.close();
+            jsonStr = sb.toString();
+            return jsonStr;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    
+    /**
+     * jsonString转json对象
+     * @param jsonStr
+     * @return
+     */
+    public static JSONObject strToJsonObj(String jsonStr) {
+    	return JSON.parseObject(jsonStr);
+    }
+}

+ 283 - 0
src/main/java/com/persagy/filemove/util/StringTools.java

@@ -0,0 +1,283 @@
+package com.persagy.filemove.util;
+
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class StringTools {
+
+	/**
+	 * 获取UUID字符串
+	 * 
+	 * @param length 指定字符长度,范围(0,36],若为null则视length=36处理
+	 * @return 固定长度的数字+小写字母+中划线组合的UUID字符串
+	 */
+	public static String getUUID(Integer length) {
+		String uuidStr = UUID.randomUUID().toString();
+		if (null != length) {
+			length = length > 36 ? 36 : length;
+			uuidStr = uuidStr.substring(0, length);
+		}
+		return uuidStr;
+	}
+	
+	/**
+	 * 获取字符串str对应的hash散列结果值
+	 * @param str
+	 * @return 000-999之间的数字字符串
+	 */
+	public static String getHashNum(String str) {
+		str = str == null ? "" : str;
+		
+		// 得到哈希正整数
+		int hashInt = Math.abs(str.hashCode());
+		
+		// 设置哈希字符值,长度为4位
+		hashInt = 100000 + hashInt % 1000;
+		String hashStr = ("" + hashInt).substring(3);
+		
+		return hashStr;
+	}
+
+	/**
+	 * 提供空字符串.
+	 */
+	public static final String EMPTY = "";
+
+	/**
+	 * 判断字符串是否为null,或者是空串"", 或者是空格串" "
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isBlank(String str) {
+		if (isEmpty(str)) {
+			return true;
+		}
+
+		return str.trim().length() == 0;
+	}
+
+	/**
+	 * 如果源字符串str为null,空串或空格串则返回默认字符串
+	 * 
+	 * @param str    源字符串
+	 * @param defStr 默认字符串
+	 * @return String
+	 */
+	public static String getDefault(String str, String defStr) {
+		return isBlank(str) ? defStr : str;
+	}
+
+	/**
+	 * 判断字符串是否为null,或者是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isEmpty(String s) {
+		return (s == null || s.length() == 0);
+	}
+
+	/**
+	 * 判断字符串是否不为null,且不是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isNotEmpty(String s) {
+		return !isEmpty(s);
+	}
+
+	public static final String toString(Object o) {
+		return o != null ? o.toString() : null;
+	}
+
+	/**
+	 * 判断是否为空格字符串 .
+	 * 
+	 * @param cs
+	 * @return boolean
+	 */
+	public static boolean isBlank(CharSequence cs) {
+		if (null == cs)
+			return false;
+		int length = cs.length();
+		for (int i = 0; i < length; i++) {
+			if (!Character.isWhitespace(cs.charAt(i)))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 比较字符串是否相等,都为null时,返回true .
+	 * 
+	 * @param string1
+	 * @param string2
+	 * @return boolean
+	 */
+	public static boolean equalsWithNull(String string1, String string2) {
+		if (string1 == null) {
+			if (string2 == null) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return string1.equals(string2);
+		}
+	}
+
+	public static boolean checkIsPhone(String phonenumber) {
+		String phone = "(^(d{3,4}-)?d{7,8})$|(1[0-9]{10})";
+		String tregEx = "[0-9]{7,8}"; // 表示a或f 0832-80691990
+		Pattern p = Pattern.compile(phone);
+		Matcher m = p.matcher(phonenumber);
+		Pattern p2 = Pattern.compile(tregEx);
+		Matcher m2 = p2.matcher(phonenumber);
+		// String regEx="[1]{1}[3,5,8,6]{1}[0-9]{9}"; //手机
+		// String tregEx="[0]{1}[0-9]{2,3}-[0-9]{7,8}"; //表示a或f 0832-80691990
+		return m.matches() || m2.matches();
+	}
+
+	/**
+	 * 判断字符串中是否包含汉字,如字符串为空,返回false .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean hasHanZi(String str) {
+		if (StringTools.isEmpty(str)) {
+			return false;
+		}
+		String regEx = "[\\u4e00-\\u9fa5]";
+
+		Pattern pat = Pattern.compile(regEx);
+		Matcher mat = pat.matcher(str);
+		return mat.find();
+
+	}
+
+	/**
+	 * 字符串中的数字转为*
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String spriceNumberic(String str) {
+		StringBuffer sb = new StringBuffer();
+		if (str != null) {
+			for (int i = 0; i < str.length(); i++) {
+				if (Character.isDigit(str.charAt(i))) {
+					sb.append("*");
+				} else {
+					sb.append(str.charAt(i));
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 去除字符里包含的回车(\n)、水平制表符(\t)、空格(\s)、换行(\r) .
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String replaceSpecilSign(String str) {
+		String dest = "";
+		if (isNotEmpty(str)) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+
+			Matcher m = p.matcher(str);
+
+			dest = m.replaceAll("");
+		}
+		return dest;
+	}
+
+	/**
+	 * 判断一个字符串是否为数字型字符串 .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isNumberic(String str) {
+		if (isEmpty(str)) {
+			return false;
+		}
+		Pattern pattern = Pattern.compile("[0-9]*");
+		return pattern.matcher(str).matches();
+	}
+
+	/**
+	 * 目标字符是否包含正则表达式所给字符 .
+	 * 
+	 * @param destStr 目标字符
+	 * @param regEx   正则表达式
+	 * @return boolean
+	 */
+	public static boolean containString(String destStr, String regEx) {
+		if (isEmpty(destStr)) {
+			return false;
+		}
+		if (isEmpty(regEx)) {
+			return false;
+		}
+		Pattern p = Pattern.compile(regEx);
+		Matcher m = p.matcher(destStr);
+		return m.find();
+	}
+
+	/**
+	 * Description: 判断字符串是否为合法的文件名(不包含后缀).
+	 * 
+	 * @param fileName
+	 * @return boolean
+	 */
+	public static boolean isFileName(String fileName) {
+		if (fileName == null || fileName.length() > 255) {
+			return false;
+		} else if (isBlank(fileName)) {
+			return true;
+		} else {
+			return fileName.matches(
+					"[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
+		}
+	}
+
+	/**
+	 * 将字符串首字母大写 .
+	 * 
+	 * @param s
+	 * @return String
+	 */
+	public static String capitalize(CharSequence s) {
+		if (null == s)
+			return null;
+		int len = s.length();
+		if (len == 0)
+			return "";
+		char char0 = s.charAt(0);
+		if (Character.isUpperCase(char0))
+			return s.toString();
+		return new StringBuilder(len).append(Character.toUpperCase(char0)).append(s.subSequence(1, len)).toString();
+	}
+
+	/**
+	 * 判断String是否为null或空
+	 * 
+	 * @param params
+	 * @return
+	 */
+	public static boolean isNull(String... params) {
+		for (String param : params) {
+			if (param == null || "".equals(param)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}

+ 0 - 0
src/main/resources/sfm-init.properties