浏览代码

Merge branch 'feature-way-of-configuration' into dev

# Conflicts:
#	pom.xml
#	report-common/src/main/java/com/uas/report/util/ResourceUtils.java
#	report/src/main/java/com/uas/report/controller/PrintController.java
sunyj 7 年之前
父节点
当前提交
2f274d9706
共有 23 个文件被更改,包括 674 次插入320 次删除
  1. 2 1
      .gitignore
  2. 1 4
      crystal2jasper/src/main/java/com/uas/report/crystal2jasper/CrystalToJasper.java
  3. 1 0
      crystal2jasper/src/test/java/com/uas/report/crystal2jasper/CrystalToJasperTest.java
  4. 64 64
      pom.xml
  5. 2 2
      report-common/src/main/java/com/uas/report/util/FileUtils.java
  6. 1 1
      report-common/src/main/java/com/uas/report/util/ResourceUtils.java
  7. 2 2
      report-common/src/main/java/com/uas/report/util/ZipUtils.java
  8. 0 9
      report/pom.xml
  9. 1 1
      report/src/main/java/com/uas/report/Application.java
  10. 336 0
      report/src/main/java/com/uas/report/DynamicProperties.java
  11. 0 127
      report/src/main/java/com/uas/report/SpecialProperties.java
  12. 14 59
      report/src/main/java/com/uas/report/SystemProperties.java
  13. 22 0
      report/src/main/java/com/uas/report/annotation/DynamicValue.java
  14. 5 5
      report/src/main/java/com/uas/report/axis/BasicResourceHandler.java
  15. 5 5
      report/src/main/java/com/uas/report/controller/PrintController.java
  16. 39 0
      report/src/main/java/com/uas/report/controller/PropertiesController.java
  17. 15 15
      report/src/main/java/com/uas/report/service/impl/FileServiceImpl.java
  18. 7 7
      report/src/main/java/com/uas/report/service/impl/PrintServiceImpl.java
  19. 43 6
      report/src/main/java/com/uas/report/util/MasterManager.java
  20. 90 0
      report/src/main/java/com/uas/report/util/ObjectUtils.java
  21. 3 12
      report/src/main/resources/application.yml
  22. 16 0
      report/src/main/resources/report.properties
  23. 5 0
      report/src/main/webapp/WEB-INF/views/console.html

+ 2 - 1
.gitignore

@@ -52,4 +52,5 @@ buildNumber.properties
 # --------------------
 # Project
 data/
-report/src/main/resources/config/
+report/src/main/resources/config/
+report/report.properties

+ 1 - 4
crystal2jasper/src/main/java/com/uas/report/crystal2jasper/CrystalToJasper.java

@@ -3,10 +3,7 @@ package com.uas.report.crystal2jasper;
 import com.uas.report.crystal2jasper.Join.JoinType;
 import com.uas.report.crystal2jasper.Link.LinkType;
 import com.uas.report.crystal2jasper.Sort.SortType;
-import com.uas.report.util.CollectionUtils;
-import com.uas.report.util.FileUtils;
-import com.uas.report.util.StringUtils;
-import com.uas.report.util.ZipUtils;
+import com.uas.report.util.*;
 import org.apache.commons.io.output.FileWriterWithEncoding;
 import org.dom4j.*;
 import org.dom4j.io.SAXReader;

+ 1 - 0
crystal2jasper/src/test/java/com/uas/report/crystal2jasper/CrystalToJasperTest.java

@@ -1,5 +1,6 @@
 package com.uas.report.crystal2jasper;
 
+import com.uas.report.util.ResourceUtils;
 import org.dom4j.DocumentException;
 import org.junit.Test;
 import org.slf4j.Logger;

+ 64 - 64
pom.xml

@@ -1,64 +1,64 @@
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>1.4.1.RELEASE</version>
-    </parent>
-    <groupId>com.uas.report</groupId>
-    <artifactId>report-parent</artifactId>
-    <packaging>pom</packaging>
-    <version>0.0.1</version>
-
-    <modules>
-        <module>report</module>
-        <module>report-common</module>
-        <module>crystal2jasper</module>
-    </modules>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <report.common.version>0.0.1</report.common.version>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>com.uas.report</groupId>
-                <artifactId>report-common</artifactId>
-                <version>${report.common.version}</version>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-compiler-plugin</artifactId>
-                    <configuration>
-                        <source>1.7</source>
-                        <target>1.7</target>
-                    </configuration>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-
-    <distributionManagement>
-        <!-- 发布release仓库 -->
-        <repository>
-            <id>platform-release</id>
-            <name>platform-release</name>
-            <url>http://113.105.74.141:8081/artifactory/libs-release-local</url>
-        </repository>
-        <!-- 发布快照版本 -->
-        <snapshotRepository>
-            <id>platform-snapshots</id>
-            <name>platform-snapshots</name>
-            <url>http://113.105.74.141:8081/artifactory/libs-snapshot-local</url>
-        </snapshotRepository>
-    </distributionManagement>
-</project>
+<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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.4.1.RELEASE</version>
+    </parent>
+    <groupId>com.uas.report</groupId>
+    <artifactId>report-parent</artifactId>
+    <packaging>pom</packaging>
+    <version>0.0.1</version>
+
+    <modules>
+        <module>report</module>
+        <module>report-common</module>
+        <module>crystal2jasper</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <report.common.version>0.0.1</report.common.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.uas.report</groupId>
+                <artifactId>report-common</artifactId>
+                <version>${report.common.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <configuration>
+                        <source>1.7</source>
+                        <target>1.7</target>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <distributionManagement>
+        <!-- 发布release仓库 -->
+        <repository>
+            <id>platform-release</id>
+            <name>platform-release</name>
+            <url>http://113.105.74.141:8081/artifactory/libs-release-local</url>
+        </repository>
+        <!-- 发布快照版本 -->
+        <snapshotRepository>
+            <id>platform-snapshots</id>
+            <name>platform-snapshots</name>
+            <url>http://113.105.74.141:8081/artifactory/libs-snapshot-local</url>
+        </snapshotRepository>
+    </distributionManagement>
+</project>

+ 2 - 2
report-common/src/main/java/com/uas/report/util/FileUtils.java

@@ -54,7 +54,7 @@ public class FileUtils {
 		}
 
 		File file = new File(filePath);
-		if (!file.getParentFile().exists()) {
+		if (file.getParentFile() != null && !file.getParentFile().exists()) {
 			file.getParentFile().mkdirs();
 		}
 		FileOutputStream fos = new FileOutputStream(file);
@@ -74,7 +74,7 @@ public class FileUtils {
 	 * @return 写入的文件
 	 */
 	public static File write(File file, String content) throws IOException {
-		if (!file.getParentFile().exists()) {
+		if (file.getParentFile() != null && !file.getParentFile().exists()) {
 			file.getParentFile().mkdirs();
 		}
 		file.createNewFile();

+ 1 - 1
crystal2jasper/src/main/java/com/uas/report/crystal2jasper/ResourceUtils.java → report-common/src/main/java/com/uas/report/util/ResourceUtils.java

@@ -1,4 +1,4 @@
-package com.uas.report.crystal2jasper;
+package com.uas.report.util;
 
 import java.io.File;
 import java.io.FileNotFoundException;

+ 2 - 2
report-common/src/main/java/com/uas/report/util/ZipUtils.java

@@ -146,7 +146,7 @@ public class ZipUtils {
 				}
 				continue;
 			}
-			if (!outFile.getParentFile().exists()) {
+			if (outFile.getParentFile() != null && !outFile.getParentFile().exists()) {
 				outFile.getParentFile().mkdirs();
 			}
 
@@ -199,7 +199,7 @@ public class ZipUtils {
 			}
 			InputStream inputStream = zipFile.getInputStream(zipEntry);
 			File outFile = new File(folder.getPath() + File.separator + zipEntry.getName());
-			if (!outFile.getParentFile().exists()) {
+			if (outFile.getParentFile() != null && !outFile.getParentFile().exists()) {
 				outFile.getParentFile().mkdirs();
 			}
 

+ 0 - 9
report/pom.xml

@@ -322,15 +322,6 @@
 					</items>
 				</configuration>
 			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<configuration>
-					<encoding>${project.build.sourceEncoding}</encoding>
-					<source>1.7</source>
-					<target>1.7</target>
-				</configuration>
-			</plugin>
 			<plugin>
 				<artifactId>maven-resources-plugin</artifactId>
 				<executions>

+ 1 - 1
report/src/main/java/com/uas/report/Application.java

@@ -41,7 +41,7 @@ public class Application extends SpringBootServletInitializer implements Applica
 	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
 		try {
 			File logFile = new File("logs/log.log");
-			if (!logFile.getParentFile().exists()) {
+			if (logFile.getParentFile() != null && !logFile.getParentFile().exists()) {
 				logFile.getParentFile().mkdir();
 			}
 			System.setErr(new PrintStream(new FileOutputStream(logFile, true)));

+ 336 - 0
report/src/main/java/com/uas/report/DynamicProperties.java

@@ -0,0 +1,336 @@
+package com.uas.report;
+
+import com.alibaba.fastjson.JSONObject;
+import com.uas.report.annotation.DynamicValue;
+import com.uas.report.model.ExportType;
+import com.uas.report.util.FileUtils;
+import com.uas.report.util.ObjectUtils;
+import com.uas.report.util.ResourceUtils;
+import com.uas.report.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * 不同环境下的配置信息(来自自定义的配置文件)
+ *
+ * @author sunyj
+ * @since 2017年1月10日 下午3:32:30
+ */
+@Component
+public class DynamicProperties {
+
+    /**
+     * 配置文件名称
+     */
+    private static final String PROPERTY_FILE_NAME = "report.properties";
+
+    /**
+     * 记录配置文件最后修改时间
+     */
+    private long propertyFileLastModified;
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+	 * 本地资源根路径
+	 */
+	@DynamicValue("localBaseDir")
+	private String localBaseDir;
+
+	/**
+	 * 本地资源图片路径
+	 */
+	@DynamicValue("localImagesDir")
+	private String localImagesDir;
+
+	/**
+	 * 本地资源jrxml模板路径
+	 */
+	@DynamicValue("localJrxmlDir")
+	private String localJrxmlDir;
+
+	/**
+	 * 标准账套(存放标准模板)
+	 */
+	@DynamicValue("standardMaster")
+	private String standardMaster;
+
+	/**
+	 * 本地是否拥有标准模板
+	 */
+	@DynamicValue("hasStandardJrxmls")
+	private Boolean hasStandardJrxmls;
+
+	/**
+	 * 标准模板地址
+	 */
+	@DynamicValue("standardJrxmlsUrl")
+	private String standardJrxmlsUrl;
+
+	/**
+	 * 主账套与其子帐套是否共用模板
+	 */
+	@DynamicValue("shareJrxmlsWithSubMaster")
+	private Boolean shareJrxmlsWithSubMaster;
+
+	/**
+	 * 数据源配置信息
+	 */
+	@DynamicValue("datasource")
+	private JSONObject dataSourceInformation;
+
+    /**
+     * PC端支持打印的最大记录行数
+     */
+    @DynamicValue("max-record-size.pc")
+    private int maxRecordSizePc;
+
+    /**
+     * 手机端支持打印的最大记录行数
+     */
+    @DynamicValue("max-record-size.phone")
+    private int maxRecordSizePhone;
+
+    /**
+     * 是否使用 xlsx
+     */
+    @DynamicValue("use-xlsx")
+    private Boolean useXlsx;
+
+    /**
+     * 预览页面所显示的导出按钮
+     */
+    @DynamicValue("page.preview.show-export-buttons")
+    private List<ExportType> pagePreviewShowExportButtons;
+
+    public DynamicProperties() {
+        mayLoad();
+    }
+
+    /**
+     * 加载配置
+     */
+    private void mayLoad() {
+        try {
+            File propertyFile = new File(PROPERTY_FILE_NAME);
+            if (!propertyFile.exists()) {
+                // 配置文件不存在时,加载旧的配置文件(以兼容旧的配置方式)
+                // TODO temporary codes
+                File oldPropertyFile = new File("application.properties");
+                if (oldPropertyFile.exists() && oldPropertyFile.isFile()) {
+                    FileUtils.copy(oldPropertyFile, propertyFile);
+                } else {
+                    // 复制类路径下默认的配置文件
+                    File defaultPropertyFile = ResourceUtils.getFile(PROPERTY_FILE_NAME);
+                    if (defaultPropertyFile == null) {
+                        throw new FileNotFoundException("配置文件不存在:" + PROPERTY_FILE_NAME);
+                    }
+                    // 是否以 spring boot jar 形式运行
+                    URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
+                    if (org.springframework.util.ResourceUtils.isJarURL(location)) {
+                        // 以 spring boot jar 形式运行时,不能直接复制默认配置文件,需以输入流的方式读取默认配置
+                        InputStream inputStream = getClass().getResourceAsStream("/" + PROPERTY_FILE_NAME);
+                        byte[] data = new byte[inputStream.available()];
+                        inputStream.read(data);
+                        FileUtils.write(propertyFile.getPath(), data);
+                    }else{
+                        FileUtils.copy(defaultPropertyFile, propertyFile);
+                    }
+                }
+            }
+            if(propertyFile.isDirectory()){
+                throw new IOException("并非文件:" + PROPERTY_FILE_NAME);
+            }
+            long lastModified = propertyFile.lastModified();
+            // 如果配置文件有修改,就重新加载
+            if (propertyFileLastModified >= lastModified) {
+                return;
+            }
+
+            logger.info("加载配置 " + PROPERTY_FILE_NAME + "...");
+            propertyFileLastModified = propertyFile.lastModified();
+            Properties properties = new Properties();
+            properties.load(new FileInputStream(propertyFile));
+
+            // TODO temporary codes
+            if(!properties.containsKey("max-record-size.pc")){
+                properties.put("max-record-size.pc", "100000");
+                properties.store(new FileOutputStream(propertyFile), "report properties updated on");
+            }
+            if(!properties.containsKey("max-record-size.phone")){
+                properties.put("max-record-size.phone", "10000");
+                properties.store(new FileOutputStream(propertyFile), "report properties updated on");
+            }
+            if(!properties.containsKey("use-xlsx")){
+                properties.put("use-xlsx", "false");
+                properties.store(new FileOutputStream(propertyFile), "report properties updated on");
+            }
+            if(!properties.containsKey("page.preview.show-export-buttons")){
+                properties.put("page.preview.show-export-buttons", "PDF, XLS, XLS_DATA");
+                properties.store(new FileOutputStream(propertyFile), "report properties updated on");
+            }
+
+            // 通过反射注入配置
+            Field[] declaredFields = getClass().getDeclaredFields();
+            for (Field declaredField : declaredFields) {
+                DynamicValue dynamicValue = declaredField.getAnnotation(DynamicValue.class);
+                if (dynamicValue == null) {
+                    continue;
+                }
+                String expression = dynamicValue.value();
+                if (StringUtils.isEmpty(expression)) {
+                    throw new IllegalStateException("配置项的表达式为空:" + declaredField.getName() + "=" + expression);
+                }
+                Object value = properties.get(expression);
+                if (ObjectUtils.isEmpty(value)) {
+                    throw new IllegalArgumentException("配置项的值为空:" + expression + "=" + value);
+                }
+                try {
+                    ObjectUtils.setValue(this, declaredField, value);
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException("通过反射注入配置失败", e);
+                }
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException("配置加载失败", e);
+        }
+    }
+
+    /**
+     * 更新配置
+     *
+     * @param json json 格式的配置
+     */
+    public void update(String json) {
+        if (StringUtils.isEmpty(json)) {
+            throw new IllegalArgumentException("json 为空");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(json);
+        // 更新 json 中指定的配置项
+        Set<Map.Entry<String, Object>> entrySet = jsonObject.entrySet();
+        for (Map.Entry<String, Object> entry : entrySet) {
+            String key = entry.getKey();
+            Object value = entry.getValue();
+            if (ObjectUtils.isEmpty(value)) {
+                throw new IllegalArgumentException("参数值为空:" + entry);
+            }
+            Field field;
+            try {
+                field = getClass().getDeclaredField(key);
+                ObjectUtils.setValue(this, field, value);
+            } catch (NoSuchFieldException e) {
+                throw new IllegalArgumentException("不支持配置项:" + key, e);
+            } catch (IllegalAccessException e) {
+                throw new IllegalStateException("通过反射修改配置失败", e);
+            }
+        }
+        save();
+    }
+
+    /**
+     * 保存配置
+     */
+    private void save() {
+        try {
+            Properties properties = new Properties();
+            Field[] declaredFields = getClass().getDeclaredFields();
+            // 通过反射读取所有配置,写入本地文件
+            for (Field declaredField : declaredFields) {
+                DynamicValue dynamicValue = declaredField.getAnnotation(DynamicValue.class);
+                if (dynamicValue == null) {
+                    continue;
+                }
+                String expression = dynamicValue.value();
+                if (StringUtils.isEmpty(expression)) {
+                    throw new IllegalStateException("配置项的表达式为空:" + declaredField.getName() + "=" + expression);
+                }
+                Object value = ObjectUtils.getValue(declaredField, this);
+                if (ObjectUtils.isEmpty(value)) {
+                    throw new IllegalArgumentException("配置项的值为空:" + expression + "=" + value);
+                }
+                // List 直接 toString,结果中会带 '[]'
+                if (value instanceof List) {
+                    List list = (List) value;
+                    StringBuilder builder = new StringBuilder();
+                    for (int i = 0; i < list.size(); i++) {
+                        if (i != 0) {
+                            builder.append(", ");
+                        }
+                        builder.append(list.get(i));
+                    }
+                    properties.setProperty(expression, builder.toString());
+                } else {
+                    properties.setProperty(expression, value.toString());
+                }
+            }
+            properties.store(new FileOutputStream(new File(PROPERTY_FILE_NAME)), "report properties updated on");
+        } catch (IOException e) {
+            throw new IllegalStateException("配置保存失败", e);
+        }
+    }
+
+    public String getLocalBaseDir() {
+        mayLoad();
+		return localBaseDir;
+	}
+
+	public String getLocalImagesDir() {
+        mayLoad();
+		return localImagesDir;
+	}
+
+	public String getLocalJrxmlDir() {
+        mayLoad();
+		return localJrxmlDir;
+	}
+
+	public String getStandardMaster() {
+        mayLoad();
+		return standardMaster;
+	}
+
+	public Boolean getHasStandardJrxmls() {
+        mayLoad();
+		return hasStandardJrxmls;
+	}
+
+	public String getStandardJrxmlsUrl() {
+        mayLoad();
+		return standardJrxmlsUrl;
+	}
+
+	public Boolean getShareJrxmlsWithSubMaster() {
+        mayLoad();
+		return shareJrxmlsWithSubMaster;
+	}
+
+	public JSONObject getDataSourceInformation() {
+        mayLoad();
+		return dataSourceInformation;
+	}
+
+    public int getMaxRecordSizePc() {
+        return maxRecordSizePc;
+    }
+
+    public int getMaxRecordSizePhone() {
+        return maxRecordSizePhone;
+    }
+
+    public Boolean getUseXlsx() {
+        return useXlsx;
+    }
+
+    public List<ExportType> getPagePreviewShowExportButtons() {
+        return pagePreviewShowExportButtons;
+    }
+}

+ 0 - 127
report/src/main/java/com/uas/report/SpecialProperties.java

@@ -1,127 +0,0 @@
-package com.uas.report;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 不同环境下的配置信息(来自spring cloud)
- * 
- * @author sunyj
- * @since 2017年1月10日 下午3:32:30
- */
-@Configuration
-public class SpecialProperties {
-
-	/**
-	 * 本地资源根路径
-	 */
-	@Value("${localBaseDir}")
-	private String localBaseDir;
-
-	/**
-	 * 本地资源图片路径
-	 */
-	@Value("${localImagesDir}")
-	private String localImagesDir;
-
-	/**
-	 * 本地资源jrxml模板路径
-	 */
-	@Value("${localJrxmlDir}")
-	private String localJrxmlDir;
-
-	/**
-	 * 标准账套(存放标准模板)
-	 */
-	@Value("${standardMaster}")
-	private String standardMaster;
-
-	/**
-	 * 本地是否拥有标准模板
-	 */
-	@Value("${hasStandardJrxmls}")
-	private boolean hasStandardJrxmls;
-
-	/**
-	 * 标准模板地址
-	 */
-	@Value("${standardJrxmlsUrl}")
-	private String standardJrxmlsUrl;
-
-	/**
-	 * 主账套与其子帐套是否共用模板
-	 */
-	@Value("${shareJrxmlsWithSubMaster}")
-	private boolean shareJrxmlsWithSubMaster;
-
-	/**
-	 * 数据源配置信息
-	 */
-	@Value("${datasource}")
-	private String dataSourceInformation;
-
-	public String getLocalBaseDir() {
-		return localBaseDir;
-	}
-
-	public void setLocalBaseDir(String localBaseDir) {
-		this.localBaseDir = localBaseDir;
-	}
-
-	public String getLocalImagesDir() {
-		return localImagesDir;
-	}
-
-	public void setLocalImagesDir(String localImagesDir) {
-		this.localImagesDir = localImagesDir;
-	}
-
-	public String getLocalJrxmlDir() {
-		return localJrxmlDir;
-	}
-
-	public void setLocalJrxmlDir(String localJrxmlDir) {
-		this.localJrxmlDir = localJrxmlDir;
-	}
-
-	public String getStandardMaster() {
-		return standardMaster;
-	}
-
-	public void setStandardMaster(String standardMaster) {
-		this.standardMaster = standardMaster;
-	}
-
-	public boolean hasStandardJrxmls() {
-		return hasStandardJrxmls;
-	}
-
-	public void setHasStandardJrxmls(boolean hasStandardJrxmls) {
-		this.hasStandardJrxmls = hasStandardJrxmls;
-	}
-
-	public String getStandardJrxmlsUrl() {
-		return standardJrxmlsUrl;
-	}
-
-	public void setStandardJrxmlsUrl(String standardJrxmlsUrl) {
-		this.standardJrxmlsUrl = standardJrxmlsUrl;
-	}
-
-	public boolean shareJrxmlsWithSubMaster() {
-		return shareJrxmlsWithSubMaster;
-	}
-
-	public void setShareJrxmlsWithSubMaster(boolean shareJrxmlsWithSubMaster) {
-		this.shareJrxmlsWithSubMaster = shareJrxmlsWithSubMaster;
-	}
-
-	public String getDataSourceInformation() {
-		return dataSourceInformation;
-	}
-
-	public void setDataSourceInformation(String dataSourceInformation) {
-		this.dataSourceInformation = dataSourceInformation;
-	}
-
-}

+ 14 - 59
report/src/main/java/com/uas/report/SystemProperties.java

@@ -1,11 +1,8 @@
 package com.uas.report;
 
-import com.uas.report.model.ExportType;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * 系统参数
  * 
@@ -27,36 +24,18 @@ public class SystemProperties {
 	@Value("${schedule.auto-start}")
 	private boolean taskAutoStart;
 
-	/**
-	 * PC端支持打印的最大记录行数
-	 */
-	@Value("${max-record-size.pc}")
-	private int maxRecordSizePc;
-
-	/**
-	 * 手机端支持打印的最大记录行数
-	 */
-	@Value("${max-record-size.phone}")
-	private int maxRecordSizePhone;
-
-	/**
-	 * 是否使用 xlsx
-	 */
-	@Value("${use-xlsx}")
-	private boolean useXlsx;
-
-	/**
-	 * 预览页面所显示的导出按钮
-	 */
-	@Value("${page.preview.show-export-buttons}")
-	private List<ExportType> pagePreviewShowExportButtons;
-
 	/**
 	 * 以 spring boot jar 方式启动时,需解压的 jar
 	 */
 	@Value("${extract-jars}")
 	private String[] extractJars;
 
+    /**
+     * 数据源的默认配置
+     */
+    @Value("${datasource-default-config}")
+	private String dataSourceDefaultConfig;
+
 	public int getTaskPeriod() {
 		return taskPeriod;
 	}
@@ -73,38 +52,6 @@ public class SystemProperties {
 		this.taskAutoStart = taskAutoStart;
 	}
 
-	public int getMaxRecordSizePc() {
-		return maxRecordSizePc;
-	}
-
-	public void setMaxRecordSizePc(int maxRecordSizePc) {
-		this.maxRecordSizePc = maxRecordSizePc;
-	}
-
-	public int getMaxRecordSizePhone() {
-		return maxRecordSizePhone;
-	}
-
-	public void setMaxRecordSizePhone(int maxRecordSizePhone) {
-		this.maxRecordSizePhone = maxRecordSizePhone;
-	}
-
-	public boolean isUseXlsx() {
-		return useXlsx;
-	}
-
-	public void setUseXlsx(boolean useXlsx) {
-		this.useXlsx = useXlsx;
-	}
-
-	public List<ExportType> getPagePreviewShowExportButtons() {
-		return pagePreviewShowExportButtons;
-	}
-
-	public void setPagePreviewShowExportButtons(List<ExportType> pagePreviewShowExportButtons) {
-		this.pagePreviewShowExportButtons = pagePreviewShowExportButtons;
-	}
-
 	public String[] getExtractJars() {
 		return extractJars;
 	}
@@ -112,4 +59,12 @@ public class SystemProperties {
 	public void setExtractJars(String[] extractJars) {
 		this.extractJars = extractJars;
 	}
+
+    public String getDataSourceDefaultConfig() {
+        return dataSourceDefaultConfig;
+    }
+
+    public void setDataSourceDefaultConfig(String dataSourceDefaultConfig) {
+        this.dataSourceDefaultConfig = dataSourceDefaultConfig;
+    }
 }

+ 22 - 0
report/src/main/java/com/uas/report/annotation/DynamicValue.java

@@ -0,0 +1,22 @@
+package com.uas.report.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation at the field level that indicates a default value expression for the affected argument.
+ *
+ * @author sunyj
+ * @since 2017/12/20 9:16
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DynamicValue {
+
+    /**
+     * The actual value expression: e.g. "#{systemProperties.myProp}".
+     */
+    String value() default "";
+}

+ 5 - 5
report/src/main/java/com/uas/report/axis/BasicResourceHandler.java

@@ -12,7 +12,7 @@ import java.util.Map;
 
 import javax.activation.DataSource;
 
-import com.uas.report.SpecialProperties;
+import com.uas.report.DynamicProperties;
 import com.uas.report.util.CollectionUtils;
 import com.uas.report.util.ContextUtils;
 import com.uas.report.util.FileUtils;
@@ -20,7 +20,7 @@ import com.uas.report.util.StringUtils;
 
 public class BasicResourceHandler implements ResourceHandler {
 
-	private SpecialProperties specialProperties = ContextUtils.getBean(SpecialProperties.class);
+	private DynamicProperties dynamicProperties = ContextUtils.getBean(DynamicProperties.class);
 
 	private FileFilter filter = new FileFilter() {
 		@Override
@@ -39,7 +39,7 @@ public class BasicResourceHandler implements ResourceHandler {
 	};
 
 	public List<Resource> listResource(String resourceURI) throws FileNotFoundException, IOException {
-		File dir = new File(specialProperties.getLocalBaseDir() + Folder.SEPARATOR + resourceURI);
+		File dir = new File(dynamicProperties.getLocalBaseDir() + Folder.SEPARATOR + resourceURI);
 		if (!dir.exists() || !dir.isDirectory() || !filter.accept(dir)) {
 			return null;
 		}
@@ -107,12 +107,12 @@ public class BasicResourceHandler implements ResourceHandler {
 	}
 
 	protected File getFile(String resourceURI) {
-		return new File(specialProperties.getLocalBaseDir() + "/" + resourceURI);
+		return new File(dynamicProperties.getLocalBaseDir() + "/" + resourceURI);
 	}
 
 	private String getResourceURI(File file) {
 		String resourceURI = file.getPath();
-		resourceURI = resourceURI.replace(new File(specialProperties.getLocalBaseDir()).getPath(), "");
+		resourceURI = resourceURI.replace(new File(dynamicProperties.getLocalBaseDir()).getPath(), "");
 		resourceURI = resourceURI.replace("\\", Folder.SEPARATOR);
 		if (!resourceURI.startsWith(Folder.SEPARATOR)) {
 			resourceURI = Folder.SEPARATOR + resourceURI;

+ 5 - 5
report/src/main/java/com/uas/report/controller/PrintController.java

@@ -1,6 +1,6 @@
 package com.uas.report.controller;
 
-import com.uas.report.SystemProperties;
+import com.uas.report.DynamicProperties;
 import com.uas.report.model.ExportType;
 import com.uas.report.model.Platform;
 import com.uas.report.model.PrintParameter;
@@ -46,8 +46,8 @@ public class PrintController {
 
     private Logger logger = LoggerFactory.getLogger(getClass());
 
-	@Autowired
-	private SystemProperties systemProperties;
+    @Autowired
+    private DynamicProperties dynamicProperties;
 
 	@Autowired
 	private PrintService printService;
@@ -120,7 +120,7 @@ public class PrintController {
                 break;
             // 该下载接口供 UAS 系统使用,应其要求,printType 为{@link PrintType.EXCEL}时,下载纯数据的 excel
             case EXCEL:
-                if (systemProperties.isUseXlsx()) {
+                if (dynamicProperties.getUseXlsx()) {
                     export(requestId, ExportType.XLSX_DATA.name(), true, request, response);
                 } else {
                     export(requestId, ExportType.XLS_DATA.name(), true, request, response);
@@ -311,6 +311,6 @@ public class PrintController {
 	@RequestMapping(value = "/exportButtons")
 	@ResponseBody
 	public List<ExportType> getPagePreviewShowExportButtons(HttpServletRequest request, HttpServletResponse response) {
-		return systemProperties.getPagePreviewShowExportButtons();
+		return dynamicProperties.getPagePreviewShowExportButtons();
 	}
 }

+ 39 - 0
report/src/main/java/com/uas/report/controller/PropertiesController.java

@@ -0,0 +1,39 @@
+package com.uas.report.controller;
+
+import com.uas.report.DynamicProperties;
+import com.uas.report.util.MasterManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 配置修改
+ *
+ * @author sunyj
+ * @since 2017/12/20 14:47
+ */
+@Controller
+@RequestMapping("/properties")
+public class PropertiesController {
+
+    @Autowired
+    private DynamicProperties dynamicProperties;
+
+    @RequestMapping("/get")
+    @ResponseBody
+    public DynamicProperties get(HttpServletRequest request) {
+        return dynamicProperties;
+    }
+
+    @RequestMapping("/update")
+    @ResponseBody
+    public boolean update(@RequestParam String json, HttpServletRequest request) {
+        dynamicProperties.update(json);
+        MasterManager.init();
+        return true;
+    }
+}

+ 15 - 15
report/src/main/java/com/uas/report/service/impl/FileServiceImpl.java

@@ -2,7 +2,7 @@ package com.uas.report.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.lowagie.text.pdf.PdfReader;
-import com.uas.report.SpecialProperties;
+import com.uas.report.DynamicProperties;
 import com.uas.report.schedule.model.TaskInformation;
 import com.uas.report.schedule.service.Executable;
 import com.uas.report.schedule.service.TaskService;
@@ -30,7 +30,7 @@ import java.util.*;
 public class FileServiceImpl implements FileService {
 
 	@Autowired
-	private SpecialProperties specialProperties;
+	private DynamicProperties dynamicProperties;
 
 	@Autowired
 	private TaskService taskService;
@@ -72,9 +72,9 @@ public class FileServiceImpl implements FileService {
 			throw new IllegalArgumentException("参数不能为空:sourceUserName,destinationUserNames");
 		}
 		byte[] data = null;
-		String stantardJrxmlsUrl = String.format(specialProperties.getStandardJrxmlsUrl(), sourceUserName);
+		String stantardJrxmlsUrl = String.format(dynamicProperties.getStandardJrxmlsUrl(), sourceUserName);
 		// 如果本机提供标准模板下载,直接从本地获取数据
-		if (specialProperties.hasStandardJrxmls()) {
+		if (dynamicProperties.getHasStandardJrxmls()) {
 			data = getStandardJrxmls(sourceUserName);
 		}
 		// 本机没有标准模板,则先下载标准模板数据
@@ -123,7 +123,7 @@ public class FileServiceImpl implements FileService {
 		}
 
 		String fileName = file.getOriginalFilename();
-		StringBuilder stringBuilder = new StringBuilder(specialProperties.getLocalBaseDir()).append("/");
+		StringBuilder stringBuilder = new StringBuilder(dynamicProperties.getLocalBaseDir()).append("/");
 		// jrxml模板和图片分别放在jrxml和Picture文件夹下,其他资源放在当前账套根路径下
 		if (fileType.equals("jrxml")) {
 			stringBuilder.append(userName).append("/").append("jrxml").append("/");
@@ -138,7 +138,7 @@ public class FileServiceImpl implements FileService {
 		stringBuilder.append(fileName);
 		String targetFilePath = stringBuilder.toString();
 		final File targetFile = new File(targetFilePath);
-		if (!targetFile.getParentFile().exists()) {
+		if (targetFile.getParentFile() != null && !targetFile.getParentFile().exists()) {
 			targetFile.getParentFile().mkdirs();
 		}
 		try {
@@ -159,7 +159,7 @@ public class FileServiceImpl implements FileService {
 		filePath = getAbsolutePath(filePath, isAbsolutePath);
 		File targetFile = new File(filePath + "/" + files[0].getOriginalFilename());
 		// 检查路径是否存在
-		if (!targetFile.getParentFile().exists()) {
+		if (targetFile.getParentFile() != null && !targetFile.getParentFile().exists()) {
 			targetFile.getParentFile().mkdirs();
 		}
 
@@ -182,7 +182,7 @@ public class FileServiceImpl implements FileService {
 	@Override
 	public String getJrxmlFilePath(String userName, String reportName) {
 		ReportUtils.checkParameters(userName, reportName);
-		return new StringBuilder(getMasterPath(userName)).append(specialProperties.getLocalJrxmlDir()).append("/")
+		return new StringBuilder(getMasterPath(userName)).append(dynamicProperties.getLocalJrxmlDir()).append("/")
 				.append(reportName).append(".jrxml").toString();
 	}
 
@@ -191,7 +191,7 @@ public class FileServiceImpl implements FileService {
 		if (StringUtils.isEmpty(userName)) {
 			throw new IllegalArgumentException("参数不能为空:userName");
 		}
-		return new StringBuilder(specialProperties.getLocalBaseDir()).append("/").append(userName).toString();
+		return new StringBuilder(dynamicProperties.getLocalBaseDir()).append("/").append(userName).toString();
 	}
 
 	@Override
@@ -199,11 +199,11 @@ public class FileServiceImpl implements FileService {
 		if (StringUtils.isEmpty(userName)) {
 			throw new IllegalArgumentException("未传入当前账套名称!");
 		}
-		if (!specialProperties.hasStandardJrxmls()) {
+		if (!dynamicProperties.getHasStandardJrxmls()) {
 			throw new IllegalStateException("没有" + userName + "标准模板!");
 		}
 		try {
-			return ZipUtils.zipFolder(getMasterPath(specialProperties.getStandardMaster()) + "/" + userName,
+			return ZipUtils.zipFolder(getMasterPath(dynamicProperties.getStandardMaster()) + "/" + userName,
 					FileServiceImpl.fileFilter);
 		} catch (Throwable e) {
 			throw new IOException("压缩失败", e);
@@ -215,10 +215,10 @@ public class FileServiceImpl implements FileService {
 		if (StringUtils.isEmpty(userName)) {
 			throw new IllegalArgumentException("未传入当前账套名称!");
 		}
-		if (!specialProperties.hasStandardJrxmls()) {
+		if (!dynamicProperties.getHasStandardJrxmls()) {
 			throw new IllegalStateException("没有" + userName + "标准模板!");
 		}
-		downloadZip(specialProperties.getStandardMaster() + "/" + userName, response);
+		downloadZip(dynamicProperties.getStandardMaster() + "/" + userName, response);
 	}
 
 	@Override
@@ -599,7 +599,7 @@ public class FileServiceImpl implements FileService {
 			return null;
 		}
 		// 获取相对路径,须将本地资源根路径替换掉,并且文件分隔符统一使用 '/'
-		return file.getPath().replace(new File(specialProperties.getLocalBaseDir()).getPath(), "").replace("\\", "/");
+		return file.getPath().replace(new File(dynamicProperties.getLocalBaseDir()).getPath(), "").replace("\\", "/");
 	}
 
 	@Override
@@ -674,7 +674,7 @@ public class FileServiceImpl implements FileService {
 		}
 		// 不是绝对路径的话,则相对于模板根路径
 		if (isAbsolutePath == null || !isAbsolutePath) {
-			filePath = specialProperties.getLocalBaseDir() + "/" + filePath;
+			filePath = dynamicProperties.getLocalBaseDir() + "/" + filePath;
 		}
 		return filePath;
 	}

+ 7 - 7
report/src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -3,7 +3,7 @@ package com.uas.report.service.impl;
 import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.druid.util.JdbcUtils;
 import com.alibaba.fastjson.JSONObject;
-import com.uas.report.SpecialProperties;
+import com.uas.report.DynamicProperties;
 import com.uas.report.SystemProperties;
 import com.uas.report.jasperreports.engine.export.CustomJRXlsExporter;
 import com.uas.report.jasperreports.engine.export.CustomJRXlsxExporter;
@@ -55,7 +55,7 @@ public class PrintServiceImpl implements PrintService {
 	private SystemProperties systemProperties;
 
 	@Autowired
-	private SpecialProperties specialProperties;
+	private DynamicProperties dynamicProperties;
 
 	private Logger logger = LoggerFactory.getLogger(getClass());
 
@@ -69,7 +69,7 @@ public class PrintServiceImpl implements PrintService {
 			throw new SQLException("获取数据源失败");
 		}
 
-		if(!exportFile.getParentFile().exists()){
+		if(exportFile.getParentFile() != null && !exportFile.getParentFile().exists()){
             exportFile.getParentFile().mkdirs();
         }
 
@@ -604,11 +604,11 @@ public class PrintServiceImpl implements PrintService {
 			File jrxmlFile = new File(jrxmlFilePath);
 			// 报表模板不存在,返回B2B标准模板账套
 			if (!jrxmlFile.exists()) {
-				return specialProperties.getStandardMaster() + "/B2B";
+				return dynamicProperties.getStandardMaster() + "/B2B";
 			}
 		} else {
 			// 如果主账套与子账套共用模板
-			if (specialProperties.shareJrxmlsWithSubMaster()) {
+			if (dynamicProperties.getShareJrxmlsWithSubMaster()) {
 				Master master = MasterManager.getMaster(userName);
 				if (master != null) {
 					// 获取账套的主账套
@@ -629,10 +629,10 @@ public class PrintServiceImpl implements PrintService {
 		int maxRecordSize = 0;
 		switch (platform) {
 		case PC:
-			maxRecordSize = systemProperties.getMaxRecordSizePc();
+			maxRecordSize = dynamicProperties.getMaxRecordSizePc();
 			break;
 		case PHONE:
-			maxRecordSize = systemProperties.getMaxRecordSizePhone();
+			maxRecordSize = dynamicProperties.getMaxRecordSizePhone();
 			break;
 		}
 

+ 43 - 6
report/src/main/java/com/uas/report/util/MasterManager.java

@@ -2,7 +2,8 @@ package com.uas.report.util;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.fastjson.JSONObject;
-import com.uas.report.SpecialProperties;
+import com.uas.report.DynamicProperties;
+import com.uas.report.SystemProperties;
 import com.uas.report.model.Master;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,24 +39,60 @@ public class MasterManager {
 	private static Logger logger = LoggerFactory.getLogger(MasterManager.class);
 
 	static {
-		initAllDataSources();
+		init();
 	}
 
 	/**
 	 * 初始化所有数据源
 	 */
-	private static void initAllDataSources() {
+	public static void init() {
+	    clear();
 		// 从配置中获取数据源信息
-		SpecialProperties specialProperties = ContextUtils.getBean(SpecialProperties.class);
-		JSONObject jsonObject = JSONObject.parseObject(specialProperties.getDataSourceInformation());
+		DynamicProperties dynamicProperties = ContextUtils.getBean(DynamicProperties.class);
+        JSONObject jsonObject = dynamicProperties.getDataSourceInformation();
 		Set<Entry<String, Object>> entrySet = jsonObject.entrySet();
 		for (Entry<String, Object> entry : entrySet) {
-			DruidDataSource dataSource = JSONObject.parseObject(entry.getValue().toString(), DruidDataSource.class);
+            JSONObject object = JSONObject.parseObject(entry.getValue().toString());
+            setDefaultConfig(object);
+            DruidDataSource dataSource = JSONObject.parseObject(entry.getValue().toString(), DruidDataSource.class);
 			dataSources.put(entry.getKey().toUpperCase(), dataSource);
 			masters.add(new Master(entry.getKey()));
 		}
 	}
 
+    /**
+     * 清除旧的数据源
+     */
+	private static void clear(){
+        Set<Entry<String, DruidDataSource>> entrySet = dataSources.entrySet();
+        for(Entry<String, DruidDataSource> entry : entrySet){
+            DruidDataSource dataSource = entry.getValue();
+            try {
+                dataSource.close();
+            } catch (Exception e) {
+                logger.error("数据源关闭失败", e);
+            }
+        }
+        dataSources = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * 加载默认数据源配置
+     */
+    private static void setDefaultConfig(JSONObject dataSource){
+        SystemProperties systemProperties = ContextUtils.getBean(SystemProperties.class);
+        JSONObject dataSourceDefaultConfig = JSONObject.parseObject(systemProperties.getDataSourceDefaultConfig());
+        // 若数据源部分配置未显式指定,则使用默认值
+        Set<Entry<String, Object>> entrySet = dataSourceDefaultConfig.entrySet();
+        for(Entry<String, Object> entry : entrySet){
+            String key = entry.getKey();
+            if(StringUtils.isEmpty(dataSource.getString(key))){
+                dataSource.put(key, entry.getValue());
+            }
+        }
+    }
+
+
 	/**
 	 * 获取账套对应的数据源
 	 *

+ 90 - 0
report/src/main/java/com/uas/report/util/ObjectUtils.java

@@ -1,8 +1,11 @@
 package com.uas.report.util;
 
 import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
 import java.io.*;
 import java.lang.reflect.Field;
+import java.lang.reflect.Type;
 import java.util.*;
 import java.util.Map.Entry;
 
@@ -299,4 +302,91 @@ public class ObjectUtils {
 		}
 		return fields;
 	}
+
+    /**
+     * 通过反射为指定的字段赋值
+     *
+     * @param object 对象
+     * @param field  字段
+     * @param value  值
+     * @throws IllegalAccessException
+     */
+    public static void setValue(Object object, Field field, Object value) throws IllegalAccessException {
+        if (object == null || field == null) {
+            throw new IllegalArgumentException("object 或 field 为空");
+        }
+        if (value != null) {
+            Type type = field.getGenericType();
+            String typeString = type.toString();
+            if (typeString.equals("class java.lang.String")) {
+            } else if (typeString.equals("class java.lang.Long") || typeString.equals("long")) {
+                value = Long.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Integer") || typeString.equals("int")) {
+                value = Integer.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Short") || typeString.equals("short")) {
+                value = Short.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Double") || typeString.equals("double")) {
+                value = Double.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Float") || typeString.equals("float")) {
+                value = Float.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Byte") || typeString.equals("byte")) {
+                value = Byte.valueOf(value.toString());
+            } else if (typeString.equals("class java.lang.Boolean") || typeString.equals("boolean")) {
+                value = Boolean.valueOf(value.toString());
+            } else if (typeString.equals("class com.alibaba.fastjson.JSONObject")) {
+                value = JSONObject.parseObject(value.toString());
+            } else if (typeString.startsWith("java.util.List")) {
+                Class<?> clazz = Object.class;
+                if (typeString.matches("^java.util.List<[\\s\\S]+?>$")) {
+                    try {
+                        clazz = Class.forName(typeString.substring(typeString.indexOf("<") + 1, typeString.length() - 1));
+                    } catch (ClassNotFoundException e) {
+                        throw new IllegalStateException("无法转换为 " + typeString, e);
+                    }
+                }
+                String[] strs = value.toString().split(",[ ]*");
+                value = castList(strs, clazz);
+            } else {
+                throw new IllegalArgumentException("不支持的类型:type=" + type + ", value=" + value);
+            }
+        }
+        if (!field.isAccessible()) {
+            field.setAccessible(true);
+            field.set(object, value);
+            field.setAccessible(false);
+        } else {
+            field.set(object, value);
+        }
+    }
+
+    /**
+     * 转换 String 数组为指定对象列表
+     *
+     * @param strs  String 数组
+     * @param clazz 目标类型
+     * @param <T>   目标类型
+     * @return 对象列表
+     */
+    private static <T> List<T> castList(String[] strs, Class<T> clazz) {
+        if (ArrayUtils.isEmpty(strs)) {
+            return null;
+        }
+        List<T> list = new ArrayList<>();
+        for (String str : strs) {
+            list.add(cast(str, clazz));
+        }
+        return list;
+    }
+
+    /**
+     * 转换对象为指定类型
+     *
+     * @param object 对象
+     * @param clazz  目标类型
+     * @param <T>    目标类型
+     * @return 目标
+     */
+    private static <T> T cast(Object object, Class<T> clazz) {
+        return object == null ? null : (T) object;
+    }
 }

+ 3 - 12
report/src/main/resources/application.yml

@@ -18,7 +18,7 @@ spring:
 security:
  basic:
   enabled: true
-  path: /console, /file/delete, /schedule/**, /druid/*
+  path: /console, /file/delete, /schedule/**, /druid/*, /properties/**
  user:
   name: admin
   password: select111***
@@ -29,15 +29,6 @@ schedule:
  period: 3600000
  auto-start: true
  
-max-record-size:
- pc: 100000
- phone: 10000
+extract-jars: report-common, jasperreports, fastjson
 
-use-xlsx: false
-
-page:
- preview:
-  # support PDF, XLS, XLS_DATA, XLSX, XLSX_DATA, DOC, TXT in com.uas.report.model.ExportType
-  show-export-buttons: PDF, XLS, XLS_DATA
-
-extract-jars: report-common, jasperreports, fastjson
+datasource-default-config: "{\"initialSize\":1,\"minIdle\":0,\"maxActive\":20,\"maxWait\":60000,\"timeBetweenEvictionRunsMillis\":60000,\"minEvictableIdleTimeMillis\":300000,\"validationQuery\":\"SELECT 1 FROM DUAL\",\"testWhileIdle\":true,\"testOnBorrow\":true,\"testOnReturn\":false,\"removeAbandoned\":true,\"removeAbandonedTimeout\":120,\"logAbandoned\":true,\"timeBetweenLogStatsMillis\":600000,\"poolPreparedStatements\":true,\"maxPoolPreparedStatementPerConnectionSize\":20,\"filters\":\"stat,slf4j\",\"connectionProperties\":\"druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000\"}"

+ 16 - 0
report/src/main/resources/report.properties

@@ -0,0 +1,16 @@
+localBaseDir=/home/uas/data/reports
+localImagesDir=/Picture
+localJrxmlDir=/jrxml
+standardMaster=STANDARD_MASTER
+hasStandardJrxmls=false
+standardJrxmlsUrl=http://print.ubtob.com/report/file/standardJrxmls?userName=%s&onlyData=1
+shareJrxmlsWithSubMaster=false
+
+max-record-size.pc=100000
+max-record-size.phone=10000
+
+use-xlsx=false
+# support PDF, XLS, XLS_DATA, XLSX, XLSX_DATA, DOC, TXT in com.uas.report.model.ExportType
+page.preview.show-export-buttons=PDF, XLS, XLS_DATA
+
+datasource={"B2B_dev":{"driverClassName":"oracle.jdbc.driver.OracleDriver","url":"jdbc:oracle:thin:@192.168.253.6:1521:orcl","username":"uuplatformdemo","password":"selectuuplatform"}, "UAS":{"driverClassName":"oracle.jdbc.driver.OracleDriver","url":"jdbc:oracle:thin:@192.168.253.6:1521:orcl","username":"UAS","password":"select!#%*("}}

+ 5 - 0
report/src/main/webapp/WEB-INF/views/console.html

@@ -96,6 +96,11 @@
 					<li><a target="_blank">print?userName=B2B/10005740&profile=test&reportName=PURCLIST&whereCondition=where rownum<30</a></li>
 					<li><a target="_blank">fileUpload?userName=B2B/1111</a></li>
 				</ol>
+                <strong><li class="title2">配置</li></strong>
+                <ol>
+                    <li><a target="_blank">properties/get</a></li>
+                    <li><a target="_blank">properties/update?json={"hasStandardJrxmls": false}</a></li>
+                </ol>
 			</ol>
 
 			<h2>5.定时任务</h2>