chenwen 3 years ago
commit
adc63e1875
100 changed files with 13175 additions and 0 deletions
  1. 14 0
      .classpath
  2. 1 0
      .gitignore
  3. 43 0
      .project
  4. 13 0
      .settings/.jsdtscope
  5. 4 0
      .settings/org.eclipse.core.resources.prefs
  6. 11 0
      .settings/org.eclipse.jdt.core.prefs
  7. 4 0
      .settings/org.eclipse.m2e.core.prefs
  8. 10 0
      .settings/org.eclipse.wst.common.component
  9. 7 0
      .settings/org.eclipse.wst.common.project.facet.core.xml
  10. 1 0
      .settings/org.eclipse.wst.jsdt.ui.superType.container
  11. 1 0
      .settings/org.eclipse.wst.jsdt.ui.superType.name
  12. 2 0
      .settings/org.eclipse.wst.validation.prefs
  13. 7 0
      .settings/org.maven.ide.eclipse.prefs
  14. 200 0
      pom.xml
  15. 92 0
      src/main/java/com/hb/proj/auth/controller/AuthController.java
  16. 26 0
      src/main/java/com/hb/proj/auth/controller/AutoLoginUtils.java
  17. 115 0
      src/main/java/com/hb/proj/auth/controller/LoginController.java
  18. 118 0
      src/main/java/com/hb/proj/auth/controller/MenuController.java
  19. 76 0
      src/main/java/com/hb/proj/auth/service/AuthService.java
  20. 141 0
      src/main/java/com/hb/proj/auth/service/MenuService.java
  21. 319 0
      src/main/java/com/hb/proj/car/controller/CarController.java
  22. 337 0
      src/main/java/com/hb/proj/car/controller/CarOilMonitorController.java
  23. 254 0
      src/main/java/com/hb/proj/car/controller/CarRptController.java
  24. 148 0
      src/main/java/com/hb/proj/car/controller/CoilTypeSumRptController.java
  25. 173 0
      src/main/java/com/hb/proj/car/controller/ERPKLSumRptController.java
  26. 188 0
      src/main/java/com/hb/proj/car/controller/ERPKlSumUtil.java
  27. 127 0
      src/main/java/com/hb/proj/car/controller/EnergyCostAccountController.java
  28. 200 0
      src/main/java/com/hb/proj/car/controller/EnergyWaterCompareController.java
  29. 157 0
      src/main/java/com/hb/proj/car/controller/EnergyWaterSumController.java
  30. 311 0
      src/main/java/com/hb/proj/car/controller/HomeRptController.java
  31. 232 0
      src/main/java/com/hb/proj/car/controller/MaterialERPController.java
  32. 63 0
      src/main/java/com/hb/proj/car/controller/MonitorRptExportBound.java
  33. 115 0
      src/main/java/com/hb/proj/car/controller/OilBoxController.java
  34. 203 0
      src/main/java/com/hb/proj/car/controller/OilMeterController.java
  35. 36 0
      src/main/java/com/hb/proj/car/controller/RptExporterController.java
  36. 124 0
      src/main/java/com/hb/proj/car/controller/WpgSumRptController.java
  37. 56 0
      src/main/java/com/hb/proj/car/quota/AbstractQuotaStandard.java
  38. 24 0
      src/main/java/com/hb/proj/car/quota/EngineQuotaStandard.java
  39. 27 0
      src/main/java/com/hb/proj/car/quota/OuterQuotaStandard.java
  40. 164 0
      src/main/java/com/hb/proj/car/quota/QuotaConfig.java
  41. 85 0
      src/main/java/com/hb/proj/car/quota/QuotaStandardSupport.java
  42. 16 0
      src/main/java/com/hb/proj/car/quota/QuotaType.java
  43. 127 0
      src/main/java/com/hb/proj/car/quota/TravelQuotaStandard.java
  44. 25 0
      src/main/java/com/hb/proj/car/quota/WorkQuotaStandard.java
  45. 158 0
      src/main/java/com/hb/proj/car/service/CarContext.java
  46. 246 0
      src/main/java/com/hb/proj/car/service/CarOilMonitorService.java
  47. 134 0
      src/main/java/com/hb/proj/car/service/CarRptService.java
  48. 285 0
      src/main/java/com/hb/proj/car/service/CarRptUtils.java
  49. 425 0
      src/main/java/com/hb/proj/car/service/CarService.java
  50. 158 0
      src/main/java/com/hb/proj/car/service/CarSumRptService.java
  51. 102 0
      src/main/java/com/hb/proj/car/service/ERPKLSumRptService.java
  52. 84 0
      src/main/java/com/hb/proj/car/service/EnergyCostAccountService.java
  53. 247 0
      src/main/java/com/hb/proj/car/service/EnergySumRptService.java
  54. 176 0
      src/main/java/com/hb/proj/car/service/MaterialERPService.java
  55. 77 0
      src/main/java/com/hb/proj/car/service/OilBoxService.java
  56. 314 0
      src/main/java/com/hb/proj/car/service/OilMeterService.java
  57. 103 0
      src/main/java/com/hb/proj/car/service/YearSumCompareService.java
  58. 356 0
      src/main/java/com/hb/proj/excel/ExcelSupport.java
  59. 108 0
      src/main/java/com/hb/proj/excel/ExcelUtils.java
  60. 62 0
      src/main/java/com/hb/proj/excel/ExpressExecuter.java
  61. 9 0
      src/main/java/com/hb/proj/excel/InsertRowCallback.java
  62. 23 0
      src/main/java/com/hb/proj/excel/OgnlExecuter.java
  63. 88 0
      src/main/java/com/hb/proj/excel/Table.java
  64. 185 0
      src/main/java/com/hb/proj/excel/TableExporter.java
  65. 34 0
      src/main/java/com/hb/proj/excel/TableTd.java
  66. 57 0
      src/main/java/com/hb/proj/excel/imp/CellConfig.java
  67. 56 0
      src/main/java/com/hb/proj/excel/imp/ExcelConfig.java
  68. 192 0
      src/main/java/com/hb/proj/excel/imp/ExcelDataExtractor.java
  69. 84 0
      src/main/java/com/hb/proj/excel/imp/ExcelImportValidator.java
  70. 78 0
      src/main/java/com/hb/proj/excel/imp/ExcelResult.java
  71. 31 0
      src/main/java/com/hb/proj/excel/imp/ExcelTool.java
  72. 464 0
      src/main/java/com/hb/proj/input/controller/CarConsumeController.java
  73. 92 0
      src/main/java/com/hb/proj/input/controller/ConsumeInputTempBound.java
  74. 76 0
      src/main/java/com/hb/proj/input/controller/InputDateLimit.java
  75. 110 0
      src/main/java/com/hb/proj/input/controller/WorkloadController.java
  76. 133 0
      src/main/java/com/hb/proj/input/controller/WpgController.java
  77. 245 0
      src/main/java/com/hb/proj/input/service/CarConsumeService.java
  78. 94 0
      src/main/java/com/hb/proj/input/service/WorkloadService.java
  79. 92 0
      src/main/java/com/hb/proj/input/service/WpgService.java
  80. 472 0
      src/main/java/com/hb/proj/model/CarConsume.java
  81. 111 0
      src/main/java/com/hb/proj/model/CarConsumeRptVO.java
  82. 179 0
      src/main/java/com/hb/proj/model/ERP.java
  83. 45 0
      src/main/java/com/hb/proj/model/ERPCalculater.java
  84. 301 0
      src/main/java/com/hb/proj/model/EnergyWaterCompareVO.java
  85. 255 0
      src/main/java/com/hb/proj/model/EnergyWaterRatioCompareVO.java
  86. 328 0
      src/main/java/com/hb/proj/model/EnergyWaterSumVO.java
  87. 164 0
      src/main/java/com/hb/proj/model/EnergyWaterSumVOUtil.java
  88. 161 0
      src/main/java/com/hb/proj/model/Menu.java
  89. 117 0
      src/main/java/com/hb/proj/model/OilAddLog.java
  90. 87 0
      src/main/java/com/hb/proj/model/OilChangeBO.java
  91. 56 0
      src/main/java/com/hb/proj/model/OilCurrentDTO.java
  92. 261 0
      src/main/java/com/hb/proj/model/OtherConsume.java
  93. 246 0
      src/main/java/com/hb/proj/model/OtherConsumeBO.java
  94. 47 0
      src/main/java/com/hb/proj/model/OtherConsumeWrapVO.java
  95. 151 0
      src/main/java/com/hb/proj/model/OtherOilCalculater.java
  96. 120 0
      src/main/java/com/hb/proj/model/Quota.java
  97. 124 0
      src/main/java/com/hb/proj/model/QuotaRulePO.java
  98. 76 0
      src/main/java/com/hb/proj/model/Workload.java
  99. 101 0
      src/main/java/com/hb/proj/model/WorkloadPO.java
  100. 198 0
      src/main/java/com/hb/proj/model/Wpg.java

+ 14 - 0
.classpath

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 1 - 0
.gitignore

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

+ 43 - 0
.project

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>lhLoggingCarNew</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+	</natures>
+</projectDescription>

+ 13 - 0
.settings/.jsdtscope

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/webapp"/>
+	<classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="target/m2e-wtp/web-resources"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+		<attributes>
+			<attribute name="hide" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+	<classpathentry kind="output" path=""/>
+</classpath>

+ 4 - 0
.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=utf8
+encoding//src/main/resources=UTF-8
+encoding/<project>=UTF-8

+ 11 - 0
.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.7

+ 4 - 0
.settings/org.eclipse.m2e.core.prefs

@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

+ 10 - 0
.settings/org.eclipse.wst.common.component

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="lhLoggingCar">
+        <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
+        <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
+        <property name="context-root" value="lhLoggingCar"/>
+        <property name="java-output-path" value="/lhLoggingCarNew/target/classes"/>
+    </wb-module>
+</project-modules>

+ 7 - 0
.settings/org.eclipse.wst.common.project.facet.core.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+  <fixed facet="wst.jsdt.web"/>
+  <installed facet="java" version="1.7"/>
+  <installed facet="jst.web" version="2.4"/>
+  <installed facet="wst.jsdt.web" version="1.0"/>
+</faceted-project>

+ 1 - 0
.settings/org.eclipse.wst.jsdt.ui.superType.container

@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary

+ 1 - 0
.settings/org.eclipse.wst.jsdt.ui.superType.name

@@ -0,0 +1 @@
+Window

+ 2 - 0
.settings/org.eclipse.wst.validation.prefs

@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1

+ 7 - 0
.settings/org.maven.ide.eclipse.prefs

@@ -0,0 +1,7 @@
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

+ 200 - 0
pom.xml

@@ -0,0 +1,200 @@
+<?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>com.hb</groupId> 
+  <artifactId>lhLoggingCarNew</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>war</packaging> 
+
+  <name>lhloggingcar Maven Webapp</name>
+  <!-- FIXME change it to the project's website -->
+  <url>http://www.example.com</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.7</maven.compiler.source>
+    <maven.compiler.target>1.7</maven.compiler.target>
+  </properties>
+
+  <dependencies>
+     <dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<version>2.5</version>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.servlet.jsp</groupId>
+			<artifactId>jsp-api</artifactId>
+			<version>2.1</version>
+			<scope>provided</scope>
+		</dependency>
+		
+       <dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-webmvc</artifactId>
+			<version>4.3.21.RELEASE</version>
+		</dependency>
+		
+			<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-tx</artifactId>
+			<version>4.3.21.RELEASE</version>
+		</dependency>
+
+		<dependency>
+	      <groupId>commons-dbcp</groupId>
+	      <artifactId>commons-dbcp</artifactId>
+	      <version>1.4</version>
+       </dependency>
+
+
+		<dependency>
+			<groupId>org.aspectj</groupId>
+			<artifactId>aspectjweaver</artifactId>
+			<version>1.7.1</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-jdbc</artifactId>
+			<version>4.3.21.RELEASE</version>
+		</dependency>
+		
+		<dependency>
+			<groupId>commons-beanutils</groupId>
+			<artifactId>commons-beanutils</artifactId>
+			<version>1.9.4</version>
+		</dependency>
+		
+		
+		
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.7.2</version>
+		</dependency>
+
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<version>1.0.7</version>
+		</dependency>
+
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>1.0.7</version>
+		</dependency>
+		
+		<dependency>
+		    <groupId>com.fasterxml.jackson.core</groupId>
+		    <artifactId>jackson-databind</artifactId>
+		    <version>2.8.11.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.6</version>
+		</dependency>
+		
+		<dependency>
+		    <groupId>com.alibaba</groupId>
+		    <artifactId>fastjson</artifactId>
+		    <version>1.2.72</version>
+		</dependency>
+		
+		<dependency>
+	         <groupId>com.hb</groupId>
+	         <artifactId>xframework</artifactId>
+	         <version>4.2</version>
+        </dependency>
+      
+      
+		<dependency>
+		    <groupId>mysql</groupId>
+		    <artifactId>mysql-connector-java</artifactId>
+		    <version>5.1.25</version>
+		</dependency>
+        
+        <dependency>
+			<groupId>net.sourceforge</groupId>
+			<artifactId>pinyin4j</artifactId>
+			<version>2.5.0</version>
+		</dependency>
+		
+		<dependency>
+		    <groupId>org.freemarker</groupId>
+		    <artifactId>freemarker</artifactId>
+		    <version>2.3.9</version>
+		</dependency>
+		
+		<dependency>
+		    <groupId>org.apache.poi</groupId>
+		    <artifactId>poi</artifactId>
+		    <version>3.17</version>
+		</dependency>
+		
+		 <dependency>
+             <groupId>org.apache.poi</groupId>
+             <artifactId>poi-ooxml</artifactId>
+             <version>3.17</version>
+         </dependency>
+         
+         <dependency>
+			<groupId>ognl</groupId>
+			<artifactId>ognl</artifactId>
+			<version>3.0.6</version>
+		</dependency>
+	   
+	   <dependency>
+		  <groupId>commons-fileupload</groupId>
+		  <artifactId>commons-fileupload</artifactId>
+		  <version>1.3</version>
+	    </dependency>
+	    
+	  <dependency>
+	    <groupId>com.squareup.okhttp3</groupId>
+	    <artifactId>okhttp</artifactId>
+	    <version>3.10.0</version>
+	  </dependency>
+	   
+  </dependencies>
+
+  <build>
+    <finalName>lhLoggingCar</finalName>
+    <plugins>
+	  		<plugin>
+				<groupId>org.apache.tomcat.maven</groupId>
+				<artifactId>tomcat7-maven-plugin</artifactId>
+				<version>2.2</version>
+				<configuration>
+					<url>http://localhost:8080/manager/text</url>
+					<path>/car</path>
+					<uriEncoding>UTF-8</uriEncoding>
+					<server>tomcat</server>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version> 
+				<configuration>
+					<encoding>utf8</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<version>2.4</version>
+				<configuration>
+					<includeEmptyDirectories>true</includeEmptyDirectories>
+				</configuration>
+			</plugin>
+			
+		</plugins>
+  </build>
+</project>

+ 92 - 0
src/main/java/com/hb/proj/auth/controller/AuthController.java

@@ -0,0 +1,92 @@
+package com.hb.proj.auth.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.auth.service.AuthService;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+
+@Controller
+@RequestMapping("/**/auth")
+public class AuthController {
+
+	@Autowired
+	private AuthService service;
+	
+	/**
+	 * 主页菜单
+	 * @param response
+	 */
+	@RequestMapping("/loadMyMenus")
+	public void loadMyMenus(HttpServletResponse response){
+		try{
+			SessionUser su=SessionThreadLocal.getSessionUser();
+			if(su==null){
+				JsonOutUtils.returnError(response, "缺少登录信息");
+				return ;
+			}
+			List<Map<String,Object>> menus=null;
+			if(su.isSysAdmin()){
+				menus=service.loadAllMenus();
+			}
+			else{
+				menus=service.loadMyMenus(su.getUserId());
+			}
+			JsonOutUtils.returnOkWithData(response, menus);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "获取菜单服务出错");
+		}
+		
+	}
+	
+	
+	/**
+	 * 可分配的权限节点(菜单,功能点暂时不需要)
+	 * @param response
+	 */
+	@RequestMapping("/loadAuthNodes")
+	public void loadAuthNodes(HttpServletResponse response){
+		List<Map<String,Object>> nodes=service.loadAllMenuNodes();
+		if(nodes==null||nodes.size()==0){
+			JsonOutUtils.returnError(response, "未找到数据");
+			return;
+		}
+		/*List<Map<String,Object>> fnodes=service.loadAllFunNodes();  //暂时不需要对功能点进行分配
+		if(fnodes!=null){
+			nodes.addAll(fnodes);
+		}*/
+		JsonOutUtils.returnOkWithData(response, nodes);
+	}
+	
+	@RequestMapping("/loadUsAuth")
+	public void loadUsAuth(String userId,HttpServletResponse response){
+		if(StringUtils.isEmpty(userId)){
+			JsonOutUtils.returnError(response, "缺少用户信息");
+			return;
+		}
+		JsonOutUtils.returnOkWithData(response, service.loadUserAuth(userId));
+	}
+	
+	
+	@RequestMapping("/save")
+	public void save(String userId,String authIds,HttpServletResponse response){
+		if(StringUtils.isEmpty(userId)||StringUtils.isEmpty(authIds)){
+			JsonOutUtils.returnError(response, "缺少必要参数");
+			return;
+		}
+		service.saveUserAuth(userId, authIds);
+		JsonOutUtils.returnOk(response);
+	}
+}

+ 26 - 0
src/main/java/com/hb/proj/auth/controller/AutoLoginUtils.java

@@ -0,0 +1,26 @@
+package com.hb.proj.auth.controller;
+
+import java.util.Map;
+
+import com.hb.proj.sysdata.service.UserService;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.xframework.util.ApplicationContextUtils;
+import com.hb.xframework.util.SessionUser;
+
+public class AutoLoginUtils {
+
+	public static SessionUser  getSessionUser(String loginId){
+		UserService  userService=ApplicationContextUtils.getBean("userService", UserService.class);
+		Map<String,Object> us=userService.getUserByLoginId(loginId);
+		if(us==null){
+			return null;
+		}
+		MySessionUser su=new MySessionUser();
+		su.setLoginId((String)us.get("loginId"));
+		su.setUserName((String)us.get("userName"));
+		su.setUserId((String)us.get("userId"));
+		su.setOrgId((String)us.get("belongOrg"));
+		su.setOrgAssistCode((String)us.get("assistCode"));
+		return su;
+	}
+}

+ 115 - 0
src/main/java/com/hb/proj/auth/controller/LoginController.java

@@ -0,0 +1,115 @@
+package com.hb.proj.auth.controller;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.sysdata.service.UserService;
+import com.hb.proj.utils.EncryptUtil;
+import com.hb.proj.utils.MVCConstants;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.xframework.util.SessionUser;
+import com.hb.xframework.util.SysAdminHandler;
+import com.hb.xframework.web.JsonOutUtils;
+
+
+@Controller
+@RequestMapping("/**/auth")
+public class LoginController {
+
+	public static Logger logger=LoggerFactory.getLogger(LoginController.class);
+	
+	@Autowired
+	private UserService userService;
+	
+	
+
+	
+	/**
+	 * 登录验证
+	 * @param loginId
+	 * @param pwd
+	 * @param remenberMe
+	 * @return
+	 */
+	@RequestMapping("/login")
+	public void login(String loginId,String pwd,HttpServletRequest request,HttpServletResponse response){
+		
+		MySessionUser su=null;
+		if(SysAdminHandler.isSysAdminIgnoreCase(loginId)){  //系统管理员登陆验证
+			String pwdStr="";
+			try {
+				pwdStr =EncryptUtil.encrypt(pwd);
+			} catch (Exception e) {	
+				e.printStackTrace();
+			}
+			if(SysAdminHandler.validateIgnoreCase(pwdStr)){				
+				su=new MySessionUser();
+				su.setLoginId("admin");
+				su.setUserName("系统管理员");
+				su.setUserId("admin");
+				su.setSysAdmin(true);
+				afterSuccessLogin(request,response,su);
+				JsonOutUtils.returnOkWithData(response, su);
+				return ;
+			}
+			else{
+				JsonOutUtils.returnError(response, "账号或密码不正确");
+				return ;
+			}		
+		}
+		else{
+			Map<String,Object> us=userService.getUserByLoginId(loginId);
+			if(us==null||!pwd.equals(us.get("pwd"))){
+				JsonOutUtils.returnError(response, "账号或密码不正确");
+				return ;
+			}
+			else{
+				
+				su=new MySessionUser();
+				su.setLoginId((String)us.get("loginId"));
+				su.setUserName((String)us.get("userName"));
+				su.setUserId((String)us.get("userId"));
+				su.setOrgId((String)us.get("orgId"));
+				su.setOrgName((String)us.get("orgName"));
+				su.setOrgAssistCode((String)us.get("assistCode"));
+				afterSuccessLogin(request,response,su);
+				JsonOutUtils.returnOkWithData(response, su);
+				return ;
+				
+			}
+		}
+		
+	}
+	
+	private void afterSuccessLogin(HttpServletRequest request,HttpServletResponse response,SessionUser su){
+		request.getSession(true).setAttribute(MVCConstants.CUR_USER_SESSION, su);
+		//addCookies(response,"usId",remenberMe?su.getLoginId():null,!remenberMe);
+	}
+	
+	/*private void addCookies(HttpServletResponse response,String key ,String value,boolean delIf){
+		 Cookie ck=new Cookie(key,value);
+		 ck.setMaxAge(delIf?-1:(60*60*24*30));
+		 ck.setPath("/");
+         response.addCookie(ck);
+	}*/
+	
+	
+	@RequestMapping("/logout")
+	public void loginout(HttpServletRequest request,HttpServletResponse response){
+		HttpSession session=request.getSession();
+		session.removeAttribute(MVCConstants.CUR_USER_SESSION);
+		session.invalidate();
+		JsonOutUtils.returnOk(response);
+	}
+	
+	
+}

+ 118 - 0
src/main/java/com/hb/proj/auth/controller/MenuController.java

@@ -0,0 +1,118 @@
+package com.hb.proj.auth.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.auth.service.MenuService;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RequestUtils;
+import com.hb.xframework.util.JsonParamHandler;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Controller
+@RequestMapping("/**/menu")
+public class MenuController {
+
+	@Autowired
+	private MenuService service;
+	
+	@RequestMapping("/get")
+	public void get(String menuId,HttpServletResponse response){
+		if(menuId==null){
+			JsonOutUtils.returnError(response, "菜单编号不能为空,操作取消");
+			return ;
+		}
+		Map<String,Object>  menu=service.getMenu(menuId);
+		JsonOutUtils.returnOkWithData(response, menu);
+	}
+	
+	@RequestMapping("/add")
+	public void add(HttpServletRequest request,HttpServletResponse response){
+		Map<String,Object> args=RequestUtils.getParams(request);
+		if(StringUtils.isEmpty((String)args.get("menuName"))){
+			JsonOutUtils.returnError(response, "缺少菜单名称");
+			return ;
+		}
+		args.remove("oldFatherMenuId");
+		if(StringUtils.isEmpty(args.get("fatherMenuId"))){
+			args.put("fatherMenuId", "0");
+		}
+		if(StringUtils.isEmpty(args.get("displayNum"))){
+			args.put("displayNum", 0);
+		}
+		else{
+			args.put("displayNum", Integer.parseInt((String)args.get("displayNum")));
+		}
+		String newAssistCode = service.generateLeveledCode((String)args.get("fatherMenuId"));
+		if(newAssistCode==null){
+			JsonOutUtils.returnError(response, "指定的父菜单不存在");
+			return ;
+		}
+		args.put("assistCode",newAssistCode);
+		SessionUser su=SessionThreadLocal.getSessionUser();
+		args.put("creator",su!=null?su.getUserName():"unknow");
+		String newMenuId=service.addMenu(args);
+		JsonOutUtils.returnOkWithData(response, newMenuId);
+	}
+	
+	
+	@RequestMapping("/update")
+	public void update(HttpServletRequest request,HttpServletResponse response){
+		Map<String,Object> args=RequestUtils.getParams(request);
+		if(StringUtils.isEmpty(args.get("fatherMenuId"))){
+			args.put("fatherMenuId", "0");
+		}
+		String oldFatherMenuId=(String)args.remove("oldFatherMenuId");
+		String fatherMenuId=(String)args.get("fatherMenuId");
+		if (!oldFatherMenuId.equals(fatherMenuId)) { // 隶属关系变动后,修正assistCode
+			String newAssistCode =service.generateLeveledCode(fatherMenuId);
+			if(newAssistCode==null){
+				JsonOutUtils.returnError(response, "指定的父菜单不存在");
+				return ;
+			}
+			service.updateMenu(args,newAssistCode);
+		}
+		else{
+			service.updateMenu(args,null);
+		}
+		JsonOutUtils.returnOk(response);
+	}
+	
+	
+	
+	@RequestMapping("/delete")
+	public void delete(String menuId,HttpServletResponse response){
+		if(menuId==null){
+			JsonOutUtils.returnError(response, "菜单编号不能为空,操作取消");
+			return ;
+		}
+		service.deleteMenu(menuId);
+		JsonOutUtils.returnOk(response);
+	}
+	
+	/**
+	 * 获得菜单子节点(ztree格式)
+	 * @param superId
+	 * @param targetDepth
+	 * @param response
+	 */
+	@RequestMapping("/treeNode")
+	public void treeNode(String superId,HttpServletResponse response){
+		List<Map<String,Object>> nodes=service.queryTreeNodeBySuperId(StringUtils.isEmpty(superId)?"0":superId);
+		if(nodes==null){
+			return ;
+		}
+		JsonOutUtils.preprocessTreeNodes(nodes, null);
+		JsonOutUtils.writeToResponse(response, JsonParamHandler.getJson(nodes));
+	}
+	
+}

+ 76 - 0
src/main/java/com/hb/proj/auth/service/AuthService.java

@@ -0,0 +1,76 @@
+package com.hb.proj.auth.service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Service
+public class AuthService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	public List<Map<String,Object>> loadMyMenus(String usId){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select * from t_menu m");
+		sql.append(" where m.menu_id in ( ");
+		sql.append(" select menu_id from t_user_menu um where um.user_id=? ");
+		
+		//sql.append(" select menu_id from t_user_function uf inner join t_function f on uf.function_id=f.function_id where uf.user_id=? ");
+		sql.append(" )  order by m.display_num");
+		return dao.queryForListMap(sql.toString(), usId);
+	}
+	
+	public List<Map<String,Object>> loadAllMenus(){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select * from t_menu m order by m.display_num");
+		return dao.queryForListMap(sql.toString());
+	}
+	
+	public List<Map<String,Object>>  loadAllMenuNodes(){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select menu_id id,menu_name name,father_menu_id p_id,'menu' node_type from t_menu m");
+		return dao.queryForListMap(sql.toString());
+	}
+	
+	public List<Map<String,Object>> loadAllFunNodes(){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select function_id id,function_name name,menu_id p_id,'fun' node_type from t_function f");
+		return dao.queryForListMap(sql.toString());
+	}
+	
+	public List<Map<String,Object>>  loadUserAuth(String userId){
+		String sql="select menu_id id from t_user_menu where user_id=?";
+		return dao.queryForListMap(sql,userId);
+	}
+	
+	public void saveUserAuth(String userId,String authIds){
+		String sql="delete from t_user_menu where user_id=?";
+		dao.getJdbcTemplate().update(sql, userId);
+		String[] ids=authIds.split(",");
+		List<Map<String,Object>> datas=new ArrayList<Map<String,Object>>(ids.length);
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		Map<String,Object> d=null;
+		SessionUser su=SessionThreadLocal.getSessionUser();
+		for(String id : ids){
+			d=new HashMap<String,Object>();
+			d.put("recordId", uuid.generate());
+			d.put("userId", userId);
+			d.put("menuId", id);
+			d.put("createTime", new Date());
+			d.put("creator", su!=null?su.getUserName():null);
+			datas.add(d);
+		}
+		dao.batchInsert(datas, "t_user_menu");
+	}
+}

+ 141 - 0
src/main/java/com/hb/proj/auth/service/MenuService.java

@@ -0,0 +1,141 @@
+package com.hb.proj.auth.service;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.PinyinFromHanzi;
+
+@Service
+public class MenuService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	
+	public List<Map<String,Object>> queryTreeNodeBySuperId(String fatherMenuId) {
+		StringBuilder sql=new StringBuilder();
+		sql.append("select m.menu_id id,m.menu_name name,m.father_menu_id p_id,menu_link, ");
+		sql.append("(select count(1) from t_menu cm where cm.father_menu_id=m.menu_id) child_count");
+		sql.append(" from t_menu  m where m.father_menu_id=?");
+		sql.append(" order by m.display_num");
+		return dao.queryForListMap(sql.toString(),fatherMenuId);
+	}
+	
+	public Map<String,Object> getMenu(String menuId){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select menu.*,");
+		sql.append("(select sm.menu_name from t_menu sm where sm.menu_id=menu.father_menu_id) father_menu_name");
+		sql.append(" from t_menu menu where menu.menu_id=?");
+		return dao.queryForSingleMap(sql.toString(), menuId);
+	}
+	
+	public String  addMenu(Map<String,Object> menu){
+		UUIDHexGenerator uuid=new UUIDHexGenerator();
+		menu.put("createTime",new Date());
+		menu.put("menuId",uuid.generate());
+		if(StringUtils.isEmpty((String)menu.get("fatherMenuId"))){
+			menu.put("fatherMenuId", "0");
+		}
+		if(menu.get("displayNum")==null){
+			Number num=getMenuMaxDispNum((String)menu.get("fatherMenuId"));
+			menu.put("displayNum",num==null?0:(num.intValue()+1));
+		}
+		dao.insert(menu, "t_menu");
+		
+		//增加菜单的时候,自动增加浏览功能项
+		Map<String,Object>  fun=new HashMap<String,Object>();
+		fun.put("functionId", uuid.generate());
+		fun.put("createTime", new Date());
+		fun.put("menuId",menu.get("menuId"));
+		fun.put("creator", menu.get("creator"));
+		fun.put("functionCode", PinyinFromHanzi.getPinyin((String)menu.get("menuName")).toUpperCase()+"_BROWSE");
+		fun.put("functionName", "浏览");
+		
+		dao.insert(fun, "t_function");
+		
+		return (String)menu.get("menuId");
+	}
+	
+	public boolean deleteMenu(String menuId){
+		String sql="delete from t_menu where menu_id=?";
+		dao.getJdbcTemplate().update(sql, menuId);
+		
+		//级联删除分配给所有用户的该的功能
+		sql="delete from t_user_function where function_id in (select function_id from t_function where menu_id=?)";
+		dao.getJdbcTemplate().update(sql,menuId);
+				
+		sql="delete from t_function where menu_id=?";
+		dao.getJdbcTemplate().update(sql,menuId);
+		return true;
+	}
+	
+	
+	
+	public boolean updateMenu(Map<String,Object> menu,String newAssistCode){
+		if(StringUtils.isNotEmpty(newAssistCode)){
+			updateAssistCode((String)menu.get("assistCode"),newAssistCode);
+			menu.put("assistCode",newAssistCode);
+		}
+		dao.update(menu, "t_menu", "menu_id");
+		return true;
+	}
+	
+	/**
+	 * 获得指定级别下的最大assistCode
+	 * @param superId
+	 * @return
+	 */
+	public String generateLeveledCode(String superId) {
+		String superAssistCode=null;
+		if("0".equals(superId)){  //顶级父节点
+			superAssistCode="C";
+		}
+		else{
+			Map<String,Object> superMenu=getMenu(superId);
+			if(superMenu==null){
+				return null;
+			}
+			superAssistCode=(String)superMenu.get("assistCode");
+			if(StringUtils.isEmpty(superAssistCode)){
+				superAssistCode="C";
+			}
+		}
+		String subMaxAssistCode =getMaxSubAssistCode(superId);
+		if (subMaxAssistCode == null || "null".equalsIgnoreCase(subMaxAssistCode)) { // 没有子编码时
+			return superAssistCode + "000";
+		}
+		String subSerial = subMaxAssistCode.replaceFirst(superAssistCode, ""); // 子编码流水号
+
+		int nextNum = Integer.parseInt(subSerial) + 1;
+		subSerial = String.format("%1$03d", nextNum);
+		return superAssistCode + subSerial;
+	}
+	
+	private String getMaxSubAssistCode(String superId) {
+		String sql = "select max(assist_code) assist_code from t_menu where father_menu_id=?";
+		Map<String,Object> rst=dao.queryForSingleMap(sql, superId);
+		return rst!=null?(String)rst.get("assistCode"):null;
+	}
+	
+	private boolean updateAssistCode(String assistCode, String newAssistCode){
+		StringBuilder sql = new StringBuilder();
+		sql.append("update t_menu set assist_code=replace(assist_code,?,?)");
+		sql.append(" where assist_code like ?");
+		dao.getJdbcTemplate().update(sql.toString(), assistCode, newAssistCode, assistCode + "%");
+		return true;
+	}
+	
+	private Number getMenuMaxDispNum(String fatherMenuId){
+		String sql="select max(m.display_num) num from t_menu m where m.father_menu_id=?";
+		Map<String,Object> rst=dao.queryForSingleMap(sql, fatherMenuId);
+		return rst!=null?((Number)rst.get("num")):null;
+	}
+}

+ 319 - 0
src/main/java/com/hb/proj/car/controller/CarController.java

@@ -0,0 +1,319 @@
+package com.hb.proj.car.controller;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarService;
+import com.hb.proj.excel.imp.ExcelDataExtractor;
+import com.hb.proj.excel.imp.ExcelResult;
+import com.hb.proj.sysdata.service.OrgService;
+import com.hb.proj.sysdata.service.SortCodeService;
+import com.hb.proj.utils.DataAuthUtils;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.RequestUtils;
+import com.hb.proj.utils.RptMonthUtil;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Controller
+@RequestMapping("/**/car")
+public class CarController {
+	
+	@Autowired
+	private CarService  service;
+	
+	@Autowired
+	private OrgService  orgService;
+	
+	@Autowired
+	private SortCodeService  codeService;
+	
+	/**
+	 * 分类统计车辆数量
+	 * @param belongOrg  //实际传入的是org对应的assistcode
+	 * @param response
+	 */
+	@RequestMapping("/rptCount")
+	public void rptCount(String belongOrg,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				JsonOutUtils.returnError(response, "缺少登录信息");
+				return;
+		    }
+			String orgAssistCode=null;
+			if(StringUtils.isEmpty(belongOrg)){
+				orgAssistCode=su.isSysAdmin()?null:su.getOrgAssistCode();
+			}
+			else{
+				orgAssistCode=belongOrg;
+			}
+			JsonOutUtils.returnOkWithData(response, service.rptCarCount(orgAssistCode));
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	@RequestMapping("/query")
+	public void query(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			args.put("showAll", su.isSysAdmin()?"1":null); //系统管理员显示全部
+			PageModel<Map<String,Object>> pagedData=service.queryCar(args,DataAuthUtils.getAuthOrgAssistCode(su),page, limit);
+			if(pagedData==null||pagedData.getData()==null||pagedData.getData().size()==0){
+				LayGridJsonUtils.wirte(response, null,0);
+				return;
+			}
+			String crtMonth=DateUtil.format(new Date(), "yyyy-MM-dd");
+			for(Map<String,Object> car : pagedData.getData()){
+				car.put("realAge", RptMonthUtil.getWorkAge((String)car.get("wkStart"),crtMonth));
+			}
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	@RequestMapping("/loadTransfer")
+	public void loadTransfer(String carId,String startDate,String endDate,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			Date st=StringUtils.isEmpty(startDate)?null:DateUtil.parse(startDate);
+			Date et=StringUtils.isEmpty(endDate)?null:DateUtil.parse(endDate);
+			PageModel<Map<String,Object>> pagedData=service.loadCarTransfer(carId,st,et,page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd HH:mm:ss");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+
+	@RequestMapping("/get")
+	public void get(String carId,HttpServletResponse response) throws Exception{
+		Map<String,Object> mapping=service.getCar(carId);
+		if(mapping!=null&&mapping.get("workStart")!=null){
+			mapping.put("workStart", DateUtil.format((Date)mapping.get("workStart"), "yyyy-MM"));
+		}
+		JsonOutUtils.returnOkWithData(response, mapping);
+	}
+	
+	@RequestMapping("/add")
+	public void add(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  car=RequestUtils.getParams(request);
+		   car.remove("belongOrgName");
+		   car.remove("oldCustomNum");
+		   MapUtils.blankValToNull(car);
+		   if(StringUtils.isEmpty((String)car.get("belongOrg"))){
+			   JsonOutUtils.returnError(response, "该车牌未填写所属单位");
+			   return ;
+		   }
+		   if(service.existsCar(request.getParameter("carNum"),null)){
+			   JsonOutUtils.returnError(response, "该车牌已经登记过,请更换");
+			   return ;
+		   }
+		   String customNum=(String)car.get("customNum");
+		   if(StringUtils.isNotEmpty(customNum)&&service.existsCustomNum(customNum,(String)car.get("carNum"))){
+			   JsonOutUtils.returnError(response, "该车辆自编号已存在,请更换");
+			   return ;
+		   }
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   car.put("creator", su!=null?su.getUserName():"unknow");
+		   car.put("modifier", car.get("creator"));
+		   car.put("workStart", car.get("workStart")+"-01");
+		   service.addCar(car);
+		   
+		   JsonOutUtils.returnOk(response);
+		  }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/update")
+	public void update(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  car=RequestUtils.getParams(request);
+		   car.remove("belongOrgName");
+		   car.remove("oldCustomNum");
+		   MapUtils.blankValToNull(car);
+		   if(service.existsCar(request.getParameter("carNum"),request.getParameter("carId"))){
+			   JsonOutUtils.returnError(response, "该车牌已经登记过,请更换");
+			   return ;
+		   }
+		   
+		   String customNum=(String)car.get("customNum");
+		   if(StringUtils.isNotEmpty(customNum)&&service.existsCustomNum(customNum,(String)car.get("carNum"))){
+			   JsonOutUtils.returnError(response, "该车辆自编号已存在,请更换");
+			   return ;
+		   }
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   car.put("modifier", su!=null?su.getUserName():"unknow");
+		   car.put("workStart", car.get("workStart")+"-01");
+		   service.updateCar(car);
+		   
+		  /* if(oldCustomNum!=null&&!oldCustomNum.equals(customNum)){ //自编号更改了,写入流转记录中的对应快照字段
+			   service.updateTransferSnapshot((String)car.get("carId"),customNum);
+		   }*/
+		   
+		   JsonOutUtils.returnOk(response);
+	   }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/delete")
+	public void delete(String carId,HttpServletResponse response){
+		try{
+			   service.deleteCar(carId);
+			   JsonOutUtils.returnOk(response);
+		   }
+		   catch(Exception e){
+			   e.printStackTrace();
+			   JsonOutUtils.returnError(response, "服务出现错误");
+		   }
+	}
+	
+	@RequestMapping("/discard")
+	public void discard(String carId,String discard,HttpServletResponse response){
+		try{
+			   service.updateForDiscard(carId,discard);
+			   JsonOutUtils.returnOk(response);
+		   }
+		   catch(Exception e){
+			   e.printStackTrace();
+			   JsonOutUtils.returnError(response, "服务出现错误");
+		   }
+	}
+	
+	
+	@RequestMapping("/importCar")
+	public void importCar(HttpServletRequest request,HttpServletResponse response){
+		try{
+			ExcelResult importRst=ExcelDataExtractor.extractExcelData(request);
+			if(importRst==null||importRst.getException()!=null){
+				JsonOutUtils.returnError(response,(importRst==null?"导入失败":importRst.getException()));
+				return;
+			}
+			else if(importRst.getListDatas()==null||importRst.getListDatas().size()==0){
+				JsonOutUtils.returnError(response,"未提取到符合格式的数据");
+				return;
+			}
+			
+			String[] msgs=processImportData(importRst); //carNums+ignorCarNums
+			boolean sameCover="1".equals(importRst.getReqParams().get("sameCover")); //相同车辆是否覆盖库中的
+			
+			String sameIgnor=service.addCars(importRst.getListDatas(),msgs[0],sameCover);
+			/**
+			 * sameIgnor  禁止覆盖时被忽略的车牌
+			 * checkIgnor 业务校验不通过的车牌
+			 * validateError 基本数据校验错误信息
+			 */
+			Map<String,Object>  rtn=MapUtils.build("sameIgnor",sameIgnor,"checkIgnor",msgs[1],"validateError",importRst.getError().toString(),"successCount",importRst.getListDatas().size());
+			JsonOutUtils.returnOkWithData(response,rtn);
+			
+			
+			
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "导入出现错误");
+		}
+	}
+	
+	/**
+	 * 对上传的原始数据进行处理,业务约束校验、数据转换(名称转编码)
+	 * 目前校验设备名称、规格型号是否与定额标准表中的对应;
+	 * 单位名称转编码;柴油车类型转编码
+	 */
+	private String[] processImportData(ExcelResult importRst){
+		Map<String,Object> orgs=orgService.loadOrgMapping();
+		Map<String,Object> coilType=codeService.loadSortCodeMapping("402881e8734da7fa01734da7fa600000");
+		Map<String,Object> deviceNames=service.loadCarDeviceNameMapping();
+		Iterator<Map<String,Object>> iterator=importRst.getListDatas().iterator();
+		Map<String,Object> itm=null;
+		String model=null;
+		StringBuilder ignorMsg=new StringBuilder();
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		
+		Set<String> carNums=new HashSet<String>();
+		String carNum=null;
+		while(iterator.hasNext()){
+			itm=iterator.next();
+			carNum=(String)itm.get("carNum");
+			if(StringUtils.isEmpty(carNum)){
+				iterator.remove();
+				ignorMsg.append(itm.get("customNum")+";");
+				continue;
+			}
+			carNum=carNum.replaceAll("\\s+", "");
+			itm.put("carNum", carNum);
+			carNums.add(carNum);
+			if(!orgs.containsKey((String)itm.get("belongOrg"))){
+				iterator.remove();
+				ignorMsg.append(carNum+";");
+				continue;
+			}
+			if(!coilType.containsKey((String)itm.get("coilCarType"))){
+				iterator.remove();
+				ignorMsg.append(carNum+";");
+				continue;
+			}
+			if(!deviceNames.containsKey((String)itm.get("deviceName"))){
+				ignorMsg.append(carNum+";");
+				iterator.remove();
+				continue;
+			}
+			else{
+				model=(String)deviceNames.get((String)itm.get("deviceName"));
+				if(StringUtils.isNotEmpty(model)&&!model.equals(itm.get("deviceModel"))){
+					ignorMsg.append(itm.get("carNum")+";");
+					iterator.remove();
+					continue;
+				}
+			}
+			
+			itm.put("belongOrg", orgs.get((String)itm.get("belongOrg")));
+			itm.put("coilCarType", orgs.get((String)itm.get("coilCarType")));
+			itm.put("carId", uuid.generate());
+			itm.put("createTime", new Date());
+			itm.put("modifyTime", new Date());
+		}
+
+		return new String[]{StringUtils.join(carNums,","),(ignorMsg.length()>0?ignorMsg.toString():null)};
+	}
+}

+ 337 - 0
src/main/java/com/hb/proj/car/controller/CarOilMonitorController.java

@@ -0,0 +1,337 @@
+package com.hb.proj.car.controller;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarOilMonitorService;
+import com.hb.proj.car.service.OilMeterService;
+import com.hb.proj.excel.ExcelUtils;
+import com.hb.proj.utils.DataAuthUtils;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MapUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.OkhttpUtils;
+import com.hb.proj.utils.RequestUtils;
+import com.hb.proj.utils.RptMonthUtil;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SysConfigUtil;
+
+@Controller
+@RequestMapping("/**/oil")
+public class CarOilMonitorController {
+
+	@Autowired
+	private CarOilMonitorService  service;
+	
+	@Autowired
+	private OilMeterService  meterService;
+	
+	/**
+	 * 油量当前数据--安装检测用
+	 * @param request
+	 * @param page
+	 * @param limit
+	 * @param response
+	 */
+	@RequestMapping("/checkCurrentOil")
+	public void checkCurrentOil(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			
+			Map<String,Object> args=RequestUtils.getParams(request);
+			PageModel<Map<String,Object>> pagedData=service.queryCarOil(args,null,page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd HH:mm:ss");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	/**
+	 * 直接从宏电平台获取数据,用于安装检测
+	 * @param request
+	 * @param dtuNum
+	 * @param response
+	 */
+	@RequestMapping("/loadOilFromHd")
+	public void loadOilFromHd(HttpServletRequest request,String dtuNum,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(dtuNum)){
+				JsonOutUtils.returnError(response, "未提供设备识别号");
+				return;
+			}
+			Map<String,String> reqArgs=new HashMap<String,String>();
+			reqArgs.put("vins", dtuNum);
+			reqArgs.put("queryDate", DateUtil.format(new Date(), "yyyy-MM-dd"));
+			String resp=OkhttpUtils.post(SysConfigUtil.getConfig("hdOilAPI"), reqArgs);
+			if(StringUtils.isEmpty(resp)){
+				JsonOutUtils.returnError(response,"未查询到油量数据:");
+				return;
+			}
+			else{
+				/*List<OilCurrentDTO> oilDats=JSON.parseObject(resp,new TypeReference<List<OilCurrentDTO>>() {});
+				if(oilDats==null||oilDats.size()==0){
+					JsonOutUtils.returnError(response,"未查询到油量数据:");
+					return;
+				}*/
+				JsonOutUtils.returnOkWithData(response, resp);
+			}
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	
+	/**
+	 * 油量采集数据查询-表格显示
+	 * @param mountId
+	 * @param startDate
+	 * @param endDate
+	 * @param page
+	 * @param limit
+	 * @param response
+	 */
+	@RequestMapping("/queryOilCollect")
+	public void queryOilCollect(String mountId,String startDate,String endDate,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(mountId)){
+				LayGridJsonUtils.error(response, "未指定油箱编号");
+				return;
+			}
+			if(StringUtils.isEmpty(startDate)||StringUtils.isEmpty(endDate)){
+				startDate=DateUtil.format(new Date(), "yyyy-MM-dd");
+				endDate=startDate+" 23:59:59";
+				startDate=startDate+" 00:00:00";
+			}
+			PageModel<Map<String,Object>> pagedData=service.queryOilCollect(mountId,DateUtil.parse(startDate),DateUtil.parse(endDate), page,limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd HH:mm:ss");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	/**
+	 * 油量采集数据查询-绘制曲线
+	 * @param mountId
+	 * @param startDate
+	 * @param endDate
+	 * @param response
+	 */
+	@RequestMapping("/queryOilCollectCurve")
+	public void queryOilCollectCurve(String mountId,String startDate,String endDate,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(mountId)){
+				JsonOutUtils.returnError(response, "未指定油箱编号");
+				return;
+			}
+			if(StringUtils.isEmpty(startDate)||StringUtils.isEmpty(endDate)){
+				startDate=DateUtil.format(new Date(), "yyyy-MM-dd");
+				endDate=startDate+" 23:59:59";
+				startDate=startDate+" 00:00:00";
+			}
+			Date sd=DateUtil.parse(startDate),ed=DateUtil.parse(endDate);
+			List<Map<String,Object>> oildatas=service.queryOilCollectForCurve(mountId,sd,ed);
+			if(oildatas==null||oildatas.size()==0){
+				JsonOutUtils.returnError(response, "未找到数据");
+				return;
+			}
+			List<Map<String,Object>> groupCurves=new ArrayList<Map<String,Object>>();
+			groupCurves.add(buildCurveData("oil", "油量",oildatas));
+			Map<String,Object> rtnCurve=MapUtils.builder("title","油量曲线","yTitle","体积/液位","yUnit","L/0.1mm","xFixedMin",sd.getTime(),"curves",groupCurves);
+			JsonOutUtils.returnOkWithData(response, rtnCurve);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	/**
+	 * 油量采集数据查询-绘制曲线(双油箱同时绘制)
+	 * @param carId
+	 * @param startDate
+	 * @param endDate
+	 * @param response
+	 */
+	@RequestMapping("/queryOilCollectDblCurve")
+	public void queryOilCollectDblCurve(String carId,String startDate,String endDate,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(carId)){
+				JsonOutUtils.returnError(response, "未指定车辆");
+				return;
+			}
+			List<Map<String,Object>> oilboxs=meterService.loadCarBoxs(carId);
+			if(oilboxs==null||oilboxs.size()==0){
+				JsonOutUtils.returnError(response, "该车辆未配置油量计设备");
+				return;
+			}
+			
+			if(StringUtils.isEmpty(startDate)||StringUtils.isEmpty(endDate)){
+				startDate=DateUtil.format(new Date(), "yyyy-MM-dd");
+				endDate=startDate+" 23:59:59";
+				startDate=startDate+" 00:00:00";
+			}
+			Date sd=DateUtil.parse(startDate),ed=DateUtil.parse(endDate);
+			
+			
+			List<Map<String,Object>> groupCurves=new ArrayList<Map<String,Object>>();
+			List<Map<String,Object>> oildatas=null;
+			for(Map<String,Object> itm : oilboxs){
+				oildatas=service.queryOilCollectForCurve((String)itm.get("val"),sd,ed);
+				if(oildatas!=null&&oildatas.size()>0){
+					groupCurves.add(buildCurveData("oil"+itm.get("txt"), "油量-"+itm.get("txt"),oildatas));
+				}
+				
+			}
+			
+			
+			Map<String,Object> rtnCurve=MapUtils.builder("title","油量曲线","yTitle","体积/液位","yUnit","L/0.1mm","xFixedMin",sd.getTime(),"curves",groupCurves);
+			JsonOutUtils.returnOkWithData(response, rtnCurve);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	
+	
+	private Map<String,Object>  buildCurveData(String id,String title,List<Map<String,Object>> datas){
+		 List<String> times=new ArrayList<String>();
+		 List<Object> vals=new ArrayList<Object>();
+		 for(Map<String,Object> d : datas){
+			 times.add(DateUtil.format((Date)d.get("dataTime"), "yyyy-MM-dd HH:mm:ss"));
+			 vals.add(d.get("data"));
+		 }
+		 return MapUtils.builder("id",id,"title",title,"xVals",times,"yVals",vals);
+	}
+	
+	/**
+	 * 供项目部通过车辆查询油量异常数据
+	 * @param request
+	 * @param page
+	 * @param limit
+	 * @param response
+	 */
+	@RequestMapping("/queryOilException")
+	public void queryOilException(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			String startDate=request.getParameter("startDate");
+			String endDate=request.getParameter("endDate");
+			if(StringUtils.isEmpty(startDate)&&StringUtils.isEmpty(endDate)){
+				String now=DateUtil.format((new Date()),"yyyy-MM-dd");
+				startDate=now+" 00:00:00";
+				endDate=now+" 23:59:59";
+				
+			}
+			else if(StringUtils.isNotEmpty(startDate)&&StringUtils.isNotEmpty(endDate)){
+				startDate+=" 00:00:00";
+				endDate+=" 23:59:59";
+			}
+			else if(StringUtils.isNotEmpty(startDate)){
+				endDate=startDate+" 23:59:59";
+				startDate+=" 00:00:00";
+			}
+			else if(StringUtils.isNotEmpty(endDate)){
+				startDate=endDate+" 00:00:00";
+				endDate+=" 23:59:59";
+			}
+			
+			args.put("startDate", startDate);
+			args.put("endDate", endDate);
+			PageModel<Map<String,Object>> pagedData=service.queryOilException(args,DataAuthUtils.getAuthOrgAssistCode(su),page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd HH:mm:ss");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	
+	@RequestMapping("/queryOilMonitorRpt")
+	public void queryOilMonitorRpt(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			if(StringUtils.isEmpty(request.getParameter("rptMonth"))){
+				args.put("rptMonth", RptMonthUtil.getDefaultMonth());
+			}
+			PageModel<Map<String,Object>> pagedData=service.queryOilMonitorRpt(args,DataAuthUtils.getAuthOrgAssistCode(su), page,limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd HH:mm:ss");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	@RequestMapping("/exportMonitorRpt")
+	public void exportMonitorRpt(HttpServletRequest request,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				JsonOutUtils.writeToResponse(response, "<script>alert('缺少登录信息');window.close();</script>","text/html;charset=UTF-8");
+				return;
+		    }
+			
+			Map<String,Object> args=RequestUtils.getParams(request);
+			if(StringUtils.isEmpty(request.getParameter("rptMonth"))){
+				args.put("rptMonth", RptMonthUtil.getDefaultMonth());
+			}
+			
+			PageModel<Map<String,Object>> pagedData=service.queryOilMonitorRpt(args,DataAuthUtils.getAuthOrgAssistCode(su), 1,10000);
+			if(pagedData==null||pagedData.getData()==null||pagedData.getData().size()==0){
+				JsonOutUtils.writeToResponse(response, "<script>alert('暂时无数据可导出');window.close();</script>","text/html;charset=UTF-8");
+				return;
+			}
+			String templateName=File.separator+"excel"+File.separator+"oilMonitorRpt.xls";
+			Map<String,Object> context=new HashMap<String,Object>();
+			context.put("ds", pagedData.getData());
+			Workbook wb=MonitorRptExportBound.bound(context,ExcelUtils.reader(templateName,request.getSession().getServletContext()));
+			ExcelUtils.exportExcel(response, "油量监测统计", wb);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.writeToResponse(response, "<script>alert('导出数据出现错误');window.close();</script>","text/html;charset=UTF-8");
+		}
+	}
+}

+ 254 - 0
src/main/java/com/hb/proj/car/controller/CarRptController.java

@@ -0,0 +1,254 @@
+package com.hb.proj.car.controller;
+
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarOilMonitorService;
+import com.hb.proj.car.service.CarRptService;
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.car.service.CarService;
+import com.hb.proj.car.service.EnergySumRptService;
+import com.hb.proj.input.service.CarConsumeService;
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.CarConsumeRptVO;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.SessionThreadLocal;
+
+
+@Controller
+@RequestMapping("/**/rpt")
+public class CarRptController {
+
+	@Autowired
+	private CarService  carService;
+	
+	@Autowired
+	private CarRptService service;
+	
+	@Autowired
+	private CarOilMonitorService  monitorService;
+	
+	
+	@Autowired
+	private CarConsumeService  consumeService;
+	
+	@Autowired
+	private EnergySumRptService  energyService;
+	
+	/**
+	 * 单车油耗明细(有两个报表:项目部用、安全科用)
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadCarConsumeDtl")
+	public void loadCarConsumeDtl(HttpServletRequest request,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				JsonOutUtils.returnError(response, "缺少登录信息");
+				return;
+			}
+			String orgAssistCode=request.getParameter("orgAssistCode");
+			String orgName=request.getParameter("orgName");
+			String startMonth=request.getParameter("startMonth");
+			String endMonth=request.getParameter("endMonth");
+			//String useType=request.getParameter("useType");  //1:安全科;其它:项目部
+			String deviceKey=request.getParameter("deviceKey");
+			String sortField=request.getParameter("sortField");
+			String sortType=request.getParameter("sortType");
+			
+			boolean rptForMgr="1".equals(request.getParameter("useType"));
+			
+			if(StringUtils.isEmpty(orgAssistCode)){
+				orgAssistCode=su.isSysAdmin()?null:su.getOrgAssistCode();
+			}
+				
+			Map<String,Object>  rootMap=rptCarConsume(rptForMgr,orgName,orgAssistCode,startMonth,endMonth,deviceKey,sortField,sortType);
+			
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,rptForMgr?"carOilCostDtlSafeDpt.ftl":"carOilCostDtl.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	/**
+	 * 为单车油耗统计、按车型统计油耗提供核心方法(包括相关导出)
+	 * @param mgrRpt 管理用统计(安全科用)
+	 * @param orgName
+	 * @param orgAssistCode
+	 * @param startMonth
+	 * @param endMonth
+	 * @param deviceKey  设备名称或型号,可以同时输入
+	 * @param sortField  排序字段
+	 * @param sortType   排序方式  desc、asc
+	 */
+	private Map<String,Object> rptCarConsume(boolean mgrRpt,String orgName,String orgAssistCode,String startMonth,String endMonth,String deviceKey,String sortField,String sortType){
+		if(StringUtils.isEmpty(startMonth)&&StringUtils.isEmpty(endMonth)){  //默认当月
+			startMonth=DateUtil.format((new Date()), "yyyy-MM");
+			endMonth=startMonth;
+		}
+		else if(StringUtils.isEmpty(endMonth)){  //只输入开始月份的
+			endMonth=startMonth;
+		}
+		else if(StringUtils.isEmpty(startMonth)){
+			startMonth=endMonth;
+		}
+		
+		List<CarConsumeRptVO> carConsumes=service.loadCarConsumeDtl(startMonth, endMonth, orgAssistCode,deviceKey,sortField,sortType);
+		
+		Map<String,Object> rootMap=new HashMap<String,Object>();
+		
+		
+		//安全科用,采用新逻辑计算实际单耗:上报加油量+上期余油-本期余油
+		if(mgrRpt){
+			Set<String>  carIds=new HashSet<String>(carConsumes.size());
+			for(CarConsume car : carConsumes){
+				carIds.add(car.getCarId());
+			}
+			
+			Map<String,Map<String,Object>> volMapping=monitorService.loadCarMonitorRpt(carIds,startMonth, endMonth); 
+			boolean hadMonitor=volMapping!=null&&volMapping.size()>0;
+			Map<String,Object> mthVol=null;
+			for(CarConsumeRptVO car : carConsumes){
+				mthVol=hadMonitor?volMapping.get(car.getCarId()):null;
+				if(mthVol!=null&&mthVol.get("startVolume")!=null&&mthVol.get("endVolume")!=null){
+					car.init(((Number)mthVol.get("startVolume")).doubleValue(),((Number)mthVol.get("endVolume")).doubleValue());
+				}
+				else{
+					car.init(null,null);
+				}
+				
+			}
+			
+			
+		}
+		else{ //项目用报表需要:计算汽油、柴油平均单价  2021.1.6
+
+			if(!startMonth.equals(endMonth)){  //跨月查询,实际单耗要重新计算
+				CarRptUtils.calculateRealCostPer100km(carConsumes);
+			}
+			
+			ERP erp=energyService.erpMonthSum(startMonth,endMonth);
+			OtherConsume  kl=energyService.otherMonthSum(startMonth, endMonth);
+			erp=ERPKlSumUtil.erpPlusKlMonth(kl,erp);
+			if(erp==null){
+				return rootMap;
+			}
+			
+			rootMap.put("oilPrice", getPrice(erp.getOilMoney(),erp.getOilCount())); //元/千克
+			rootMap.put("coilPrice", getPrice(erp.getCoilMoney(),erp.getCoilCount())); //元/千克
+		}
+		
+		String rptMonthTitle=startMonth.replace("-", "年")+"月";
+		String rptMonthCell=(startMonth.split("-"))[1]+"月";
+		if(!startMonth.equals(endMonth)){
+			rptMonthTitle+="——"+endMonth.replace("-", "年")+"月";
+			rptMonthCell+="-"+(endMonth.split("-"))[1]+"月";
+		}
+		
+		
+		rootMap.put("orgName", orgName!=null?orgName:"");
+		rootMap.put("rptMonthTitle", rptMonthTitle);
+		rootMap.put("rptMonthCell", rptMonthCell);
+		rootMap.put("datas", carConsumes);
+		
+		Map<String,Object> otherConsume=consumeService.loadOtherConsume(startMonth, endMonth, orgAssistCode);
+		rootMap.put("otherConsume", otherConsume);
+		
+		return rootMap;
+	}
+	
+	private String getPrice(Double money,Double count){
+		if(money==null||count==null){
+			return null;
+		}
+		DecimalFormat  df=new DecimalFormat("#0.000");
+		return df.format((money*10)/count);
+	}
+
+	
+	/**
+	 * 各车型(其实是设备名称)油耗汇总表,需要在loadCarConsumeDtl方法的结果集上,在程序内部进行分组统计
+	 * (如果直接在sql中按设备名分组,丢失设备型号,行驶油耗无法计算)
+	 * @param orgName
+	 * @param orgAssistCode
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadCarTypeConsume")
+	public void loadCarTypeConsume(String orgName,String orgAssistCode,String startMonth,String endMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				JsonOutUtils.returnError(response, "缺少登录信息");
+				return;
+			}
+			
+			if(StringUtils.isEmpty(orgAssistCode)){
+			   orgAssistCode=su.isSysAdmin()?null:su.getOrgAssistCode();
+		    }
+			if(StringUtils.isEmpty(startMonth)&&StringUtils.isEmpty(endMonth)){  //默认当月
+				startMonth=DateUtil.format((new Date()), "yyyy-MM");
+				endMonth=startMonth;
+			}
+			else if(StringUtils.isEmpty(startMonth)){
+				startMonth=endMonth;
+			}
+			else if(StringUtils.isEmpty(endMonth)){
+				endMonth=startMonth;
+			}
+			
+			List<CarConsume> carConsumes=service.loadCarTypeConsume(startMonth, endMonth, orgAssistCode);
+			String rptMonthTitle=startMonth.replace("-", "年")+"月";
+			if(!startMonth.equals(endMonth)){
+				rptMonthTitle+="——"+endMonth.replace("-", "年")+"月";
+			}
+			
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("orgName", orgName!=null?orgName:"");
+			rootMap.put("rptMonthTitle", rptMonthTitle);
+			rootMap.put("datas", carConsumes);
+			
+			Map<String,Object> otherConsume=consumeService.loadOtherConsume(startMonth, endMonth, orgAssistCode);
+			rootMap.put("otherConsume", otherConsume);
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"carTypeOilCostRpt.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+}

+ 148 - 0
src/main/java/com/hb/proj/car/controller/CoilTypeSumRptController.java

@@ -0,0 +1,148 @@
+package com.hb.proj.car.controller;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarSumRptService;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.DateUtil;
+/**
+ * 柴油车汇总统计
+ */
+@Controller
+@RequestMapping("/**/rpt")
+public class CoilTypeSumRptController {
+
+	@Autowired
+	private CarSumRptService service;
+	
+	
+	@RequestMapping("/checkLackRptData")
+	public void checkLackRptData(String rptYear,Integer rptQuarter,String rptMonth,HttpServletResponse response){
+		try{
+			if(!StringUtils.isBlank(rptMonth)){
+				JsonOutUtils.returnOkWithData(response, service.checkLackRptData(rptMonth));
+				return;
+			}
+			else if(rptQuarter!=null&&!StringUtils.isBlank(rptYear)){
+				Calendar  ca=Calendar.getInstance();
+				int month=ca.get(Calendar.MONTH)+1;
+				int nowQuarter=(int)Math.ceil(month/3.0);
+				if(rptQuarter==nowQuarter&&rptYear.equals(String.valueOf(ca.get(Calendar.YEAR)))){  //当前季度
+					JsonOutUtils.returnOkWithData(response, service.checkLackRptData(DateUtil.format(ca.getTime(), "yyyy-MM")));
+					return;
+				}
+			}
+			else if(!StringUtils.isBlank(rptYear)){
+				Date now=new Date();
+				if(rptYear.equals(DateUtil.format(now, "yyyy"))){  //当年
+					JsonOutUtils.returnOkWithData(response, service.checkLackRptData(DateUtil.format(now, "yyyy-MM")));
+					return;
+				}
+			}
+			JsonOutUtils.returnOk(response);
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	/**
+	 * 柴油车分类耗油统计
+	 * @param rptYear
+	 * @param rptQuarter  季度
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadCoilCarSum")
+	public void loadCoilCarSum(String rptYear,Integer rptQuarter,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(rptYear)){
+				rptYear=DateUtil.format(new Date(), "yyyy");
+			}
+			if(rptQuarter==null){
+				Calendar  ca=Calendar.getInstance();
+				int month=ca.get(Calendar.MONTH)+1;
+				rptQuarter=(int)Math.ceil(month/3.0);
+			}
+			int emth=rptQuarter*3,smth=emth-2;
+			
+			String startMonth=rptYear+"-"+String.format("%02d", smth);
+			String endMonth=rptYear+"-"+String.format("%02d", emth);
+			
+			String[] numName={"一","二","三","四"};
+			String rptTitle=rptYear+"年"+numName[rptQuarter-1]+"季度";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptTitle", rptTitle);
+			
+			List<Map<String,Object>>  orgs=service.loadAllSubOrgs();
+			List<Map<String,Object>>  coilTypes=service.loadCoilCarTypes();
+			rootMap.put("orgDS", orgs); //所有项目部
+			rootMap.put("carTypeDS", coilTypes); //柴油车类型
+			rootMap.put("carCountDS", service.loadCoilCarCountRpt(startMonth,endMonth)); //柴油车按类型、单位统计数量
+			rootMap.put("coilCostDS", service.loadCoilCarRealCost(startMonth,endMonth)); //柴油车按类型、单位统计耗油量
+			
+			rootMap.put("formulaDS",getFormulaDS(coilTypes,orgs));
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"coilCarSortRpt.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	//报表中公式的生成
+	private Map<String,String> getFormulaDS(List<Map<String,Object>> coilTypes,List<Map<String,Object>> orgs){
+		Map<String,String>  ds=new HashMap<String,String>();
+		char cn=0;
+		//横向合计公式
+		String exp=null,exp2=null;
+		for(int j=0,len2=coilTypes.size();j<len2;j++){
+			exp=""; //车辆数合计
+			exp2=""; //耗油量合计
+			for(int i=0,len=orgs.size();i<len;i++){
+				cn=(char)(i*2+65+4);  //从E列开始
+				exp+="+"+String.valueOf(cn)+""+(j+3);
+				cn=(char)(i*2+65+5);  //从F列开始
+				exp2+="+"+String.valueOf(cn)+""+(j+3);
+			}
+			ds.put((String)coilTypes.get(j).get("codeId"), exp.substring(1));
+			ds.put((coilTypes.get(j).get("codeId")+"_coil"), exp2.substring(1));
+			
+			
+		}
+		
+		//纵向合计公式
+		int typeStartIdx=3,typeEndIdx=coilTypes.size()+typeStartIdx-1;
+		for(int i=0,len=orgs.size();i<len;i++){
+			cn=(char)(i*2+65+4);  //从E列开始,车辆数
+			ds.put((String)orgs.get(i).get("orgId"), String.format("sum(%s%d:%s%d)", cn,typeStartIdx,cn,typeEndIdx));
+			cn=(char)(i*2+65+5);  //从F列开始,耗油数
+			ds.put((orgs.get(i).get("orgId")+"_coil"),String.format("sum(%s%d:%s%d)", cn,typeStartIdx,cn,typeEndIdx));
+		}
+		
+		//总合计
+		ds.put("totalCar",String.format("sum(%s%d:%s%d)", "C",typeStartIdx,"C",typeEndIdx));
+		ds.put("totalCoil",String.format("sum(%s%d:%s%d)", "D",typeStartIdx,"D",typeEndIdx));
+		
+		return ds;
+	}
+	
+	
+}

+ 173 - 0
src/main/java/com/hb/proj/car/controller/ERPKLSumRptController.java

@@ -0,0 +1,173 @@
+package com.hb.proj.car.controller;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.car.service.CarSumRptService;
+import com.hb.proj.car.service.ERPKLSumRptService;
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.OtherConsumeWrapVO;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+
+@Controller
+@RequestMapping("/**/rpt")
+public class ERPKLSumRptController {
+
+	@Autowired
+	private ERPKLSumRptService  service;
+	
+	@Autowired
+	private CarSumRptService baseService;
+	
+	/**
+	 * 统计指定年份各月份的考核里程、行驶里程。目前统计的是全分公司
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/rptMile")
+	public void rptMile(String year,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(year)){
+				Calendar ca=Calendar.getInstance();
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			
+			List<Map<String,Object>>  rptdatas=new ArrayList<Map<String,Object>>(12);
+		
+			String[] mthNames={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
+			for(int i=1;i<=12;i++){
+				rptdatas.add(MapUtils.build("month",mthNames[i-1]));
+			}
+			List<Map<String,Object>> miles=service.rptCheckAndTravelMile(year);
+			if(miles!=null&&miles.size()>0){
+				int monthNum=0;
+				for(Map<String,Object> itm : miles){
+					monthNum=Integer.parseInt((String)itm.get("rptDate"));
+					rptdatas.get(monthNum-1).putAll(itm);
+				}
+			}
+			
+			String rptTitle=year+"年";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptTitle", rptTitle);
+			rootMap.put("datas", rptdatas); 
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"mileYearRpt.ftl");
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	/**
+	 * ERP昆仑卡汇总表(统计数据来源于其它油耗表,录入的各单位各月份的合计数据,不在通过单车数据累加2020.9.15)
+	 * @param rptMonth
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadERPKLSum")
+	public void loadERPKLSum(String rptMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(rptMonth)){
+				rptMonth=DateUtil.format(new Date(), "yyyy-MM");
+			}
+			String startMonth=(rptMonth.split("-"))[0]+"-01";
+			Map<String,CarConsume> thisMonthIdx=builderIndex(service.loadERPKLSumMile(rptMonth, rptMonth));
+			Map<String,CarConsume> sumRptIdx=builderIndex(service.loadERPKLSumMile(startMonth, rptMonth));
+			
+			Map<String,OtherConsumeWrapVO> otherMonth=builderOtherIndex(service.loadOtherConsume(rptMonth, rptMonth));
+			Map<String,OtherConsumeWrapVO> otherSum=builderOtherIndex(service.loadOtherConsume(startMonth, rptMonth));
+			
+			String rptMonthTitle=rptMonth.replace("-", "年")+"月";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptMonthTitle", rptMonthTitle);
+			rootMap.put("monthCar", thisMonthIdx); //当月统计数据集
+			rootMap.put("sumCar", sumRptIdx);  //累计统计数据集
+			rootMap.put("monthOth", otherMonth);  //当月统计数据集
+			rootMap.put("sumOth", otherSum);   //累计统计数据集
+			
+			List<Map<String,Object>> orgs=baseService.loadAllSubOrgs();
+			rootMap.put("orgDS", orgs); //所有项目部
+			
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"erpKlSum.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+
+	private Map<String,CarConsume> builderIndex(List<CarConsume> sumData){
+		Map<String,CarConsume> index=new HashMap<String,CarConsume>();
+		CarConsume total=new CarConsume();
+		for(CarConsume car : sumData){
+			index.put(car.getBelongOrg(), car);
+			addCarConsume(total,car);
+		}
+		
+		index.put("合计", total);
+		return index;
+	}
+	
+	private void addCarConsume(CarConsume t,CarConsume d){
+	
+		//t.setCheckMile(CarRptUtils.addDouble(t.getCheckMile(),d.getCheckMile()));
+		//t.setTravelMile(CarRptUtils.addDouble(t.getTravelMile(),d.getTravelMile()));
+		t.setEngineCostKg(CarRptUtils.addDouble(t.getEngineCostKg(),d.getEngineCostKg()));
+		t.setEngineWorkHour(CarRptUtils.addDouble(t.getEngineWorkHour(),d.getEngineWorkHour()));
+	}
+	
+	
+
+	/**
+	 * 报表中需要显示汽油、柴油总量,freemarker表达式无法满足,后台程序进行计算
+	 * @param sumData
+	 * @return
+	 */
+	private Map<String,OtherConsumeWrapVO> builderOtherIndex(List<OtherConsume> sumData){
+		Map<String,OtherConsumeWrapVO> index=new HashMap<String,OtherConsumeWrapVO>();
+		OtherConsume total=new OtherConsume();
+		for(OtherConsume other : sumData){
+			index.put(other.getOrgId(), new OtherConsumeWrapVO(other));
+			addOtherConsume(total,other);
+		}
+		
+		index.put("合计", new OtherConsumeWrapVO(total));
+		return index;
+	}
+	
+	private void addOtherConsume(OtherConsume d1,OtherConsume d2){
+		d1.setOilCountKg(CarRptUtils.addDouble(d1.getOilCountKg(), d2.getOilCountKg()));
+		d1.setCoilCountKg(CarRptUtils.addDouble(d1.getCoilCountKg(), d2.getCoilCountKg()));
+		d1.setOilErpCountKg(CarRptUtils.addDouble(d1.getOilErpCountKg(), d2.getOilErpCountKg()));
+		d1.setCoilErpCountKg(CarRptUtils.addDouble(d1.getCoilErpCountKg(), d2.getCoilErpCountKg()));
+		
+		d1.setOilKlCountKg(CarRptUtils.addDouble(d1.getOilKlCountKg(), d2.getOilKlCountKg()));
+		d1.setCoilKlCountKg(CarRptUtils.addDouble(d1.getCoilKlCountKg(), d2.getCoilKlCountKg()));
+		
+		d1.setOilKlMoney(CarRptUtils.addDouble(d1.getOilKlMoney(), d2.getOilKlMoney()));
+		d1.setCoilKlMoney(CarRptUtils.addDouble(d1.getCoilKlMoney(), d2.getCoilKlMoney()));
+	}
+}

+ 188 - 0
src/main/java/com/hb/proj/car/controller/ERPKlSumUtil.java

@@ -0,0 +1,188 @@
+package com.hb.proj.car.controller;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCorrect;
+
+/**
+ * 物资ERP+昆仑卡 数据校正工具类(用于数据校正报表及所有从数据校正取数据的报表,统一处理逻辑,便于维护、复用)
+ * @author hb
+ *
+ */
+
+public class ERPKlSumUtil {
+
+	/**
+	 * 水电气 合计 实际值+修正值
+	 * @param sumWpg
+	 * @param sumWpgCorrrect
+	 */
+	public static  Wpg processWpgSum(Wpg  sumWpg,WpgCorrect sumWpgCorrrect){
+		if(sumWpgCorrrect==null){
+			return sumWpg;
+		}
+		else if(sumWpg==null){ 
+			sumWpg=new Wpg();
+			sumWpg.setWaterCount(sumWpgCorrrect.getWaterCountCorrect());
+			sumWpg.setWaterCost(sumWpgCorrrect.getWaterCostCorrect());
+			sumWpg.setPowerCount(sumWpgCorrrect.getPowerCountCorrect());
+			sumWpg.setPowerCost(sumWpgCorrrect.getPowerCostCorrect());
+			sumWpg.setNgasCount(sumWpgCorrrect.getNgasCountCorrect());
+			sumWpg.setNgasCost(sumWpgCorrrect.getNgasCostCorrect());
+			sumWpg.setLgasCount(sumWpgCorrrect.getLgasCountCorrect());
+			sumWpg.setLgasCost(sumWpgCorrrect.getLgasCostCorrect());
+			
+			sumWpg.setPowerCoal(sumWpgCorrrect.getPowerCorrectCoal());
+			sumWpg.setNgasCoal(sumWpgCorrrect.getNgasCorrectCoal());
+			sumWpg.setLgasCoal(sumWpgCorrrect.getLgasCorrectCoal());
+			
+			return sumWpg;
+		}
+		else{
+			sumWpg.setWaterCount(CarRptUtils.addDouble(sumWpg.getWaterCount(), sumWpgCorrrect.getWaterCountCorrect()));
+			sumWpg.setWaterCost(CarRptUtils.addDouble(sumWpg.getWaterCost(), sumWpgCorrrect.getWaterCostCorrect()));
+			sumWpg.setPowerCount(CarRptUtils.addDouble(sumWpg.getPowerCount(), sumWpgCorrrect.getPowerCountCorrect()));
+			sumWpg.setPowerCost(CarRptUtils.addDouble(sumWpg.getPowerCost(), sumWpgCorrrect.getPowerCostCorrect()));
+			sumWpg.setNgasCount(CarRptUtils.addDouble(sumWpg.getNgasCount(), sumWpgCorrrect.getNgasCountCorrect()));
+			sumWpg.setNgasCost(CarRptUtils.addDouble(sumWpg.getNgasCost(), sumWpgCorrrect.getNgasCostCorrect()));
+			sumWpg.setLgasCount(CarRptUtils.addDouble(sumWpg.getLgasCount(), sumWpgCorrrect.getLgasCountCorrect()));
+			sumWpg.setLgasCost(CarRptUtils.addDouble(sumWpg.getLgasCost(), sumWpgCorrrect.getLgasCostCorrect()));
+			
+			//折算煤校正
+			sumWpg.setPowerCoal(CarRptUtils.addDouble(sumWpg.getPowerCoal(), sumWpgCorrrect.getPowerCorrectCoal()));
+			sumWpg.setNgasCoal(CarRptUtils.addDouble(sumWpg.getNgasCoal(), sumWpgCorrrect.getNgasCorrectCoal()));
+			sumWpg.setLgasCoal(CarRptUtils.addDouble(sumWpg.getLgasCoal(), sumWpgCorrrect.getLgasCorrectCoal()));
+			
+			return sumWpg;
+		}
+		
+	}
+	
+	
+	/**
+	 *  ERP昆仑卡当月=物资erp当月数据+物资erp差额校正+项目部昆仑卡数据 (单位:吨、万元)2020.10.13
+	 * @param kl 单位万元,吨
+	 * @param erp 单位元,吨
+	 * @return
+	 */
+	public static ERP erpPlusKlMonth(OtherConsume kl,ERP  erp){
+		if(kl==null&&erp==null){
+			return null;
+		}
+		ERP rtnERP=new ERP();
+		if(erp==null){
+			rtnERP.setOilCount(kl.getOilKlCountKg());  //借用物资ERP当月字段
+			rtnERP.setCoilCount(kl.getCoilKlCountKg()); 
+			rtnERP.setOilMoney(kl.getOilKlMoney());
+			rtnERP.setCoilMoney(kl.getCoilKlMoney());
+			rtnERP.setOilCoal(kl.getOilKlCoal());
+			rtnERP.setCoilCoal(kl.getCoilKlCoal());
+			return rtnERP;
+		}
+		else if(kl==null){
+			rtnERP.setOilCount(CarRptUtils.addDouble(erp.getOilCount(),erp.getOilCountCorrect()));  //借用物资ERP当月字段
+			rtnERP.setCoilCount(CarRptUtils.addDouble(erp.getCoilCount(),erp.getCoilCountCorrect())); 
+			rtnERP.setOilMoney(CarRptUtils.addDouble(money10K(erp.getOilMoney()),money10K(erp.getOilMoneyCorrect())));
+			rtnERP.setCoilMoney(CarRptUtils.addDouble(money10K(erp.getCoilMoney()),money10K(erp.getCoilMoneyCorrect())));
+			rtnERP.setOilCoal(CarRptUtils.addDouble(erp.getOilCoal(),erp.getOilCorrectCoal()));
+			rtnERP.setCoilCoal(CarRptUtils.addDouble(erp.getCoilCoal(),erp.getCoilCorrectCoal()));
+			return rtnERP;
+		}
+		
+		
+		Double val=null;
+		//油量
+		val=CarRptUtils.addDouble(kl.getOilKlCountKg(),erp.getOilCount());
+		val=CarRptUtils.addDouble(val,erp.getOilCountCorrect());
+		rtnERP.setOilCount(val);  //借用字段存有erp+昆仑卡值
+		val=CarRptUtils.addDouble(kl.getCoilKlCountKg(),erp.getCoilCount());
+		val=CarRptUtils.addDouble(val,erp.getCoilCountCorrect());
+		rtnERP.setCoilCount(val);  //借用字段存有erp+昆仑卡值	
+		
+		//标煤
+		val=CarRptUtils.addDouble(erp.getOilCoal(),erp.getOilCorrectCoal());
+		rtnERP.setOilCoal(CarRptUtils.addDouble(val,kl.getOilKlCoal()));
+		
+		val=CarRptUtils.addDouble(erp.getCoilCoal(),erp.getCoilCorrectCoal());
+		rtnERP.setCoilCoal(CarRptUtils.addDouble(val,kl.getCoilKlCoal()));
+		
+		//erp 中金额是元,昆仑卡数据已经转换为万元,需要转换
+		val=CarRptUtils.addDouble(kl.getOilKlMoney(),money10K(erp.getOilMoney()));
+		val=CarRptUtils.addDouble(val,money10K(erp.getOilMoneyCorrect()));
+		rtnERP.setOilMoney(val);
+		val=CarRptUtils.addDouble(kl.getCoilKlMoney(),money10K(erp.getCoilMoney()));
+		val=CarRptUtils.addDouble(val,money10K(erp.getCoilMoneyCorrect()));
+		rtnERP.setCoilMoney(val);
+		
+		return rtnERP;
+	}
+	
+	/**
+	 * ERP昆仑卡累计=物资erp累计数据+项目部昆仑卡累计数据 (单位:吨、万元)2020.10.13
+	 * @param erp
+	 * @param kl
+	 * @return
+	 */
+	public static  ERP erpPlusKlSum(ERP  erp,OtherConsume kl){
+		if(kl==null&&erp==null){
+			return null;
+		}
+		ERP rtnERP=new ERP();
+		if(erp==null){
+			rtnERP.setOilCountSum(kl.getOilKlCountKg());  //借用物资ERP当月字段
+			rtnERP.setCoilCountSum(kl.getCoilKlCountKg()); 
+			rtnERP.setOilMoneySum(kl.getOilKlMoney());
+			rtnERP.setCoilMoneySum(kl.getCoilKlMoney());
+			rtnERP.setOilSumCoal(kl.getOilKlCoal());
+			rtnERP.setCoilSumCoal(kl.getCoilKlCoal());
+			return rtnERP;
+		}
+		else if(kl==null){
+			rtnERP.setOilCountSum(erp.getOilCountSum());  //借用物资ERP当月字段
+			rtnERP.setCoilCountSum(erp.getCoilCountSum()); 
+			rtnERP.setOilMoneySum(money10K(erp.getOilMoneySum()));
+			rtnERP.setCoilMoneySum(money10K(erp.getCoilMoneySum()));
+			rtnERP.setOilSumCoal(erp.getOilSumCoal());
+			rtnERP.setCoilSumCoal(erp.getCoilSumCoal());
+			return rtnERP;
+		}
+		
+		Double val=null;
+		//油量
+		val=CarRptUtils.addDouble(kl.getOilKlCountKg(),erp.getOilCountSum());
+		//val=CarRptUtils.addDouble(val,erp.getOilCountCorrect());
+		rtnERP.setOilCountSum(val);  //借用字段存有erp+昆仑卡值
+		val=CarRptUtils.addDouble(kl.getCoilKlCountKg(),erp.getCoilCountSum());
+		//val=CarRptUtils.addDouble(val,erp.getCoilCountCorrect());
+		rtnERP.setCoilCountSum(val);  //借用字段存有erp+昆仑卡值
+		
+		//标煤(昆仑卡折算煤+erp累计折算煤+erp当月校正折算煤)
+		val=CarRptUtils.addDouble(kl.getOilKlCoal(),erp.getOilSumCoal());
+		//val=CarRptUtils.addDouble(val,erp.getOilCorrectCoal());
+		rtnERP.setOilSumCoal(val);  //借用字段存有erp+昆仑卡值
+		
+		val=CarRptUtils.addDouble(kl.getCoilKlCoal(),erp.getCoilSumCoal());
+		//val=CarRptUtils.addDouble(val,erp.getCoilCorrectCoal());
+		rtnERP.setCoilSumCoal(val);
+		
+		//erp 中金额是元,昆仑卡数据已经转换为万元,需要转换
+		val=CarRptUtils.addDouble(kl.getOilKlMoney(),money10K(erp.getOilMoneySum()));
+		//val=CarRptUtils.addDouble(val,money10K(erp.getOilMoneyCorrect()));
+		rtnERP.setOilMoneySum(val);
+		val=CarRptUtils.addDouble(kl.getCoilKlMoney(),money10K(erp.getCoilMoneySum()));
+		//val=CarRptUtils.addDouble(val,money10K(erp.getCoilMoneyCorrect()));
+		rtnERP.setCoilMoneySum(val);
+		
+		return rtnERP;
+	}
+	
+	    //元转为万元
+		private static Double  money10K(Double m){
+			if(m==null){
+				return null;
+			}
+			return m.doubleValue()/10000.0;
+		}
+}

+ 127 - 0
src/main/java/com/hb/proj/car/controller/EnergyCostAccountController.java

@@ -0,0 +1,127 @@
+package com.hb.proj.car.controller;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.ERPKLSumRptService;
+import com.hb.proj.car.service.EnergySumRptService;
+import com.hb.proj.car.service.MaterialERPService;
+import com.hb.proj.model.EnergyWaterSumVO;
+import com.hb.proj.model.EnergyWaterSumVOUtil;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.MapUtils;
+/**
+ * 辽河分公司能源消耗台帐
+ */
+@Controller
+@RequestMapping("/**/rpt")
+public class EnergyCostAccountController {
+	
+	@Autowired
+	private EnergySumRptService service;
+	
+	@Autowired
+	private ERPKLSumRptService  othService;
+	
+	@Autowired
+	private MaterialERPService materService;
+	
+	/**
+	 * 考核里程、行驶里程、定额汽油、柴油取自单车油耗,其余取自数据校正表
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/rptEnergyCost")
+	public void rptEnergyCost(String year,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(year)){
+				Calendar ca=Calendar.getInstance();
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			List<Map<String,Object>>  mths=new ArrayList<Map<String,Object>>(12);
+			
+			String[] mthNames={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
+			Map<String,Object> perMth=null;
+			for(int i=1;i<=12;i++){
+				perMth=MapUtils.build("month",mthNames[i-1],"monthNum",String.format("%02d",i));
+				addSumVerticalFormula(i,perMth);
+				mths.add(perMth);
+			}
+			
+			//按月统计分组油水电气
+			Map<String,EnergyWaterSumVO> energyWaters=EnergyWaterSumVOUtil.buildForCostAccount(service.erpMonthGrp(year), service.otherMonthGrp(year), service.wpgSumRpt(year), service.wpgCorrectSumRpt(year));
+			
+			//按月统计考核里程、行驶里程
+			List<Map<String,Object>> miles=othService.rptCarMileAndQuota(year);
+			
+			//油耗(ERP累计+昆仑累计)、水电气 分月累计(上报月数据+月校正数据)  直接各月相加,不用数据校正总的累计
+			
+			
+			
+			String rptTitle=year+"年";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptTitle", rptTitle);
+			rootMap.put("rptSubTitle", rptTitle+"12月30日");
+			rootMap.put("months", mths); 
+			rootMap.put("ds",energyWaters);
+			
+			rootMap.put("miles",builderMileIndex(miles));
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"energyCostAccount.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	private Map<String,Map<String,Object>> builderMileIndex(List<Map<String,Object>> miles){
+		if(miles==null||miles.size()==0){
+			return null;
+		}
+		Map<String,Map<String,Object>> idx=new HashMap<String,Map<String,Object>>();
+		for(Map<String,Object> m : miles){
+			idx.put((String)m.get("rptDate"), m);
+		}
+		return idx;
+		
+	}
+	
+	
+	
+	
+	//
+	private void addSumVerticalFormula(int month,Map<String,Object> holder){
+		String clm="CDEFGHIJKLMNOPQRSTU";
+		char cn=0;
+		for(int i=0,len=clm.length();i<len;i++){
+			cn=clm.charAt(i);
+			holder.put(String.valueOf(cn), builderFormual(cn,month));
+		}	
+		
+		
+		
+	}
+	
+	private String builderFormual(char clm,int month){
+		StringBuilder rtn=new StringBuilder();
+		for(int i=1;i<=month;i++){
+			rtn.append("+"+clm+(i*2-1));
+		}
+		return rtn.substring(1);
+	}
+}

+ 200 - 0
src/main/java/com/hb/proj/car/controller/EnergyWaterCompareController.java

@@ -0,0 +1,200 @@
+package com.hb.proj.car.controller;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.EnergySumRptService;
+import com.hb.proj.car.service.MaterialERPService;
+import com.hb.proj.car.service.YearSumCompareService;
+import com.hb.proj.input.service.WorkloadService;
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.EnergyWaterCompareVO;
+import com.hb.proj.model.EnergyWaterRatioCompareVO;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCorrect;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.SessionThreadLocal;
+/**
+ * 用能用水累计同比
+ */
+@Controller
+@RequestMapping("/**/rpt")
+public class EnergyWaterCompareController {
+	
+	@Autowired
+	private YearSumCompareService compService;
+	
+	@Autowired
+	private MaterialERPService erpService;
+	
+	@Autowired
+	private EnergySumRptService service;
+	
+	@Autowired
+	private WorkloadService wkservice;
+	
+	/**
+	 *  报表E7第二表:万元比值同比  中的建筑面积上报保存
+	 *  目前是保存在workload表中,报表是按年统计,而workload表是按月存储记录的。所以建筑面积数据只存储一条,且固定在1月份。
+	 *  便于任何月份都能查询到
+	 * @param year
+	 * @param builderArea
+	 * @param prebuilderArea
+	 * @param response
+	 */
+	@RequestMapping("/saveWYRatioCompare")
+	public void saveWYRatioCompare(String year,String builderArea,String prebuilderArea,HttpServletResponse response){
+		if(StringUtils.isEmpty(year)){
+			JsonOutUtils.returnError(response, "缺少年份");
+			return;
+		}
+		String rptMonth=year+"-01";
+		String preprtMonth=String.valueOf(Integer.parseInt(year)-1)+"-01";
+		String us=SessionThreadLocal.getSessionUser().getUserName();
+		if(!StringUtils.isEmpty(builderArea)){
+			erpService.saveBuilderArea(rptMonth, Double.parseDouble(builderArea), us);
+		}
+		if(!StringUtils.isEmpty(prebuilderArea)){
+			erpService.saveBuilderArea(preprtMonth, Double.parseDouble(prebuilderArea), us);
+		}
+		JsonOutUtils.returnOk(response);
+	}
+	
+	/**
+	 * 报表E7第二表:万元比值同比
+	 * @param year
+	 * @param response
+	 */
+	@RequestMapping("/yearWYRatioCompare")
+	public void yearWYRatioCompare(String year,HttpServletRequest request,HttpServletResponse response){
+		try{
+			String month="12";
+			Calendar ca=Calendar.getInstance();
+			if(StringUtils.isEmpty(year)){
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			if(Integer.parseInt(year)==ca.get(Calendar.YEAR)){ //等于当前年份,月份就应该为当前月份,否则为12月份
+				//当年且当月>25号,否则用上一个月
+				if(ca.get(Calendar.DAY_OF_MONTH)>25){
+					month=String.format("%02d", ca.get(Calendar.MONTH)+1);
+				}
+				else{
+					month=String.format("%02d", ca.get(Calendar.MONTH));
+				}
+			}
+			
+			String preyear=String.valueOf(Integer.parseInt(year)-1);
+			String startMonth=year+"-01",endMonth=year+"-"+month;
+			String preStartMonth=preyear+"-01",preEndMonth=preyear+"-"+month;
+			
+			EnergyWaterRatioCompareVO  ratioVO=builderVO(service,startMonth,endMonth);
+			EnergyWaterRatioCompareVO  preratioVO=builderVO(service,preStartMonth,preEndMonth);
+			
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("ratio", ratioVO);
+			rootMap.put("preratio", preratioVO);
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"yearWYRatioCompare.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	
+	private EnergyWaterRatioCompareVO  builderVO(EnergySumRptService service,String startMonth,String endMonth){
+		ERP erp=service.erpMonthSum(startMonth,endMonth);
+		OtherConsume  kl=service.otherMonthSum(startMonth, endMonth);
+		erp=ERPKlSumUtil.erpPlusKlMonth(kl, erp);
+		
+		Wpg wpg=service.wpgMonthSum(startMonth,endMonth);
+		WpgCorrect wpgcrt=service.wpgCorrectMonthSum(startMonth,endMonth);
+		wpg=ERPKlSumUtil.processWpgSum(wpg,wpgcrt);
+		CarConsume consume=service.carOilMonthSum(startMonth, endMonth);
+		return new EnergyWaterRatioCompareVO(erp,wpg,service.workloadMonthSum(startMonth,endMonth),consume!=null?consume.getCheckMile():null);
+		
+	}
+	
+	
+	/**
+	 * 用能用水年度对比
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/yearSumCompare")
+	public void yearSumCompare(String year,HttpServletRequest request,HttpServletResponse response){
+		try{
+			String month="12";
+			Calendar ca=Calendar.getInstance();
+			if(StringUtils.isEmpty(year)){
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			if(Integer.parseInt(year)==ca.get(Calendar.YEAR)){ //等于当前年份,月份就应该为当前月份,否则为12月份
+				//当年且当月>25号,否则用上一个月
+				if(ca.get(Calendar.DAY_OF_MONTH)>25){
+					month=String.format("%02d", ca.get(Calendar.MONTH)+1);
+				}
+				else{
+					month=String.format("%02d", ca.get(Calendar.MONTH));
+				}
+			}
+			
+			String preyear=String.valueOf(Integer.parseInt(year)-1);
+			String startMonth=year+"-01",endMonth=year+"-"+month;
+			String preStartMonth=preyear+"-01",preEndMonth=preyear+"-"+month;
+			
+			EnergyWaterCompareVO  yearSum=builderCompareVO(service,startMonth,endMonth);
+		
+			EnergyWaterCompareVO preYearSum=builderCompareVO(service,preStartMonth,preEndMonth);
+			
+			yearSum.setComparedValue(preYearSum);
+			
+			String rptTitle=year+"年";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptTitle", rptTitle);
+			rootMap.put("yearSum", yearSum);
+			rootMap.put("preYearSum", preYearSum);
+			
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"yearSumCompare.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	private EnergyWaterCompareVO  builderCompareVO(EnergySumRptService service,String startMonth,String endMonth){
+		ERP erp=service.erpMonthSum(startMonth,endMonth);
+		OtherConsume  kl=service.otherMonthSum(startMonth, endMonth);
+		erp=ERPKlSumUtil.erpPlusKlMonth(kl, erp);
+		
+		Wpg wpg=service.wpgMonthSum(startMonth,endMonth);
+		WpgCorrect wpgcrt=service.wpgCorrectMonthSum(startMonth,endMonth);
+		wpg=ERPKlSumUtil.processWpgSum(wpg,wpgcrt);
+		
+		return new EnergyWaterCompareVO(erp,wpg);
+		
+	}
+	
+	
+	
+}

+ 157 - 0
src/main/java/com/hb/proj/car/controller/EnergyWaterSumController.java

@@ -0,0 +1,157 @@
+package com.hb.proj.car.controller;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.car.service.EnergySumRptService;
+import com.hb.proj.car.service.MaterialERPService;
+import com.hb.proj.input.service.WorkloadService;
+import com.hb.proj.model.EnergyWaterSumVO;
+import com.hb.proj.model.EnergyWaterSumVOUtil;
+import com.hb.proj.model.Workload;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+/**
+ * 用能用水统计汇总
+ */
+@Controller
+@RequestMapping("/**/rpt")
+public class EnergyWaterSumController {
+	
+	@Autowired
+	private EnergySumRptService service;
+	
+	@Autowired
+	private WorkloadService wkservice;
+	
+	@Autowired
+	private MaterialERPService erpService;
+	
+	
+	
+	/**
+	 * 各月水电气=上报数据+当月校正数据=数据校正中的水电气统计中的总合计
+	 * 各月汽油、柴油=部门上报的数据(t_other_consume)+当月数据校正+物资ERP填报当月数据=数据校正中表二中的当月数据
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/rptEnergyWaterSum")
+	public void rptEnergyWaterSum(String year,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(year)){
+				Calendar ca=Calendar.getInstance();
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			List<Map<String,Object>>  mths=new ArrayList<Map<String,Object>>(12);
+			
+			String[] mthNames={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
+			Map<String,Object> perMth=null;
+			for(int i=1;i<=12;i++){
+				perMth=MapUtils.build("month",mthNames[i-1],"monthNum",String.format("%02d",i));
+				mths.add(perMth);
+			}
+			String preyear=String.valueOf(Integer.parseInt(year)-1);
+			
+			Map<String,EnergyWaterSumVO> voIndex=EnergyWaterSumVOUtil.build(service.erpMonthGrp(year), service.otherMonthGrp(year), service.wpgSumRpt(year), service.wpgCorrectSumRpt(year), service.workloadSumRpt(year));
+			Map<String,EnergyWaterSumVO> preVoIndex=EnergyWaterSumVOUtil.build(service.erpMonthGrp(preyear), service.otherMonthGrp(preyear), service.wpgSumRpt(preyear), service.wpgCorrectSumRpt(preyear), service.workloadSumRpt(preyear));
+			EnergyWaterSumVOUtil.caculateCompare(voIndex, preVoIndex);
+			preVoIndex.clear();
+			preVoIndex=null;
+			
+			
+			String rptTitle=year+"年";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptTitle", rptTitle);
+			rootMap.put("year", year);
+			rootMap.put("months", mths); 
+			rootMap.put("ds", voIndex); 
+			rootMap.put("sums",addSumFormula()); 
+			
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"energyWaterSum.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	
+	
+	
+	
+	
+	private Map<String,String> addSumFormula(){
+		Map<String,Object> sorts=MapUtils.build("ngas",1,"power",2,"oil",3,"coil",4,"lgas",5,"coal",6,"water",7,"well",8,"industry",9,"added",10);
+		int clm=0,clm2=0;
+		String f1="",f2="";
+		Map<String,String> formulas=new HashMap<String,String>();
+		for(String s : sorts.keySet()){
+			f1="";
+			f2="";
+			for(int i=1;i<=12;i++){
+				clm=3+(i-1)*3+1;  //money
+				clm2=3+(i-1)*3+2; //count
+				f1+="+"+getChar(clm)+sorts.get(s);
+				f2+="+"+getChar(clm2)+sorts.get(s);
+			}
+			formulas.put(s+"Money", f1.substring(1));
+			formulas.put(s+"Count", f2.substring(1));
+		}
+		return formulas;
+		
+	}
+	
+	private String getChar(int val){
+		if(val==26){
+			return "Z";
+		}
+		int h=val/26;
+		int l=val%26;
+		return (h>0?String.valueOf((char)(h+64)):"")+(l>0?String.valueOf((char)(l+64)):"") ;
+	}
+	
+	
+	/**
+	 * 通过报表上报工作量和工业产值
+	 * @param workload
+	 * @param response
+	 */
+	@RequestMapping("/saveWorkload")
+	public void saveWorkload(String jsonDatas,String year,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				JsonOutUtils.returnError(response, "缺少登录信息,请登录后再试");
+				return;
+			}
+			
+			List<Workload> workload=JSON.parseObject(jsonDatas,new TypeReference<List<Workload>>() {});
+			wkservice.saveWorkloadFromRpt(workload,year);
+			JsonOutUtils.returnOk(response);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+}

+ 311 - 0
src/main/java/com/hb/proj/car/controller/HomeRptController.java

@@ -0,0 +1,311 @@
+package com.hb.proj.car.controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.EnergySumRptService;
+import com.hb.proj.car.service.MaterialERPService;
+import com.hb.proj.car.service.YearSumCompareService;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.EnergyWaterCompareVO;
+import com.hb.proj.model.EnergyWaterSumVO;
+import com.hb.proj.model.EnergyWaterSumVOUtil;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Workload;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCorrect;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.RptMonthUtil;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+
+@Controller
+@RequestMapping("/**/home/rpt")
+public class HomeRptController {
+
+	@Autowired
+	private EnergySumRptService  service;
+	
+	@Autowired
+	private YearSumCompareService yearService;
+	
+	@Autowired
+	private MaterialERPService crtService;
+	
+	/**
+	 * 首页工作量统计表
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/workloadRpt")
+	public void workloadRpt(String year,HttpServletRequest request,HttpServletResponse response){
+		Calendar ca=Calendar.getInstance();
+		String nowYear=String.valueOf(ca.get(Calendar.YEAR));
+		if(StringUtils.isEmpty(year)){
+			year=nowYear;
+		}
+		int nowMonth=12;
+		if(year.equals(nowYear)){  //统计的是今年 就截至到当前月份的前一月,否则就是12月份
+			nowMonth=RptMonthUtil.getMonthNum(ca)-1;
+			if(nowMonth==0){
+				nowMonth=1;
+			}
+		}
+		String endMonth=String.format("%02d",nowMonth);
+		
+		String preyear=String.valueOf(Integer.parseInt(year)-1);
+		List<Map<String,Object>>  mths=new ArrayList<Map<String,Object>>(12);
+		String[] mthNames={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
+		Map<String,Object> perMth=null;
+		for(int i=1;i<=12;i++){
+			perMth=MapUtils.build("month",mthNames[i-1],"monthNum",String.format("%02d",i));
+			mths.add(perMth);
+		}
+		
+		Map<String,Object> rootMap=new HashMap<String,Object>();
+		rootMap.put("months", mths); 
+		rootMap.put("workload", buildIndex(service.workloadSumRpt(year+"-01",year+"-"+endMonth))); 
+		rootMap.put("preworkload", buildIndex(service.workloadSumRpt(preyear+"-01",preyear+"-"+endMonth))); 
+		RptOuter.clearTemplateCache();
+		RptOuter.write(request,response,rootMap,"homeWorkload.ftl");
+	}
+	
+	private Map<String,Workload> buildIndex(List<Workload> workloads){
+		Map<String,Workload>  index=new HashMap<String,Workload>();
+		for(Workload wd : workloads){
+			index.put(DateUtil.format(wd.getRptMonth(), "MM"), wd);
+		}
+		return index;
+	}
+	
+	/**
+	 * 首页工作量图
+	 * @param response
+	 */
+	@RequestMapping("/workloadRptChart")
+	public void workloadRptChart(String year,HttpServletResponse response){
+		if(StringUtils.isEmpty(year)){
+			Calendar ca=Calendar.getInstance();
+			year=String.valueOf(ca.get(Calendar.YEAR));
+		}
+		String preyear=String.valueOf(Integer.parseInt(year)-1);
+		
+		List<Integer> wc=getWellCounts(service.workloadSumRpt(year));
+		List<Integer> prewc=getWellCounts(service.workloadSumRpt(preyear));
+		
+		Map<String,Object> rootMap=new HashMap<String,Object>();
+		rootMap.put("wc", wc); 
+		rootMap.put("prewc", prewc); 
+		
+		JsonOutUtils.returnOkWithData(response, rootMap);
+	}
+	
+	private List<Integer>  getWellCounts(List<Workload> workloads){
+		List<Integer> wellCounts=Arrays.asList(0,0,0,0,0,0,0,0,0,0,0,0);
+		int idx=0;
+		for(Workload wd : workloads){
+			 idx=Integer.parseInt(DateUtil.format(wd.getRptMonth(), "MM"))-1;
+			 if(wd.getWellCount()!=null){
+				 wellCounts.set(idx, wd.getWellCount());
+			 }
+			
+		}
+		return wellCounts;
+	}
+	
+	/**
+	 * 用能用水耗量同比
+	 * @param year
+	 * @param type
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/energyCompareRpt")
+	public void energyCompareRpt(String year,String type,HttpServletRequest request,HttpServletResponse response){
+		try{
+			String month="12";
+			Calendar ca=Calendar.getInstance();
+			if(StringUtils.isEmpty(year)){
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			if(Integer.parseInt(year)==ca.get(Calendar.YEAR)){ //等于当前年份,月份就应该为当前月份,否则为12月份
+				//当年且当月>25号,否则用上一个月
+				if(ca.get(Calendar.DAY_OF_MONTH)>25){
+					month=String.format("%02d", ca.get(Calendar.MONTH)+1);
+				}
+				else{
+					month=String.format("%02d", ca.get(Calendar.MONTH));
+				}
+				
+			}
+			String preyear=String.valueOf(Integer.parseInt(year)-1);
+			String startMonth=year+"-01",endMonth=year+"-"+month;
+			String preStartMonth=preyear+"-01",preEndMonth=preyear+"-"+month;
+			
+			
+			
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("yearSum", builderCompareVO(service,startMonth,endMonth));
+			rootMap.put("preYearSum", builderCompareVO(service,preStartMonth,preEndMonth));
+			if("grid".equals(type)){ //统计表格
+				RptOuter.clearTemplateCache();
+				RptOuter.write(request,response,rootMap,"homeEnergyCompare.ftl");
+			}
+			else if("chart".equals(type)){  //统计图
+				JsonOutUtils.returnOkWithData(response, rootMap);
+			}
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	/**
+	 * 能耗费用占比分析  
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/costRatioRpt")
+	public void costRatioRpt(String year,String type,HttpServletRequest request,HttpServletResponse response){
+		try{
+			String month="12";
+			Calendar ca=Calendar.getInstance();
+			if(StringUtils.isEmpty(year)){
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			if(Integer.parseInt(year)==ca.get(Calendar.YEAR)){ //等于当前年份,月份就应该为当前月份,否则为12月份
+				//当年且当月>25号,否则用上一个月
+				if(ca.get(Calendar.DAY_OF_MONTH)>25){
+					month=String.format("%02d", ca.get(Calendar.MONTH)+1);
+				}
+				else{
+					month=String.format("%02d", ca.get(Calendar.MONTH));
+				}
+				
+			}
+			String preyear=String.valueOf(Integer.parseInt(year)-1);
+			String startMonth=year+"-01",endMonth=year+"-"+month;
+			String preStartMonth=preyear+"-01",preEndMonth=preyear+"-"+month;
+			
+			
+			
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("yearSum", builderCompareVO(service,startMonth,endMonth));
+			rootMap.put("preYearSum", builderCompareVO(service,preStartMonth,preEndMonth));
+			if("grid".equals(type)){ //统计表格
+				RptOuter.clearTemplateCache();
+				RptOuter.write(request,response,rootMap,"homeCostRatio.ftl");
+			}
+			else if("chart".equals(type)){  //统计图
+				JsonOutUtils.returnOkWithData(response, rootMap);
+			}
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	/**
+	 * 能耗折算标准煤占比分析
+	 * @param year
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/coalRatioRpt")
+	public void coalRatioRpt(String year,String type,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(year)){
+				Calendar ca=Calendar.getInstance();
+				year=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			String startMonth=year+"-01";
+			String endMonth=year+"-12";
+			
+		    Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("yearSum", builderCompareVO(service,startMonth,endMonth));
+			if("grid".equals(type)){ //统计表格
+				RptOuter.clearTemplateCache();
+				RptOuter.write(request,response,rootMap,"homeCoalRatio.ftl");
+			}
+			else if("chart".equals(type)){  //统计图
+				JsonOutUtils.returnOkWithData(response, rootMap);
+			}
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	private EnergyWaterCompareVO  builderCompareVO(EnergySumRptService service,String startMonth,String endMonth){
+		ERP erp=service.erpMonthSum(startMonth,endMonth);
+		OtherConsume  kl=service.otherMonthSum(startMonth, endMonth);
+		erp=ERPKlSumUtil.erpPlusKlMonth(kl, erp);
+		
+		Wpg wpg=service.wpgMonthSum(startMonth,endMonth);
+		WpgCorrect wpgcrt=service.wpgCorrectMonthSum(startMonth,endMonth);
+		wpg=ERPKlSumUtil.processWpgSum(wpg,wpgcrt);
+		
+		return new EnergyWaterCompareVO(erp,wpg);
+		
+	}
+	
+	
+	/**
+	 * 首页按月统计能源,水消耗量
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/energyMonthCost")
+	public void energyMonthCost(String year,String type,HttpServletRequest request,HttpServletResponse response){
+		if(StringUtils.isEmpty(year)){
+			Calendar ca=Calendar.getInstance();
+			year=String.valueOf(ca.get(Calendar.YEAR));
+		}
+		
+		if("chart".equals(type)){
+			Map<String,EnergyWaterSumVO> voIndex=EnergyWaterSumVOUtil.build(service.erpMonthGrp(year), service.otherMonthGrp(year), service.wpgSumRpt(year), service.wpgCorrectSumRpt(year), service.workloadSumRpt(year));
+			JsonOutUtils.returnOkWithData(response, voIndex);
+			return;
+		}
+		
+		List<Map<String,Object>>  mths=new ArrayList<Map<String,Object>>(12);
+		String[] mthNames={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
+		Map<String,Object> perMth=null;
+		for(int i=1;i<=12;i++){
+			perMth=MapUtils.build("month",mthNames[i-1],"monthNum",String.format("%02d",i));
+			mths.add(perMth);
+		}
+		Map<String,EnergyWaterSumVO> voIndex=EnergyWaterSumVOUtil.build(service.erpMonthGrp(year), service.otherMonthGrp(year), service.wpgSumRpt(year), service.wpgCorrectSumRpt(year), service.workloadSumRpt(year));
+		
+		Map<String,Object> rootMap=new HashMap<String,Object>();
+		rootMap.put("months", mths); 
+		rootMap.put("ds", voIndex); 
+		
+		
+		RptOuter.clearTemplateCache();
+		RptOuter.write(request,response,rootMap,"homeEnergyMonthCost.ftl");
+	}
+	
+}

+ 232 - 0
src/main/java/com/hb/proj/car/controller/MaterialERPController.java

@@ -0,0 +1,232 @@
+package com.hb.proj.car.controller;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+import com.hb.proj.car.service.MaterialERPService;
+import com.hb.proj.car.service.YearSumCompareService;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.WorkloadPO;
+import com.hb.proj.model.WpgCorrect;
+import com.hb.proj.utils.DataUtils;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.RptOuter;
+import com.hb.proj.utils.WebConfig;
+import com.hb.xframework.util.ApplicationContextUtils;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.JsonParamHandler;
+import com.hb.xframework.util.SessionThreadLocal;
+
+@Controller
+@RequestMapping("/**/erp")
+public class MaterialERPController {
+	
+	@Autowired
+	private MaterialERPService service;
+	
+	@Autowired
+	private YearSumCompareService compservice;
+
+	@RequestMapping("/load")
+	public void loadERP(String rptMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				JsonOutUtils.returnError(response, "缺少登录信息");
+				return;
+			}
+			if(StringUtils.isEmpty(rptMonth)){
+				rptMonth=DateUtil.format(new Date(), "yyyy-MM");
+			}
+			String[] mths=rptMonth.split("-");
+			String startMonth=mths[0]+"-01";
+			//包含了当月和累计数据,不需要单独取累计数据
+			ERP  erp=service.rptERPSum(rptMonth,rptMonth);
+			
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptMonth", rptMonth);
+			rootMap.put("ratio",QuotaStandardSupport.getConfig());
+			rootMap.put("erp", erp);
+			rootMap.put("wpg", service.rptWpgSum(rptMonth,rptMonth));
+			rootMap.put("wpgCorrect", service.rptWpgCorrectSum(rptMonth,rptMonth));
+			
+			rootMap.put("workload", service.loadWorkloadByMonth(rptMonth));
+			
+			//工业产值截止到上月累计
+			String preMonth=startMonth;
+			int mthNum=Integer.parseInt(mths[1]);
+			if(mthNum>2){
+				preMonth=mths[0]+"-"+String.format("%02d", mthNum-1);
+			}
+			
+			rootMap.put("workloadSum", service.loadWorkloadMonthSum(startMonth,preMonth));
+			
+			
+			
+			OtherConsume kl=service.rptOtherConsume(rptMonth, rptMonth);
+			ERP erpKl=ERPKlSumUtil.erpPlusKlMonth(kl,erp);
+			rootMap.put("erpKl",erpKl);
+			
+			OtherConsume  klSum=service.rptOtherConsume(startMonth, rptMonth);
+			ERP erpKlSum=ERPKlSumUtil.erpPlusKlSum(erp, klSum);
+			rootMap.put("erpKlSum",erpKlSum);
+			
+			
+			//9.24 第二个表的运输用油 = 柴油合计-当月其他用油
+			//运输用柴油=当月柴油(ERP+昆仑卡)-当月其他用油(所有项目部当月合计)
+			Double trasport=null;
+			if(erpKl!=null&&erpKl.getCoilCount()!=null){
+				double othcoil=0;
+				if(kl!=null&&kl.getCoilCountKg()!=null){
+					othcoil=kl.getCoilCountKg().doubleValue();
+				}
+				trasport=erpKl.getCoilCount().doubleValue()-othcoil;
+				
+			}
+			rootMap.put("trasportOil", trasport);
+			
+			//累计运输用柴油
+			trasport=null;
+			if(erpKlSum!=null&&erpKlSum.getCoilCountSum()!=null){
+				double othcoil=0;
+				if(klSum!=null&&klSum.getCoilCountKg()!=null){
+					othcoil=klSum.getCoilCountKg().doubleValue();
+				}
+				trasport=erpKlSum.getCoilCountSum().doubleValue()-othcoil;
+				
+			}
+			rootMap.put("trasportSumOil", trasport);
+			
+			
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"materialERP.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	/**
+	 * erp+昆仑卡 数据校正 上报
+	 * @param rptMonth
+	 * @param erp
+	 * @param wpg
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/save")
+	public void save(String rptMonth,String erp,String wpg,String workload,HttpServletRequest request,HttpServletResponse response){
+		if(StringUtils.isEmpty(rptMonth)){
+			JsonOutUtils.returnError(response, "缺少月份");
+			return;
+		}
+		MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+		//物资erp数据
+		Map<String,Object> erpObj=JsonParamHandler.getMapParam(erp);
+		String oilRatio=(String)erpObj.remove("oilRatio");
+		String oilRatio95=(String)erpObj.remove("oilRatio95");
+		String coilRatio=(String)erpObj.remove("coilRatio");
+		
+		ERP  erpPO=JSON.parseObject(erp,new TypeReference<ERP>() {});
+		erpPO.setRptMonth(DateUtil.parse(rptMonth+"-01"));
+		erpPO.setModifier(su!=null?su.getUserName():"");
+		
+		service.saveERPData(erpPO);
+		
+		//水电气数据
+		WpgCorrect wpgcrt=JSON.parseObject(wpg,new TypeReference<WpgCorrect>() {});
+		wpgcrt.setRptMonth(DateUtil.parse(rptMonth+"-01"));
+		wpgcrt.setModifier(su!=null?su.getUserName():"");
+		service.saveWpgCorrect(wpgcrt);
+		
+		//产值
+		WorkloadPO wkload=JSON.parseObject(workload,new TypeReference<WorkloadPO>() {});
+		wkload.setRptMonth(DateUtil.parse(rptMonth+"-01"));
+		wkload.setModifier(su!=null?su.getUserName():"");
+		service.saveWorkload(wkload);
+		
+		
+		//燃油折算系数(在此模块中也提供了燃油折算系数的设置功能)
+		if(DataUtils.isDouble(oilRatio)&&DataUtils.isDouble(oilRatio95)&&DataUtils.isDouble(coilRatio)){
+			QuotaConfig config=QuotaStandardSupport.getConfig();
+			config.setOilRatio(Double.parseDouble(oilRatio));
+			config.setOilRatio95(Double.parseDouble(oilRatio95));
+			config.setCoilRatio(Double.parseDouble(coilRatio));
+			WebConfig  webConfig=ApplicationContextUtils.getBean("webConfig", WebConfig.class);
+			webConfig.save(config);
+		}
+		
+		//add 2020.12.17检查物资ERp汽、柴油吨数和ERP昆仑卡汇总表当月合计数据的差额,并提示到前端
+		String msg="";
+		OtherConsume oth=compservice.oilSumRpt(rptMonth,rptMonth);
+		if(oth!=null){
+			Double oilOthERP=oth.getOilErpCountKg(); //已转化为吨
+			Double coilOthERP=oth.getCoilErpCountKg(); //已转化为吨
+			Double diff=doubleDiff(erpPO.getOilCount(),oilOthERP);
+			
+			if(diff!=null){
+				msg+=String.format("汽油吨数相差%.3f;", diff);
+			}
+			diff=doubleDiff(erpPO.getCoilCount(),coilOthERP);
+			if(diff!=null){
+				msg+=String.format("柴油吨数相差%.3f;", diff);
+			}
+		}
+		if(StringUtils.isEmpty(msg)){
+			JsonOutUtils.returnOk(response);
+		}
+		else{
+			JsonOutUtils.returnOkWithData(response, "物资站ERP当月数据与ERP昆仑卡汇总表:"+msg);
+		}
+		
+		
+	}
+	
+	private Double doubleDiff(Double d1,Double d2){
+		Double diff=0.0;
+		
+		if(d1!=null&&d2!=null){
+			diff=Math.abs(d1.doubleValue()-d2.doubleValue());
+		}
+		else if(d1==null){
+			diff=d2;
+		}
+		else if(d2==null){
+			diff=d1;
+		}
+		if(diff!=null&&!Double.isNaN(diff)&&diff.doubleValue()>0){
+			return diff;
+		}
+		else{
+			return null;
+		}
+		
+	}
+}

+ 63 - 0
src/main/java/com/hb/proj/car/controller/MonitorRptExportBound.java

@@ -0,0 +1,63 @@
+package com.hb.proj.car.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import com.hb.proj.excel.ExcelSupport;
+
+/**
+ * 油量监控报表 导出
+ * @author 
+ *
+ */
+public class MonitorRptExportBound {
+
+	@SuppressWarnings("unchecked")
+	public static Workbook bound(Map<String,Object> context,Workbook wb){
+		Sheet sheet=wb.getSheetAt(0);
+		Row  row=null;
+		int parseIndex=1;  //开始解析的行索引,从0开始计数
+		while(!ExcelSupport.isNullRow(sheet, parseIndex))
+		{
+			 row=sheet.getRow(parseIndex);
+			
+			 if(parseIndex==1){
+				 String datasetName=ExcelSupport.getDatasetName(row.getCell(0));
+				 parseIndex=fillDatas((List<Map<String,Object>>)context.get(datasetName),sheet,row);
+				 continue;
+			 }
+			 context.put("r", parseIndex);
+			
+			 parseIndex++;
+		}
+        return wb;
+	}
+	public static int fillDatas(List<Map<String,Object>> dataset,Sheet sheet,Row row){
+		int dataRowStart=row.getRowNum();
+		if(dataset==null||dataset.size()==0){
+			sheet.removeRow(row);  //删除数据,保留行
+			return ++dataRowStart;
+		}
+		ExcelSupport.insertRow(sheet, dataRowStart, dataset.size()-1);  //模板行也显示数据,-1  特殊-2
+		Map<String,List<String>>  mapFields=ExcelSupport.getFields(row);
+		List<String> fields=mapFields.get("fields");
+		int rowIdx=row.getRowNum();
+		for(Map<String,Object> data : dataset){
+			row=sheet.getRow(rowIdx++);
+			for(int f=0,flen=fields.size();f<flen;f++){
+				if("recordNum".equals(fields.get(f))){
+					ExcelSupport.setValue(row.getCell(f),rowIdx-1);
+				}
+				else{
+					ExcelSupport.setValue(row.getCell(f),data.get(fields.get(f)));
+				}
+				
+			}
+		}
+		return rowIdx;
+	}
+}

+ 115 - 0
src/main/java/com/hb/proj/car/controller/OilBoxController.java

@@ -0,0 +1,115 @@
+package com.hb.proj.car.controller;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.OilBoxService;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.RequestUtils;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+/**
+ * 油箱标定管理
+ * 标定基本算法:
+ * 1. 底部,顶部不规则部分有一定高度,单独计算,其他部分按立方体计算(除去壁厚)
+ * 2. 一般油不会用完才加油,也不会加满。顶部暂不考虑,只考虑底部
+ * 3.底部高度为h,容积差额为四个圆角造成的。(其它不规格油箱暂不考虑)
+ * 4.高度>h时,只需要减去四角的差额;高度<h时,先按立方体计算,减去以液位高为半径的圆角差额,再减一个以液位高为边长的正立方体
+ */
+@Controller
+@RequestMapping("/**/oilbox")
+public class OilBoxController {
+
+	@Autowired
+	private OilBoxService service;
+	
+	
+	
+	@RequestMapping("/query")
+	public void query(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			PageModel<Map<String,Object>> pagedData=service.queryOilBox(args,page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	@RequestMapping("/get")
+	public void get(String recordId,HttpServletResponse response) throws Exception{
+		Map<String,Object> mapping=service.getOilBox(recordId);
+		JsonOutUtils.returnOkWithData(response, mapping);
+	}
+	
+	@RequestMapping("/add")
+	public void add(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  oilBox=RequestUtils.getParams(request);
+		   MapUtils.blankValToNull(oilBox);
+		  
+		   
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   oilBox.put("modifier",  su!=null?su.getUserName():"unknow");
+		   service.addOilBox(oilBox);
+		   
+		   JsonOutUtils.returnOk(response);
+		  }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/update")
+	public void update(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  oilBox=RequestUtils.getParams(request);
+		   MapUtils.blankValToNull(oilBox);
+		  
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   oilBox.put("modifier", su!=null?su.getUserName():"unknow");
+		   service.updateOilBox(oilBox);
+		   JsonOutUtils.returnOk(response);
+	   }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/delete")
+	public void delete(String recordId,HttpServletResponse response){
+		try{
+			   service.deleteOilBox(recordId);
+			   JsonOutUtils.returnOk(response);
+		   }
+		   catch(Exception e){
+			   e.printStackTrace();
+			   JsonOutUtils.returnError(response, "服务出现错误");
+		   }
+	}
+	
+	
+}

+ 203 - 0
src/main/java/com/hb/proj/car/controller/OilMeterController.java

@@ -0,0 +1,203 @@
+package com.hb.proj.car.controller;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.OilMeterService;
+import com.hb.proj.utils.DataAuthUtils;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.proj.utils.OkhttpUtils;
+import com.hb.proj.utils.RequestUtils;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.JsonParamHandler;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+import com.hb.xframework.util.SysConfigUtil;
+
+/**
+ * 油量计管理
+ */
+@Controller
+@RequestMapping("/**/meter")
+public class OilMeterController {
+
+	@Autowired
+	private OilMeterService service;
+	
+	/**
+	 * 供项目部通过车辆查询油量数据
+	 * @param request
+	 * @param page
+	 * @param limit
+	 * @param response
+	 */
+	@RequestMapping("/queryFromCar")
+	public void queryFromCar(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			PageModel<Map<String,Object>> pagedData=service.queryOilMeterFromCar(args,DataAuthUtils.getAuthOrgAssistCode(su),page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	/**
+	 * 油量计管理查询
+	 * @param request
+	 * @param page
+	 * @param limit
+	 * @param response
+	 */
+	@RequestMapping("/query")
+	public void query(HttpServletRequest request,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+		    }
+			Map<String,Object> args=RequestUtils.getParams(request);
+			args.put("showAll", su.isSysAdmin()?"1":null); //系统管理员显示全部
+			PageModel<Map<String,Object>> pagedData=service.queryOilMeter(args,DataAuthUtils.getAuthOrgAssistCode(su),page, limit);
+			LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	@RequestMapping("/get")
+	public void get(String recordId,HttpServletResponse response) throws Exception{
+		Map<String,Object> mapping=service.getOilMeter(recordId);
+		if(mapping!=null&&mapping.get("installDate")!=null){
+			mapping.put("installDate", DateUtil.format((Date)mapping.get("installDate"), "yyyy-MM-dd"));
+		}
+		JsonOutUtils.returnOkWithData(response, mapping);
+	}
+	
+	
+	
+	@RequestMapping("/add")
+	public void add(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  oilMeter=RequestUtils.getParams(request);
+		   MapUtils.blankValToNull(oilMeter);
+		  
+		   String meterNum=(String)oilMeter.get("meterNum");
+		   if(StringUtils.isNotEmpty(meterNum)&&service.existsMeterNum(meterNum,null)){
+			   JsonOutUtils.returnError(response, "该油量计识别码已在其它车辆使用,请更换");
+			   return ;
+		   }
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   oilMeter.put("modifier",  su!=null?su.getUserName():"unknow");
+		   service.addOilMeter(oilMeter);
+		   
+		   JsonOutUtils.returnOk(response);
+		  }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/update")
+	public void update(HttpServletRequest request,HttpServletResponse response){
+	   try{
+		   Map<String,Object>  oilMeter=RequestUtils.getParams(request);
+		   MapUtils.blankValToNull(oilMeter);
+		  
+		   
+		   String meterNum=(String)oilMeter.get("meterNum");
+		   if(StringUtils.isNotEmpty(meterNum)&&service.existsMeterNum(meterNum,(String)oilMeter.get("recordId"))){
+			   JsonOutUtils.returnError(response, "该油量计识别码已在其它车辆使用,请更换");
+			   return ;
+		   }
+		   SessionUser su=SessionThreadLocal.getSessionUser();
+		   oilMeter.put("modifier", su!=null?su.getUserName():"unknow");
+		   service.updateOilMeter(oilMeter);
+		   JsonOutUtils.returnOk(response);
+	   }
+	   catch(Exception e){
+		   e.printStackTrace();
+		   JsonOutUtils.returnError(response, "服务出现错误");
+	   }
+		
+	}
+	
+	@RequestMapping("/delete")
+	public void delete(String recordId,HttpServletResponse response){
+		try{
+			   service.deleteOilMeter(recordId);
+			   JsonOutUtils.returnOk(response);
+		   }
+		   catch(Exception e){
+			   e.printStackTrace();
+			   JsonOutUtils.returnError(response, "服务出现错误");
+		   }
+	}
+	
+	@RequestMapping("/loadCarBoxs")
+	public void loadCarBoxs(String jsonConfig,HttpServletResponse response){
+		Map<String,Object> args=JsonParamHandler.getMapParam(jsonConfig);
+		List<Map<String,Object>> rst=service.loadCarBoxs((String)args.get("carId"));
+		JsonOutUtils.returnOkWithData(response, MapUtils.build((String)args.get("selectId"),rst));
+	}
+	
+	/**
+	 * 从当前采集数据中同步油位计和车辆的关联
+	 * @param response
+	 */
+	@RequestMapping("/syn")
+	public void syn(HttpServletResponse response){
+		try{
+			   service.addMetersFromSampling();
+			   JsonOutUtils.returnOk(response);
+		   }
+		   catch(Exception e){
+			   e.printStackTrace();
+			   JsonOutUtils.returnError(response, "服务出现错误");
+		   }
+	}
+	
+	/**
+	 * 同步采集程序(重新加载油箱标定,以便新加设备生效)
+	 * @param response
+	 */
+	@RequestMapping("/updateCollect")
+	public void updateCollect(HttpServletResponse response){
+		try{
+			String resp=OkhttpUtils.get(SysConfigUtil.getConfig("collecter")+"/out/reloadCalibrater.do");
+			JsonOutUtils.returnOkWithData(response, resp);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "同步采集程序出错");
+		}
+	}
+
+}

+ 36 - 0
src/main/java/com/hb/proj/car/controller/RptExporterController.java

@@ -0,0 +1,36 @@
+package com.hb.proj.car.controller;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.excel.Table;
+import com.hb.proj.excel.TableExporter;
+
+@Controller
+@RequestMapping("/**/rpt")
+public class RptExporterController {
+
+	@RequestMapping("/export/tableToXls")
+	public void tableToXls(String expData,HttpServletRequest request,HttpServletResponse response) throws IOException{
+		Table htmlTab=JSON.parseObject(expData,new TypeReference<Table>() {});
+		
+		response.setContentType("APPLICATION/OCTET-STREAM");
+		response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(htmlTab.getTitle(),"UTF-8") + ".xls");
+        OutputStream os=response.getOutputStream();
+		HSSFWorkbook  workbook=TableExporter.buildExcel(htmlTab);
+		workbook.write(os);
+		os.flush();
+		os.close();
+		response.flushBuffer();
+	}
+}

+ 124 - 0
src/main/java/com/hb/proj/car/controller/WpgSumRptController.java

@@ -0,0 +1,124 @@
+package com.hb.proj.car.controller;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.car.service.CarSumRptService;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.MapUtils;
+import com.hb.proj.utils.RptOuter;
+import com.hb.xframework.util.DateUtil;
+
+@Controller
+@RequestMapping("/**/rpt")
+public class WpgSumRptController {
+
+	@Autowired
+	private CarSumRptService service;
+	
+	/**
+	 * 水电气汇总  同比折线图
+	 * @param rptMonth
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadWpgForChart")
+	public void loadWpgForChart(String rptMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(rptMonth)){
+				Calendar ca=Calendar.getInstance();
+				if(ca.get(Calendar.DAY_OF_MONTH)>25){  //超过25号才用本月否则用上一月
+					rptMonth=String.valueOf(ca.get(Calendar.YEAR))+"-"+String.format("%02d", ca.get(Calendar.MONTH)+1);
+				}
+				else{
+					rptMonth=String.valueOf(ca.get(Calendar.YEAR))+"-"+String.format("%02d", ca.get(Calendar.MONTH));
+				}
+			}
+			String[] ymtr=rptMonth.split("-");
+			String startMonth=ymtr[0]+"-01";
+			String preyear=String.valueOf(Integer.parseInt(ymtr[0])-1);
+			String preStartMonth=preyear+"-01";
+			String preEndMonth=preyear+"-12";   //preyear+"-"+ymtr[1];
+			
+			List<Wpg>  yearDatas=service.loadWpgGroupOrgAndMth(startMonth, rptMonth);
+			List<Wpg>  preyearDatas=service.loadWpgGroupOrgAndMth(preStartMonth, preEndMonth);
+			List<Map<String,Object>> orgs=service.loadAllSubOrgs();
+			JsonOutUtils.returnOkWithData(response, MapUtils.builder("year",yearDatas,"pre",preyearDatas,"org",orgs),"MM");
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	/**
+	 * 水电气汇总表---报表
+	 * @param rptMonth
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadWpgSum")
+	public void loadWpgSum(String rptMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(rptMonth)){
+				rptMonth=DateUtil.format(new Date(), "yyyy-MM");
+			}
+			String startMonth=(rptMonth.split("-"))[0]+"-01";
+			Map<String,Wpg> thisMonthIdx=builderIndex(service.loadWpg(rptMonth, rptMonth));
+			Map<String,Wpg> sumRptIdx=builderIndex(service.loadWpg(startMonth, rptMonth));
+			
+			String rptMonthTitle=rptMonth.replace("-", "年")+"月";
+			Map<String,Object> rootMap=new HashMap<String,Object>();
+			rootMap.put("rptMonthTitle", rptMonthTitle);
+			rootMap.put("monthDS", thisMonthIdx); //当月统计数据集
+			rootMap.put("sumDS", sumRptIdx);  //累计统计数据集
+			rootMap.put("orgDS", service.loadAllSubOrgs()); //所有项目部
+			
+			RptOuter.clearTemplateCache();
+			RptOuter.write(request,response,rootMap,"wpgSum.ftl");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+	}
+	
+	private Map<String,Wpg> builderIndex(List<Wpg> wpgs){
+		Map<String,Wpg> index=new HashMap<String,Wpg>();
+		Wpg total=new Wpg();
+		for(Wpg w : wpgs){
+			index.put(w.getOrgId(), w);
+			addWpg(total,w);
+		}
+		
+		index.put("合计", total);
+		return index;
+	}
+	
+	private void addWpg(Wpg t,Wpg d){
+		t.setWaterCount(CarRptUtils.addDouble(t.getWaterCount(), d.getWaterCount()));
+		t.setWaterCost(CarRptUtils.addDouble(t.getWaterCost(),d.getWaterCost()));
+		t.setPowerCount(CarRptUtils.addDouble(t.getPowerCount(),d.getPowerCount()));
+		t.setPowerCost(CarRptUtils.addDouble(t.getPowerCost(),d.getPowerCost()));
+		t.setNgasCount(CarRptUtils.addDouble(t.getNgasCount(),d.getNgasCount()));
+		t.setNgasCost(CarRptUtils.addDouble(t.getNgasCost(),d.getNgasCost()));
+		t.setLgasCount(CarRptUtils.addDouble(t.getLgasCount(),d.getLgasCount()));
+		t.setLgasCost(CarRptUtils.addDouble(t.getLgasCost(),d.getLgasCost()));
+	}
+	
+	
+}

+ 56 - 0
src/main/java/com/hb/proj/car/quota/AbstractQuotaStandard.java

@@ -0,0 +1,56 @@
+package com.hb.proj.car.quota;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+
+public abstract class AbstractQuotaStandard {
+
+private Map<String,Quota> standards=null;
+	
+	public AbstractQuotaStandard(){
+		standards=new HashMap<String,Quota>();
+	}
+	
+	public void addQuota(Quota q){
+		standards.put(getQuotaKey(q), q);
+	}
+	
+	public void clearQuota(){
+		if(standards!=null&&standards.size()>0){
+			standards.clear();
+		}
+	}
+	
+	public void load(List<Quota>  quotas){
+		if(standards!=null&&standards.size()>0){
+			standards.clear();
+		}
+		if(quotas==null||quotas.size()==0){
+			return;
+		}
+		for(Quota  q : quotas){
+			standards.put(getQuotaKey(q), q);
+		}
+	}
+	
+	public Quota  getQuota(String key){
+		return standards.get(key);
+	}
+	
+	public Collection<Quota>  getQuotas(){
+		return standards.values();
+	}
+	
+	public  String getQuotaKey(Quota quota){
+		return quota.getQuotaKey();
+	}
+	
+	//public abstract String getRealKey(CarContext context);
+	
+	public abstract void fillCarQuota(CarContext context);
+}

+ 24 - 0
src/main/java/com/hb/proj/car/quota/EngineQuotaStandard.java

@@ -0,0 +1,24 @@
+package com.hb.proj.car.quota;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+
+public class EngineQuotaStandard  extends AbstractQuotaStandard {
+	
+	/*@Override
+	public String getQuotaKey(Quota quota) {
+		return quota.getDeviceName();
+	}*/
+
+	public String getRealKey(CarContext context) {
+		return context.getQuotaEngineKey();
+	}
+
+	@Override
+	public void fillCarQuota(CarContext context) {
+		 Quota quota=getQuota(getRealKey(context));
+		 if(quota!=null&&quota.getQuotaCount()!=null){
+			 context.setEngineQuota(quota.getQuotaCount().doubleValue());
+		 }
+	}
+}

+ 27 - 0
src/main/java/com/hb/proj/car/quota/OuterQuotaStandard.java

@@ -0,0 +1,27 @@
+package com.hb.proj.car.quota;
+
+import java.util.Collection;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+
+@Deprecated
+public class OuterQuotaStandard extends AbstractQuotaStandard {
+
+	@Override
+	public String getQuotaKey(Quota quota) {
+		return quota.getDeviceName();
+	}
+
+
+	@Override
+	public void fillCarQuota(CarContext context) {
+		Collection<Quota> quotas=getQuotas();
+		if(quotas!=null&&quotas.size()>0){
+			Quota q=quotas.iterator().next();
+			context.setOuterQuota(q.getQuotaCount()!=null?q.getQuotaCount().doubleValue():null);
+		}
+
+	}
+
+}

+ 164 - 0
src/main/java/com/hb/proj/car/quota/QuotaConfig.java

@@ -0,0 +1,164 @@
+package com.hb.proj.car.quota;
+/**
+ * 定额其他配置项(油品折算系数,取暖月份)
+ * @author hb
+ *
+ */
+public class QuotaConfig {
+
+	private double oilRatio=1;   //默认为92#汽油 升-公斤
+	
+	private double oilRatio95=1; //95#汽油折算系数 升-公斤
+	
+	private double coilRatio=1;	 //柴油折算系数 升-公斤
+	
+	private double oilCoalRatio=1;  //汽油折算标准煤系数  吨-吨
+	
+	private double coilCoalRatio=1;  //柴油折算标准煤系数  吨-吨
+	
+	private double powerCoalRatio=1;  //电能折算标准煤系数  万千瓦时-吨
+	
+	private double ygasCoalRatio=1;  //液化气折算标准煤系数  吨-吨
+	
+	private double ngasCoalRatio=1;  //天然气折算标准煤系数  万立方米-吨
+	
+	private Integer rptStart=null;  //数据上报期限本月几号开始(含),空表示不做限制
+	
+	private Integer rptEnd=null;   //数据上报期限下月几号截止(不含),空表示不做限制
+	
+	private String  quotaRiseMonths;   //百公里定额上浮月份,整数,半角英文分隔
+	
+	private double quotaRiseCount;    //百公里定额上浮量
+	
+	private String quotaRiseDeviceNames;  //百公里定额上浮 车型
+	
+	private int[]  warmMonths=null;
+	
+	private Integer monthSplitDay; //统计月份划分日
+
+	public double getOilRatio() {
+		return oilRatio;
+	}
+
+	public void setOilRatio(double oilRatio) {
+		this.oilRatio = oilRatio;
+	}
+
+	public double getCoilRatio() {
+		return coilRatio;
+	}
+
+	public void setCoilRatio(double coilRatio) {
+		this.coilRatio = coilRatio;
+	}
+
+	public int[] getWarmMonths() {
+		return warmMonths;
+	}
+
+	public void setWarmMonths(int[] warmMonths) {
+		this.warmMonths = warmMonths;
+	}
+
+	public double getOilCoalRatio() {
+		return oilCoalRatio;
+	}
+
+	public void setOilCoalRatio(double oilCoalRatio) {
+		this.oilCoalRatio = oilCoalRatio;
+	}
+
+	public double getCoilCoalRatio() {
+		return coilCoalRatio;
+	}
+
+	public void setCoilCoalRatio(double coilCoalRatio) {
+		this.coilCoalRatio = coilCoalRatio;
+	}
+
+	public double getPowerCoalRatio() {
+		return powerCoalRatio;
+	}
+
+	public void setPowerCoalRatio(double powerCoalRatio) {
+		this.powerCoalRatio = powerCoalRatio;
+	}
+
+	public double getYgasCoalRatio() {
+		return ygasCoalRatio;
+	}
+
+	public void setYgasCoalRatio(double ygasCoalRatio) {
+		this.ygasCoalRatio = ygasCoalRatio;
+	}
+
+	public double getNgasCoalRatio() {
+		return ngasCoalRatio;
+	}
+
+	public void setNgasCoalRatio(double ngasCoalRatio) {
+		this.ngasCoalRatio = ngasCoalRatio;
+	}
+
+	public double getOilRatio95() {
+		return oilRatio95;
+	}
+
+	public void setOilRatio95(double oilRatio95) {
+		this.oilRatio95 = oilRatio95;
+	}
+
+	public Integer getRptStart() {
+		return rptStart;
+	}
+
+	public void setRptStart(Integer rptStart) {
+		this.rptStart = rptStart;
+	}
+
+	public Integer getRptEnd() {
+		return rptEnd;
+	}
+
+	public void setRptEnd(Integer rptEnd) {
+		this.rptEnd = rptEnd;
+	}
+
+	
+
+	public double getQuotaRiseCount() {
+		return quotaRiseCount;
+	}
+
+	public void setQuotaRiseCount(double quotaRiseCount) {
+		this.quotaRiseCount = quotaRiseCount;
+	}
+
+	public String getQuotaRiseMonths() {
+		return quotaRiseMonths;
+	}
+
+	public void setQuotaRiseMonths(String quotaRiseMonths) {
+		this.quotaRiseMonths = quotaRiseMonths;
+	}
+
+	public String getQuotaRiseDeviceNames() {
+		return quotaRiseDeviceNames;
+	}
+
+	public void setQuotaRiseDeviceNames(String quotaRiseDeviceNames) {
+		this.quotaRiseDeviceNames = quotaRiseDeviceNames;
+	}
+
+	public Integer getMonthSplitDay() {
+		return monthSplitDay;
+	}
+
+	public void setMonthSplitDay(Integer monthSplitDay) {
+		this.monthSplitDay = monthSplitDay!=null?monthSplitDay:16;
+	}
+
+	
+
+	
+}

+ 85 - 0
src/main/java/com/hb/proj/car/quota/QuotaStandardSupport.java

@@ -0,0 +1,85 @@
+package com.hb.proj.car.quota;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+
+public class QuotaStandardSupport {
+
+	public static  TravelQuotaStandard  travelQuotas=new TravelQuotaStandard();
+	
+	public static  WorkQuotaStandard  workQuotas=new WorkQuotaStandard();
+	
+	public static  EngineQuotaStandard  engineQuotas=new EngineQuotaStandard();
+	
+	public static  OuterQuotaStandard  outerQuotas=new OuterQuotaStandard();
+	
+	public static QuotaConfig  config;
+	
+	public static void clear(){
+		travelQuotas.clearQuota();
+		workQuotas.clearQuota();
+		engineQuotas.clearQuota();
+		outerQuotas.clearQuota();
+		travelQuotas=null;
+		workQuotas=null;
+		engineQuotas=null;
+		outerQuotas=null;
+	}
+	
+	public static void loadQuota(List<Quota>  quotas){
+		if(quotas==null||quotas.size()==0){
+			return ;
+		}
+		travelQuotas.clearQuota();
+		workQuotas.clearQuota();
+		engineQuotas.clearQuota();
+		outerQuotas.clearQuota();
+		
+		Map<String,AbstractQuotaStandard>  quotaMap=new HashMap<String,AbstractQuotaStandard>();
+		quotaMap.put(QuotaType.TRAVEL.getName(), travelQuotas);
+		quotaMap.put(QuotaType.WORK.getName(), workQuotas);
+		quotaMap.put(QuotaType.ENGINE.getName(), engineQuotas);
+		quotaMap.put(QuotaType.WARM.getName(), outerQuotas);
+		
+		for(Quota q: quotas){
+			quotaMap.get(q.getQuotaType()).addQuota(q);
+		}
+		quotas=null;
+	}
+	
+	public static void setConfig(QuotaConfig cfg){  //取暖月份设置,油品折算系数
+		config=cfg;
+	}
+	
+	public static QuotaConfig  getConfig(){
+		return config;
+	}
+	
+	/**
+	 * 根据车辆基本信息+月上报信息,查找对应的定额标准
+	 * @param context
+	 */
+	public static void fillCarQuota(CarContext context){
+		travelQuotas.fillCarQuotaSpec(context,config);
+		workQuotas.fillCarQuota(context);
+		engineQuotas.fillCarQuota(context);
+		outerQuotas.fillCarQuota(context);
+	}
+	
+	public static void main(String[] args){
+		String s="09,10;11,12";
+		s=","+(s.trim()).replaceAll("\\D+", ",")+",";
+		s=s.replaceAll(",0", ","); 
+		
+		System.out.println(s);
+		
+		s="10";
+		System.out.println(s.replaceFirst("^0", ""));
+	}
+}

+ 16 - 0
src/main/java/com/hb/proj/car/quota/QuotaType.java

@@ -0,0 +1,16 @@
+package com.hb.proj.car.quota;
+
+public enum QuotaType {
+	
+	TRAVEL("百公里耗油"),WORK("作业每小时耗油"),ENGINE("车载发电机每小时耗油"),WARM("车载取暖每小时耗油");
+
+	private String name;
+	
+	private QuotaType(String name){
+		this.name=name;
+	}
+	
+	public String getName(){
+		return name;
+	}
+}

+ 127 - 0
src/main/java/com/hb/proj/car/quota/TravelQuotaStandard.java

@@ -0,0 +1,127 @@
+package com.hb.proj.car.quota;
+
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+import com.hb.proj.utils.DataUtils;
+
+//定额标准取于定额表,需要同步更新
+public class TravelQuotaStandard extends AbstractQuotaStandard{
+
+	/**
+	 * recordId_areaCode
+	 */
+	@Override
+	public String getQuotaKey(Quota quota) {
+		return quota.getQuotaKey()+"_"+quota.getWorkArea();
+	}
+
+	public String getRealKey(CarContext context) {
+		return context.getQuotaTravalWorkKey()+"_"+context.getWorkArea();
+	}
+
+	@Override
+	public void fillCarQuota(CarContext context) {
+		 String key=getRealKey(context);
+		 Quota quota=getQuota(key);
+		 if(quota!=null&&quota.getQuotaCount()!=null){
+			 context.setTravalQuota(quota.getQuotaCount().doubleValue());
+		 }
+	}
+
+	/**
+	 * 百公里定额的确定特殊:定额+上浮量(月份上浮)+上浮量(车辆年限上浮)  2021.11.15
+	 * @param context
+	 * @param config
+	 */
+	public void fillCarQuotaSpec(CarContext context,QuotaConfig  config) {
+		 String key=getRealKey(context);
+		 Quota quota=getQuota(key);
+		 if(quota!=null&&quota.getQuotaCount()!=null){
+			 context.setTravalQuota(quota.getQuotaCount().doubleValue());
+			 addRiseQuota(context,quota,config);
+		 }
+	}
+	
+	//增加上浮量(月份,车型相关)  定额标准中有设备名称(车型) 2021.11.11
+	//增加上浮量2(使用年限相关) 2021.11.15
+	private void addRiseQuota(CarContext context,Quota quota,QuotaConfig  config){
+				//根据使用年份上浮的规则,年份以5的倍数划分
+				int calYears=(int)(Math.floor(context.getWorkYear()/5)*5);
+				Double risePercent=getRisePercent(calYears,quota.getRiseMap());
+				if(risePercent!=null&&!Double.isNaN(risePercent)){
+					context.setTravalQuota(DataUtils.round(context.getTravalQuota()*risePercent, 2));
+					
+				}
+				/*if(quota.getRiseMap()!=null&&quota.getRiseMap().containsKey(calYears)){
+					Double riseVal=quota.getRiseMap().get(calYears);
+					context.setTravalQuota(context.getTravalQuota()+(riseVal!=null&&!Double.isNaN(riseVal)?riseVal.doubleValue():0));  //增加上浮量
+				}*/
+		
+				//判断上报月份是否在指定的油耗上浮月份中(针对的是百公里定额)
+				String riseMths=config.getQuotaRiseMonths();
+				if(StringUtils.isEmpty(riseMths)||riseMths.trim().length()==0){  //没有设置上浮月份表示不上浮
+					return;
+				}
+				
+				riseMths=","+(riseMths.trim()).replaceAll("\\D+", ",")+",";
+				riseMths=riseMths.replaceAll(",0", ",");  //月份统一为首位不带0
+				String rptMonth=(context.getRptMonth()).replaceFirst("^0", "");
+				boolean riseMthIf=riseMths.indexOf(","+rptMonth+",")>=0;
+				
+				if(!riseMthIf){ //不满足上浮月份条件
+					return;
+				}
+				
+				boolean riseDeviceIf=true;  //默认不限制设备类型
+				String riseDevices=config.getQuotaRiseDeviceNames();
+				if(StringUtils.isNotEmpty(riseDevices)&&riseDevices.trim().length()>0){
+					riseDevices=","+(riseDevices.trim()).replaceAll("[,;,;、]+", ",")+",";
+					String dn=quota.getDeviceName()!=null?quota.getDeviceName().trim():null;
+					riseDeviceIf=dn==null?false:(riseDevices.indexOf(","+dn+",")>=0);
+				}
+				
+				if(riseMthIf&&riseDeviceIf){   //2021.11.11 新百公里定额中的上浮规则中,需要为指定车型且在指定月份里
+					context.setTravalQuota(context.getTravalQuota()+config.getQuotaRiseCount());  //增加上浮量
+				}
+				
+	}
+	
+	/**
+	 * 以5年为步长,复合递增
+	 * @param calYears
+	 * @param riseMap
+	 * @return
+	 */
+	private Double getRisePercent(int calYears,Map<Integer, Double> riseMap){
+		if(calYears>15){
+			calYears=15;  //车龄大于15年的按15年算上浮量
+		}
+		if(riseMap==null||!riseMap.containsKey(calYears)){
+			return null;
+		}
+		if(riseMap.get(5)==null){
+			riseMap.put(5, 0.0);
+		}
+		if(riseMap.get(10)==null){
+			riseMap.put(10, 0.0);
+		}
+		if(riseMap.get(15)==null){
+			riseMap.put(15, 0.0);
+		}
+		
+		if(calYears==5){
+			return 1+riseMap.get(5)/100.0;
+		}
+		if(calYears==10){
+			return (1+riseMap.get(5)/100.0)*(1+riseMap.get(10)/100.0);
+		}
+		if(calYears==15){
+			return (1+riseMap.get(5)/100.0)*(1+riseMap.get(10)/100.0)*(1+riseMap.get(15)/100.0);
+		}
+		return null;
+	}
+}

+ 25 - 0
src/main/java/com/hb/proj/car/quota/WorkQuotaStandard.java

@@ -0,0 +1,25 @@
+package com.hb.proj.car.quota;
+
+import com.hb.proj.car.service.CarContext;
+import com.hb.proj.model.Quota;
+
+public class WorkQuotaStandard  extends AbstractQuotaStandard {
+
+	/*@Override
+	public String getQuotaKey(Quota quota) {
+		return quota.getDeviceName()+"_"+(StringUtils.isNotEmpty(quota.getDeviceModel())?quota.getDeviceModel():"xxx");
+	}*/
+
+	public String getRealKey(CarContext context) {
+		return context.getQuotaTravalWorkKey();
+	}
+
+	@Override
+	public void fillCarQuota(CarContext context) {
+		 Quota quota=getQuota(getRealKey(context));
+		 if(quota!=null&&quota.getQuotaCount()!=null){
+			 context.setWorkQuota(quota.getQuotaCount().doubleValue());
+		 }
+	}
+
+}

+ 158 - 0
src/main/java/com/hb/proj/car/service/CarContext.java

@@ -0,0 +1,158 @@
+package com.hb.proj.car.service;
+
+
+public class CarContext {
+
+	private String deviceName;
+	
+	private String deviceModel;
+	
+	private String quotaTravalWorkKey ;  //定额标准新的关联方式,直接关联到对应定额记录的主键 百公里和作业 2021-10
+	
+	private String quotaEngineKey ;   //关联到对应定额记录的主键 发电机每小时油耗 2021-10
+	
+	private String workArea; //作业区域编码
+	
+	
+	private int    workYear;  //实际使用的年数
+	
+	
+	private String rptMonth;   //上报月份MM
+	
+	private double travalQuota;  //百公里定额油耗
+	
+	private double workQuota;   //作业每小时油耗
+	
+	private double engineQuota;  //发电机工作每小时油耗
+	
+	private double outerQuota;   //野外车载取暖每小时油耗
+	
+	public CarContext (String quotaKey,String quotaEngineKey,String workArea,String rptMonth){
+		this.workArea=workArea;
+		this.quotaTravalWorkKey=quotaKey;
+		this.quotaEngineKey=quotaEngineKey;
+		this.rptMonth=rptMonth;
+	}
+	
+	public CarContext(){
+		
+	}
+	
+	/**
+	 * 使用年数计算精确到月份且要足月
+	 * @param deviceName
+	 * @param deviceModel
+	 * @param deviceAge
+	 */
+	public CarContext(String deviceName,String deviceModel,int deviceAge){
+		this.deviceName=deviceName;
+		this.deviceModel=deviceModel;
+		this.workYear=deviceAge;
+		/*if(workStart==null){
+			this.workYear=1;
+			return;
+		}
+		Calendar ca=Calendar.getInstance();
+		int y=ca.get(Calendar.YEAR),m=ca.get(Calendar.MONTH)+1;
+		ca.setTime(workStart);
+		int y2=ca.get(Calendar.YEAR),m2=ca.get(Calendar.MONTH)+1;
+		this.workYear=m2>=m?(y-y2):(y-y2-1);*/
+		
+		
+		
+	}
+
+	public String getDeviceName() {
+		return deviceName;
+	}
+
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
+	}
+
+	public String getDeviceModel() {
+		return deviceModel;
+	}
+
+	public void setDeviceModel(String deviceModel) {
+		this.deviceModel = deviceModel;
+	}
+
+	public int getWorkYear() {
+		return workYear;
+	}
+
+	public void setWorkYear(int workYear) {
+		this.workYear = workYear;
+	}
+
+	
+
+	
+
+	public double getTravalQuota() {
+		return travalQuota;
+	}
+
+	public void setTravalQuota(double travalQuota) {
+		this.travalQuota = travalQuota;
+	}
+
+	public double getWorkQuota() {
+		return workQuota;
+	}
+
+	public void setWorkQuota(double workQuota) {
+		this.workQuota = workQuota;
+	}
+
+	public double getEngineQuota() {
+		return engineQuota;
+	}
+
+	public void setEngineQuota(double engineQuota) {
+		this.engineQuota = engineQuota;
+	}
+
+	public double getOuterQuota() {
+		return outerQuota;
+	}
+
+	public void setOuterQuota(double outerQuota) {
+		this.outerQuota = outerQuota;
+	}
+
+	public String getQuotaTravalWorkKey() {
+		return quotaTravalWorkKey;
+	}
+
+	public void setQuotaTravalWorkKey(String quotaTravalWorkKey) {
+		this.quotaTravalWorkKey = quotaTravalWorkKey;
+	}
+
+	public String getQuotaEngineKey() {
+		return quotaEngineKey;
+	}
+
+	public void setQuotaEngineKey(String quotaEngineKey) {
+		this.quotaEngineKey = quotaEngineKey;
+	}
+
+	public String getWorkArea() {
+		return workArea;
+	}
+
+	public void setWorkArea(String workArea) {
+		this.workArea = workArea;
+	}
+
+	public String getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(String rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	
+}

+ 246 - 0
src/main/java/com/hb/proj/car/service/CarOilMonitorService.java

@@ -0,0 +1,246 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.OilAddLog;
+import com.hb.proj.model.OilChangeBO;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.FieldAttrConverter;
+import com.hb.xframework.dao.util.PageModel;
+
+@Service
+public class CarOilMonitorService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 车辆当前油量数据查询
+	 * @param args
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> queryCarOil(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select g.org_name,oil.*");
+		sql.append(" from t_oil_current oil ");
+		sql.append(" left join t_car car on car.car_num like concat('%',left(dtu_num,instr(dtu_num,'_')-1),'%')");
+		sql.append(" left join t_org g on car.belong_org=g.org_id");
+		sql.append(" ) tab where 1=1 ");
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("dtuNum"))){
+			sql.append(" and (dtu_num like ?)");
+			sqlParams.add("%"+args.get("dtuNum")+"%");
+		}
+		if(args!=null&&"1".equals((String)args.get("sort"))){
+			sql.append(" order by data_time desc ");
+			
+		}
+		else{
+			sql.append(" order by dtu_num ");
+		}
+		
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	/**
+	 * 油量采集数据查询--分页表格
+	 * @param mountId
+	 * @param startDate
+	 * @param endDate
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>>  queryOilCollect(String mountId,Date startDate,Date endDate,int pageNo,int pageSize){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select t.* from t_oil_history_2 t");
+		sql.append(" where mount_id=? and data_time between ? and ?");
+		sql.append(" order by data_time desc");
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,mountId,startDate,endDate);
+	}
+	
+	/**
+	 * 油量采集数据查询--曲线绘制
+	 * @param mountId
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 */
+	public List<Map<String,Object>> queryOilCollectForCurve(String mountId,Date startDate,Date endDate){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select t.*,oil_volume data from t_oil_history_2 t");
+		sql.append(" where mount_id=? and data_time between ? and ? and oil_volume is not null and oil_volume>0");
+		sql.append(" order by data_time asc");
+		return dao.queryForListMap(sql.toString(),mountId,startDate,endDate);
+	}
+	
+	
+	/**
+	 * 油量异常数据监控查询
+	 * @param args
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> queryOilException(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select g.assist_code,g.org_name belong_org_name,t.car_num,t.custom_num,t.device_model,t.device_name,t.discard_if,");
+		sql.append(" oil_type,m.box_num,c.*");
+		sql.append(" from t_oil_change c inner join t_car t on c.car_id=t.car_id");
+		sql.append(" left join t_oil_meter m on c.mount_id=m.record_id");
+		sql.append(" left join t_org g on t.belong_org=g.org_id ");
+		sql.append(" ) tab where discard_if=0 ");
+		
+		sql.append(" and DATE_FORMAT(data_time,'%Y-%m-%d %T') between ? and ?");
+		sqlParams.add(args.get("startDate"));
+		sqlParams.add(args.get("endDate"));
+		
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("carOrCustomNum"))){
+			sql.append(" and (car_num like ? or custom_num like ?)");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+		}
+		
+		if(authAssistCodes!=null){ //权限过滤  单位assistCode
+			sql.append(getPartSQL(authAssistCodes,sqlParams));
+		}
+		//客户端指定排序规则
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("sortField"))){
+			String sortField=FieldAttrConverter.getFieldName((String)args.get("sortField"));
+			sql.append(" order by "+sortField+" "+(args.get("sortAction")==null?"asc":args.get("sortAction")));
+		}
+		else{
+			sql.append(" order by data_time desc,custom_num,car_num");
+		}
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	private String getPartSQL(Set<String> authAssistCodes,List<Object> sqlParams){
+		StringBuilder sql=new StringBuilder();
+		for(String c : authAssistCodes){
+			sql.append("or assist_code like ?");
+			sqlParams.add(c+"%");
+		}
+		return "and ("+sql.substring(2)+")";
+	}
+	
+	public PageModel<Map<String,Object>>  queryOilMonitorRpt(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select m.box_num,box_name,r.*,t.car_num,t.custom_num,t.device_model,t.device_name,t.oil_type,consume.rpt_volume,(IFNULL(consume.rpt_volume,0)-IFNULL(add_volume,0)) diff_volume,g.org_name belong_org_name,g.assist_code ");
+		sql.append(" from t_oil_monitor_report r ");
+		sql.append(" left join t_oil_meter m on r.mount_id=m.record_id");
+		sql.append(" inner join t_car t on m.belong_car_id=t.car_id and t.discard_if=0");
+		sql.append(" left join t_oil_box box on m.box_id=box.record_id");
+		sql.append(" left join t_org g on t.belong_org=g.org_id ");
+		sql.append(" left join (");
+		sql.append(" select  car_id,IFNULL(oil_erp,0)+IFNULL(oil_kl,0)+IFNULL(coil_erp,0)+IFNULL(coil_kl,0) rpt_volume");
+		sql.append(" from t_car_consume c where  DATE_FORMAT(rpt_date,'%Y-%m')=? ");
+		sql.append(" ) consume on r.car_id=consume.car_id");
+		sql.append(" ) rpt where rpt_month=? ");
+		
+		sqlParams.add(args.get("rptMonth"));
+		sqlParams.add(args.get("rptMonth"));
+		
+		
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("carKey"))){
+			sql.append(" and (car_num like ? or custom_num like ?)");
+			sqlParams.add("%"+args.get("carKey")+"%");
+			sqlParams.add("%"+args.get("carKey")+"%");
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("belongOrg"))){  //入参belongOrg为assistCode
+			sql.append(" and assist_code like ?");
+			sqlParams.add(args.get("belongOrg")+"%");
+		}
+		if(authAssistCodes!=null){ //权限过滤  单位assistCode
+			sql.append(getPartSQL(authAssistCodes,sqlParams));
+		}
+		//客户端指定排序规则
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("sortField"))){
+			String sortField=FieldAttrConverter.getFieldName((String)args.get("sortField"));
+			sql.append(" order by "+sortField+" "+(args.get("sortAction")==null?"asc":args.get("sortAction")));
+		}
+		else{
+			sql.append(" order by custom_num asc,box_num asc");
+		}				
+		
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlParams.toArray());
+	}
+	
+	/**
+	 * 查询指定车辆的油量监控统计,用于单车油耗统计报表(安全科用),用月初、月终余油计算耗油
+	 * @param carIds
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public Map<String,Map<String,Object>> loadCarMonitorRpt(Set<String> carIds,String startMonth,String endMonth){
+		String carIdstr="'"+StringUtils.join(carIds, "','")+"'";
+		StringBuilder sql=new StringBuilder();
+		List<Map<String,Object>>  rst=null;
+		if(startMonth.equals(endMonth)){
+			sql.append("select car_id,start_volume,end_volume ");
+			sql.append("from t_oil_monitor_report r  where r.car_id in ("+carIdstr+") and rpt_month=? ");
+			rst=dao.queryForListMap(sql.toString(),endMonth);
+		}
+		else{
+			sql.append("select t1.car_id,start_volume,end_volume from ( ");
+			sql.append("select car_id,start_volume from t_oil_monitor_report r ");
+			sql.append("where r.car_id in ("+carIdstr+") and rpt_month=? ");
+			sql.append(") t1 ");
+			sql.append("inner join( ");
+			sql.append("select car_id,end_volume from t_oil_monitor_report r ");
+			sql.append("where r.car_id in ("+carIdstr+") and rpt_month=? ");
+			sql.append(") t2  on t1.car_id=t2.car_id ");
+			
+			rst= dao.queryForListMap(sql.toString(), startMonth,endMonth);
+		}
+		
+		if(rst==null||rst.size()==0){
+			return null;
+		}
+		Map<String,Map<String,Object>>  mapping=new HashMap<String,Map<String,Object>>(rst.size());
+		for(Map<String,Object> itm : rst){
+			mapping.put((String)itm.get("carId"), itm);
+		}
+		
+		return mapping;
+	}
+	
+	/**
+	 * 查找实际加油记录对应的测量加油记录
+	 * @param log
+	 * @return
+	 */
+	public List<OilChangeBO>  loadCarOilAdd(OilAddLog log){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append(" select m.box_num,c.* from t_oil_change c ");
+		sql.append(" left join t_oil_meter m on c.mount_id=m.record_id");
+		sql.append(" where c.car_id=? and date_format(c.data_time,'%Y-%m-%d')=date_format(?,'%Y-%m-%d') and diff_volume>0");
+		return dao.queryForListPojo(sql.toString(), OilChangeBO.class, log.getCarId(),log.getAddTime());
+	}
+	
+	public OilChangeBO  getOilChange(String id){
+		String sql="select * from t_oil_change where id=?";
+		return dao.queryForObject(sql, OilChangeBO.class, id);
+	}
+}

+ 134 - 0
src/main/java/com/hb/proj/car/service/CarRptService.java

@@ -0,0 +1,134 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.CarConsumeRptVO;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.FieldAttrConverter;
+
+@Service
+public class CarRptService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	
+	
+
+	/**
+	 * 查询车辆油耗明细记录(野外时长直接取用,录入时做月份限制即可)
+	 * 可能查询还需要根据投产月份,统计月份分开查询,涉及到使用年数的计算(如百公里定额),目前:sql语句中计算出已使用年数,并按年数分组
+	 * 使用年限的计算,和人年龄一样,只要月份是超过投产月份的就认为是进入下一年的。
+	 * 由于在上报数据是就会计算。所以此时不需要计算。直接分组求和即可(除了实际单耗要重新计算)
+	 * @param startMonth
+	 * @param endMonth
+	 * @param orgAssistCode
+	 * @param deviceKey
+	 * @param sortField
+	 * @param sortType
+	 * @return
+	 */
+	public List<CarConsumeRptVO>  loadCarConsumeDtl(String startMonth,String endMonth,String orgAssistCode,String deviceKey,String sortField,String sortType){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select c.car_num,c.device_name,c.device_model,c.work_start,c.oil_type,cg.org_name,oil.* ");
+		sql.append(" from t_car c ");
+		
+		sql.append(" inner join (  ");
+		
+		sql.append("select car_id,group_concat(distinct d.code_name) work_area,max(custom_num) custom_num,sum(travel_mile) travel_mile,sum(work_hour) work_hour,sum(engine_work_hour) engine_work_hour,sum(out_hour) out_hour,  ");
+		sql.append("sum(coil_zsh) coil_zsh,sum(coil_meter_kg) coil_meter_kg,sum(oil_meter_kg) oil_meter_kg,sum(oil_erp) oil_erp,sum(oil_kl) oil_kl,sum(coil_erp) coil_erp,sum(coil_kl) coil_kl, ");
+		sql.append("sum(check_mile) check_mile,group_concat(distinct quota_per100km) union_quota_per100km,max(real_cost_per100km) real_cost_per100km,sum(oil_real_cost) oil_real_cost,sum(coil_real_cost) coil_real_cost, ");
+		sql.append("sum(oil_total_quota) oil_total_quota,sum(coil_total_quota) coil_total_quota ,sum(work_cost) work_cost,sum(out_cost) out_cost,sum(engine_cost) engine_cost ");
+		
+		sql.append(" from t_car_consume s ");
+		sql.append(" left join t_org g on s.rpt_org=g.org_id");
+		sql.append(" left join t_sort_code d on s.work_area=d.code_id");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y-%m') between ? and ?   and   g.assist_code like ? ");
+		
+		sql.append(" group by car_id");
+		
+		
+		
+		sql.append(" )  oil  on c.car_id=oil.car_id ");
+		
+		sql.append(" left join t_org  cg on c.belong_org=cg.org_id");
+		
+		sql.append(" where 1=1 ");
+		
+		params.add(startMonth);
+		params.add(endMonth);
+		params.add(orgAssistCode+"%");
+		
+		if(StringUtils.isNotEmpty(deviceKey)){
+			String[] dns=deviceKey.split("[,,;;\\-~\\|\\s]+");
+			if(dns.length>1){ //两个参数
+				sql.append(" and ((device_name like ?  and device_model like ?) or (device_name like ?  and device_model like ?))");
+				params.add("%"+dns[0]+"%");
+				params.add("%"+dns[1]+"%");
+				params.add("%"+dns[1]+"%");
+				params.add("%"+dns[0]+"%");
+			}
+			else{
+				sql.append(" and (device_name like ? or device_model like ?)");
+				params.add("%"+dns[0]+"%");
+				params.add("%"+dns[0]+"%");
+			}
+		}
+		
+		if(StringUtils.isNotEmpty(sortField)){
+			sql.append(" order by "+FieldAttrConverter.getFieldName(sortField)+" "+(StringUtils.isEmpty(sortType)?"":sortType));
+		}
+		else{
+			sql.append(" order by cg.display_num,custom_num,car_num");
+		}
+		
+		
+		
+		return dao.queryForListPojo(sql.toString(),CarConsumeRptVO.class, params.toArray());
+	}
+	
+	/**
+	 * 按车型统计油耗。直接按车型分组求和即可
+	 * @param startMonth
+	 * @param endMonth
+	 * @param orgAssistCode
+	 * @return
+	 */
+	public List<CarConsume>  loadCarTypeConsume(String startMonth,String endMonth,String orgAssistCode){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("select device_name,sum(travel_mile) travel_mile,sum(work_hour) work_hour,sum(engine_work_hour) engine_work_hour,sum(out_hour) out_hour,  ");
+		sql.append("sum(coil_zsh) coil_zsh,sum(coil_meter) coil_meter,sum(oil_meter) oil_meter,sum(oil_erp) oil_erp,sum(oil_kl) oil_kl,sum(coil_erp) coil_erp,sum(coil_kl) coil_kl, ");
+		sql.append("sum(check_mile) check_mile,sum(oil_real_cost) oil_real_cost,sum(coil_real_cost) coil_real_cost,sum(oil_total_quota) oil_total_quota,sum(coil_total_quota) coil_total_quota ");
+		
+		sql.append(" from t_car c  left join t_car_consume s on c.car_id=s.car_id and DATE_FORMAT(s.rpt_date,'%Y-%m') between ? and ?");
+		sql.append(" left join t_org g on s.rpt_org=g.org_id");
+		sql.append(" where  g.assist_code like ?");
+		sql.append(" group by device_name");
+		
+		sql.append(" order by device_name");
+		
+		params.add(startMonth);
+		params.add(endMonth);
+		params.add(orgAssistCode+"%");
+		return dao.queryForListPojo(sql.toString(),CarConsume.class, params.toArray());
+	}
+	
+
+	
+
+	
+	
+	
+	
+	
+
+}

+ 285 - 0
src/main/java/com/hb/proj/car/service/CarRptUtils.java

@@ -0,0 +1,285 @@
+package com.hb.proj.car.service;
+
+import java.text.DecimalFormat;
+import java.util.List;
+
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+import com.hb.proj.model.CarConsume;
+import com.hb.xframework.util.DateUtil;
+
+public class CarRptUtils {
+
+	
+	
+	/**
+	 * oilWeightRatio 带权重的汽油折算系数
+	 * @param car
+	 * @param oilWeightRatio
+	 */
+	public static void rptCalculate(CarConsume car,Double oilWeightRatio){
+		if(car.getRealAge()==null){  //初始数据可能车还未输入投产日期,无法计算使用年数
+			return;
+		}
+		/*if(car.getRealAge()>20){ //车辆使用年限超过20年的都按20年计算取定额数值
+			car.setRealAge(20);
+		}*/
+		//CarContext  carContext=new CarContext(car.getDeviceName(),car.getDeviceModel(),car.getRealAge()); 
+		//车辆和定额标准的关联采用新的方式2021-10
+		CarContext  carContext=new CarContext(car.getQuotaRuleId(),car.getQuotaAlternatorId(),car.getWorkArea(),DateUtil.format(car.getRptDate(), "MM"));
+		carContext.setDeviceName(car.getDeviceName()); //2021.11.11 新百公里定额中的上浮规则(固定月份上浮)中,需要为指定车型
+		carContext.setWorkYear(car.getRealAge()); //2021.11.15 新百公里定额中的上浮规则(根据使用年限上浮)
+		QuotaStandardSupport.fillCarQuota(carContext);
+		calculate(car,carContext,oilWeightRatio);
+	}
+	
+	
+	/**
+	 * 计算实际单耗.跨月统计时不能是实际单耗的相加,应重新按公式计算
+	 * @param car
+	 */
+	public static void calculateRealCostPer100km(List<? extends CarConsume>  cars){
+		if(cars==null||cars.size()==0){
+			return;
+		}
+		Double realCost=null;
+		for(CarConsume car :  cars){
+			realCost="汽油".equals(car.getOilType())?car.getOilRealCost():car.getCoilRealCost(); //单位kg
+			
+			if(realCost!=null&&car.getCheckMile()!=null&&car.getCheckMile()>0){
+				realCost=getLfromKg(realCost,car.getOilType());
+				car.setRealCostPer100km(realCost*100/car.getCheckMile());
+				if(Double.isNaN(car.getRealCostPer100km())){
+					car.setRealCostPer100km(0.0);
+				}
+				car.setRealCostPer100km(formatVal(car.getRealCostPer100km()));
+			}
+		}
+		
+				
+	}
+	
+	
+	/**
+	 * 计算定额总量(定额标准*里程(工作小时))和考核里程
+	 * 行驶里程/100*百公里定额+作业小时*作业定额+发动机工作小时*发动机定额+野外小时*野外定额
+	 * 
+	 * 考核里程是行驶里程+(作业小时耗油+野外小时耗油+发动机耗油)*100/定额单耗
+	 * 
+	 * 实际单耗:实际百公里消耗量=实际消耗量(kg)、折算系数-》转实际消耗(升)*100/考核里程
+	 * 数据录入使用的单位升,报表中会转成kg
+	 * 没有  汽柴油混用的车
+	 * 
+	 * 对于计算字段数据,每次都应计算一次。避免使用旧数据入库
+	 */
+	public static void calculate(CarConsume car,CarContext  carContext,Double oilWeightRatio){
+		
+		car.setQuotaPer100km(carContext.getTravalQuota());
+		//car.setOilMeter(getKgFromL(car.getOilMeter(),"汽油"));  //从库中取出的是升,转为kg
+		//car.setCoilMeter(getKgFromL(car.getCoilMeter(),"柴油"));  //从库中取出的是升,转为kg
+		
+		if(car.getOilType()==null){
+			car.setOilType("汽油");
+		}
+		
+		double totalQuota=0;
+		
+		car.setWorkCost(car.getWorkHour()!=null?(car.getWorkHour()*carContext.getWorkQuota()):null);
+		car.setEngineCost(car.getEngineWorkHour()!=null?(car.getEngineWorkHour()*carContext.getEngineQuota()):null);
+		car.setOutCost(car.getOutHour()!=null?(car.getOutHour()*carContext.getOuterQuota()):null);
+		
+		//发动机耗油kg 默认发动机为柴油
+		if(car.getEngineCost()!=null){
+			car.setEngineCostKg(getKgFromL(car.getEngineCost(),"柴油",null));
+		}
+		
+		totalQuota+=car.getWorkCost()!=null?car.getWorkCost():0;
+		totalQuota+=car.getEngineCost()!=null?car.getEngineCost():0;
+		totalQuota+=car.getOutCost()!=null?car.getOutCost():0;
+		
+		double checkMile=totalQuota*100/carContext.getTravalQuota();
+		if(Double.isNaN(checkMile)||Double.isInfinite(checkMile)){
+			checkMile=0;
+		}
+		
+		if(car.getTravelMile()!=null){
+			totalQuota+=car.getTravelMile()*carContext.getTravalQuota()/100.0;
+		}
+		
+		totalQuota=getKgFromL(totalQuota,car.getOilType(),oilWeightRatio) ; //升转为kg
+		
+		if("汽油".equals(car.getOilType())){
+			car.setOilTotalQuota(formatVal(totalQuota));
+		}
+		else{
+			car.setCoilTotalQuota(formatVal(totalQuota));
+		}
+		//考核里程
+		car.setCheckMile(checkMile+(car.getTravelMile()!=null?car.getTravelMile():0));
+		
+		car.setCheckMile(formatVal(car.getCheckMile()));
+		
+		
+		
+		//实际单耗
+		//实际耗量=erp(升-转公斤)+昆仑(公斤)
+		Double realCost=null,realCostLiter=null; //单位公斤,升
+		if("汽油".equals(car.getOilType())){
+			car.setOilErpKg(getKgFromL(car.getOilErp(),car.getOilType(),oilWeightRatio)); //erp 升转为 kg
+			car.setOilKlKg(getKgFromL(car.getOilKl(),car.getOilType(),oilWeightRatio)); //昆仑卡 升转为 kg 
+			
+			realCost=addDouble(car.getOilErpKg(),car.getOilKlKg());
+			car.setOilRealCost(realCost);
+			
+			realCostLiter=addDouble(car.getOilErp(),car.getOilKl());
+			
+			car.setOilMeterKg(getKgFromL(car.getOilMeter(),car.getOilType(),oilWeightRatio));
+			car.setOilCoal(toCoal(car.getOilRealCost(),car.getOilType()));  //转为标准吨煤
+		}
+		else{
+			car.setCoilErpKg(getKgFromL(car.getCoilErp(),car.getOilType(),null)); //erp 升转为 kg
+			car.setCoilKlKg(getKgFromL(car.getCoilKl(),car.getOilType(),null));  //昆仑卡 升转为 kg 
+			
+			
+			realCost=addDouble(car.getCoilErpKg(),car.getCoilKlKg()); //中石化柴油不参与统计  +getVal(car.getCoilZsh()
+			car.setCoilRealCost(realCost);
+			
+			realCostLiter=addDouble(car.getCoilErp(),car.getCoilKl());
+			
+			car.setCoilMeterKg(getKgFromL(car.getCoilMeter(),car.getOilType(),null));
+			car.setCoilCoal(toCoal(car.getCoilRealCost(),car.getOilType()));  //转为标准吨煤
+			
+		}
+		if(realCostLiter!=null&&car.getCheckMile()!=null&&car.getCheckMile()>0){ //公里数可能为0,影响后面处理
+			car.setRealCostPer100km(realCostLiter*100/car.getCheckMile());
+			if(Double.isNaN(car.getRealCostPer100km())){
+				car.setRealCostPer100km(0.0);
+			}
+			car.setRealCostPer100km(formatVal(car.getRealCostPer100km()));
+		}
+		else{
+			car.setRealCostPer100km(null);
+		}
+		
+	}
+	
+	
+	private static double formatVal(double data){
+		if(Double.isNaN(data)){
+			return data;
+		}
+		DecimalFormat df=new DecimalFormat("#0.00");
+		return Double.parseDouble(df.format(data));
+	}
+	
+	/*private static double getVal(Double data){
+		return data==null?0:data.doubleValue();
+	}*/
+	
+	/**
+	 * 指定了折算系数的用指定的,否则用默认的
+	 * @param data
+	 * @param oilType
+	 * @param oilWeightRatio
+	 * @return
+	 */
+	public static double getKgFromL(Double data,String oilType,Double oilWeightRatio){
+		if(data==null){
+			return 0;
+		}
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		if("汽油".equals(oilType)){
+			return oilWeightRatio!=null?(data*oilWeightRatio.doubleValue()):(data*qc.getOilRatio());   //默认92号
+		}
+		else{
+			return data*qc.getCoilRatio();
+		}
+	}
+	
+	
+	//获得带权重(92#:95#)的汽油折算系数---加权值
+	public static double getOilWeightRatio(Double oil92,Double oil95){
+		if(oil92==null){
+			oil92=0.0;
+		}
+		if(oil95==null){
+			oil95=0.0;
+		}
+		if(oil92==0&&oil95==0){
+			return 1;
+		}
+		double w92=oil92/(oil92+oil95),w95=oil95/(oil92+oil95);  //计算权重
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		return qc.getOilRatio()*w92+qc.getOilRatio95()*w95;
+	}
+	
+	public static double getLfromKg(Double data,String oilType){
+		if(data==null){
+			return 0;
+		}
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		if("汽油".equals(oilType)){
+			return data/qc.getOilRatio();
+		}
+		else{
+			return data/qc.getCoilRatio();
+		}
+	}
+	
+	private static double toCoal(Double data,String oilType){
+		if(data==null){
+			return 0;
+		}
+		QuotaConfig config=QuotaStandardSupport.getConfig();
+		if("汽油".equals(oilType)){
+			return data*config.getOilCoalRatio()/1000.0;
+		}
+		else{
+			return data*config.getCoilCoalRatio()/1000.0;
+		}
+	}
+	
+	
+	public static void sumConsume(CarConsume main,CarConsume extra){
+		//考核里程,行驶里程
+		main.setCheckMile(addDouble(main.getCheckMile(),extra.getCheckMile()));
+		main.setTravelMile(addDouble(main.getTravelMile(),extra.getTravelMile()));
+		main.setWorkHour(addInteger(main.getWorkHour(),extra.getWorkHour()));
+		main.setOutHour(addInteger(main.getOutHour(),extra.getOutHour()));
+		main.setEngineWorkHour(addDouble(main.getEngineWorkHour(),extra.getEngineWorkHour()));
+		main.setOilTotalQuota(addDouble(main.getOilTotalQuota(),extra.getOilTotalQuota()));
+		main.setCoilTotalQuota(addDouble(main.getCoilTotalQuota(),extra.getCoilTotalQuota()));
+		main.setOilRealCost(addDouble(main.getOilRealCost(),extra.getOilRealCost()));
+		main.setCoilRealCost(addDouble(main.getCoilRealCost(),extra.getCoilRealCost()));
+		main.setOilMeter(addDouble(main.getOilMeter(),extra.getOilMeter()));
+		main.setCoilMeter(addDouble(main.getCoilMeter(),extra.getCoilMeter()));
+		main.setOilMeterKg(addDouble(main.getOilMeterKg(),extra.getOilMeterKg()));
+		main.setCoilMeterKg(addDouble(main.getCoilMeterKg(),extra.getCoilMeterKg()));
+	}
+	
+	public static Double addDouble(Double d1,Double d2){
+		if(d2==null||Double.isNaN(d2)){
+			return d1!=null?d1.doubleValue():null;
+		}
+		if(d1==null||Double.isNaN(d1)){
+			return d2!=null?d2.doubleValue():null;
+		}
+		else{
+			return d1.doubleValue()+d2.doubleValue();
+		}
+	}
+	
+	public static Integer addInteger(Integer t1,Integer t2){
+		if(t2==null){
+			return t1;
+		}
+		if(t1==null){
+			t1=t2;
+		}
+		else{
+			t1=t1.intValue()+t2.intValue();
+		}
+		return t1;
+	}
+	
+}

+ 425 - 0
src/main/java/com/hb/proj/car/service/CarService.java

@@ -0,0 +1,425 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.car.quota.QuotaType;
+import com.hb.proj.input.controller.InputDateLimit;
+import com.hb.proj.utils.CodeConstant;
+import com.hb.proj.utils.RptMonthUtil;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.FieldAttrConverter;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+/**
+ * loadCarObjMapping,loadCarForInput  两个方法分别用于导入数据车辆数据转换、通过界面上报 时,
+ * 加载车辆基本信息(oil_type,device_name,quota_rule_id,quota_alternator_id)这些信息是必要信息设计定额的相关计算
+ * 且已定额表的数据为准,车辆信息表中的对应数据不再使用
+ * @author hb
+ *
+ */
+@Service
+public class CarService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 分类统计车辆数量:汽油车、柴油车、报废车
+	 * @param orgAssistCode
+	 * @return
+	 */
+	public Map<String,Object> rptCarCount(String orgAssistCode){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(300);
+		sql.append("select type,count(1) car_count from ( ");
+		sql.append(" select (case when c.oil_type='汽油' and c.discard_if=0 then 'oil'  when c.oil_type='柴油' and c.discard_if=0 then 'coil' ");
+		sql.append(" when c.discard_if=1 then 'discard' end) type ");
+		sql.append(" from t_car c ");
+		if(StringUtils.isNotEmpty(orgAssistCode)){
+			sql.append(" where exists (select org_id from t_org g2 where g2.org_id=c.belong_org and g2.assist_code like ?) ");
+			sqlParams.add(orgAssistCode+"%");
+		}
+		sql.append(" )tab group by type ");
+		return dao.queryForMapping(sql.toString(), "type", "car_count", sqlParams.size()>0?sqlParams.toArray():null);
+	}
+	
+	public PageModel<Map<String,Object>> queryCar(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		boolean showAll=args!=null&&"1".equals(args.get("showAll")) ;//是否明确显示全部含报废车辆
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select g.assist_code,g.org_name belong_org_name,d1.code_name coil_car_type_name, DATE_FORMAT(work_start,'%Y-%m') wk_start,");
+		sql.append(" t.car_num,t.custom_num,t.car_id,t.discard_if,");
+		sql.append(" r.oil_type,r.device_name,r.device_model,r.quota_power,r2.device_model alternator_model_name");
+		sql.append(" from t_car t ");
+		sql.append(" left join t_org g on t.belong_org=g.org_id ");
+		sql.append(" left join t_sort_code d1 on t.coil_car_type=d1.code_id ");
+		//sql.append(" left join t_oil_box b on t.oil_box_id=b.record_id");
+		sql.append(" left join t_quota_rule r on t.quota_rule_id=r.record_id");
+		sql.append(" left join t_quota_rule r2 on t.quota_alternator_id=r2.record_id and r2.quota_type='车载发电机每小时耗油'");
+		sql.append(" ) tab where 1=1 ");
+		if(!showAll){ //并非显示全部,则去掉报废车
+			sql.append(" and discard_if=0  ");
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("deviceKey"))){
+			String[] dns=((String)args.get("deviceKey")).split("[,,;;\\-~\\|\\s]+");
+			if(dns.length>1){ //两个参数
+				sql.append(" and ((device_name like ?  and device_model like ?) or (device_name like ?  and device_model like ?))");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+			else{
+				sql.append(" and (device_name like ? or device_model like ?)");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("carOrCustomNum"))){
+			sql.append(" and (car_num like ? or custom_num like ?)");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("belongOrg"))){  //入参belongOrg为assistCode
+			sql.append(" and assist_code like ?");
+			sqlParams.add(args.get("belongOrg")+"%");
+		}
+		if(authAssistCodes!=null){ //权限过滤  单位assistCode
+			sql.append(getPartSQL(authAssistCodes,sqlParams));
+		}
+		//客户端指定排序规则
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("sortField"))){
+			String sortField=FieldAttrConverter.getFieldName((String)args.get("sortField"));
+			sql.append(" order by "+sortField+" "+(args.get("sortAction")==null?"asc":args.get("sortAction")));
+		}
+		else{
+			sql.append(" order by custom_num,car_num");
+		}
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	/**
+	 * 获取可以上报的车辆(上报月份内没有报废或报废时间在上报月份内或之后;
+	 * 转入时间<inputMonth+1
+	 * 转出时间>=inputMonth
+	 * )
+	 * 用于上报界面、上报模板生成
+	 * 2020.11.2最新要求:当月报废当月就不再出现
+	 * 2021.10.28 按统计月份的划分日期进行判断(默认16号,已实际配置为准)
+	 * (定额计算设计到:quota_alternator_id,quota_rule_id,device_name,oil_type 这些信息以定额标准表中的为准)
+	 * 
+	 * @param carOrCustomNum
+	 * @param inputMonth
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> loadCarForInput(String carOrCustomNum,String inputMonth,Set<String> authAssistCodes,int pageNo,int pageSize){
+		
+		Date[] rst=InputDateLimit.getStartEndInRptMonth(inputMonth);
+		
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(300);
+		sql.append("select DATE_FORMAT(work_start,'%Y-%m') wk_start,tab.custom_num,car.car_num,car.car_id,r.oil_type,r.device_name,r.device_model, "); //select 后的字段为必要内容不能删减
+		sql.append(" car.quota_alternator_id,car.quota_rule_id");
+		sql.append(" from(");
+		sql.append(" select distinct car_id,custom_num from t_car_transfer  t1 ");
+		sql.append(" left join t_org g on t1.belong_org=g.org_id ");
+		sql.append(" where DATE_FORMAT(start_date,'%Y-%m-%d')<?  and (end_date is null or DATE_FORMAT(end_date,'%Y-%m-%d')>=?) ");
+		
+		sqlParams.add(DateUtil.format(rst[1], "yyyy-MM-dd"));
+		sqlParams.add(DateUtil.format(rst[0], "yyyy-MM-dd"));
+		
+		sql.append(getPartSQL(authAssistCodes,sqlParams));
+		sql.append(" ) tab ");
+		
+		sql.append(" inner join t_car car  on tab.car_id=car.car_id");
+		sql.append(" left join t_quota_rule r on car.quota_rule_id=r.record_id");
+		sql.append(" where (discard_if=0 or (discard_if=1 and DATE_FORMAT(discard_time,'%Y-%m')>?)) ") ; //在上报月份内非报废或者报废时间在上报月份之后
+		
+		sqlParams.add(inputMonth);
+		
+		
+		
+		if(StringUtils.isNotEmpty(carOrCustomNum)){
+			sql.append(" and (car_num like ? or tab.custom_num like ?)");
+			sqlParams.add("%"+carOrCustomNum+"%");
+			sqlParams.add("%"+carOrCustomNum+"%");
+		}
+		
+		
+		sql.append(" order by custom_num,car_num");
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	private String getPartSQL(Set<String> authAssistCodes,List<Object> sqlParams){
+		StringBuilder sql=new StringBuilder();
+		for(String c : authAssistCodes){
+			sql.append("or assist_code like ?");
+			sqlParams.add(c+"%");
+		}
+		return "and ("+sql.substring(2)+")";
+	}
+	
+	public Map<String, Object> getCar(String carId) {
+		StringBuilder sql=new StringBuilder();
+		sql.append("select t.*,g.org_name belong_org_name,");
+		sql.append(" t.car_num,t.custom_num,t.oil_type,t.car_id,");
+		sql.append(" r.device_name,r.device_model,r.quota_power");
+		sql.append(" from t_car t");
+		sql.append(" left join t_org g on t.belong_org=g.org_id");
+		sql.append(" left join t_quota_rule r on t.quota_rule_id=r.record_id");
+		sql.append(" where t.car_id=?");
+		return dao.queryForSingleMap(sql.toString(), carId);
+	}
+	
+	public boolean addCar(Map<String, Object> car) {
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		car.put("carId", uuid.generate());
+		car.put("createTime", new Date());
+		car.put("modifyTime", new Date());
+		dao.insert(car,"t_car");
+		
+		addCarTransfer(car,true);
+		return true;
+	}
+	
+	public boolean updateCar(Map<String, Object> car) {
+		car.put("modifyTime", new Date());
+		dao.update(car,"t_car","car_id");
+		addCarTransfer(car,false);
+		return true;
+	}
+
+	public boolean deleteCar(String carId) {
+		String sql="delete from t_car  where car_id=?";
+		dao.getJdbcTemplate().update(sql,carId);
+		return true;
+	}
+	
+	public boolean updateForDiscard(String carId,String discard) {
+		String sql=null;
+		if("1".equals(discard)){  //报废标记
+			sql="update t_car set discard_if=?,discard_time=?,modify_time=? where car_id=?";
+			dao.getJdbcTemplate().update(sql,discard,new Date(),new Date(),carId);
+		}
+		else if("0".equals(discard)){ //恢复使用
+			sql="update t_car set discard_if=?,discard_time=?,modify_time=? where car_id=?";
+			dao.getJdbcTemplate().update(sql,discard,null,new Date(),carId);
+		}
+		
+		return true;
+	}
+	
+	
+	public boolean existsCar(String carNum,String carId){
+		Map<String,Object> rst=null;
+		String sql="select t.* from t_car t  where car_num=? and car_id!=?";
+		if(StringUtils.isEmpty(carId)){
+			sql="select t.* from t_car t  where car_num=?";
+			rst=dao.queryForSingleMap(sql, carNum);
+		}
+		else{
+			rst=dao.queryForSingleMap(sql, carNum,carId);
+		}
+		return rst!=null&&rst.size()>0;
+	}
+	
+	/**
+	 * 检测自编号是否已占用(报废车辆的自编号可以重复使用)
+	 * @param customNum
+	 * @param carNum
+	 * @return
+	 */
+	public boolean existsCustomNum(String customNum,String carNum){
+		String sql="select t.* from t_car t  where custom_num=? and car_num!=? and discard_if=0";
+		Map<String,Object> rst=dao.queryForSingleMap(sql, customNum,carNum);
+		return rst!=null&&rst.size()>0;
+	}
+	
+	
+	public Map<String,Object> loadCarDeviceNameMapping(){
+		String sql="select device_name,device_model from t_quota_standard where quota_type=?";
+		return dao.queryForMapping(sql, "device_name", "device_model",QuotaType.TRAVEL.getName());
+	}
+	
+	
+	/**
+	 * 导入车辆数据
+	 * @param newCars
+	 * @param carNums 本次导入的车辆车牌号
+	 * @param sameCover 是否覆盖同车记录
+	 */
+	public String addCars(List<Map<String,Object>> newCars,String carNums,boolean sameCover){
+		if(newCars==null||newCars.size()==0){
+			return null;
+		}
+		carNums="'"+carNums.replaceAll(",", "','")+"'";
+		StringBuilder sameIgnor=new StringBuilder();
+		if(sameCover){
+			dao.getJdbcTemplate().update("delete from t_car where car_num in("+carNums+")");
+			dao.batchInsert(newCars,"t_car");
+		}
+		else{
+			Map<String,Object>  dbCars=dao.queryForMapping("select car_num,car_id from t_car where car_num in("+carNums+")", "car_num", "car_id");
+			if(dbCars==null||dbCars.size()==0){
+				dao.batchInsert(newCars,"t_car");
+				
+			}
+			else{
+				String dbCarNums=StringUtils.join(dbCars.keySet(),",");
+				Iterator<Map<String,Object>> iterator=newCars.iterator();
+				String carNum=null;
+				while(iterator.hasNext()){
+					carNum=(String)iterator.next().get("carNum");
+					if(dbCarNums.indexOf(carNum)>=0){
+						sameIgnor.append(carNum+";");
+						iterator.remove();
+					}
+				}
+				if(newCars.size()>0){
+					dao.batchInsert(newCars,"t_car");
+				}
+			}
+			
+			
+			
+		}
+		if(newCars.size()>0){
+			for(Map<String,Object> car : newCars){
+				addCarTransfer(car,false);
+			}
+		}
+		return sameIgnor.length()>0?sameIgnor.toString():null;
+	}
+	
+	
+	public Map<String,Object>  loadCarMapping(){
+		String sql="select car_num,car_id from t_car";
+		return dao.queryForMapping(sql, "car_num", "car_id");
+	}
+	
+	
+	//导入时将车牌映射为系统内车辆信息(定额计算设计到:quota_alternator_id,quota_rule_id,device_name,oil_type)
+	//这些信息以定额标准表中的为准
+	public Map<String,Object>  loadCarObjMapping(){
+		String sql="select t.car_num,t.car_id,t.work_start,t.quota_alternator_id,t.quota_rule_id,r.oil_type,r.device_model,r.device_name from t_car t left join t_quota_rule r on t.quota_rule_id=r.record_id";
+		List<Map<String,Object>>  cars=dao.queryForListMap(sql);
+		if(cars==null||cars.size()==0){
+			return null;
+		}
+		Map<String,Object>  mapping=new HashMap<String,Object>();
+		for(Map<String,Object> itm : cars){
+			mapping.put((String)itm.get("carNum"), itm);
+		}
+		return mapping;
+	}
+	
+	/**
+	 * 记录车辆的流转日志
+	 * @param car
+	 */
+	public void addCarTransfer(Map<String, Object> car,boolean newCar){
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		Map<String,Object> transfer=MapUtils.clone(car, "carId","modifier","modifyTime","belongOrg","customNum");
+		transfer.put("startDate", new Date());
+		transfer.put("recordId", uuid.generate());
+		transfer.put("transferDate", new Date()); //实际流转时间
+		if(newCar){ //新增车辆直接增加流转日志
+			dao.insert(transfer,"t_car_transfer");
+			return;
+		}
+		//通过流转记录判断单位是否改变(因为数据可能来源于导入数据,无法提前判断)
+		String sql="select record_id,car_id,belong_org,custom_num from t_car_transfer where car_id=? and end_date is null order by modify_time desc limit 1";
+		Map<String,Object> rst=dao.queryForSingleMap(sql, transfer.get("carId"));
+		
+		if(rst==null||rst.size()==0){  //不是新车却找不到历史流转,当作新车直接增加流转日志
+			dao.insert(transfer,"t_car_transfer");
+			return;
+		}
+		
+		if(!(transfer.get("belongOrg").equals(rst.get("belongOrg")))){ //车辆最新所属单位发生改变,才记录(同时也会记录当前的customNum)
+			//部门间流转,为使流转当月车辆在前后两个部门可见,人为指定流转生效时间为当月15号,2021-11-25
+			//统计月划分日改为可配置的,不能再固定为15号,而是配置日期-1 提前一天 2022-4-6;
+			int mthday=RptMonthUtil.getMonthSplitDay();
+			Calendar ca=Calendar.getInstance();
+			ca.set(Calendar.DAY_OF_MONTH, mthday-1);
+			sql="update t_car_transfer  set  end_date=?,modifier=?,modify_time=sysdate(),transfer_date=sysdate() where record_id=?";
+			dao.getJdbcTemplate().update(sql,ca.getTime(),transfer.get("modifier"),rst.get("recordId"));
+			
+			
+			transfer.put("startDate", ca.getTime());
+			transfer.put("modifyTime", new Date());
+			dao.insert(transfer,"t_car_transfer");
+			
+			return;
+		}
+		else if(!(transfer.get("customNum").equals(rst.get("customNum")))){ //与历史记录中的最新自编号不一致时,更新历史记录
+			dao.getJdbcTemplate().update("update t_car_transfer  set  custom_num=?,modifier=?,modify_time=sysdate() where record_id=?",transfer.get("customNum"),transfer.get("modifier"),rst.get("recordId"));
+		}
+		
+		
+		
+	}
+	
+	/**
+	 * 查询单车的流程记录
+	 * @param carId
+	 * @param startDate
+	 * @param endDate
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> loadCarTransfer(String carId,Date startDate,Date endDate,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select g.org_name belong_org_name,c.car_num,ct.* from t_car_transfer ct inner join t_car c on ct.car_id=c.car_id");
+		sql.append(" left join t_org g on ct.belong_org=g.org_id");
+		sql.append(" where ct.car_id=?");
+		sqlParams.add(carId);
+		if(startDate!=null){
+			sql.append(" and start_date>=? ");
+			sqlParams.add(startDate);
+		}
+		if(endDate!=null){
+			sql.append(" and start_date<=? ");
+			sqlParams.add(endDate);
+		}
+		sql.append(" order by start_date desc");
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlParams.toArray());
+	}
+	
+	public Map<String,Object>  loadWorkAreaMapping(){
+		String sql="select code_id,code_name from t_sort_code where father_code_id=?";
+		return dao.queryForMapping(sql, "code_name","code_id", CodeConstant.SORT_WORK_AREA);
+	}
+	
+	/**
+	 * 更新流转记录中的自编号快照(目前只需要,自编号快照)
+	 * @param carId
+	 * @param customNum
+	 */
+	public void updateTransferSnapshot(String carId,String customNum){
+		String sql="update  t_car_transfer  set custom_num=?,modify_time=? where record_id=(select record_id from (select record_id from t_car_transfer  where car_id=? order by start_date desc limit 1) tab)";
+		dao.getJdbcTemplate().update(sql,customNum,new Date(),carId);
+	}
+	
+}

+ 158 - 0
src/main/java/com/hb/proj/car/service/CarSumRptService.java

@@ -0,0 +1,158 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.Wpg;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+
+@Service
+public class CarSumRptService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 查询所有项目部
+	 * @return
+	 */
+	public List<Map<String,Object>> loadAllSubOrgs(){
+		String sql="select org_id,org_name from t_org g where length(assist_code)=7 order by display_num";
+		return dao.queryForListMap(sql);
+	}
+	
+	/**
+	 * 查询柴油类型编码
+	 * @return
+	 */
+	public List<Map<String,Object>>  loadCoilCarTypes(){
+		String sql="SELECT code_id,code_name,spare1 FROM t_sort_code  d where d.father_code_id='402881e8734da7fa01734da7fa600000' order by display_num";
+		return dao.queryForListMap(sql);
+	}
+	
+	/**
+	 * 统计柴油车数量(按柴油车类型和单位)需求根据车辆调动特殊处理(车辆流转记录)
+	 * 一个季度内同一车在一单位内可能多次调入,车辆数只算一次(distinct car_id)
+	 * @return
+	 */
+	public Map<String,Object>  loadCoilCarCountRpt(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("select  concat(coil_car_type,'_',belong_org) ckey,count(distinct car_id) car_count  from (  ");
+		sql.append(" select cf.car_id,cf.belong_org,c.coil_car_type  from t_car_transfer cf  ");
+		sql.append(" inner join t_car c on cf.car_id=c.car_id  ");
+		sql.append(" where coil_car_type is not null and oil_type='柴油' and  c.discard_if=0 ");
+		sql.append(" and DATE_FORMAT(start_date,'%Y-%m') <=?  and (end_date is null or  DATE_FORMAT(end_date,'%Y-%m')>=?) ");
+		sql.append(" ) tab  ");
+		sql.append(" group by belong_org,coil_car_type ");
+		
+		return dao.queryForMapping(sql.toString(), "ckey", "car_count",endMonth,startMonth);
+	}
+	
+	/**
+	 * 统计柴油车耗油量(按柴油车类型和单位)
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public Map<String,Object>  loadCoilCarRealCost(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select concat(coil_car_type,'_',rpt_org) ckey,coil_real_cost from ( ");
+		sql.append(" select coil_car_type,rpt_org,sum(s.coil_real_cost) coil_real_cost ");
+		sql.append(" from t_car_consume s ");
+		sql.append(" inner join t_car c on s.car_id=c.car_id ");
+		sql.append(" where coil_car_type is not null and oil_type='柴油' and DATE_FORMAT(rpt_date,'%Y-%m') between ? and ? group by coil_car_type,rpt_org ");
+		sql.append(" ) tab ");
+		return dao.queryForMapping(sql.toString(), "ckey", "coil_real_cost",startMonth,endMonth);
+	}
+	
+	
+	/**
+	 * 统计水电气消耗
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public List<Wpg> loadWpg(String startMonth,String endMonth){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT w.org_id,sum(water_count)  water_count,sum(water_cost) water_cost, ");
+		sql.append(" sum(power_count)  power_count,sum(power_cost) power_cost, ");
+		sql.append(" sum(ngas_count)  ngas_count,sum(ngas_cost) ngas_cost, ");
+		sql.append(" sum(lgas_count)  lgas_count,sum(lgas_cost) lgas_cost ");
+		sql.append(" FROM t_wpg_account  w  where w.org_id is not null and  DATE_FORMAT(rpt_month,'%Y-%m') between ? and ? ");
+		sql.append(" group by w.org_id ");
+		
+		
+		params.add(startMonth);
+		params.add(endMonth);
+		
+		return dao.queryForListPojo(sql.toString(),Wpg.class,params.toArray());
+	}
+	
+	
+	/**
+	 * 统计水电气消耗 按单位、月份分组
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public List<Wpg> loadWpgGroupOrgAndMth(String startMonth,String endMonth){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT max(rpt_month) rpt_month,w.org_id,sum(water_count)  water_count,sum(water_cost) water_cost, ");
+		sql.append(" sum(power_count)  power_count,sum(power_cost) power_cost, ");
+		sql.append(" sum(ngas_count)  ngas_count,sum(ngas_cost) ngas_cost, ");
+		sql.append(" sum(lgas_count)  lgas_count,sum(lgas_cost) lgas_cost ");
+		sql.append(" FROM t_wpg_account  w  where w.org_id is not null and  DATE_FORMAT(rpt_month,'%Y-%m') between ? and ? ");
+		sql.append(" group by w.org_id, DATE_FORMAT(rpt_month,'%Y-%m') ");
+		sql.append(" order by org_id,DATE_FORMAT(rpt_month,'%Y-%m')");
+		
+		params.add(startMonth);
+		params.add(endMonth);
+		
+		return dao.queryForListPojo(sql.toString(),Wpg.class,params.toArray());
+	}
+	
+	public boolean checkLackRptData(String rptMonth){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select g.org_id,tab.coil_count from t_org g left join (");
+		sql.append("select org_id, sum(ifnull(coil_erp_count,0)+ifnull(coil_kl_count,0)) coil_count ");
+		sql.append(" from t_other_consume");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y-%m')=?  group by org_id");
+		sql.append(" ) tab on g.org_id=tab.org_id");
+		sql.append(" where length(g.assist_code)>4  and ifnull(g.org_type,'')!='unsubmitcoil' "); //限定为项目部,排除不需要上报油耗项目部
+		
+		List<Map<String,Object>> rst=dao.queryForListMap(sql.toString(), rptMonth);
+		if(rst==null||rst.size()==0){  
+			return false;
+		}
+		Double total=0.0;
+		Number val=null;
+		boolean findUnRpt=false;
+		for(Map<String,Object> itm : rst){
+			val=(Number)itm.get("coilCount");
+			if(val==null||val.doubleValue()==0){  //发现未上报的项目部
+				findUnRpt=true;
+			}
+			else{
+				total+=val.doubleValue();
+			}
+		}
+		
+		if(total==0){ //全都未上报,就不提醒了,只有部分项目部未上报的才提醒
+			return false;
+		}
+		else{
+			return findUnRpt;
+		}
+		
+		
+	}
+}

+ 102 - 0
src/main/java/com/hb/proj/car/service/ERPKLSumRptService.java

@@ -0,0 +1,102 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsume;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+
+@Service
+public class ERPKLSumRptService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 统计各月份的考核里程、行驶里程、汽油柴油定额。目前统计的是全分公司
+	 * @param year
+	 * @return
+	 */
+	public List<Map<String,Object>>  rptCarMileAndQuota(String year){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select rpt_date, sum(check_mile) check_mile,sum(travel_mile) travel_mile,sum(oil_total_quota) oil_total_quota,sum(coil_total_quota) coil_total_quota ");
+		sql.append("from( ");
+		sql.append("select DATE_FORMAT(rpt_date,'%m') rpt_date,s.check_mile,s.travel_mile,s.oil_total_quota,s.coil_total_quota ");
+		sql.append("from t_car_consume s");
+		sql.append(" inner join t_car c on s.car_id=c.car_id");
+		sql.append(" where DATE_FORMAT(rpt_date,'%Y')=?");
+		sql.append(") tab ");
+		sql.append("group by rpt_date ");
+		
+		return dao.queryForListMap(sql.toString(),year);
+	}
+	
+	/**
+	 * 统计各月份的考核里程、行驶里程。目前统计的是全分公司
+	 * @param year
+	 * @return
+	 */
+	public List<Map<String,Object>>  rptCheckAndTravelMile(String year){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select rpt_date, sum(check_mile) check_mile,sum(travel_mile) travel_mile,sum(out_hour) out_hour,sum(work_hour) work_hour,sum(engine_work_hour) engine_work_hour ");
+		sql.append("from( ");
+		sql.append("select DATE_FORMAT(rpt_date,'%m') rpt_date,s.check_mile,s.travel_mile,s.out_hour,s.work_hour,s.engine_work_hour ");
+		sql.append("from t_car_consume s");
+		sql.append(" inner join t_car c on s.car_id=c.car_id");
+		sql.append(" where DATE_FORMAT(rpt_date,'%Y')=?");
+		sql.append(") tab ");
+		sql.append("group by rpt_date ");
+		
+		return dao.queryForListMap(sql.toString(),year);
+	}
+	
+	/**
+	 * ERP昆仑卡汇总统计-考核里程、行驶里程(2021.11 更改为:考核里程、发电机耗油--->2022.1.25更改为:发电机小时、发电机耗油)
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public List<CarConsume> loadERPKLSumMile(String startMonth,String endMonth){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select * from (");
+		sql.append("select rpt_org belong_org,sum(engine_work_hour) engine_work_hour,sum(travel_mile) travel_mile,sum(check_mile) check_mile,sum(engine_cost_kg)/1000 engine_cost_kg");
+		
+		sql.append(" from t_car_consume s   ");
+		sql.append(" inner join t_car c on s.car_id=c.car_id");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y-%m') between ? and ? ");
+		sql.append(" group by rpt_org");
+		sql.append(" ) tab ");
+		params.add(startMonth);
+		params.add(endMonth);
+		
+		return dao.queryForListPojo(sql.toString(),CarConsume.class,params.toArray());
+	}
+	
+	
+	/**
+	 * 其它油耗
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public List<OtherConsume> loadOtherConsume(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select org_id,sum(oil_count_kg)/1000 oil_count_kg,sum(coil_count_kg)/1000 coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg)/1000 oil_erp_count_kg,sum(coil_erp_count_kg)/1000 coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg)/1000 oil_kl_count_kg,sum(coil_kl_count_kg)/1000 coil_kl_count_kg,");
+		sql.append(" sum(oil_kl_money) oil_kl_money,sum(coil_kl_money) coil_kl_money");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y-%m') between ? and ? ");
+		sql.append(" group by org_id");
+		
+		return dao.queryForListPojo(sql.toString(),OtherConsume.class,startMonth,endMonth);
+	}
+	
+	
+}

+ 84 - 0
src/main/java/com/hb/proj/car/service/EnergyCostAccountService.java

@@ -0,0 +1,84 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Wpg;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+
+@Service
+public class EnergyCostAccountService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 油能源统计-根据要求从t_other_consume取(各项目部录入月累计消耗数据),不再通过车辆累加
+	 * @param rptYear
+	 * @return
+	 */
+	public List<OtherConsume> oilSumRpt(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  max(s.rpt_month) rpt_month,");
+		sql.append(" sum(oil_count_kg) oil_count_kg,sum(coil_count_kg) coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg) oil_erp_count_kg,sum(coil_erp_count_kg) coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg) oil_kl_count_kg,sum(coil_kl_count_kg) coil_kl_count_kg,");
+		sql.append(" sum(oil_coal) oil_coal,sum(coil_coal) coil_coal");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(s.rpt_month,'%Y-%m')");
+		params.add(rptYear);
+		return dao.queryForListPojo(sql.toString(),OtherConsume.class,params.toArray());
+	}
+	
+	/**
+	 * 统计分公司油耗(按月分组)
+	 * @param rptYear
+	 * @return
+	 */
+	public List<CarConsume> rptCompOilCost(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(s.rpt_date) rpt_date,sum(travel_mile) travel_mile,sum(check_mile) check_mile,");
+		sql.append("sum(oil_total_quota) oil_total_quota,sum(coil_total_quota) coil_total_quota,");
+		sql.append("sum(oil_real_cost) oil_real_cost,sum(coil_real_cost) coil_real_cost,sum(oil_coal+coil_coal) oil_coal ");
+		sql.append(" from t_car_consume s   ");
+		sql.append(" inner join t_car c on s.car_id=c.car_id");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(s.rpt_date,'%Y-%m')");
+		
+		params.add(rptYear);
+		
+		
+		return dao.queryForListPojo(sql.toString(),CarConsume.class,params.toArray());
+	}
+	
+	/**
+	 * 统计分公司水电气(按月分组)
+	 * @param rptYear
+	 * @return
+	 */
+	public List<Wpg> rptCompWpg(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT max(rpt_month) rpt_month,sum(water_count)/10000  water_count,sum(water_count_quota)/10000 water_count_quota, ");
+		sql.append(" sum(power_count)/10000  power_count,sum(power_count_quota)/10000  power_count_quota, ");
+		sql.append(" sum(ngas_count)/10000  ngas_count,sum(ngas_count_quota)/10000 ngas_count_quota, ");
+		sql.append(" sum(lgas_count)  lgas_count,sum(lgas_count_quota) lgas_count_quota,sum(power_coal) power_coal, sum(lgas_coal) lgas_coal,sum(ngas_coal) ngas_coal");
+		sql.append(" FROM t_wpg_account  w  where  DATE_FORMAT(rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m') ");
+		
+		
+		params.add(rptYear);
+		
+		
+		return dao.queryForListPojo(sql.toString(),Wpg.class,params.toArray());
+	}
+}

+ 247 - 0
src/main/java/com/hb/proj/car/service/EnergySumRptService.java

@@ -0,0 +1,247 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Workload;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCorrect;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+
+/**
+ * 用能用水统计汇总-表6(含各项目部上报的合计数据+物资站ERP数据)
+ * @author hb
+ *
+ */
+
+@Service
+public class EnergySumRptService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	public CarConsume carOilMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select sum(check_mile) check_mile");
+		sql.append(" from t_car_consume s");
+		sql.append(" inner join t_car c on s.car_id=c.car_id");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y-%m')  between ?  and ? ");
+		return dao.queryForObject(sql.toString(), CarConsume.class,startMonth,endMonth);
+	}
+	
+	/**
+	 * 油能源统计
+	 * @param rptYear
+	 * @return
+	 */
+	public List<CarConsume> carOilSumRpt(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  max(s.rpt_date) rpt_date,sum(oil_real_cost)/1000 oil_real_cost,sum(coil_real_cost)/1000 coil_real_cost,sum(oil_coal)oil_coal, sum(coil_coal) coil_coal, ");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_car_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(s.rpt_date,'%Y-%m')");
+		params.add(rptYear);
+		return dao.queryForListPojo(sql.toString(),CarConsume.class,params.toArray());
+	}
+	
+	/**
+	 * 按年查询按月分组,物资ERP数据
+	 * @param year
+	 * @return
+	 */
+	public List<ERP> erpMonthGrp(String year){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(rpt_month) rpt_month,sum(oil_count) oil_count,sum(oil_money) oil_money,sum(coil_count) coil_count,sum(coil_money) coil_money,");
+		sql.append("sum(oil_count_correct) oil_count_correct,sum(oil_money_correct) oil_money_correct,");
+		sql.append("sum(coil_count_correct) coil_count_correct,sum(coil_money_correct) coil_money_correct,");
+		sql.append("sum(oil_coal) oil_coal,sum(coil_coal) coil_coal,sum(oil_correct_coal) oil_correct_coal,sum(coil_correct_coal) coil_correct_coal,");
+		sql.append("sum(oil_sum_coal) oil_sum_coal,sum(coil_sum_coal) coil_sum_coal,");
+		sql.append("sum(oil_count_sum) oil_count_sum,sum(coil_count_sum) coil_count_sum,sum(oil_money_sum) oil_money_sum,sum(coil_money_sum) coil_money_sum ");
+		sql.append(" from t_material_erp");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m')");
+		return dao.queryForListPojo(sql.toString(), ERP.class,year);
+	}
+	
+	/**
+	 * 多月累计物资ERP数据
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public ERP erpMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(rpt_month) rpt_month,sum(oil_count) oil_count,sum(oil_money) oil_money,sum(coil_count) coil_count,sum(coil_money) coil_money,");
+		sql.append("sum(oil_count_correct) oil_count_correct,sum(oil_money_correct) oil_money_correct,");
+		sql.append("sum(coil_count_correct) coil_count_correct,sum(coil_money_correct) coil_money_correct,");
+		sql.append("sum(oil_coal) oil_coal,sum(coil_coal) coil_coal,sum(oil_correct_coal) oil_correct_coal,sum(coil_correct_coal) coil_correct_coal,");
+		sql.append("sum(oil_sum_coal) oil_sum_coal,sum(coil_sum_coal) coil_sum_coal,");
+		sql.append("sum(oil_count_sum) oil_count_sum,sum(coil_count_sum) coil_count_sum,sum(oil_money_sum) oil_money_sum,sum(coil_money_sum) coil_money_sum ");
+		sql.append(" from t_material_erp");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ? ");
+		return dao.queryForObject(sql.toString(), ERP.class,startMonth,endMonth);
+	}
+	
+	/**
+	 * 油能源统计-根据要求从t_other_consume取(各项目部录入月累计消耗数据),不再通过车辆累加2020.9.15
+	 * @param rptYear
+	 * @return
+	 */
+	public List<OtherConsume> otherMonthGrp(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  max(s.rpt_month) rpt_month,");
+		sql.append(" sum(oil_count_kg)/1000 oil_count_kg,sum(coil_count_kg)/1000 coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg)/1000 oil_erp_count_kg,sum(coil_erp_count_kg)/1000 coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg)/1000 oil_kl_count_kg,sum(coil_kl_count_kg)/1000 coil_kl_count_kg,");
+		sql.append(" sum(oil_kl_coal) oil_kl_coal,sum(coil_kl_coal) coil_kl_coal,");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(s.rpt_month,'%Y-%m')");
+		params.add(rptYear);
+		return dao.queryForListPojo(sql.toString(),OtherConsume.class,params.toArray());
+	}
+	
+	/**
+	 * 多月累计各项目部上报油耗数据
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public OtherConsume otherMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  max(s.rpt_month) rpt_month,");
+		sql.append(" sum(oil_count_kg)/1000 oil_count_kg,sum(coil_count_kg)/1000 coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg)/1000 oil_erp_count_kg,sum(coil_erp_count_kg)/1000 coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg)/1000 oil_kl_count_kg,sum(coil_kl_count_kg)/1000 coil_kl_count_kg,");
+		sql.append(" sum(oil_kl_coal) oil_kl_coal,sum(coil_kl_coal) coil_kl_coal,");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y-%m') between ?  and ? ");
+		return dao.queryForObject(sql.toString(),OtherConsume.class,startMonth,endMonth);
+	}
+	
+	
+	/**
+	 * 水电气能耗-按年查询按月分组
+	 * @param rptYear
+	 * @return
+	 */
+	public List<Wpg> wpgSumRpt(String rptYear){
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT max(rpt_month) rpt_month,sum(water_count)/10000  water_count,sum(water_cost)/10000 water_cost, ");
+		sql.append(" sum(power_count)/10000  power_count,sum(power_cost)/10000 power_cost, ");
+		sql.append(" sum(ngas_count)/10000  ngas_count,sum(ngas_cost)/10000 ngas_cost, ");
+		sql.append(" sum(lgas_count)/1000  lgas_count,sum(lgas_cost)/10000  lgas_cost,sum(power_coal) power_coal, sum(lgas_coal) lgas_coal,sum(ngas_coal) ngas_coal");
+		sql.append(" FROM t_wpg_account  w  where  DATE_FORMAT(rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m') ");
+		return dao.queryForListPojo(sql.toString(),Wpg.class,rptYear);
+	}
+	
+	
+	/**
+	 * 多月累计水电气能耗
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public Wpg wpgMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT max(rpt_month) rpt_month,sum(water_count)/10000  water_count,sum(water_cost)/10000 water_cost, ");
+		sql.append(" sum(power_count)/10000  power_count,sum(power_cost)/10000 power_cost, ");
+		sql.append(" sum(ngas_count)/10000  ngas_count,sum(ngas_cost)/10000 ngas_cost, ");
+		sql.append(" sum(lgas_count)/1000  lgas_count,sum(lgas_cost)/10000  lgas_cost,sum(power_coal) power_coal, sum(lgas_coal) lgas_coal,sum(ngas_coal) ngas_coal");
+		sql.append(" FROM t_wpg_account  w  where  DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ? ");
+		return dao.queryForObject(sql.toString(),Wpg.class,startMonth,endMonth);
+	}
+	
+	
+	/**
+	 * 水电气按年查询,按月分组
+	 * @param rptYear
+	 * @return
+	 */
+	public List<WpgCorrect> wpgCorrectSumRpt(String rptYear){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(rpt_month) rpt_month,sum(water_count_correct) water_count_correct,sum(water_cost_correct) water_cost_correct,sum(power_count_correct) power_count_correct,sum(power_cost_correct) power_cost_correct,");
+		sql.append("sum(ngas_count_correct) ngas_count_correct,sum(ngas_cost_correct) ngas_cost_correct,sum(lgas_count_correct) lgas_count_correct,sum(lgas_cost_correct) lgas_cost_correct,");
+		sql.append("sum(power_correct_coal) power_correct_coal,sum(ngas_correct_coal) ngas_correct_coal,sum(lgas_correct_coal) lgas_correct_coal");
+		sql.append(" from t_wpg_correct where  DATE_FORMAT(rpt_month,'%Y') = ?");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m') ");
+		return dao.queryForListPojo(sql.toString(),WpgCorrect.class,rptYear);
+	}
+	
+	/**
+	 * 多月累计水电气修正值
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public WpgCorrect wpgCorrectMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(rpt_month) rpt_month,sum(water_count_correct) water_count_correct,sum(water_cost_correct) water_cost_correct,sum(power_count_correct) power_count_correct,sum(power_cost_correct) power_cost_correct,");
+		sql.append("sum(ngas_count_correct) ngas_count_correct,sum(ngas_cost_correct) ngas_cost_correct,sum(lgas_count_correct) lgas_count_correct,sum(lgas_cost_correct) lgas_cost_correct,");
+		sql.append("sum(power_correct_coal) power_correct_coal,sum(ngas_correct_coal) ngas_correct_coal,sum(lgas_correct_coal) lgas_correct_coal");
+		sql.append(" from t_wpg_correct where  DATE_FORMAT(rpt_month,'%Y-%m')  between ?  and ? ");
+		return dao.queryForObject(sql.toString(),WpgCorrect.class,startMonth,endMonth);
+	}
+	
+	
+	/**
+	 * 工作量,产值统计---按年查询按月分组
+	 * @param rptYear
+	 * @return
+	 */
+	public List<Workload> workloadSumRpt(String rptYear){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("SELECT max(rpt_month) rpt_month,sum(well_count) well_count, ");
+		sql.append(" sum(industry_value) industry_value,sum(added_value) added_value ");
+		sql.append(" FROM  t_workload_value w ");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m') ");
+		params.add(rptYear); 
+		return dao.queryForListPojo(sql.toString(),Workload.class,params.toArray());
+	}
+	
+	/**
+	 * 工作量,产值统计---按跨月查询按月分组
+	 * @param startMonth
+	 * @param endMonth
+	 * @return
+	 */
+	public List<Workload> workloadSumRpt(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("SELECT max(rpt_month) rpt_month,sum(well_count) well_count, ");
+		sql.append(" sum(industry_value) industry_value,sum(added_value) added_value ");
+		sql.append(" FROM  t_workload_value w ");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m') ");
+		return dao.queryForListPojo(sql.toString(),Workload.class,startMonth,endMonth);
+	}
+	
+	/**
+	 * 工作量,产值统计---多月累计
+	 * @param rptYear
+	 * @return
+	 */
+	public Workload workloadMonthSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("SELECT sum(well_count) well_count,sum(builder_area) builder_area,");
+		sql.append(" sum(industry_value) industry_value,sum(added_value) added_value ");
+		sql.append(" FROM  t_workload_value w ");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ?  ");
+		return dao.queryForObject(sql.toString(),Workload.class,startMonth,endMonth);
+	}
+}

+ 176 - 0
src/main/java/com/hb/proj/car/service/MaterialERPService.java

@@ -0,0 +1,176 @@
+package com.hb.proj.car.service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.ERP;
+import com.hb.proj.model.ERPCalculater;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Workload;
+import com.hb.proj.model.WorkloadPO;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCorrect;
+import com.hb.proj.model.WpgCorrectCalculater;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.DateUtil;
+
+@Service
+public class MaterialERPService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 保存建筑面积到workload表月份固定为1月份
+	 * @param rptMonth
+	 * @param builderArea
+	 * @param us
+	 * @return
+	 */
+	public boolean saveBuilderArea(String rptMonth,Double builderArea,String us){
+		String sql="select record_id from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		Map<String,Object> record=dao.queryForSingleMap(sql,rptMonth);
+		if(record!=null&&record.size()>0){ //存在1月份记录,则直接修改
+			sql="update t_workload_value set builder_area=? where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+			dao.getJdbcTemplate().update(sql, builderArea,rptMonth);
+		}
+		else{ //无则插入
+			sql="insert into t_workload_value(record_id,builder_area,rpt_month,modifier,modify_time) values(?,?,?,?,?)";
+			UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+			dao.getJdbcTemplate().update(sql, uuid.generate(),builderArea,rptMonth+"-01",us,new Date());
+		}
+		return true;
+	}
+	
+	public boolean saveERPData(ERP erp) {
+		String sql="delete from t_material_erp where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		dao.getJdbcTemplate().update(sql,DateUtil.format(erp.getRptMonth(), "yyyy-MM"));
+		ERPCalculater.calculate(erp);
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		erp.setRecordId(uuid.generate());
+		erp.setModifyTime(new Date());
+		dao.insertPojo(erp,"t_material_erp");
+		return true;
+	}
+	
+	public boolean saveWpgCorrect(WpgCorrect wpgcrt) {
+		String sql="delete from t_wpg_correct where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		dao.getJdbcTemplate().update(sql,DateUtil.format(wpgcrt.getRptMonth(), "yyyy-MM"));
+		
+	    WpgCorrectCalculater.calculate(wpgcrt);  //换算处理
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		wpgcrt.setRecordId(uuid.generate());
+		wpgcrt.setModifyTime( new Date());
+		dao.insertPojo(wpgcrt,"t_wpg_correct");
+		return true;
+	}
+	
+	public boolean saveWorkload(WorkloadPO wkload){
+		String rptMonth=DateUtil.format(wkload.getRptMonth(), "yyyy-MM");
+		if(rptMonth.endsWith("-01")){ //如果是1月份,1月份存储有建筑面积删除前先取出
+			String sql="select builder_area from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+			Map<String,Object> oldData=dao.queryForSingleMap(sql, rptMonth);
+			if(oldData.get("builderArea")!=null){   //存储有建筑面积的,再存回去,避免丢失
+				wkload.setBuilderArea(((Number)oldData.get("builderArea")).doubleValue()); 
+			}
+			else{
+				wkload.setBuilderArea(null);  //建筑面积不在此处修改,所以必须要明确值不能用对象默认(默认是未知)
+			}
+			
+		}
+		String sql="delete from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		dao.getJdbcTemplate().update(sql,rptMonth);
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		wkload.setRecordId(uuid.generate());
+		wkload.setModifyTime( new Date());
+		dao.insertPojo(wkload,"t_workload_value");
+		return true;
+	}
+	
+	public List<ERP> rptMonthGrpERP(String year){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select max(rpt_month) rpt_month,sum(oil_count) oil_count,sum(oil_money) oil_money,sum(coil_count) coil_count,sum(coil_money) coil_money,");
+		sql.append("sum(oil_count_correct) oil_count_correct,sum(oil_money_correct) oil_money_correct,");
+		sql.append("sum(coil_count_correct) coil_count_correct,sum(coil_money_correct) coil_money_correct,");
+		sql.append("sum(oil_count_sum) oil_count_sum,sum(coil_count_sum) coil_count_sum,sum(oil_money_sum) oil_money_sum,sum(coil_money_sum) coil_money_sum ");
+		sql.append(" from t_material_erp");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y') = ? ");
+		sql.append(" group by DATE_FORMAT(rpt_month,'%Y-%m')");
+		return dao.queryForListPojo(sql.toString(), ERP.class,year);
+	}
+	
+	
+	public ERP  rptERPSum(String startMonth,String rptMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select sum(oil_count) oil_count,sum(oil_money) oil_money,sum(coil_count) coil_count,sum(coil_money) coil_money,");
+		sql.append("sum(oil_count_correct) oil_count_correct,sum(oil_money_correct) oil_money_correct,");
+		sql.append("sum(coil_count_correct) coil_count_correct,sum(coil_money_correct) coil_money_correct,");
+		sql.append("sum(oil_coal) oil_coal,sum(coil_coal) coil_coal,sum(oil_correct_coal) oil_correct_coal,sum(coil_correct_coal) coil_correct_coal,");
+		sql.append("sum(oil_sum_coal) oil_sum_coal,sum(coil_sum_coal) coil_sum_coal,");
+		sql.append("sum(oil_count_sum) oil_count_sum,sum(coil_count_sum) coil_count_sum,sum(oil_money_sum) oil_money_sum,sum(coil_money_sum) coil_money_sum ");
+		sql.append(" from t_material_erp");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y-%m') between ? and ?");
+		return dao.queryForObject(sql.toString(), ERP.class, startMonth,rptMonth);
+	}
+	
+	public Wpg rptWpgSum(String startMonth,String rptMonth){
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("select sum(water_count)/10000  water_count,sum(water_cost)/10000 water_cost, ");
+		sql.append(" sum(power_count)/10000  power_count,sum(power_cost)/10000  power_cost, ");
+		sql.append(" sum(ngas_count)/10000  ngas_count,sum(ngas_cost)/10000 ngas_cost, ");
+		sql.append(" sum(lgas_count)/1000  lgas_count,sum(lgas_cost)/10000 lgas_cost,");
+		sql.append(" sum(lgas_coal) lgas_coal,sum(ngas_coal) ngas_coal,sum(power_coal) power_coal");
+		sql.append(" from t_wpg_account  w  where org_id is not null and   DATE_FORMAT(rpt_month,'%Y-%m') between ? and ? ");
+		return dao.queryForObject(sql.toString(),Wpg.class,startMonth,rptMonth);
+	}
+	
+	public WpgCorrect rptWpgCorrectSum(String startMonth,String rptMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select sum(water_count_correct) water_count_correct,sum(water_cost_correct) water_cost_correct,sum(power_count_correct) power_count_correct,sum(power_cost_correct) power_cost_correct,");
+		sql.append("sum(ngas_count_correct) ngas_count_correct,sum(ngas_cost_correct) ngas_cost_correct,sum(lgas_count_correct) lgas_count_correct,sum(lgas_cost_correct) lgas_cost_correct,");
+		sql.append("sum(power_correct_coal) power_correct_coal,sum(ngas_correct_coal) ngas_correct_coal,sum(lgas_correct_coal) lgas_correct_coal ");
+		sql.append(" from t_wpg_correct where DATE_FORMAT(rpt_month,'%Y-%m') between ? and ?");
+		return dao.queryForObject(sql.toString(),WpgCorrect.class,startMonth,rptMonth);
+	}
+	
+	public CarConsume rptKLSum(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select ");
+		sql.append("sum(oil_kl_kg)/1000 oil_kl_kg,sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_kg)/1000 coil_kl_kg, ");
+		sql.append("sum(coil_kl_money)/10000 coil_kl_money,sum(coil_erp_kg)/1000 coil_erp_kg ");
+		sql.append(" from t_car_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y-%m') between ? and ? ");
+	    return dao.queryForObject(sql.toString(),CarConsume.class,startMonth,endMonth);
+	}
+	
+	public OtherConsume  rptOtherConsume(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  ");
+		sql.append(" sum(oil_count_kg)/1000 oil_count_kg,sum(coil_count_kg)/1000 coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg)/1000 oil_erp_count_kg,sum(coil_erp_count_kg)/1000 coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg)/1000 oil_kl_count_kg,sum(coil_kl_count_kg)/1000 coil_kl_count_kg,");
+		sql.append(" sum(oil_kl_coal) oil_kl_coal,sum(coil_kl_coal) coil_kl_coal,");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y-%m') between ?  and ?");
+		
+	    return dao.queryForObject(sql.toString(),OtherConsume.class,startMonth,endMonth);
+	}
+	
+	public Workload loadWorkloadByMonth(String month){
+		String sql="select * from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		return dao.queryForObject(sql,Workload.class,month);
+	}
+	
+	public Workload loadWorkloadMonthSum(String startMonth,String endMonth){
+		String sql="select sum(well_count) well_count,sum(industry_value) industry_value, sum(added_value) added_value from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ?";
+		return dao.queryForObject(sql,Workload.class,startMonth,endMonth);
+	}
+}

+ 77 - 0
src/main/java/com/hb/proj/car/service/OilBoxService.java

@@ -0,0 +1,77 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+
+
+@Service
+public class OilBoxService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 油箱标定查询
+	 * @param args
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> queryOilBox(Map<String,Object> args,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from t_oil_box b where 1=1");
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("boxName"))){
+			sql.append(" and box_name like ? ");
+			sqlParams.add("%"+args.get("boxName")+"%");
+		}
+		
+		
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	
+	
+	public Map<String, Object> getOilBox(String recordId) {
+		StringBuilder sql=new StringBuilder();
+		sql.append("select b.*  from t_oil_box b ");
+		sql.append(" where b.record_id=?");
+		return dao.queryForSingleMap(sql.toString(), recordId);
+	}
+	
+	public boolean addOilBox(Map<String, Object> oilBox) {
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		oilBox.put("recordId", uuid.generate());
+		oilBox.put("modifyTime", new Date());
+		dao.insert(oilBox,"t_oil_box");
+		return true;
+	}
+	
+	public boolean updateOilBox(Map<String, Object> oilBox) {
+		oilBox.put("modifyTime", new Date());
+		dao.update(oilBox,"t_oil_box","record_id");
+		return true;
+	}
+
+	public boolean deleteOilBox(String recordId) {
+		String sql="delete from t_oil_box  where record_id=?";
+		dao.getJdbcTemplate().update(sql,recordId);
+		return true;
+	}
+	
+	
+	
+	
+}

+ 314 - 0
src/main/java/com/hb/proj/car/service/OilMeterService.java

@@ -0,0 +1,314 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.FieldAttrConverter;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+
+
+@Service
+public class OilMeterService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 项目部用户通过车信息查询油量计设备(下一步通过设备查询油量数据)
+	 * @param args
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> queryOilMeterFromCar(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select g.assist_code,g.org_name belong_org_name,t.*,");
+		sql.append("(select count(1) from t_oil_meter m where m.belong_car_id=t.car_id) meter_count,");
+		sql.append(" DATE_FORMAT(work_start,'%Y-%m') wk_start");
+		sql.append(" from t_car t  ");
+		sql.append(" left join t_org g on t.belong_org=g.org_id ");
+		sql.append(" ) tab where discard_if=0 ");
+		
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("deviceKey"))){
+			String[] dns=((String)args.get("deviceKey")).split("[,,;;\\-~\\|\\s]+");
+			if(dns.length>1){ //两个参数
+				sql.append(" and ((device_name like ?  and device_model like ?) or (device_name like ?  and device_model like ?))");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+			else{
+				sql.append(" and (device_name like ? or device_model like ?)");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("carOrCustomNum"))){
+			sql.append(" and (car_num like ? or custom_num like ?)");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+		}
+		
+		if(authAssistCodes!=null){ //权限过滤  单位assistCode
+			sql.append(getPartSQL(authAssistCodes,sqlParams));
+		}
+		//客户端指定排序规则
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("sortField"))){
+			String sortField=FieldAttrConverter.getFieldName((String)args.get("sortField"));
+			sql.append(" order by "+sortField+" "+(args.get("sortAction")==null?"asc":args.get("sortAction")));
+		}
+		else{
+			sql.append(" order by custom_num,car_num");
+		}
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	/**
+	 * 油量计设备管理查询
+	 * @param args
+	 * @param authAssistCodes
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	public PageModel<Map<String,Object>> queryOilMeter(Map<String,Object> args,Set<String> authAssistCodes,int pageNo,int pageSize){
+		boolean showAll=args!=null&&"1".equals(args.get("showAll")) ;//是否明确显示全部含报废车辆
+		List<Object> sqlParams=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from (");
+		sql.append("select g.assist_code,g.org_name belong_org_name,t.car_num,t.custom_num,t.device_model,t.device_name,t.discard_if,b.box_name,");
+		sql.append(" m.*");
+		sql.append(" from t_oil_meter m  inner join t_car t on m.belong_car_id=t.car_id");
+	    sql.append(" left join t_oil_box b on m.box_id=b.record_id");
+		sql.append(" left join t_org g on t.belong_org=g.org_id ");
+		sql.append(" ) tab where 1=1 ");
+		if(!showAll){ //并非显示全部,则去掉报废车
+			sql.append(" and discard_if=0  ");
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("deviceKey"))){
+			String[] dns=((String)args.get("deviceKey")).split("[,,;;\\-~\\|\\s]+");
+			if(dns.length>1){ //两个参数
+				sql.append(" and ((device_name like ?  and device_model like ?) or (device_name like ?  and device_model like ?))");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[1]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+			else{
+				sql.append(" and (device_name like ? or device_model like ?)");
+				sqlParams.add("%"+dns[0]+"%");
+				sqlParams.add("%"+dns[0]+"%");
+			}
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("carOrCustomNum"))){
+			sql.append(" and (car_num like ? or custom_num like ?)");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+			sqlParams.add("%"+args.get("carOrCustomNum")+"%");
+		}
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("belongOrg"))){  //入参belongOrg为assistCode
+			sql.append(" and assist_code like ?");
+			sqlParams.add(args.get("belongOrg")+"%");
+		}
+		if(authAssistCodes!=null){ //权限过滤  单位assistCode
+			sql.append(getPartSQL(authAssistCodes,sqlParams));
+		}
+		//客户端指定排序规则
+		if(args!=null&&StringUtils.isNotEmpty((String)args.get("sortField"))){
+			String sortField=FieldAttrConverter.getFieldName((String)args.get("sortField"));
+			sql.append(" order by "+sortField+" "+(args.get("sortAction")==null?"asc":args.get("sortAction")));
+		}
+		else{
+			sql.append(" order by custom_num,car_num,box_num");
+		}
+		Object[] sqlArgs=sqlParams.size()>0?sqlParams.toArray():null;
+		return dao.queryForPagedListMap(sql.toString(),pageNo, pageSize,sqlArgs);
+	}
+	
+	private String getPartSQL(Set<String> authAssistCodes,List<Object> sqlParams){
+		StringBuilder sql=new StringBuilder();
+		for(String c : authAssistCodes){
+			sql.append("or assist_code like ?");
+			sqlParams.add(c+"%");
+		}
+		return "and ("+sql.substring(2)+")";
+	}
+	
+	public Map<String, Object> getOilMeter(String recordId) {
+		StringBuilder sql=new StringBuilder();
+		sql.append("select m.*,t.car_num,b.box_name,b.record_id oil_box_id  from t_oil_meter m ");
+		sql.append(" left join t_car t on m.belong_car_id=t.car_id");
+		sql.append(" left join t_oil_box b on m.box_id=b.record_id");
+		sql.append(" where m.record_id=?");
+		return dao.queryForSingleMap(sql.toString(), recordId);
+	}
+	
+	
+	
+	
+	public boolean addOilMeter(Map<String, Object> oilMeter) {
+		if(oilMeter==null){
+			return false;
+		}
+
+		
+		UUIDHexGenerator uuid=UUIDHexGenerator.getInstance();
+		oilMeter.put("recordId", uuid.generate());
+		oilMeter.put("modifyTime", new Date());
+		dao.insert(oilMeter,"t_oil_meter");
+		
+		
+		return true;
+	}
+	
+	/**
+	 * 建立车、油箱、油量计关联
+	 * @param carId
+	 * @param boxSerial
+	 * @param oilBoxId
+	 * @param oilMeterId
+	 */
+	/*private void createCarBoxMeterMapping(String carId,String boxSerial,String oilBoxId,String oilMeterId){
+		String sql="update t_car set oil_box_id=?,oil_meter_id=? where car_id=?";
+		if("2".equals(boxSerial)){
+			sql="update t_car set oil_box_id2=?,oil_meter_id2=? where car_id=?";
+		}
+		dao.getJdbcTemplate().update(sql, oilBoxId,oilMeterId,carId);
+	}*/
+	
+	public boolean updateOilMeter(Map<String, Object> oilMeter) {
+	
+		oilMeter.put("modifyTime", new Date());
+		dao.update(oilMeter,"t_oil_meter","record_id");
+		
+		
+		return true;
+	}
+
+	public boolean deleteOilMeter(String recordId) {
+		String sql="delete from t_oil_meter  where record_id=?";
+		dao.getJdbcTemplate().update(sql,recordId);  //删除油量计后,也清除和车辆的关联关系
+		
+		return true;
+	}
+	
+	//检测油位计设备识别码是否在用
+	public boolean existsMeterNum(String meterNum,String recordId){
+		Map<String,Object> rst=null;
+		if(StringUtils.isNotEmpty(recordId)){
+			rst=dao.queryForSingleMap("select meter_num from t_oil_meter m where meter_num=? and record_id!=?", meterNum,recordId);
+		}
+		else{
+			rst=dao.queryForSingleMap("select meter_num from t_oil_meter m where meter_num=?", meterNum);
+		}
+		return rst!=null&&rst.size()>0;
+		
+	}
+	
+	/**
+	 * 查询指定车辆的油箱配置
+	 * @param carId
+	 * @return
+	 */
+	public List<Map<String,Object>> loadCarBoxs(String carId){
+		String sql="select record_id val,box_num txt from t_oil_meter where belong_car_id=?";
+		return dao.queryForListMap(sql, carId);
+	}
+	
+	//从采集数据中同步油量计设备,临时用(适用一车一油位计且按规律编号,多油位计不适用)
+	public Integer addMetersFromSampling(){
+		String sql="select dtu_num,(case when left(dtu_num,1)='L' then CONCAT('辽',dtu_num) else dtu_num end) car_num from t_oil_current where  not exists(select meter_num from t_oil_meter where meter_num=dtu_num)";
+		Map<String,Object> rst=dao.queryForMapping(sql, "dtu_num", "car_num");
+		if(rst==null||rst.size()==0){
+			return 0;
+		}
+		
+		sql="select car_id,replace(car_num,'-','') car_num from t_car where replace(car_num,'-','') in ('"+StringUtils.join(rst.values(),"','")+"')";
+		Map<String,Object> carMap=dao.queryForMapping(sql,"car_num","car_id");
+		
+		List<Object[]> params=new ArrayList<Object[]>(rst.size());
+		List<Object> values=null;
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		for(String dtuNum : rst.keySet()){
+			if(carMap.get(rst.get(dtuNum))==null){
+				continue;
+			}
+			values=new ArrayList<Object>(6);
+			values.add(uuid.generate());
+			//values.add(carMap.get(rst.get(dtuNum)));
+			values.add(dtuNum);
+			values.add(dtuNum.startsWith("辽")?"3318":"DTU");
+			values.add(new Date());
+			values.add("sys");
+			params.add(values.toArray());
+		}
+		
+		if(params.size()==0){
+			return 0;
+		}
+		
+		sql="insert into t_oil_meter(record_id,meter_num,transfer_type,modify_time,modifier) values(?,?,?,?,?)";
+		
+		dao.getJdbcTemplate().batchUpdate(sql, params);
+		
+		//增加油量计与车辆的关联
+		List<Object[]> params2=new ArrayList<Object[]>(rst.size());
+		Object[] values2=null;
+		for(Object[] args : params){
+			values2=new Object[2];
+			values2[0]=args[0];  //args[0]:t_oil_meter recordId;
+			values2[1]=carMap.get(rst.get(args[1])); //args[1]:t_oil_meter meter_num
+			params2.add(values2);
+		}
+		
+		sql="update t_car set oil_meter_id=? where car_id=?";
+		dao.getJdbcTemplate().batchUpdate(sql, params2);
+		
+		return params.size();
+	}
+	
+	
+	/**
+	 * 更新油量设备配置表中体积换算系数
+	 * @param carId
+	 * @param ratio
+	 * @param ratio2
+	 */
+	public void updateCarVolumeRatio(String carId,Double ratio,Double ratio2){
+		if(ratio==null||ratio.doubleValue()<=0){ //油箱1系数都无效就不再处理
+			return;
+		}
+		String sql="select volume_ratio from t_oil_meter where belong_car_id=? and box_num='1'";
+		Map<String,Object> rst=dao.queryForSingleMap(sql, carId);
+		if(rst!=null&&rst.get("volumeRatio")!=null){ //已经标定过的再标定就进行累计标定
+			ratio=((Number)rst.get("volumeRatio")).doubleValue()*ratio.doubleValue();
+		}
+		sql="update t_oil_meter set volume_ratio=?,ratio_modify_time=? where belong_car_id=? and box_num='1'";
+		dao.getJdbcTemplate().update(sql,ratio,new Date(),carId);
+		
+		
+		if(ratio2==null||ratio2.doubleValue()<=0){ 
+			return;
+		}
+		sql="select volume_ratio from t_oil_meter where belong_car_id=? and box_num='2'";
+		rst=dao.queryForSingleMap(sql, carId);
+		if(rst!=null&&rst.get("volumeRatio")!=null){ //已经标定过的再标定就进行累计标定
+			ratio2=((Number)rst.get("volumeRatio")).doubleValue()*ratio2.doubleValue();
+		}
+		sql="update t_oil_meter set volume_ratio=?,ratio_modify_time=? where belong_car_id=? and box_num='2'";
+		dao.getJdbcTemplate().update(sql,ratio2,new Date(),carId);
+	}
+}

+ 103 - 0
src/main/java/com/hb/proj/car/service/YearSumCompareService.java

@@ -0,0 +1,103 @@
+package com.hb.proj.car.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsume;
+import com.hb.proj.model.Wpg;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+
+/**
+ * 用能用水累计同比-表6
+ * @author hb
+ *
+ */
+
+@Service
+public class YearSumCompareService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	/**
+	 * 油能源统计-根据要求从t_other_consume取(各项目部录入月累计消耗数据),不再通过车辆累加2020.9.15
+	 * @param rptYear
+	 * @return
+	 */
+	public OtherConsume oilSumRpt(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  ");
+		sql.append(" sum(oil_count_kg)/1000 oil_count_kg,sum(coil_count_kg)/1000 coil_count_kg,");
+		sql.append(" sum(oil_erp_count_kg)/1000 oil_erp_count_kg,sum(coil_erp_count_kg)/1000 coil_erp_count_kg,");
+		sql.append(" sum(oil_kl_count_kg)/1000 oil_kl_count_kg,sum(coil_kl_count_kg)/1000 coil_kl_count_kg,");
+		sql.append(" sum(oil_kl_coal) oil_kl_coal,sum(coil_kl_coal) coil_kl_coal,");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_other_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_month,'%Y-%m') between ?  and ?");
+		return dao.queryForObject(sql.toString(),OtherConsume.class,startMonth,endMonth);
+	}
+	
+	/**
+	 * 油能源统计 全年12个月
+	 * @param rptYear
+	 * @return
+	 */
+	public CarConsume oilYearSumRpt(String rptYear){
+		return oilYearSumRpt(rptYear,null);
+	}
+	
+	
+	/**
+	 * 油能源统计
+	 * @param rptYear
+	 * @param maxMM 最大月份
+	 * @return
+	 */
+	public CarConsume oilYearSumRpt(String rptYear,Integer maxMM){
+		List<Object> params=new ArrayList<Object>();
+		StringBuilder sql=new StringBuilder();
+		sql.append("select  sum(oil_real_cost)/1000 oil_real_cost,sum(coil_real_cost)/1000 coil_real_cost,sum(oil_coal)oil_coal, sum(coil_coal) coil_coal, ");
+		sql.append(" sum(oil_kl_money)/10000 oil_kl_money,sum(coil_kl_money)/10000 coil_kl_money");
+		sql.append(" from t_car_consume s   ");
+		sql.append(" where DATE_FORMAT(s.rpt_date,'%Y') = ? ");
+		params.add(rptYear);
+		if(maxMM!=null){
+			sql.append(" and DATE_FORMAT(s.rpt_date,'%m') <= ? ");
+			params.add(String.format("%02d",maxMM));
+		}
+		
+		return dao.queryForObject(sql.toString(),CarConsume.class,params.toArray());
+	}
+	
+	/**
+	 * 水电气能耗  全年12月
+	 * @param rptYear
+	 * @return
+	 */
+	public Wpg wpgYearSumRpt(String rptYear){
+		return wpgYearSumRpt(rptYear,null);
+	}
+	
+	/**
+	 * 水电气能耗
+	 * @param rptYear
+	 * @return
+	 */
+	public Wpg wpgYearSumRpt(String startMonth,String endMonth){
+		StringBuilder sql=new StringBuilder();
+		
+		sql.append("SELECT sum(water_count)/10000  water_count,sum(water_cost)/10000 water_cost, ");
+		sql.append(" sum(power_count)/10000  power_count,sum(power_cost)/10000 power_cost, ");
+		sql.append(" sum(ngas_count)/10000  ngas_count,sum(ngas_cost)/10000 ngas_cost, ");
+		sql.append(" sum(lgas_count)/1000  lgas_count,sum(lgas_cost)/10000  lgas_cost,sum(power_coal) power_coal, sum(lgas_coal) lgas_coal,sum(ngas_coal) ngas_coal");
+		sql.append(" FROM t_wpg_account  w  where  DATE_FORMAT(rpt_month,'%Y-%m') between ?  and ? ");
+		
+		return dao.queryForObject(sql.toString(),Wpg.class,startMonth,endMonth);
+	}
+	
+	
+}

+ 356 - 0
src/main/java/com/hb/proj/excel/ExcelSupport.java

@@ -0,0 +1,356 @@
+package com.hb.proj.excel;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import com.hb.xframework.sqlmapper.parse.OgnlExecuter;
+
+public class ExcelSupport {
+
+	/**
+	 * 获取单元格的字符形式值
+	 * @param cell
+	 * @return
+	 */
+	public static String getCellStringValue(Cell cell){
+		if(cell==null){
+			return "";
+		}
+		String cellValue="";
+		
+		CellType ct=cell.getCellTypeEnum();
+		if(ct==CellType.BLANK||ct==CellType.ERROR){
+			cellValue="";
+		}
+		else if(ct==CellType.NUMERIC||ct==CellType.FORMULA){
+			if (HSSFDateUtil.isCellDateFormatted(cell)) {
+				Date date = cell.getDateCellValue();
+				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+				cellValue = sdf.format(date);
+			} else {
+				cellValue=String.valueOf(cell.getNumericCellValue());
+			}
+		}
+		else if(ct==CellType.STRING){
+			cellValue = cell.getRichStringCellValue().toString().trim();
+		}
+		return cellValue;
+	}
+	
+	/**
+	 * 设置单元格的值
+	 * @param cell
+	 * @param val
+	 */
+	public static void setValue(Cell cell,Object val){
+		if(val==null){
+			return;
+		}
+		if(val instanceof Number){
+			cell.setCellValue(((Number)val).doubleValue());
+		}
+		else if(val instanceof Date){
+			cell.setCellValue((Date)val);
+		}
+		else if(val instanceof String && ((String)val).startsWith("=")){
+			cell.setCellFormula(((String)val).substring(1));
+		}
+		else{
+			cell.setCellValue(val==null?null:String.valueOf(val).replaceAll("<br>|<BR>", "\n"));
+		}
+	}
+	
+	/**
+	 * 插入新行
+	 * @param sheet
+	 * @param startRow 需要在其后插入行的索引
+	 * @param rows  需要插入的行数
+	 */
+	public static void insertRow(Sheet sheet, int startRow, int rows) {
+	    int afterRow=startRow;
+	    startRow++;
+	    if(startRow<=sheet.getLastRowNum()){
+	    	sheet.shiftRows(startRow, sheet.getLastRowNum(), rows, true, false);
+	    }
+	    if(rows<0){
+	    	return;
+	    }
+        Row targetRow = null;//参照目标
+        targetRow = sheet.getRow(afterRow);
+
+        for (int i = 0; i < rows; i++) {
+            Row sourceRow = null;//原始位置
+          
+            Cell sourceCell = null;
+            Cell targetCell = null;
+            sourceRow = sheet.createRow(startRow);
+            sourceRow.setHeight(targetRow.getHeight());
+
+            for (int m = targetRow.getFirstCellNum(); m < targetRow.getPhysicalNumberOfCells(); m++) {
+                sourceCell = sourceRow.createCell(m);
+                targetCell = targetRow.getCell(m);
+                sourceCell.setCellStyle(targetCell.getCellStyle());
+                sourceCell.setCellType(targetCell.getCellTypeEnum());
+            }
+            startRow++;
+        }
+
+    }
+	
+	public static void insertRow(Sheet sheet, int startRow, int rows,InsertRowCallback  rowCallback) {
+	    int afterRow=startRow;
+	    startRow++;
+	    if(startRow<sheet.getLastRowNum()){
+	    	sheet.shiftRows(startRow, sheet.getLastRowNum(), rows, true, false);
+	    }
+        Row targetRow = null;//参照目标
+        targetRow = sheet.getRow(afterRow);
+
+        for (int i = 0; i < rows; i++) {
+            Row sourceRow = null;//原始位置
+          
+            Cell sourceCell = null;
+            Cell targetCell = null;
+            sourceRow = sheet.createRow(startRow);
+            sourceRow.setHeight(targetRow.getHeight());
+
+            for (int m = targetRow.getFirstCellNum(); m < targetRow.getPhysicalNumberOfCells(); m++) {
+                sourceCell = sourceRow.createCell(m);
+                targetCell = targetRow.getCell(m);
+                sourceCell.setCellStyle(targetCell.getCellStyle());
+                sourceCell.setCellType(targetCell.getCellTypeEnum());
+            }
+            rowCallback.process(sheet,sourceRow);
+            startRow++;
+        }
+
+    }
+	
+	public static void insertColumn(Sheet sheet,int startColumn,int columns){
+		int afterCell=startColumn;
+		Row row=null;
+		Cell targetCell,newCell=null;
+		int columnWith=sheet.getColumnWidth(startColumn);
+		for (int j = 0, rlen = sheet.getPhysicalNumberOfRows(); j < rlen; j++) {
+			row = sheet.getRow(j);
+			targetCell = row.getCell(startColumn);
+			if(targetCell==null){
+				break;
+			}
+			for (int i = afterCell+1,len=columns+afterCell; i <= len ; i++) {
+				sheet.setColumnWidth(i, columnWith);
+				newCell = row.createCell(i);
+				newCell.setCellStyle(targetCell.getCellStyle());
+				newCell.setCellType(targetCell.getCellTypeEnum());
+				
+			}
+		}
+
+	}
+	
+	/**
+	 * 判断是否为空行
+	 * @param sheet
+	 * @param rowIndex
+	 * @return
+	 */
+	public static boolean isNullRow(Sheet sheet, int rowIndex) {
+		Row row = sheet.getRow(rowIndex);
+		if (row == null) {
+			return true;
+		}
+		String val = null;
+		for (int c = 0, clen = row.getPhysicalNumberOfCells(); c < clen; c++) {
+			val = getCellStringValue(row.getCell(c));
+			if (StringUtils.isNotEmpty(val)) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * 执行单值替换表达式
+	 * @param express
+	 * @param context
+	 * @return
+	 */
+	public static Object executeContextExp(String express,Map<String,Object> context){
+		boolean isStr=exists(express,"\\$=\\s*\\S+\\s*\\{|\\}\\s*\\S+");
+		express=express.replaceFirst("\\$=", "");
+		Pattern pattern=Pattern.compile("\\{([^\\{]+)\\}");  
+		Matcher matcher=pattern.matcher(express);
+		String findItm=null;
+		Object rst=null;
+		while(matcher.find()){
+			findItm=matcher.group(1);
+			rst=OgnlExecuter.getValue(findItm, context);
+			if(!isStr){
+				return rst;
+			}
+			express=express.replace("{"+findItm+"}", rst!=null?String.valueOf(rst):"");
+		}
+		return express;
+	}
+	
+	/**
+	 * 获得行中的所有表达式
+	 * @param row
+	 * @return
+	 */
+	public static Map<String,List<String>> getFields(Row row){
+		int clen=row.getPhysicalNumberOfCells();
+		List<String>  fields=new ArrayList<String>(clen);
+		List<String>  groupFields=new ArrayList<String>();
+		Cell cell=null;
+		String cellVal=null;
+		String field=null;
+		for(int c=0;c<clen;c++){
+			cell=row.getCell(c);
+			cellVal=ExcelSupport.getCellStringValue(cell);
+			if(StringUtils.isEmpty(cellVal)||cellVal.indexOf("&=")<0){  //不需要表达式的
+				fields.add(null);
+				continue;
+			}
+			if(cellVal.contains("group")){
+				groupFields.add(String.valueOf(c));
+			}
+			field=extractString(cellVal, "^&=(?:group\\()?(?:\\w+\\.)?([\\w-]+)", 1, 0);
+			fields.add(field);
+			cell.setCellValue(""); //获取表达式后清空,避免没数据填充时,表达式还在
+		}
+		Map<String,List<String>>  rst=new HashMap<String,List<String>>();
+		rst.put("fields", fields);
+		rst.put("groupFields", groupFields);
+		return rst;
+	}
+	
+	public static List<String> getFieldExpress(Row row){
+		int clen=row.getPhysicalNumberOfCells();
+		List<String>  fields=new ArrayList<String>(clen);
+		Cell cell=null;
+		String cellVal=null;
+		String field=null;
+		for(int c=0;c<clen;c++){
+			cell=row.getCell(c);
+			cellVal=ExcelSupport.getCellStringValue(cell);
+			
+			field=extractString(cellVal, "^&=(?:group\\()?(?:\\w+\\.)?([\\w-]+)", 1, 0);
+			if(field==null){
+				field=cellVal;
+			}
+			fields.add(field);
+		}
+		return fields;
+	}
+	
+	/**
+	 * 分组合并单元格
+	 * @param startIdx
+	 * @param endIdx
+	 * @param sheet
+	 * @param groupIdxs
+	 */
+	public static void processGroups(int startIdx,int endIdx,Sheet sheet,List<String> groupIdxs){
+		List<int[]>  preGroupAreas=null;
+		List<int[]>  tempGroupAreas=null;
+		for(String gidx : groupIdxs){
+			tempGroupAreas=null;
+			if(preGroupAreas==null){
+				tempGroupAreas=processGroup(startIdx,endIdx,sheet,Integer.parseInt(gidx));
+			}
+			else{
+				for(int[]  idxs : preGroupAreas){
+					if(idxs[0]<idxs[1]){
+						if(tempGroupAreas==null){
+							tempGroupAreas=new ArrayList<int[]>();
+						}
+						tempGroupAreas.addAll(processGroup(idxs[0],idxs[1],sheet,Integer.parseInt(gidx)));
+					}
+				}
+			}
+			preGroupAreas=tempGroupAreas;
+			
+		}
+	}
+	
+	public static List<int[]> processGroup(int startIdx,int endIdx,Sheet sheet,int groupIdx){
+		Cell cell=null;
+		String cellVal=null,preCellVal=null;
+		int preStart=startIdx,i=startIdx;
+		List<int[]>  groupAreas=new ArrayList<int[]>(); //存在分组各区间
+		for(;i<=endIdx;i++){
+			cell=sheet.getRow(i).getCell(groupIdx);
+			cellVal=ExcelSupport.getCellStringValue(cell);
+			if(preCellVal!=null&&!cellVal.equals(preCellVal)){  //不同的数据出现,上面的就要合并
+				sheet.addMergedRegion(new CellRangeAddress(preStart,i-1,groupIdx,groupIdx));
+				groupAreas.add(new int[]{preStart,i-1});
+				preStart=i;
+			}
+			preCellVal=cellVal;
+			
+		}
+		if(preStart<i-1){
+			sheet.addMergedRegion(new CellRangeAddress(preStart,i-1,groupIdx,groupIdx));
+			groupAreas.add(new int[]{preStart,i-1});
+		}
+		return groupAreas;
+	}
+	
+	/**
+	 * 获得指定捕获组(从0开始计数)
+	 * 
+	 * @param src
+	 * @param exp
+	 * @return
+	 */
+	public static String extractString(String src, String exp, int groupIndex,int fromIndex) {
+		if (src == null || exp == null) {
+			return null;
+		}
+		Pattern p = Pattern.compile(exp);
+		Matcher m = p.matcher(src);
+		return m.find(fromIndex) ? m.group(groupIndex) : null;
+	}
+	
+	
+	public static boolean  exists(String src,String regExp){
+		if(src==null||src.length()==0){
+			return false;
+		}
+		Pattern pattern=Pattern.compile(regExp);  
+		Matcher matcher=pattern.matcher(src);
+		return matcher.find();
+	}
+	
+	/**
+	 * 从单元个表达式中获取数据集名称
+	 * @param cell
+	 * @return
+	 */
+	public static String getDatasetName(Cell cell){
+		String cellVal=getCellStringValue(cell);
+		if(cellVal.indexOf("&=")<0){
+			return null;
+		}
+		String dsName=extractString(cellVal, "^&=(?:group\\()?(\\w+)\\.(\\w+)", 1, 0);
+		return dsName!=null?dsName:"ds";
+	}
+	
+	
+	
+}

+ 108 - 0
src/main/java/com/hb/proj/excel/ExcelUtils.java

@@ -0,0 +1,108 @@
+package com.hb.proj.excel;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.web.context.support.ServletContextResourceLoader;
+
+public class ExcelUtils {
+	
+	
+  
+	public static Workbook reader(String path,ServletContext servletContext) throws Exception{
+		ResourceLoader loader=new ServletContextResourceLoader(servletContext);
+		Resource resource=loader.getResource(path);
+		if(!resource.exists()){
+			throw new Exception("未找到对应资源:"+path);
+		}
+		Workbook wb =WorkbookFactory.create(resource.getInputStream());
+		return wb;
+	}
+	
+	public static Workbook reader(String path) throws Exception{
+		FileInputStream is=new FileInputStream(path);
+		Workbook wb =WorkbookFactory.create(is);
+		return wb;
+	}
+	
+	
+	
+
+	public void save(String path,Workbook wb) throws IOException{
+		FileOutputStream os = new FileOutputStream(path);
+		try {
+			wb.write(os);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		finally{
+			if(os!=null){
+				os.close();
+			}
+			if(wb!=null){
+				wb.close();
+			}
+		}
+	}
+	public void writer(String path) throws IOException {
+		FileOutputStream os = new FileOutputStream(path);
+		// 创建工作表
+		HSSFWorkbook wb = new HSSFWorkbook();
+		HSSFSheet sheet = wb.createSheet();
+		HSSFRow row = sheet.createRow(0);
+		HSSFCell cell = row.createCell(0);
+		cell.setCellValue("测试的啦");
+		try {
+			wb.write(os);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		finally{
+			if(os!=null){
+				os.close();
+			}
+			if(wb!=null){
+				wb.close();
+			}
+		}
+	}
+	
+	  
+	/**
+	 * 输出报表到浏览器 
+	 * @param response
+	 * @param exportFileName
+	 * @param wb
+	 * @throws Exception
+	 */
+	public static void exportExcel(HttpServletResponse response,String exportFileName,Workbook wb) throws Exception{
+		response.setContentType("APPLICATION/OCTET-STREAM");
+		response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(exportFileName,"UTF-8") + ".xls");
+		OutputStream os=response.getOutputStream();
+		wb.write(os);
+		wb.close();
+		os.flush();
+		os.close();
+		response.flushBuffer();
+		
+	}
+	  
+	
+
+
+	
+}

+ 62 - 0
src/main/java/com/hb/proj/excel/ExpressExecuter.java

@@ -0,0 +1,62 @@
+package com.hb.proj.excel;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 表达式执行器
+ * @author jpsoft
+ *
+ */
+public class ExpressExecuter {
+	
+	public static Object execute(String express,Map<String,Object> context){
+		if(express.startsWith("$=")){
+			return executeContextExp(express,context);
+		}
+		else if(express.startsWith("&f=")){
+			
+		}
+		return null;
+	}
+	
+	
+	/**
+	 * 执行单值替换表达式
+	 * @param express
+	 * @param context
+	 * @return
+	 */
+	public static String executeContextExp(String express,Map<String,Object> context){
+		Pattern pattern=Pattern.compile("\\{(.+)\\}");  
+		Matcher matcher=pattern.matcher(express);
+		String findItm=null;
+		Object rst=null;
+		while(matcher.find()){
+			findItm=matcher.group(1);
+			rst=OgnlExecuter.getValue(findItm, context);
+			express=express.replace("{"+findItm+"}", rst!=null?String.valueOf(rst):"");
+		}
+		return express.replaceFirst("\\$=", "");
+	}
+	
+	
+	public static int diffInDays(Date d1,Date d2){
+		long t1=d1.getTime();
+		long t2=d2.getTime();
+		long diff=t2-t1;
+		long days=diff/(1000*60*60*24);
+		return (int)days;
+	}
+	
+	public static Date getNextDay(Date d){
+		Calendar  ca = Calendar.getInstance();
+		ca.setTime(d);
+		ca.add(Calendar.DAY_OF_MONTH, 1);
+		return ca.getTime();
+	}
+
+}

+ 9 - 0
src/main/java/com/hb/proj/excel/InsertRowCallback.java

@@ -0,0 +1,9 @@
+package com.hb.proj.excel;
+
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+
+public interface InsertRowCallback {
+
+	Row process(Sheet sheet,Row row);
+}

+ 23 - 0
src/main/java/com/hb/proj/excel/OgnlExecuter.java

@@ -0,0 +1,23 @@
+package com.hb.proj.excel;
+
+import ognl.Ognl;
+import ognl.OgnlContext;
+import ognl.OgnlException;
+
+public class OgnlExecuter {
+
+	 private static final  OgnlContext context=new OgnlContext();  
+	  
+	 /* static{
+		  context.put("StringUtils", new StringUtils());
+	  }*/
+	 public static Object getValue(String expression, Object root){
+		    try {
+		      Object expressNode=Ognl.parseExpression(expression);
+		      return Ognl.getValue(expressNode,context, root);
+		    } catch (OgnlException e) {
+		       //throw new RuntimeException("Error evaluating expression '" + expression + "'. Cause: " + e, e);
+		    	return null;
+		    }
+	 }
+}

+ 88 - 0
src/main/java/com/hb/proj/excel/Table.java

@@ -0,0 +1,88 @@
+package com.hb.proj.excel;
+
+public class Table {
+
+	private String title;
+	
+	private String secTitle; //二级标题
+	
+	private int rowCount;
+	
+	private int columnCount;
+	
+	private int[] clmWidth;
+	
+	private Integer freezeClm;
+	
+	private Integer freezeRow;
+	
+	private TableTd[]   tds;
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public int getRowCount() {
+		return rowCount;
+	}
+
+	public void setRowCount(int rowCount) {
+		this.rowCount = rowCount;
+	}
+
+	public int getColumnCount() {
+		return columnCount;
+	}
+
+	public void setColumnCount(int columnCount) {
+		this.columnCount = columnCount;
+	}
+
+	public TableTd[] getTds() {
+		return tds;
+	}
+
+	public void setTds(TableTd[] tds) {
+		this.tds = tds;
+	}
+
+	public Integer getFreezeClm() {
+		return freezeClm;
+	}
+
+	public void setFreezeClm(Integer freezeClm) {
+		this.freezeClm = freezeClm;
+	}
+
+	public Integer getFreezeRow() {
+		return freezeRow;
+	}
+
+	public void setFreezeRow(Integer freezeRow) {
+		this.freezeRow = freezeRow;
+	}
+
+	public int[] getClmWidth() {
+		return clmWidth;
+	}
+
+	public void setClmWidth(int[] clmWidth) {
+		this.clmWidth = clmWidth;
+	}
+
+	public String getSecTitle() {
+		return secTitle;
+	}
+
+	public void setSecTitle(String secTitle) {
+		this.secTitle = secTitle;
+	}
+
+	
+
+	
+}

+ 185 - 0
src/main/java/com/hb/proj/excel/TableExporter.java

@@ -0,0 +1,185 @@
+package com.hb.proj.excel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+public class TableExporter {
+
+	public static HSSFWorkbook buildExcel(Table tab){
+		HSSFWorkbook workbook = new HSSFWorkbook();
+        HSSFSheet sheet = workbook.createSheet(tab.getTitle());
+        sheet.setDefaultColumnWidth(10);
+        sheet.setDefaultRowHeight((short)450);
+        //创建基本单元格
+        buildBase(tab,workbook,sheet);
+        
+        fillCell(tab,sheet);
+        
+        //插入标题
+        int lockRowExtr=0;
+        if(StringUtils.isNotEmpty(tab.getSecTitle())){
+        	insertSecTitleRow(tab,workbook,sheet);
+        	lockRowExtr+=1;
+        }
+        insertTitleRow(tab,workbook,sheet);
+        lockRowExtr+=1;
+        
+        if(tab.getFreezeClm()!=null&&tab.getFreezeRow()!=null){
+        	 sheet.createFreezePane(tab.getFreezeClm(), tab.getFreezeRow()+lockRowExtr);
+        }
+       
+        
+        return workbook;
+	}
+	
+	//插入标题栏
+	private static void insertTitleRow(Table tab,HSSFWorkbook workbook,HSSFSheet sheet){
+		sheet.shiftRows(0, sheet.getLastRowNum(),1,true,false);
+        HSSFRow row=sheet.createRow(0);
+        row.setHeight((short)550);
+        HSSFCell cell=row.createCell(0);
+        CellRangeAddress region = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex()+tab.getColumnCount()-1);
+		sheet.addMergedRegion(region);
+		
+		
+		 Font font=workbook.createFont();
+		 font.setFontHeightInPoints((short) 20);
+	     font.setFontName("Courier New ");
+	     font.setBold(true);
+	     CellStyle style=workbook.createCellStyle();
+	     style.setVerticalAlignment(VerticalAlignment.CENTER);
+	     style.setAlignment(HorizontalAlignment.CENTER);
+	     style.setFont(font);
+	     cell.setCellStyle(style);
+	     cell.setCellValue(tab.getTitle());
+	}
+	
+	//插入二级标题栏
+	private static void insertSecTitleRow(Table tab,HSSFWorkbook workbook,HSSFSheet sheet){
+		sheet.shiftRows(0, sheet.getLastRowNum(),1,true,false);
+        HSSFRow row=sheet.createRow(0);
+        row.setHeight((short)550);
+        HSSFCell cell=row.createCell(0);
+        CellRangeAddress region = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex()+tab.getColumnCount()-1);
+		sheet.addMergedRegion(region);
+		
+		
+		 Font font=workbook.createFont();
+		 font.setFontHeightInPoints((short) 14);
+	     font.setFontName("Courier New ");
+	     //font.setBold(true);
+	     CellStyle style=workbook.createCellStyle();
+	     style.setVerticalAlignment(VerticalAlignment.CENTER);
+	     style.setAlignment(HorizontalAlignment.LEFT);
+	     style.setFont(font);
+	     cell.setCellStyle(style);
+	     cell.setCellValue(tab.getSecTitle());
+	}	
+	
+	//在excel中单元格合并后,索引还是从原有格算起
+	private static void fillCell(Table tab,HSSFSheet sheet){
+		TableTd[]  tds=tab.getTds();
+		int maxClm=tab.getColumnCount();
+		int clmIdx=0,rowIdx=0;
+		HSSFCell cell=null;
+		CellRangeAddress region=null;
+		Map<String,String> cellUseTag=new HashMap<String,String>(); //已经被使用的单元格
+		String val=null;
+		for(int i=0,len=tds.length;i<len;){
+			if(clmIdx>=maxClm){ //换行
+				rowIdx+=1;
+				clmIdx=0;
+			}
+			if(cellUseTag.containsKey(clmIdx+"_"+rowIdx)){ //已经使用过(被合并单元格占用)
+				clmIdx++;
+				continue;
+			}
+			cell=sheet.getRow(rowIdx).getCell(clmIdx);
+			
+			val=tds[i].getTxt();
+			if(val.indexOf("<br>")>0){
+				cell.setCellValue(new HSSFRichTextString(val.replace("<br>", "\r\n")));
+				sheet.getRow(rowIdx).setHeight((short)700);
+			}
+			else{
+				cell.setCellValue(tds[i].getTxt());
+			}
+			
+			if(tds[i].getColspan()>1||tds[i].getRowspan()>1){  //合并单元格
+				region = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex()+tds[i].getRowspan()-1, cell.getColumnIndex(), cell.getColumnIndex()+tds[i].getColspan()-1);
+				sheet.addMergedRegion(region);
+				clmIdx+=tds[i].getColspan();  //下一列
+				addUseTag(cellUseTag,region.getFirstRow(),region.getLastRow(),region.getFirstColumn(),region.getLastColumn());
+			}
+			else{
+				addUseTag(cellUseTag,rowIdx,clmIdx);
+				clmIdx+=1; //下一列
+			}
+			i++; //只有实际使用了Td才向后迭代
+		}
+	}
+	
+	
+	private static void addUseTag(Map<String,String> cellUseTag,int rowIdx,int clmIdx){
+		addUseTag(cellUseTag,rowIdx,rowIdx,clmIdx,clmIdx);
+	}
+	
+	private static void addUseTag(Map<String,String> cellUseTag,int startRow,int endRow,int startClm,int endClm){
+		int clmIdx=startClm;
+		while(startRow<=endRow){
+			clmIdx=startClm;
+			while(clmIdx<=endClm){
+				cellUseTag.put(clmIdx+"_"+startRow, "1");
+				clmIdx++;
+			}
+			startRow++;
+		}
+	}
+	
+	
+	private static void buildBase(Table tab,HSSFWorkbook workbook, HSSFSheet sheet){
+		HSSFCellStyle cellStyle=workbook.createCellStyle();
+        cellStyle.setWrapText(true);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setBorderTop(BorderStyle.THIN);
+        cellStyle.setBorderRight(BorderStyle.THIN);
+        cellStyle.setBorderBottom(BorderStyle.THIN);
+        cellStyle.setBorderLeft(BorderStyle.THIN);
+        cellStyle.setTopBorderColor(IndexedColors.BLACK.index);
+        cellStyle.setRightBorderColor(IndexedColors.BLACK.index);
+        cellStyle.setBottomBorderColor(IndexedColors.BLACK.index);
+        cellStyle.setLeftBorderColor(IndexedColors.BLACK.index);
+        HSSFRow row=null;
+        HSSFCell cell=null;
+        for(int r=0,len=tab.getRowCount();r<len;r++){
+        	row = sheet.createRow(r);
+        	for(int c=0,clen=tab.getColumnCount();c<clen;c++){
+        		cell=row.createCell(c);
+        		cell.setCellStyle(cellStyle);
+        	}
+        }
+        //设置各列宽度
+        int[] clmw=tab.getClmWidth();
+        for(int c=0,clen=tab.getColumnCount();c<clen;c++){
+        	sheet.setColumnWidth(c, (int)(clmw[c]*35.7));  //35.7  px转poi单元格宽度
+        }
+	}
+	
+	
+}

+ 34 - 0
src/main/java/com/hb/proj/excel/TableTd.java

@@ -0,0 +1,34 @@
+package com.hb.proj.excel;
+
+public class TableTd {
+
+	private String txt;
+	
+	private int rowspan=1;
+	
+	private int colspan=1;
+
+	public String getTxt() {
+		return txt;
+	}
+
+	public void setTxt(String txt) {
+		this.txt = txt;
+	}
+
+	public int getRowspan() {
+		return rowspan;
+	}
+
+	public void setRowspan(int rowspan) {
+		this.rowspan = rowspan;
+	}
+
+	public int getColspan() {
+		return colspan;
+	}
+
+	public void setColspan(int colspan) {
+		this.colspan = colspan;
+	}
+}

+ 57 - 0
src/main/java/com/hb/proj/excel/imp/CellConfig.java

@@ -0,0 +1,57 @@
+package com.hb.proj.excel.imp;
+
+public class CellConfig {
+
+	private String id;
+	
+	private String name;
+	
+	private String title;
+	
+	private String dataType;
+	
+	private Boolean require=false;
+	
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public String getDataType() {
+		return dataType;
+	}
+
+	public void setDataType(String dataType) {
+		this.dataType = dataType;
+	}
+
+	public Boolean isRequire() {
+		return require;
+	}
+
+	public void setRequire(Boolean require) {
+		this.require = require;
+	}
+
+	
+}

+ 56 - 0
src/main/java/com/hb/proj/excel/imp/ExcelConfig.java

@@ -0,0 +1,56 @@
+package com.hb.proj.excel.imp;
+
+import java.util.List;
+
+public class ExcelConfig {
+
+	private int sheet;  //被导入的数据的sheet索引从0开始,默认为0
+	
+	private String start;  //数据区域的最左上角单元格索引,以excel中的命名方式
+	
+	private String end;
+	
+	private List<CellConfig> block ;  //区块格子
+	
+	private List<CellConfig> cells ;  //零散提取格子
+
+	public int getSheet() {
+		return sheet;
+	}
+
+	public void setSheet(int sheet) {
+		this.sheet = sheet;
+	}
+
+	public String getStart() {
+		return start;
+	}
+
+	public void setStart(String start) {
+		this.start = start;
+	}
+
+	public List<CellConfig> getBlock() {
+		return block;
+	}
+
+	public void setBlock(List<CellConfig> block) {
+		this.block = block;
+	}
+
+	public List<CellConfig> getCells() {
+		return cells;
+	}
+
+	public void setCells(List<CellConfig> cells) {
+		this.cells = cells;
+	}
+
+	public String getEnd() {
+		return end;
+	}
+
+	public void setEnd(String end) {
+		this.end = end;
+	}
+}

+ 192 - 0
src/main/java/com/hb/proj/excel/imp/ExcelDataExtractor.java

@@ -0,0 +1,192 @@
+package com.hb.proj.excel.imp;
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+
+import com.hb.xframework.util.JsonParamHandler;
+
+
+
+
+public class ExcelDataExtractor {
+	
+	/**
+	 * 只支持单文件上传,需要传入template参数
+	 * @param request
+	 * @param response
+	 * @return
+	 * @throws Exception
+	 */
+	public static ExcelResult extractExcelData(HttpServletRequest request) throws Exception{
+		return extractExcelData(request,null);
+	}
+	
+	
+	public static ExcelResult extractExcelData(HttpServletRequest request,Map<String,String> otherParams) throws Exception{
+		
+		request.setCharacterEncoding("UTF-8");
+		DiskFileItemFactory factory = new DiskFileItemFactory();
+		factory.setSizeThreshold(10*1024*1024);
+		ServletFileUpload sfu = new ServletFileUpload(factory);
+		sfu.setSizeMax(10*1024 * 1024); // img size 10m
+		List<FileItem> items =sfu.parseRequest(request);
+		
+		Map<String,Object> extParams=new HashMap<String,Object>();
+		FileItem uploadFile=null;
+		for(FileItem itm : items){
+			if(itm.isFormField()){
+				extParams.put(itm.getFieldName(), itm.getString("UTF-8"));
+			}
+			else{
+				uploadFile=itm;
+			}
+			
+		}
+		if(StringUtils.isEmpty((String)extParams.get("config"))){  //excel配置
+			ExcelResult   excelRst=new ExcelResult();
+			excelRst.setException("缺失导入配置,取消操作");
+			return excelRst;
+		}
+		
+		ExcelConfig config=JsonParamHandler.getObject((String)extParams.get("config"), ExcelConfig.class);
+		
+		ExcelResult er= getDatas(uploadFile, config,request);
+		if(er!=null){
+			er.setReqParams(extParams);
+		}
+		return er;
+	}
+
+	
+	
+	public  static ExcelResult getDatas(FileItem item,ExcelConfig config,HttpServletRequest request) throws Exception{
+		ExcelResult   excelRst=new ExcelResult();
+		Workbook wb=WorkbookFactory.create(item.getInputStream());
+		Sheet sheet = wb.getSheetAt(config.getSheet());
+		List<CellConfig>  cellConfigs=config.getCells();
+		Object[] rsts=null;
+		if(cellConfigs!=null&&cellConfigs.size()>0){
+			for(CellConfig  cc : cellConfigs){
+				rsts=extractCell(sheet,cc);
+				
+				if(StringUtils.isNotEmpty((String)rsts[0])){
+					excelRst.addError((String)rsts[0]);
+				}
+				else{
+					excelRst.addOtherVal(cc.getName(), rsts[1]);
+				}
+			}
+		}
+		cellConfigs=config.getBlock();
+		if(cellConfigs!=null&&cellConfigs.size()>0){
+			extractBlock(sheet,config.getStart(),config.getEnd(),cellConfigs,excelRst);
+		}
+		return excelRst;
+	
+	}
+	
+	private static Cell getCell(Sheet sheet,CellConfig cellConfig){
+		int[]  indexs=ExcelTool.getIndex(cellConfig.getId());  //基于excel的索引
+		
+		return sheet.getRow(indexs[1]-1).getCell(indexs[0]-1);  //从0开始的索引
+		
+	}
+	
+	private static Object[] extractCell(Sheet sheet,CellConfig cellConfig){
+		Cell cell=getCell(sheet,cellConfig);
+		String val=getCellStringValue(cell);
+		return ExcelImportValidator.validate(val, cellConfig.getId(), cellConfig);  //数据验证,通过后进行数据类型转换   //rst[0]:验证结果;rst[1]:转换后的值
+	}
+	
+	private static void extractBlock(Sheet sheet,String start,String end,List<CellConfig>  headers,ExcelResult excelHolder){
+		int[]  startIndexs=ExcelTool.getIndex(start);
+		int[]  endIndexs=ExcelTool.getIndex(end);
+		int starRow=startIndexs[1]; //从1开始计算的
+		int endRow=endIndexs[1];
+		Object[]  rst=null;
+		Map<String,Object>  rowData=null;
+		while(starRow<=endRow&&!isNullRow(sheet.getRow(starRow-1))){
+			rowData=new HashMap<String,Object>();
+			for(CellConfig  cc : headers){
+				cc.setId(cc.getId().replaceAll("\\d+", String.valueOf(starRow))); //更新行号
+				rst=extractCell(sheet,cc);
+				
+				if(StringUtils.isNotEmpty((String)rst[0])){
+					excelHolder.addError((String)rst[0]);
+					rowData.clear();
+					break; //只要有一个字段不符合格式要求就不入库
+				}
+				else{
+					rowData.put(cc.getName(), rst[1]);
+				}
+			}
+			if(rowData.size()>0){
+				excelHolder.addRowVal(rowData);
+				
+			}
+			starRow++;
+		}
+		
+	}
+	
+	
+
+	private static String getCellStringValue(Cell cell){
+		if(cell==null){
+			return "";
+		}
+		String cellValue="";
+		switch (cell.getCellTypeEnum()) {
+		case NUMERIC:
+		case FORMULA: {
+			if (HSSFDateUtil.isCellDateFormatted(cell)) {
+				Date date = cell.getDateCellValue();
+				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+				cellValue = sdf.format(date);
+			} else {
+				DecimalFormat  numdf=new DecimalFormat("#0.##");
+				cellValue=numdf.format(cell.getNumericCellValue());
+			}
+			break;
+		}
+		case STRING:
+			cellValue = cell.getRichStringCellValue().toString().trim();
+			break;
+		default:
+			cellValue="";
+		}
+		
+		return cellValue;
+	}
+	
+	
+	private static boolean isNullRow(Row row){
+		if(row==null){
+			return true;
+		}
+		String val1=getCellStringValue(row.getCell(0));
+		String val2=getCellStringValue(row.getCell(1));
+		String val3=getCellStringValue(row.getCell(2));
+		if("".equals(val1.trim())&&"".equals(val2.trim())&&"".equals(val3.trim())){
+			return true;
+		}
+		return false;
+	}
+}

+ 84 - 0
src/main/java/com/hb/proj/excel/imp/ExcelImportValidator.java

@@ -0,0 +1,84 @@
+package com.hb.proj.excel.imp;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.hb.xframework.util.DateUtil;
+
+public class ExcelImportValidator {
+
+	 public static boolean validate_date(String value,String format){
+	       String yyyyMMdd="^\\d{4}(\\-|\\/)\\d{1,2}(\\-|\\/)\\d{1,2}( (((0|1)[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9]))?$";
+	       Pattern p = Pattern.compile(yyyyMMdd);
+	 	   Matcher m = p.matcher(value);
+	 	   if(m.matches()){
+	 		   String joinStr=value.indexOf("-")>0?"-":"/";
+	 		   String[] ymd=(value.split(" "))[0].split(joinStr);
+	 		   int mon=Integer.parseInt(ymd[1]);
+	 		   int d=Integer.parseInt(ymd[2]);
+	 		   if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12){
+	 			   return d>0&&d<=31;
+	 		   }
+	 		   else if(mon==2){
+	 			  return d>0&&d<=29;
+	 		   }
+	 		   else if(mon==4||mon==6||mon==9||mon==11) {
+	 			  return d>0&&d<=30;
+	 		   }
+	 		   else{
+	 			   return false;
+	 		   }
+	 	   }
+	       return false;
+			
+		}
+	 
+	 public static boolean validate_int(String value){
+	    	Pattern p = Pattern.compile("^-?\\d+$");
+	  	    Matcher m = p.matcher(value);
+	        return m.matches();
+	 }
+	 
+	 public static boolean validate_number(String value){
+	    	Pattern p = Pattern.compile("^-?\\d+(\\.\\d+)?$");
+	  	    Matcher m = p.matcher(value);
+	        return m.matches();
+	 }
+	 
+	 public static Object[] validate(String value,String cellName,CellConfig rule){
+		    if(rule.isRequire()&&StringUtils.isEmpty(value)){
+	    		return new Object[]{"第"+cellName+"格,"+rule.getTitle()+",不应为空",null};
+	    	}
+		    if(StringUtils.isEmpty(value)){
+		    	return new Object[]{null,null};
+		    }
+	    	boolean rst=true;
+	    	String dataType=rule.getDataType();
+	    	Object valObj=value;
+	    	if("date".equals(dataType)){
+	    		rst=validate_date(value,null);
+	    		if(rst){
+	    			valObj=DateUtil.parse(value);
+	    		}
+	    	}
+	    	else if("int".equals(dataType)){
+	    		rst=validate_int(value);
+	    		if(rst){
+	    			valObj=Integer.parseInt(value);
+	    		}
+	    	}
+	    	else if("number".equals(dataType)){
+	    		rst=validate_number(value);
+	    		if(rst){
+	    			valObj=Double.parseDouble(value);
+	    		}
+	    	}
+	    	if(!rst){
+	    		return new Object[]{"第"+cellName+"格,"+rule.getTitle()+",数据格式不对",valObj};
+	    	}
+	        return new Object[]{null,valObj};
+	    }
+	    
+}

+ 78 - 0
src/main/java/com/hb/proj/excel/imp/ExcelResult.java

@@ -0,0 +1,78 @@
+package com.hb.proj.excel.imp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ExcelResult {
+
+	private List<Map<String,Object>> listDatas; //区块单元格集值
+	
+	private Map<String,Object>  otherData; //零散的单元格值
+	
+	private Map<String,Object>  reqParams;  //导入时附带的参数
+	
+	private StringBuilder error;
+	
+	private String exception;
+	
+	
+	public ExcelResult(){
+		this.listDatas=new ArrayList<Map<String,Object>>();
+		this.otherData=new HashMap<String,Object>();
+		this.error=new StringBuilder();
+	}
+
+	public List<Map<String, Object>> getListDatas() {
+		return listDatas;
+	}
+
+	public void setListDatas(List<Map<String, Object>> listDatas) {
+		this.listDatas = listDatas;
+	}
+
+	public Map<String, Object> getOtherData() {
+		return otherData;
+	}
+
+	public void setOtherData(Map<String, Object> otherData) {
+		this.otherData = otherData;
+	}
+
+	public StringBuilder getError() {
+		return error;
+	}
+
+	public void setError(StringBuilder error) {
+		this.error = error;
+	}
+	
+	public void addError(String error){
+		this.error.append(error+";");
+	}
+	
+	public void addOtherVal(String name,Object val){
+		this.otherData.put(name, val);
+	}
+	
+	public void addRowVal(Map<String,Object> record){
+		this.listDatas.add(record);
+	}
+
+	public String getException() {
+		return exception;
+	}
+
+	public void setException(String exception) {
+		this.exception = exception;
+	}
+
+	public Map<String, Object> getReqParams() {
+		return reqParams;
+	}
+
+	public void setReqParams(Map<String, Object> reqParams) {
+		this.reqParams = reqParams;
+	}
+}

+ 31 - 0
src/main/java/com/hb/proj/excel/imp/ExcelTool.java

@@ -0,0 +1,31 @@
+package com.hb.proj.excel.imp;
+
+import java.util.Date;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.hb.xframework.util.DateUtil;
+
+public class ExcelTool {
+
+	public static int[] getIndex(String columnName){  //columnName=A1
+		if(StringUtils.isEmpty(columnName)){
+			return null;
+		}
+		String[] ary=columnName.toUpperCase().split("\\d+");
+		char[]  chars=ary[0].toCharArray();
+		int c=0;
+		for(int i=chars.length-1,m=0;i>=0;i--,m++){
+			c+=(chars[i]-64)*Math.pow(26, m);
+		}
+		return new int[]{c,Integer.parseInt(columnName.replace(ary[0], ""))};
+	}
+	
+	
+	public static void main(String... args){
+		int[] rst=ExcelTool.getIndex("AA10");
+		System.out.println(rst[0]+":"+rst[1]);
+		Date t=DateUtil.parse("2017-9-8");
+		System.out.println(t.getTime());
+	}
+}

+ 464 - 0
src/main/java/com/hb/proj/input/controller/CarConsumeController.java

@@ -0,0 +1,464 @@
+package com.hb.proj.input.controller;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.car.service.CarService;
+import com.hb.proj.excel.ExcelUtils;
+import com.hb.proj.excel.imp.ExcelDataExtractor;
+import com.hb.proj.excel.imp.ExcelResult;
+import com.hb.proj.input.service.CarConsumeService;
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsumeBO;
+import com.hb.proj.sysdata.service.OrgService;
+import com.hb.proj.sysdata.service.SortCodeService;
+import com.hb.proj.utils.DataAuthUtils;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.xframework.dao.util.PageModel;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+
+
+@Controller
+@RequestMapping("/**/consume")
+public class CarConsumeController {
+	
+	@Autowired
+	private CarConsumeService service;
+	
+	@Autowired
+	private CarService  carService;
+	
+	@Autowired
+	private OrgService  orgService;
+	
+	@Autowired
+	private SortCodeService  codeService;
+
+	/**
+	 * 加载上报数据,没有则提供空白行(本部门的车辆基本信息)供填写(页面上报列表应以已上报数据为主为结果集(同一车不同地区是多条记录))
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/load")
+	public void load(String carOrCustomNum,String rptMonth,Integer page,Integer limit,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+			}
+			Set<String>  authAssistCode=DataAuthUtils.getAuthOrgAssistCode(su);
+			if(authAssistCode==null||authAssistCode.size()==0){
+				LayGridJsonUtils.error(response, "缺少上报单位信息");
+				return;
+			}
+			if(StringUtils.isEmpty(rptMonth)){
+				Calendar ca=Calendar.getInstance();
+				rptMonth=ca.get(Calendar.YEAR)+"-"+String.format("%02d", ca.get(Calendar.MONTH)); //默认上报上个月
+			}
+			PageModel<Map<String,Object>> pagedData=carService.loadCarForInput(carOrCustomNum,rptMonth,authAssistCode,page, limit);
+			if(pagedData==null||pagedData.getData()==null||pagedData.getData().size()==0){
+				LayGridJsonUtils.wirte(response, null,0);
+				return;
+			}
+			
+			Map<String,Map<String,Object>> carMap=new LinkedHashMap<String,Map<String,Object>>(pagedData.getData().size());
+			for(Map<String,Object> car : pagedData.getData()){
+				car.put("rptDate", rptMonth+"-01");
+				car.put("realAge", getWorkAge((String)car.get("wkStart"),rptMonth));
+				carMap.put((String)car.get("carId"), car);
+			}
+			List<Map<String,Object>> rundatas=service.loadConsume(rptMonth,su.getOrgId(), carMap.keySet());
+			if(rundatas==null||rundatas.size()==0){
+				LayGridJsonUtils.wirte(response, pagedData.getData(),pagedData.getTotalRow());
+				return;
+			}
+			Map<String,Object>  car=null;
+			for(Map<String,Object> run : rundatas){  //车辆数据+运行数据合并
+				car=carMap.get((String)run.get("carId"));
+				if(car!=null){
+					run.putAll(car) ;    //car.putAll(run);以已上报记录为主为结果集,车辆信息中的customNum会覆盖已上报记录中的cuostomNum
+					//carMap.remove((String)run.get("carId")); //此时还不能删除,还有同车不同地区的记录需要用
+					car.put("hadUs", "1");  //标记为已使用
+				}
+			}
+			//还有上报的车辆也要加入结果集中
+			for(String key : carMap.keySet()){
+				car=carMap.get(key);
+				if(!car.containsKey("hadUs")){
+					rundatas.add(car);
+				}
+			}
+			
+			LayGridJsonUtils.wirte(response, rundatas,rundatas.size(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+		
+	}
+	
+	
+	
+	/**
+	 * 保存车辆油耗上报数据
+	 * @param jsonDatas
+	 * @param  oil92 92汽油总量 来自 other上报
+	 * @param  oil95 95汽油总量 来自 other上报
+	 * @param response
+	 */
+	@RequestMapping("/save")
+	public void save(String jsonDatas,Double oil92,Double oil95,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null||StringUtils.isEmpty(su.getOrgId())){  
+				JsonOutUtils.returnError(response, "缺少登录信息或上报单位,请用非管理账号登录后再试");
+				return;
+			}
+			
+			List<CarConsume> consumes=JSON.parseObject(jsonDatas,new TypeReference<List<CarConsume>>() {});
+			if(consumes==null||consumes.size()==0){
+				JsonOutUtils.returnOk(response);
+				return;
+			}
+			
+			//检测当前是否在上报期限内
+			String limitRst=consumes.get(0).getRptDate()==null?null:InputDateLimit.check(DateUtil.format(consumes.get(0).getRptDate(), "yyyy-MM"));
+			if(limitRst!=null){
+				JsonOutUtils.returnError(response,limitRst);
+				return;
+			}
+			
+			service.saveConsume(consumes,CarRptUtils.getOilWeightRatio(oil92, oil95));
+			JsonOutUtils.returnOk(response);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	/**
+	 * 根据投产月份和统计月份计算实际使用年数
+	 * @param startMonth
+	 * @param rptMonth
+	 * @return
+	 */
+	private Integer getWorkAge(String startMonth,String rptMonth){
+		if(StringUtils.isEmpty(startMonth)||StringUtils.isEmpty(rptMonth)){
+			return null;
+		}
+		String[] ym=startMonth.split("-"),ym2=rptMonth.split("-");
+		int age=Integer.parseInt(ym2[0])-Integer.parseInt(ym[0]);
+		if(Integer.parseInt(ym2[1])>=Integer.parseInt(ym[1])){  //足月
+			return age+1;
+		}
+		else{
+			return age;
+		}
+	}
+	
+	
+	/**
+	 * 加载各项目部每月其它用油
+	 * @param rptMonth
+	 * @param response
+	 */
+	@RequestMapping("/other/load")
+	public void loadOtherConsume(String rptMonth,HttpServletResponse response){
+		MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+		if(su==null||StringUtils.isEmpty(su.getOrgId())){  //测试暂时不用
+			JsonOutUtils.returnError(response, "缺少登录信息或上报单位");
+			return;
+		}
+		OtherConsumeBO otherConsume=service.getOtherConsume(rptMonth, su.getOrgId());
+		if(otherConsume==null){
+			JsonOutUtils.returnOk(response);
+		}
+		JsonOutUtils.returnOkWithData(response, otherConsume);
+	}
+	
+	/**
+	 * 保存各项目部每月其它用油
+	 * @param rptMonth
+	 * @param oil
+	 * @param coil
+	 * @param response
+	 */
+	
+	@RequestMapping("/other/save")
+	public void saveOtherConsume(String jsonData,HttpServletResponse response){
+		MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+		if(su==null){  //测试暂时不用
+			JsonOutUtils.returnError(response, "缺少登录信息");
+			return;
+		}
+		
+		OtherConsumeBO  othOil=JSON.parseObject(jsonData,new TypeReference<OtherConsumeBO>() {});
+		
+		//检测当前是否在上报期限内
+		String limitRst=InputDateLimit.check(DateUtil.format(othOil.getRptMonth(), "yyyy-MM"));
+		if(limitRst!=null){
+			JsonOutUtils.returnError(response,limitRst);
+			return;
+		}
+		
+		othOil.setModifier(su.getUserName());
+		othOil.setOrgId(su.getOrgId());
+		service.saveOtherConsume(othOil,true);
+		JsonOutUtils.returnOk(response);
+	}
+	
+	
+	/**
+	 * 导入车辆油耗、其它油耗数据
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/importCarConsume")
+	public void importCarConsume(HttpServletRequest request,HttpServletResponse response){
+		try{
+			ExcelResult importRst=ExcelDataExtractor.extractExcelData(request);
+			if(importRst==null||importRst.getException()!=null){
+				JsonOutUtils.returnError(response,(importRst==null?"导入失败":importRst.getException()));
+				return;
+			}
+			else if(importRst.getListDatas()==null||importRst.getListDatas().size()==0){
+				JsonOutUtils.returnError(response,"未提取到符合格式的数据");
+				return;
+			}
+			Map<String,Object> otherImp=importRst.getOtherData();
+			if(otherImp==null||otherImp.get("rptOrg")==null||otherImp.get("rptMonth")==null){
+				JsonOutUtils.returnError(response,"缺少上报单位或上报月份");
+				return;
+			}
+			
+			//检测当前是否在上报期限内
+			String limitRst=InputDateLimit.check(DateUtil.format((Date)otherImp.get("rptMonth"), "yyyy-MM"));
+			if(limitRst!=null){
+				JsonOutUtils.returnError(response,limitRst);
+				return;
+			}
+			
+			
+			Map<String,Object> orgs=orgService.loadOrgMapping();
+			if(!orgs.containsKey(otherImp.get("rptOrg"))){
+				JsonOutUtils.returnError(response,"上报单位并非系统内的单位");
+				return;
+			}
+			
+			otherImp.put("orgId", orgs.get(otherImp.get("rptOrg"))); //上报单位转为orgId
+			
+			String jsonData=JSON.toJSONString(otherImp);
+			OtherConsumeBO othConsume=JSON.parseObject(jsonData,new TypeReference<OtherConsumeBO>() {});
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			othConsume.setModifier(su!=null?su.getUserName():null);
+			
+			String[] msgs=processImportData(importRst,othConsume.getRptMonth()); //carNums+ignorCarNums
+			
+			boolean sameCover="1".equals(importRst.getReqParams().get("sameCover")); //相同车辆、月份是否覆盖库中的
+			
+			String  jsonConsume=JSON.toJSONString(importRst.getListDatas());
+			List<CarConsume> consumes=JSON.parseObject(jsonConsume,new TypeReference<List<CarConsume>>() {});
+			
+			String equalMsg=equalCheck(consumes,othConsume);
+			String sameIgnor=service.addConsumesFromExcel(consumes,othConsume,sameCover);
+			
+			/**
+			 * sameIgnor  禁止覆盖时被忽略的车牌
+			 * checkIgnor 业务校验不通过的车牌
+			 * validateError 基本数据校验错误信息
+			 */
+			Map<String,Object>  rtn=MapUtils.build("equalMsg",equalMsg,"sameIgnor",sameIgnor,"checkIgnor",msgs[1],"validateError",importRst.getError().toString(),"successCount",consumes.size());
+			JsonOutUtils.returnOkWithData(response,rtn);
+			
+			
+			
+			
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "导入出现错误");
+		}
+	}
+	
+	/**
+	 * 检测项目部上报的总计数据是否和单车的合计数据一致
+	 * @param consumes
+	 * @param othConsume
+	 * @return
+	 */
+	private String equalCheck(List<CarConsume> consumes,OtherConsumeBO othConsume){
+		Double oilErp=null,oilKl=null,coilErp=null,coilKl=null;
+		for(CarConsume car : consumes){
+			oilErp=CarRptUtils.addDouble(oilErp,car.getOilErp());
+			oilKl=CarRptUtils.addDouble(oilKl,car.getOilKl());
+			coilErp=CarRptUtils.addDouble(coilErp,car.getCoilErp());
+			coilKl=CarRptUtils.addDouble(coilKl,car.getCoilKl());
+		}
+		Double oilErpTotal=CarRptUtils.addDouble(othConsume.getOilErp92(),othConsume.getOilErp95());
+		Double oilKlTotal=CarRptUtils.addDouble(othConsume.getOilKl92(),othConsume.getOilKl95());
+		
+		//单车合计还要加上其它用油才能与总计比较一致性,比较时只能比较汽油、柴油总量(因为其它用油不区分ERP、昆仑卡)
+		Double oilTotal=CarRptUtils.addDouble(oilErpTotal,oilKlTotal);
+		Double coilTotal=CarRptUtils.addDouble(othConsume.getCoilErpCount(),othConsume.getCoilKlCount());
+		Double oilSum=CarRptUtils.addDouble(oilErp,oilKl);
+		oilSum=CarRptUtils.addDouble(oilSum,othConsume.getOilCount());
+		
+		Double coilSum=CarRptUtils.addDouble(coilErp,coilKl);
+		coilSum=CarRptUtils.addDouble(coilSum,othConsume.getCoilCount());
+		
+		StringBuilder msg=new StringBuilder();
+		if(!equalDouble(oilSum,oilTotal)){
+			msg.append(String.format("汽油耗量总计【ERP+昆仑卡=%s】和单车合计【单车ERP+单车昆仑卡+其它=%s】不一致;",getStr(oilTotal),getStr(oilSum)));
+		}
+		if(!equalDouble(coilSum,coilTotal)){
+			msg.append(String.format("柴油耗量总计【ERP+昆仑卡=%s】和单车合计【单车ERP+单车昆仑卡+其它=%s】不一致;",getStr(coilTotal),getStr(coilSum)));
+		}
+		return msg.length()>0?msg.toString():null;
+	}
+	
+	private boolean equalDouble(Double d1,Double d2){
+		if(d1==null&&d2==null){
+			return true;
+		}
+		if(d1!=null&&d2!=null&&d1.doubleValue()==d2.doubleValue()){
+			return true;
+		}
+		return false;
+	}
+	
+	private String getStr(Object obj){
+		return obj==null?"空":obj.toString();
+	}
+	
+	/**
+	 * 对上传的原始数据进行处理,业务约束校验、数据转换(名称转编码)
+	 * 目前校验车牌是否与系统内的对应,对应则转为carId
+	 */
+	@SuppressWarnings("unchecked")
+	private String[] processImportData(ExcelResult importRst,Date rptMonth){
+		Map<String,Object>  cars=carService.loadCarObjMapping();
+		Map<String,Object>  workAreas=carService.loadWorkAreaMapping();
+		StringBuilder ignorMsg=new StringBuilder();
+		Set<String> impcarNums=new HashSet<String>();
+		Iterator<Map<String,Object>> iterator=importRst.getListDatas().iterator();
+		Map<String,Object> itm=null;
+		Map<String,Object> car=null;
+		String carNum=null;
+		while(iterator.hasNext()){
+			itm=iterator.next();
+			itm.put("rptDate", DateUtil.format(rptMonth, "yyyy-MM-dd"));
+			carNum=(String)itm.get("carNum");
+			carNum=carNum.replaceAll("\\s+", "");
+			if(StringUtils.isEmpty(carNum)){
+				iterator.remove();
+				ignorMsg.append(itm.get("customNum")+";");
+				continue;
+			}
+			itm.put("carNum", carNum);
+			if(!cars.containsKey(carNum)){   //||!workAreas.containsKey((String)itm.get("workArea"))
+				iterator.remove();
+				ignorMsg.append(itm.get("carNum")+";");
+				continue;
+			}
+			else{
+				car=(Map<String,Object>)cars.get(carNum);
+				impcarNums.add(carNum);
+				itm.put("workArea", workAreas.get((String)itm.get("workArea")));
+				itm.put("quotaAlternatorId", car.get("quotaAlternatorId"));
+				itm.put("quotaRuleId", car.get("quotaRuleId"));
+				itm.put("carId", car.get("carId"));
+				itm.put("oilType", car.get("oilType"));
+				itm.put("deviceName", car.get("deviceName"));
+				itm.put("deviceModel", car.get("deviceModel"));
+				itm.put("realAge", getWorkAge(DateUtil.format((Date)car.get("workStart"), "yyyy-MM"),DateUtil.format(rptMonth, "yyyy-MM"))); //realAge 必须有,否则不会对基础数据进行自动计算
+			}
+			
+			
+			
+		}
+		
+		return new String[]{StringUtils.join(impcarNums,","),(ignorMsg.length()>0?ignorMsg.toString():null)};
+	}
+	
+	/**
+	 * 下载导入模板(以车辆基本信息为主)
+	 * @param rptMonth
+	 * @param response
+	 */
+	@RequestMapping("/downloadTemp")
+	public void downloadTemp(String rptMonth,HttpServletRequest request,HttpServletResponse response){
+		try{
+			if(StringUtils.isEmpty(rptMonth)){
+				JsonOutUtils.writeToResponse(response, "<script>alert('缺少上报月份');window.close();</script>","text/html;charset=UTF-8");
+				return;
+			}
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  //测试暂时不用
+				JsonOutUtils.writeToResponse(response, "<script>alert('缺少登录信息');window.close();</script>","text/html;charset=UTF-8");
+				return;
+			}
+			Set<String>  authAssistCode=DataAuthUtils.getAuthOrgAssistCode(su);
+			if(authAssistCode==null||authAssistCode.size()==0){
+				JsonOutUtils.writeToResponse(response, "<script>alert('缺少上报单位信息');window.close();</script>","text/html;charset=UTF-8");
+				return;
+			}
+			PageModel<Map<String,Object>> pagedData=carService.loadCarForInput(null,rptMonth,authAssistCode,1, 1000);
+			if(pagedData==null||pagedData.getData()==null||pagedData.getData().size()==0){
+				JsonOutUtils.writeToResponse(response, "<script>alert('没有车辆需要上报数据');window.close();</script>","text/html;charset=UTF-8");
+				return;
+			}
+			
+			Map<String,Object> workAreaMap=carService.loadWorkAreaMapping();
+			
+			
+			String rptOrg=su.getOrgName()!=null?su.getOrgName():"";
+			String templateName=File.separator+"excel"+File.separator+"车辆油耗上报导入模板.xls";
+			Map<String,Object> context=new HashMap<String,Object>();
+			context.put("ds", pagedData.getData());
+			context.put("rptOrg", rptOrg);
+			context.put("rptMonth", DateUtil.parse(rptMonth+"-01"));
+			
+			if(workAreaMap!=null&&workAreaMap.size()>0){
+				String[] wa=new String[workAreaMap.size()];
+				workAreaMap.keySet().toArray(wa);
+				context.put("workAreas",wa);
+			}
+			
+			Workbook wb=ConsumeInputTempBound.bound(context,ExcelUtils.reader(templateName,request.getSession().getServletContext()));
+			ExcelUtils.exportExcel(response, "车辆油耗上报模板("+rptOrg+rptMonth+")", wb);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.writeToResponse(response, "<script>alert('下载导入模板出现错误');window.close();</script>","text/html;charset=UTF-8");
+		}
+	}
+	
+}

+ 92 - 0
src/main/java/com/hb/proj/input/controller/ConsumeInputTempBound.java

@@ -0,0 +1,92 @@
+package com.hb.proj.input.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hssf.usermodel.DVConstraint;
+import org.apache.poi.hssf.usermodel.HSSFDataValidation;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddressList;
+
+import com.hb.proj.excel.ExcelSupport;
+
+public class ConsumeInputTempBound {
+
+	@SuppressWarnings("unchecked")
+	public static Workbook bound(Map<String,Object> context,Workbook wb){
+		Sheet sheet=wb.getSheetAt(0);
+		Row  row=null;
+		Cell cell=null;
+		int parseIndex=1;  //开始解析的行索引,从0开始计数
+		String cellVal=null;
+		
+		preProcess(sheet,context);
+		
+        while(!ExcelSupport.isNullRow(sheet, parseIndex))
+		{
+			 row=sheet.getRow(parseIndex);
+			 if(parseIndex==1){ //特殊处理
+				 ExcelSupport.setValue(row.getCell(1),context.get("rptMonth"));
+			 }
+			 if(parseIndex==6){
+				 String datasetName=ExcelSupport.getDatasetName(row.getCell(0));
+				 parseIndex=fillDatas((List<Map<String,Object>>)context.get(datasetName),sheet,row);
+				 continue;
+			 }
+			 context.put("r", parseIndex);
+			 for(int c=0,clen=row.getPhysicalNumberOfCells();c<clen;c++){
+				 cell=row.getCell(c);
+				 cellVal=ExcelSupport.getCellStringValue(cell);
+				 if(cellVal.startsWith("$=")){
+					 ExcelSupport.setValue(cell,ExcelSupport.executeContextExp(cellVal,context));
+					 continue;
+				 }
+				 else{
+					 continue;
+				 }
+			 }
+			 parseIndex++;
+		}
+        return wb;
+	}
+	public static int fillDatas(List<Map<String,Object>> dataset,Sheet sheet,Row row){
+		int dataRowStart=row.getRowNum();
+		if(dataset==null||dataset.size()==0){
+			sheet.removeRow(row);  //删除数据,保留行
+			return ++dataRowStart;
+		}
+		ExcelSupport.insertRow(sheet, dataRowStart, dataset.size()-1);  //模板行也显示数据,-1  特殊-2
+		Map<String,List<String>>  mapFields=ExcelSupport.getFields(row);
+		List<String> fields=mapFields.get("fields");
+		int rowIdx=row.getRowNum();
+		for(Map<String,Object> data : dataset){
+			row=sheet.getRow(rowIdx++);
+			for(int f=0,flen=fields.size();f<flen;f++){
+				ExcelSupport.setValue(row.getCell(f),data.get(fields.get(f)));
+			}
+		}
+		return rowIdx;
+	}
+	
+	/**
+	 * 预处理 地区设置为下拉选择
+	 * @param context
+	 */
+	@SuppressWarnings("unchecked")
+	public static void preProcess(Sheet sheet,Map<String,Object> context){
+		String[] workAreas=(String[])context.get("workAreas");
+		List<Map<String,Object>> ds=(List<Map<String,Object>>)context.get("ds");
+		if(workAreas==null||workAreas.length==0||ds==null||ds.size()==0){
+			return ;
+		}
+		int firstRow=6,endRow=firstRow+ds.size()-1;
+		
+		CellRangeAddressList regions = new CellRangeAddressList(firstRow,endRow, 2, 2);
+		DVConstraint constraint = DVConstraint.createExplicitListConstraint(workAreas);
+		HSSFDataValidation data_validation_list = new HSSFDataValidation(regions, constraint);  
+        sheet.addValidationData(data_validation_list); 
+	}
+}

+ 76 - 0
src/main/java/com/hb/proj/input/controller/InputDateLimit.java

@@ -0,0 +1,76 @@
+package com.hb.proj.input.controller;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+import com.hb.proj.utils.RptMonthUtil;
+import com.hb.xframework.util.DateUtil;
+
+
+/**
+ * @author xe
+ *
+ */
+public class InputDateLimit {
+	
+	/**
+	 * 根据统计月份获得月份的开始日期和结束日期(上月16号00:00:00到本月15号23:59:59)
+	 * 
+	 * @param yyyy-MM
+	 * @return start-end 不含end在内
+	 */
+	public static Date[] getStartEndInRptMonth(String yyyMM){
+		String splitDate=String.format("%s-%02d", yyyMM,RptMonthUtil.getMonthSplitDay());
+		Date end=DateUtil.parse(splitDate);
+		Calendar ca=Calendar.getInstance();
+		ca.setTime(end);
+		ca.add(Calendar.MONTH, -1);
+		return new Date[]{ca.getTime(),end};
+	}
+	
+	/**
+	 * 上报数据前进行上报期限的判断
+	 * 一般为本月16日零点-下月1日零点前
+	 * @param rptMonth
+	 * @return
+	 */
+	public static String check(String rptMonth){
+		if(StringUtils.isEmpty(rptMonth)){
+			return "未指定上报月份";
+		}
+		QuotaConfig quotaConfig=QuotaStandardSupport.getConfig();
+		if(quotaConfig.getRptStart()==null&&quotaConfig.getRptEnd()==null){ //未设定期限
+			return null;
+		}
+		
+		int rptMthNum=Integer.parseInt((rptMonth.split("-"))[1]);
+		Calendar ca=Calendar.getInstance();
+		int nowMth=ca.get(Calendar.MONTH)+1;
+		int day=ca.get(Calendar.DAY_OF_MONTH);
+		int diffMth=nowMth-rptMthNum;
+		if(diffMth>1){ //延期两个月及以上
+			return "已过上报最后期限【"+(rptMthNum+1)+"月"+quotaConfig.getRptEnd()+"日前】";
+		}
+		if(diffMth==1&&day>quotaConfig.getRptEnd().intValue()){ //次月超过规定日期。属于过期上报
+			return "已过上报最后期限【"+(rptMthNum+1)+"月"+quotaConfig.getRptEnd()+"日前】";
+		}
+		else if(diffMth<0){ //当前月份小于上报数据月份。属于超前上报
+			return "早于上报开始时间【"+rptMthNum+"月"+quotaConfig.getRptStart()+"日】";
+		}
+		else if(diffMth==0&&day<quotaConfig.getRptStart()){ //早于规定的起始日期
+			return "早于上报开始时间【"+rptMthNum+"月"+quotaConfig.getRptStart()+"日】";
+		}
+		return null;
+	}
+	
+	public static void main(String[] args){
+		Date[] rst=InputDateLimit.getStartEndInRptMonth("2021-10");
+		System.out.println(rst[0]);
+		System.out.println(rst[1]);
+	}
+
+}

+ 110 - 0
src/main/java/com/hb/proj/input/controller/WorkloadController.java

@@ -0,0 +1,110 @@
+package com.hb.proj.input.controller;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.input.service.WorkloadService;
+import com.hb.proj.model.Workload;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+
+
+@Controller
+@RequestMapping("/**/workload")
+public class WorkloadController {
+	
+	@Autowired
+	private WorkloadService service;
+
+	/**
+	 * 加载上报数据,没有则提供空白行供填写
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/load")
+	public void loadWorkload(HttpServletRequest request,String rptYear,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+			}
+			if(StringUtils.isEmpty(rptYear)){
+				Calendar ca=Calendar.getInstance();
+				rptYear=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			List<Map<String,Object>>  workload=service.queryWorkload(rptYear);
+			workload=wrapRecords(rptYear,workload);
+			LayGridJsonUtils.wirte(response, workload,workload.size(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+	}
+	
+	private List<Map<String,Object>> wrapRecords(String rptYear,List<Map<String,Object>>  wpg){
+		Map<String,Map<String,Object>> wpgIdx=null;
+		if(wpg!=null&&wpg.size()>0){
+			wpgIdx=new HashMap<String,Map<String,Object>>();
+			for(Map<String,Object> itm : wpg){
+				itm.put("rptMonth",DateUtil.format((Date)itm.get("rptMonth"), "yyyy-MM-dd"));
+				wpgIdx.put((String)itm.get("rptMonth"), itm);  
+			}
+		}
+		String key=null;
+		List<Map<String,Object>>  rst=new ArrayList<Map<String,Object>>(12);
+		Map<String,Object> newItm=null;
+		for(int i=1;i<=12;i++){
+			key=rptYear+"-"+String.format("%02d",i)+"-01";
+			newItm=MapUtils.build("rptMonth",key);
+			if(wpgIdx!=null&&wpgIdx.get(key)!=null){
+				newItm.putAll(wpgIdx.get(key));
+			}
+			rst.add(newItm);
+		}
+		
+		return rst;
+	}
+	
+	
+	@RequestMapping("/save")
+	public void saveWorkload(String jsonDatas,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				JsonOutUtils.returnError(response, "缺少登录信息,请登录后再试");
+				return;
+			}
+			
+			List<Workload> workload=JSON.parseObject(jsonDatas,new TypeReference<List<Workload>>() {});
+			service.saveWorkload(workload);
+			JsonOutUtils.returnOk(response);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	
+}

+ 133 - 0
src/main/java/com/hb/proj/input/controller/WpgController.java

@@ -0,0 +1,133 @@
+package com.hb.proj.input.controller;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+import com.hb.proj.input.service.WpgService;
+import com.hb.proj.model.Wpg;
+import com.hb.proj.utils.JsonOutUtils;
+import com.hb.proj.utils.LayGridJsonUtils;
+import com.hb.proj.utils.MySessionUser;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+
+
+@Controller
+@RequestMapping("/**/wpg")
+public class WpgController {
+	
+	@Autowired
+	private WpgService service;
+
+	/**
+	 * 加载上报数据,没有则提供空白行供填写
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/loadWpg")
+	public void loadWpg(HttpServletRequest request,String rptYear,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				LayGridJsonUtils.error(response, "缺少登录信息");
+				return;
+			}
+			if(StringUtils.isEmpty(rptYear)){
+				Calendar ca=Calendar.getInstance();
+				rptYear=String.valueOf(ca.get(Calendar.YEAR));
+			}
+			List<Map<String,Object>>  wpg=service.queryWpg(rptYear, su.getOrgId());
+			wpg=wrapRecords(rptYear,wpg);
+			LayGridJsonUtils.wirte(response, wpg,wpg.size(),"yyyy-MM-dd");
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			LayGridJsonUtils.error(response, "服务出现错误");
+		}
+	}
+	
+	private List<Map<String,Object>> wrapRecords(String rptYear,List<Map<String,Object>>  wpg){
+		Map<String,Map<String,Object>> wpgIdx=null;
+		if(wpg!=null&&wpg.size()>0){
+			wpgIdx=new HashMap<String,Map<String,Object>>();
+			for(Map<String,Object> itm : wpg){
+				itm.put("rptMonth",DateUtil.format((Date)itm.get("rptMonth"), "yyyy-MM-dd"));
+				wpgIdx.put((String)itm.get("rptMonth"), itm);  
+			}
+		}
+		String key=null;
+		List<Map<String,Object>>  rst=new ArrayList<Map<String,Object>>(12);
+		Map<String,Object> newItm=null;
+		for(int i=1;i<=12;i++){
+			key=rptYear+"-"+String.format("%02d",i)+"-01";
+			newItm=MapUtils.build("rptMonth",key);
+			if(wpgIdx!=null&&wpgIdx.get(key)!=null){
+				newItm.putAll(wpgIdx.get(key));
+			}
+			rst.add(newItm);
+		}
+		
+		return rst;
+	}
+	
+	
+	@RequestMapping("/save")
+	public void save(String jsonDatas,HttpServletResponse response){
+		try{
+			MySessionUser su=(MySessionUser)SessionThreadLocal.getSessionUser();
+			if(su==null){  
+				JsonOutUtils.returnError(response, "缺少登录信息,请登录后再试");
+				return;
+			}
+			
+			List<Wpg> wpgs=JSON.parseObject(jsonDatas,new TypeReference<List<Wpg>>() {});
+			String msg=checkWpg(wpgs);
+			service.saveWpg(wpgs);
+			
+			JsonOutUtils.returnOkWithData(response, msg);
+		}
+		catch(Exception e){
+			e.printStackTrace();
+			JsonOutUtils.returnError(response, "服务出现错误");
+		}
+		
+	}
+	
+	private String checkWpg(List<Wpg> wpgs){
+		if(wpgs==null||wpgs.size()==0){
+			return null;
+		}
+		StringBuilder msg=new StringBuilder();
+		String mth=null;
+		Iterator<Wpg>  iterator=wpgs.iterator();
+		Wpg wpg=null;
+		while(iterator.hasNext()){
+			wpg=iterator.next();
+			mth=DateUtil.format(wpg.getRptMonth(), "yyyy-MM");
+			if(InputDateLimit.check(mth)!=null){
+				msg.append(mth+";");
+				iterator.remove();
+			}
+		}
+		QuotaConfig quotaConfig=QuotaStandardSupport.getConfig();
+		return msg.length()>0?("以下月份的数据不在上报期限内(本月"+quotaConfig.getRptStart()+"号至下月"+quotaConfig.getRptEnd()+"号前),将忽略【"+msg.toString()+"】"):null;
+	}
+}

+ 245 - 0
src/main/java/com/hb/proj/input/service/CarConsumeService.java

@@ -0,0 +1,245 @@
+package com.hb.proj.input.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.model.CarConsume;
+import com.hb.proj.model.OtherConsumeBO;
+import com.hb.proj.model.OtherOilCalculater;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Service
+public class CarConsumeService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	
+	/**
+	 * 根据上报月份和车辆信息查询上报的运行数据
+	 * @param rptMonth
+	 * @param rptOrg
+	 * @param carIds
+	 * @return
+	 */
+	public List<Map<String,Object>>  loadConsume(String rptMonth,String rptOrg,Set<String> carIds){
+		if(carIds==null||carIds.size()==0){
+			return null;
+		}
+		String ids="'"+StringUtils.join(carIds,"','")+"'";
+		String sql="select r.* from t_car_consume r where car_id in ("+ids+") and rpt_org=? and DATE_FORMAT(rpt_date,'%Y-%m')=? order by custom_num";
+		return dao.queryForListMap(sql, rptOrg,rptMonth);
+	}
+	
+	
+	/**
+	 * 保存车辆上报数据
+	 * @param datas
+	 * @param weightRatio 带权重的汽油折算系数
+	 * @throws Exception
+	 */
+	public void saveConsume(List<CarConsume> datas,Double oilWeightRatio) throws Exception{
+		Set<String> existIds=new HashSet<String>();  //过滤出存在库里的运行记录,先进行删除再统一入库
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		final SessionUser su=SessionThreadLocal.getSessionUser();
+		for(CarConsume car : datas){
+			if(car.getRecordId()!=null){
+				existIds.add(car.getRecordId());
+			}
+			car.setRecordId(uuid.generate()) ; //作为新记录,重新设置主键
+			
+			//入库前进行基本统计数据的计算
+			CarRptUtils.rptCalculate(car,oilWeightRatio);
+		}
+		deleteConsume(existIds); //删除旧记录
+		StringBuilder pnsb=new StringBuilder();
+		pnsb.append("recordId,carId,travelMile,workHour,outHour,engineWorkHour,rptDate,modifyTime,modifier,rptOrg");
+		pnsb.append(",oilErp,oilKl,oilMeter,oilKlMoney,coilErp,coilKl,coilMeter,coilKlMoney,coilZsh");
+		pnsb.append(",checkMile,realCostPer100km,quotaPer100km,oilRealCost,coilRealCost,oilTotalQuota,coilTotalQuota,oilCoal,coilCoal,oilErpKg,oilKlKg,coilErpKg,coilKlKg,oilMeterKg,coilMeterKg");
+		pnsb.append(",workCost,outCost,engineCost,engineCostKg,customNum,workArea");
+		String[] pnary=pnsb.toString().split(",");
+		Map<String,Object> extraData=MapUtils.build("rptOrg",su.getOrgId(),"modifier",(su!=null?su.getUserName():"unknow"),"modifyTime",(new Date()));
+		dao.batchBeanInsert(datas, "t_car_consume", Arrays.asList(pnary),extraData);
+	}
+	
+	
+	
+	private void deleteConsume(Set<String> ids){
+		if(ids==null||ids.size()==0){
+			return;
+		}
+		String str="'"+StringUtils.join(ids,"','")+"'";
+		String sql="delete from t_car_consume where record_id in("+str+")";
+		dao.getJdbcTemplate().update(sql);
+	}
+	
+
+	public OtherConsumeBO  getOtherConsume(String rptMonth,String orgId){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select * from t_other_consume where org_id=? and DATE_FORMAT(rpt_month,'%Y-%m')=?");
+		return dao.queryForObject(sql.toString(),OtherConsumeBO.class, orgId,rptMonth);
+	}
+	
+	public Map<String,Object>  loadOtherConsume(String startMonth,String endMonth,String orgAssistCode){
+		StringBuilder sql=new StringBuilder(100);
+		sql.append("select sum(oil_count_kg) oil_count_kg,sum(coil_count_kg) coil_count_kg from t_other_consume c");
+		sql.append(" inner join t_org g on c.org_id=g.org_id");
+		sql.append(" where g.assist_code like ? and DATE_FORMAT(rpt_month,'%Y-%m') between ? and ?");
+		return dao.queryForSingleMap(sql.toString(), orgAssistCode+"%",startMonth,endMonth);
+	}
+	
+	public void saveOtherConsume(OtherConsumeBO consume,boolean sameCover){
+		if(sameCover){
+			String sql="delete from t_other_consume where org_id=? and DATE_FORMAT(rpt_month,'%Y-%m')=?";
+			dao.getJdbcTemplate().update(sql,consume.getOrgId(),DateUtil.format(consume.getRptMonth(), "yyyy-MM"));
+		}
+		
+		OtherOilCalculater.calculate(consume);
+		
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		consume.setRecordId(uuid.generate());
+		consume.setModifyTime(new Date());
+		dao.insertPojo(consume, "t_other_consume");
+		
+	}
+	
+	/**
+	 * 导入油耗数据(包括车辆油耗和其它油耗)
+	 * @param carCosumes
+	 * @param othConsume
+	 * @param sameCover
+	 * @return
+	 * @throws Exception
+	 */
+	public String addConsumesFromExcel(List<CarConsume> carCosumes,OtherConsumeBO othConsume,boolean sameCover) throws Exception{
+		 Double w92=CarRptUtils.addDouble(othConsume.getOilKl92(), othConsume.getOilErp92());
+		 Double w95=CarRptUtils.addDouble(othConsume.getOilKl95(), othConsume.getOilErp95());
+		 Double oilWeightRatio=CarRptUtils.getOilWeightRatio(w92, w95);
+		 String rst=addCarConsumesFromExcel(carCosumes,othConsume.getRptMonth(),othConsume.getOrgId(),sameCover,oilWeightRatio);
+		 addOtherConsumeFromExcel(othConsume,sameCover);
+		 return rst;
+	}
+	
+	/**
+	 * 导入其它油耗数据
+	 * @param othConsume
+	 * @param sameCover
+	 * @return
+	 */
+	public boolean addOtherConsumeFromExcel(OtherConsumeBO othConsume,boolean sameCover){
+		if(sameCover){ //允许覆盖,则先删除
+			saveOtherConsume(othConsume,sameCover);
+		}
+		else{
+			String sql="select record_id from t_other_consume where org_id=? and DATE_FORMAT(rpt_month,'%Y-%m')=?";
+			Map<String,Object> rst=dao.queryForSingleMap(sql, othConsume.getOrgId(),DateUtil.format(othConsume.getRptMonth(), "yyyy-MM"));
+			if(rst==null||rst.size()==0){ //不存在则入库
+				saveOtherConsume(othConsume,sameCover);
+			}
+			
+		}
+		return true;
+	}
+	
+	/**
+	 * 导入车辆油耗数据
+	 * @param importCosumes
+	 * @param rptMonth
+	 * @param orgId
+	 * @param sameCover
+	 * @param weightRatio 92# 95#带权重的汽油折算系数
+	 * @return
+	 */
+	public String addCarConsumesFromExcel(List<CarConsume> importCosumes,Date rptMonth,String orgId,boolean sameCover,Double oilWeightRatio) throws Exception{
+		String yyyyMM=DateUtil.format(rptMonth, "yyyy-MM");
+		if(sameCover){ //允许覆盖(同车同部门同月份同地区),则先删除  2021.11.5全覆盖以Excel里的为准,即同部门同月份全删除
+			delSameConsumeForImport(yyyyMM,orgId);
+			saveConsume(importCosumes,oilWeightRatio);
+			return null;
+		}
+		else{
+			
+			String sameIgnor=excludeSameConsumeForImport(importCosumes,yyyyMM,orgId);
+			
+			if(importCosumes.size()>0){
+				saveConsume(importCosumes,oilWeightRatio);
+			}
+			
+			return sameIgnor;
+		}
+		
+	}
+	
+	/**
+	 * 导入前允许覆盖时,先删除旧的(同车同部门同月份同地区 才能唯一确定一条记录)
+	 * 2021.11.5全覆盖以Excel里的为准,即同部门同月份全删除
+	 * @param importCosumes 已取消按记录覆盖
+	 * @param rptMonth  yyyy-MM
+	 * @param rptOrg
+	 */
+	private void delSameConsumeForImport(String rptMonth,String rptOrg){
+		/*if(importCosumes==null||importCosumes.size()==0){
+			return;
+		}
+		List<Object[]> batchParams=new ArrayList<Object[]>(importCosumes.size());
+		for(CarConsume  carcon : importCosumes){
+			batchParams.add(new Object[]{carcon.getWorkArea(),rptOrg,rptMonth,carcon.getCarId()});
+		}
+		String sql="delete from t_car_consume where work_area=? and rpt_org=? and DATE_FORMAT(rpt_date,'%Y-%m')=? and  car_id =?  ";
+		dao.getJdbcTemplate().batchUpdate(sql, batchParams);*/
+		String sql="delete from t_car_consume where  rpt_org=? and DATE_FORMAT(rpt_date,'%Y-%m')=? ";
+		dao.getJdbcTemplate().update(sql, rptOrg,rptMonth);
+	}
+	
+	/**
+	 * 导入前不允许覆盖时,先排除库中有的记录
+	 * @param importCosumes
+	 * @param rptMonth  yyyy-MM
+	 * @param rptOrg
+	 * @return 被忽略的车辆
+	 */
+	private String excludeSameConsumeForImport(List<CarConsume> importCosumes,String rptMonth,String rptOrg){
+		if(importCosumes==null||importCosumes.size()==0){
+			return null;
+		}
+		List<String> carIds=new ArrayList<String>(importCosumes.size());
+		for(CarConsume  carcon : importCosumes){
+			carIds.add(carcon.getCarId());
+		}
+		String cardstr="'"+StringUtils.join(carIds,"','")+"'";
+		String sql="select concat(car_id,'_',work_area) id,1 val from t_car_consume where  rpt_org=? and DATE_FORMAT(rpt_date,'%Y-%m')=? and  car_id in ("+cardstr+")";
+		Map<String,Object>  dbCons=dao.queryForMapping(sql,"id","val",rptOrg,rptMonth);
+		if(dbCons==null||dbCons.size()==0){
+			return null;
+		}
+		StringBuilder sameIgnor=new StringBuilder();
+		Iterator<CarConsume> iterator=importCosumes.iterator();
+		CarConsume carCon=null;
+		while(iterator.hasNext()){
+			carCon=iterator.next();
+			if(dbCons.containsKey(carCon.getCarId()+"_"+carCon.getWorkArea())){
+				sameIgnor.append(carCon.getCarNum()+";");
+				iterator.remove();
+			}
+		}
+		
+		return sameIgnor.length()>0?sameIgnor.toString():null;
+	}
+	
+}

+ 94 - 0
src/main/java/com/hb/proj/input/service/WorkloadService.java

@@ -0,0 +1,94 @@
+package com.hb.proj.input.service;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.Workload;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Service
+public class WorkloadService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	public List<Map<String,Object>>  queryWorkload(String rptYear){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select w.* from t_workload_value w ");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y')=? ");
+		return dao.queryForListMap(sql.toString(), rptYear);
+	}
+	
+	public void saveWorkload(List<Workload> datas) throws Exception{
+		Set<String> dbIds=new HashSet<String>();  //过滤出存在库里的记录,先进行删除再统一入库
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		final SessionUser su=SessionThreadLocal.getSessionUser();
+		for(Workload wd : datas){
+			if(wd.getRecordId()!=null){
+				dbIds.add(wd.getRecordId());
+			}
+			wd.setRecordId(uuid.generate()) ;  //作为新记录,重新设置主键
+			wd.setRptOrg(su.getOrgId());
+			
+		}
+		deleteWorkload(dbIds);
+		
+		StringBuilder pnsb=new StringBuilder();
+		pnsb.append("recordId,rptMonth,rptOrg,wellCount,industryValue,addedValue,modifyTime,modifier");
+		String[] pnary=pnsb.toString().split(",");
+		Map<String,Object> extraData=MapUtils.build("modifier",(su!=null?su.getUserName():"unknow"),"modifyTime",(new Date()));
+		dao.batchBeanInsert(datas, "t_workload_value", Arrays.asList(pnary),extraData);
+	}
+	
+	
+	/**
+	 * 通过报表直接上报
+	 * @param datas
+	 * @throws Exception
+	 */
+	public void saveWorkloadFromRpt(List<Workload> datas,String year) throws Exception{
+		//1月份存储有建筑面积删除前先取出
+		String sql="select builder_area from t_workload_value where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+		Map<String,Object> oldData=dao.queryForSingleMap(sql, year+"-01");
+		//先删除再保存
+		sql="delete from t_workload_value where DATE_FORMAT(rpt_month,'%Y')=?";
+		dao.getJdbcTemplate().update(sql,year);
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		final SessionUser su=SessionThreadLocal.getSessionUser();
+		for(Workload wd : datas){
+			wd.setRecordId(uuid.generate()) ;  //作为新记录,重新设置主键
+		}
+		StringBuilder pnsb=new StringBuilder();
+		pnsb.append("recordId,rptMonth,rptOrg,wellCount,industryValue,addedValue,modifyTime,modifier");
+		String[] pnary=pnsb.toString().split(",");
+		Map<String,Object> extraData=MapUtils.build("modifier",(su!=null?su.getUserName():"unknow"),"modifyTime",(new Date()));
+		dao.batchBeanInsert(datas, "t_workload_value", Arrays.asList(pnary),extraData);
+		
+		if(oldData!=null&&oldData.get("builderArea")!=null){ //存储有建筑面积的,再存回去,避免丢失
+			sql="update t_workload_value set builder_area=? where DATE_FORMAT(rpt_month,'%Y-%m')=?";
+			dao.getJdbcTemplate().update(sql, oldData.get("builderArea"),year+"-01");
+		}
+	}
+	
+	
+	private void deleteWorkload(Set<String> ids){
+		if(ids==null||ids.size()==0){
+			return;
+		}
+		String str="'"+StringUtils.join(ids,"','")+"'";
+		String sql="delete from t_workload_value where record_id in("+str+")";
+		dao.getJdbcTemplate().update(sql);
+	}
+}

+ 92 - 0
src/main/java/com/hb/proj/input/service/WpgService.java

@@ -0,0 +1,92 @@
+package com.hb.proj.input.service;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.hb.proj.model.Wpg;
+import com.hb.proj.model.WpgCalculater;
+import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
+import com.hb.xframework.util.DateUtil;
+import com.hb.xframework.util.MapUtils;
+import com.hb.xframework.util.SessionThreadLocal;
+import com.hb.xframework.util.SessionUser;
+
+@Service
+public class WpgService {
+
+	@Autowired
+	private SpringJdbcDAO  dao;
+	
+	public List<Map<String,Object>>  queryWpg(String rptYear,String orgId){
+		StringBuilder sql=new StringBuilder();
+		sql.append("select w.* from t_wpg_account w ");
+		sql.append(" where DATE_FORMAT(rpt_month,'%Y')=? and org_id=? ");
+		return dao.queryForListMap(sql.toString(), rptYear,orgId);
+	}
+	
+	public void saveWpg(List<Wpg> datas) throws Exception{
+		Set<String> dbIds=new HashSet<String>();  //过滤出存在库里的记录,先进行删除再统一入库
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		final SessionUser su=SessionThreadLocal.getSessionUser();
+		for(Wpg wpg : datas){
+			if(wpg.getRecordId()!=null){
+				dbIds.add(wpg.getRecordId());
+			}
+			wpg.setRecordId(uuid.generate()) ;  //作为新记录,重新设置主键
+			wpg.setOrgId(su.getOrgId());
+			//入库前进行基本统计数据的计算,并清除旧的计算值
+			WpgCalculater.calculate(wpg);
+		}
+		deleteWpgData(dbIds);
+		
+		StringBuilder pnsb=new StringBuilder();
+		pnsb.append("recordId,rptMonth,orgId,waterCount,waterCountQuota,waterCost,powerCount,powerCountQuota,powerCost,modifyTime,modifier");
+		pnsb.append(",ngasCount,ngasCountQuota,ngasCost,lgasCount,lgasCountQuota,lgasCost,powerCoal,lgasCoal,ngasCoal");
+		String[] pnary=pnsb.toString().split(",");
+		Map<String,Object> extraData=MapUtils.build("modifier",(su!=null?su.getUserName():"unknow"),"modifyTime",(new Date()));
+		dao.batchBeanInsert(datas, "t_wpg_account", Arrays.asList(pnary),extraData);
+	}
+	
+	public void  saveWpg2(List<Map<String,Object>> datas){
+		Set<String> dbIds=new HashSet<String>();  //过滤出存在库里的记录,先进行删除再统一入库
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		SessionUser su=SessionThreadLocal.getSessionUser();
+		for(Map<String,Object> d : datas){
+			if(d.get("recordId")!=null){
+				dbIds.add((String)d.get("recordId"));
+			}
+			MapUtils.blankValToNull(d);
+			d.put("rptMonth", DateUtil.parse(d.get("rptMonth")+"-01")) ;  //月份字符串转成日期对象,同时转换字段
+			d.put("orgId", su.getOrgId());
+			d.put("modifyTime",new Date());
+			d.put("createTime",new Date());
+			d.put("recordId", uuid.generate()); //作为新记录,重新设置主键
+			d.put("modifier", su!=null?su.getUserName():"unknow");
+			d.put("creator", d.get("modifier"));
+			
+		}
+		
+		deleteWpgData(dbIds);
+		List<String> pns=Arrays.asList("recordId","rptMonth","orgId","waterCount","waterCost","powerCount","powerCost","ngasCount","ngasCost","lgasCount","lgasCost","createTime","modifyTime","creator","modifier","waterCountQuota","powerCountQuota","ngasCountQuota","lgasCountQuota");
+		dao.batchInsert(datas,"t_wpg_account", pns);
+	}
+	
+	
+	private void deleteWpgData(Set<String> ids){
+		if(ids==null||ids.size()==0){
+			return;
+		}
+		String str="'"+StringUtils.join(ids,"','")+"'";
+		String sql="delete from t_wpg_account where record_id in("+str+")";
+		dao.getJdbcTemplate().update(sql);
+	}
+}

+ 472 - 0
src/main/java/com/hb/proj/model/CarConsume.java

@@ -0,0 +1,472 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class CarConsume {
+	
+	private String recordId;  //t_car_consume表主键
+	
+	private String carId;
+	
+	private String carNum;
+	
+	private String customNum;
+
+	private String deviceName;
+	
+	private String deviceModel;
+	
+	private Double travelMile;
+	
+	private Integer workHour;
+	
+	private Integer outHour;
+	
+	private Double engineWorkHour;
+	
+	private Date rptDate;  //统计月份
+	
+	private Integer  realAge;  //设备已使用年数
+	
+	private Double  oilTotalQuota=0.0;  //汽油月定额总量(单位公斤)
+	
+	private Double  coilTotalQuota=0.0; //柴油月定额总量(单位公斤)
+	
+	private String oilType;
+	
+	private Double  checkMile; //考核里程  km
+	
+	private Double   oilRealCost=0.0;  //汽油实耗量 单位kg
+	
+	private Double   coilRealCost=0.0;  //柴油实耗量 单位kg
+	
+	private Double   realCostPer100km;  //实际单耗  单位升
+	
+	private Double   quotaPer100km ;   //定额单耗 
+	
+	private Double  oilErp ;  //
+	
+	private Double oilKl ;
+	
+	private Double oilMeter=0.0 ;
+	
+	private Double  coilErp ;  //
+	
+	private Double coilKl ;
+	
+	private Double coilMeter=0.0 ;
+	
+	private Double coilZsh;  //柴油中石化
+	
+	private Double coilKlMoney ;
+
+	private Double oilKlMoney ;
+	
+	private Double oilCoal; //汽油实际耗量折算吨煤
+	
+	private Double coilCoal;  //柴油实际耗量折算吨煤
+	
+	private Double oilKlKg;  //汽油昆仑卡 升转kg
+	
+	private Double coilKlKg;
+	
+	private Double oilErpKg;   //汽油ERP 升转kg
+	
+	private Double coilErpKg;
+	
+	private Double oilMeterKg;  //汽油流量计 kg
+	
+	private Double coilMeterKg; 
+	
+	private String belongOrg;
+	
+	private Double workCost;  //作业耗油升
+	
+	private Double outCost;   //野外耗油升
+	
+	private Double engineCost;  //发电油耗升
+	
+	private Double engineCostKg; //发电油耗  kg
+	
+	private String workArea; //作业区域
+	
+	private String quotaRuleId; // 关联到t_quota_rule  百公里、作业定额 记录主键 
+	
+	private String quotaAlternatorId; // 关联到t_quota_rule  发电机定额记录主键
+	
+	
+
+	public String getCarId() {
+		return carId;
+	}
+
+	public void setCarId(String carId) {
+		this.carId = carId;
+	}
+
+	public String getCarNum() {
+		return carNum;
+	}
+
+	public void setCarNum(String carNum) {
+		this.carNum = carNum;
+	}
+
+	public String getCustomNum() {
+		return customNum;
+	}
+
+	public void setCustomNum(String customNum) {
+		this.customNum = customNum;
+	}
+
+	public String getDeviceName() {
+		return deviceName;
+	}
+
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
+	}
+
+	public String getDeviceModel() {
+		return deviceModel;
+	}
+
+	public void setDeviceModel(String deviceModel) {
+		this.deviceModel = deviceModel;
+	}
+
+	public Double getTravelMile() {
+		return this.travelMile;
+	}
+
+	public void setTravelMile(Double travelMile) {
+		this.travelMile = travelMile;
+	}
+
+	public Integer getWorkHour() {
+		return workHour;
+	}
+
+	public void setWorkHour(Integer workHour) {
+		this.workHour = workHour;
+	}
+
+	public Integer getOutHour() {
+		return outHour;
+	}
+
+	public void setOutHour(Integer outHour) {
+		this.outHour = outHour;
+	}
+
+	public Double getEngineWorkHour() {
+		return engineWorkHour;
+	}
+
+	public void setEngineWorkHour(Double engineWorkHour) {
+		this.engineWorkHour = engineWorkHour;
+	}
+
+	/*public Date getRptDate() {
+		return rptDate;
+	}
+
+	public void setRptDate(Date rptDate) {
+		this.rptDate = rptDate;
+	}*/
+
+
+
+	public String getOilType() {
+		return this.oilType;
+	}
+
+	public void setOilType(String oilType) {
+		this.oilType = oilType;
+	}
+
+	public Double getCheckMile() {
+		return checkMile;
+	}
+
+	public void setCheckMile(Double checkMile) {
+		this.checkMile = checkMile;
+	}
+
+	public Double getOilRealCost() {
+		return oilRealCost;
+	}
+
+	public void setOilRealCost(Double oilRealCost) {
+		this.oilRealCost = oilRealCost;
+	}
+
+	public Double getCoilRealCost() {
+		return coilRealCost;
+	}
+
+	public void setCoilRealCost(Double coilRealCost) {
+		this.coilRealCost = coilRealCost;
+	}
+
+	public Double getRealCostPer100km() {
+		return realCostPer100km;
+	}
+
+	public void setRealCostPer100km(Double realCostPer100km) {
+		this.realCostPer100km = realCostPer100km;
+	}
+
+	public Double getOilErp() {
+		return oilErp;
+	}
+
+	public void setOilErp(Double oilErp) {
+		this.oilErp = oilErp;
+	}
+
+	public Double getOilKl() {
+		return oilKl;
+	}
+
+	public void setOilKl(Double oilKl) {
+		this.oilKl = oilKl;
+	}
+
+	public Double getOilMeter() {
+		return oilMeter;
+	}
+
+	public void setOilMeter(Double oilMeter) {
+		this.oilMeter = oilMeter;
+	}
+
+	public Double getCoilErp() {
+		return coilErp;
+	}
+
+	public void setCoilErp(Double coilErp) {
+		this.coilErp = coilErp;
+	}
+
+	public Double getCoilKl() {
+		return coilKl;
+	}
+
+	public void setCoilKl(Double coilKl) {
+		this.coilKl = coilKl;
+	}
+
+	public Double getCoilMeter() {
+		return coilMeter;
+	}
+
+	public void setCoilMeter(Double coilMeter) {
+		this.coilMeter = coilMeter;
+	}
+
+	public Double getCoilZsh() {
+		return coilZsh;
+	}
+
+	public void setCoilZsh(Double coilZsh) {
+		this.coilZsh = coilZsh;
+	}
+
+	public Double getQuotaPer100km() {
+		return quotaPer100km;
+	}
+
+	public void setQuotaPer100km(Double quotaPer100km) {
+		this.quotaPer100km = quotaPer100km;
+	}
+
+	public Double getOilTotalQuota() {
+		return oilTotalQuota;
+	}
+
+	public void setOilTotalQuota(Double oilTotalQuota) {
+		this.oilTotalQuota = oilTotalQuota;
+	}
+
+	public Double getCoilTotalQuota() {
+		return coilTotalQuota;
+	}
+
+	public void setCoilTotalQuota(Double coilTotalQuota) {
+		this.coilTotalQuota = coilTotalQuota;
+	}
+
+	public Integer getRealAge() {
+		return realAge;
+	}
+
+	public void setRealAge(Integer realAge) {
+		this.realAge = realAge;
+	}
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+
+	public Date getRptDate() {
+		return rptDate;
+	}
+
+	public void setRptDate(Date rptDate) {
+		this.rptDate = rptDate;
+	}
+
+	public Double getCoilKlMoney() {
+		return coilKlMoney;
+	}
+
+	public void setCoilKlMoney(Double coilKlMoney) {
+		this.coilKlMoney = coilKlMoney;
+	}
+
+	public Double getOilKlMoney() {
+		return oilKlMoney;
+	}
+
+	public void setOilKlMoney(Double oilKlMoney) {
+		this.oilKlMoney = oilKlMoney;
+	}
+
+	public String getBelongOrg() {
+		return belongOrg;
+	}
+
+	public void setBelongOrg(String belongOrg) {
+		this.belongOrg = belongOrg;
+	}
+
+	public Double getOilCoal() {
+		return oilCoal;
+	}
+
+	public void setOilCoal(Double oilCoal) {
+		this.oilCoal = oilCoal;
+	}
+
+	public Double getCoilCoal() {
+		return coilCoal;
+	}
+
+	public void setCoilCoal(Double coilCoal) {
+		this.coilCoal = coilCoal;
+	}
+
+	public Double getOilKlKg() {
+		return oilKlKg;
+	}
+
+	public void setOilKlKg(Double oilKlKg) {
+		this.oilKlKg = oilKlKg;
+	}
+
+	public Double getCoilKlKg() {
+		return coilKlKg;
+	}
+
+	public void setCoilKlKg(Double coilKlKg) {
+		this.coilKlKg = coilKlKg;
+	}
+
+	public Double getOilErpKg() {
+		return oilErpKg;
+	}
+
+	public void setOilErpKg(Double oilErpKg) {
+		this.oilErpKg = oilErpKg;
+	}
+
+	public Double getCoilErpKg() {
+		return coilErpKg;
+	}
+
+	public void setCoilErpKg(Double coilErpKg) {
+		this.coilErpKg = coilErpKg;
+	}
+
+	public Double getOilMeterKg() {
+		return oilMeterKg;
+	}
+
+	public void setOilMeterKg(Double oilMeterKg) {
+		this.oilMeterKg = oilMeterKg;
+	}
+
+	public Double getCoilMeterKg() {
+		return coilMeterKg;
+	}
+
+	public void setCoilMeterKg(Double coilMeterKg) {
+		this.coilMeterKg = coilMeterKg;
+	}
+
+	public Double getWorkCost() {
+		return workCost;
+	}
+
+	public void setWorkCost(Double workCost) {
+		this.workCost = workCost;
+	}
+
+	public Double getOutCost() {
+		return outCost;
+	}
+
+	public void setOutCost(Double outCost) {
+		this.outCost = outCost;
+	}
+
+	public Double getEngineCost() {
+		return engineCost;
+	}
+
+	public void setEngineCost(Double engineCost) {
+		this.engineCost = engineCost;
+	}
+
+	public String getWorkArea() {
+		return workArea;
+	}
+
+	public void setWorkArea(String workArea) {
+		this.workArea = workArea;
+	}
+
+	public String getQuotaRuleId() {
+		return quotaRuleId;
+	}
+
+	public void setQuotaRuleId(String quotaRuleId) {
+		this.quotaRuleId = quotaRuleId;
+	}
+
+	public String getQuotaAlternatorId() {
+		return quotaAlternatorId;
+	}
+
+	public void setQuotaAlternatorId(String quotaAlternatorId) {
+		this.quotaAlternatorId = quotaAlternatorId;
+	}
+
+	public Double getEngineCostKg() {
+		return engineCostKg;
+	}
+
+	public void setEngineCostKg(Double engineCostKg) {
+		this.engineCostKg = engineCostKg;
+	}
+
+	
+	
+	
+}

+ 111 - 0
src/main/java/com/hb/proj/model/CarConsumeRptVO.java

@@ -0,0 +1,111 @@
+package com.hb.proj.model;
+
+public class CarConsumeRptVO extends CarConsume {
+
+	
+	private Double travelPer100km; //只计算行驶的百公里油耗
+	
+	private Double startVolume;  //月初余油
+	
+	private Double endVolume;  //月终余油
+	
+	private Double realCostMeter;  //实际加油(含油箱余油计算)实际耗油升=上报加油+月初余油-月终余油
+	
+	private String unionQuotaPer100km ; //联合百公里定额(为了适应同车不同地区的记录)
+	
+	private String orgName;   //当前所属部门
+	
+
+	public void init(Double startVol,Double endVol){ //diffVolume=月初余油-月终余油 
+		if("汽油".equals(this.getOilType())){
+			realCostMeter=CarConsumeRptVO.addDouble(this.getOilErp(),this.getOilKl());
+		}
+		else{
+			realCostMeter=CarConsumeRptVO.addDouble(this.getCoilErp(),this.getCoilKl());
+		}
+		
+		if(realCostMeter==null){
+			return;
+		}
+		if(startVol!=null&&endVol!=null){
+			startVolume=startVol;
+			endVolume=endVol;
+			realCostMeter=CarConsumeRptVO.addDouble(realCostMeter,startVol.doubleValue()-endVol.doubleValue());
+		}
+		
+		
+		Double noTravelCost=CarConsumeRptVO.addDouble(this.getWorkCost(),this.getOutCost());
+		noTravelCost=CarConsumeRptVO.addDouble(noTravelCost,this.getEngineCost());
+		if(noTravelCost==null){ //非行驶用油:作业、野外、发电
+			noTravelCost=0.0;  //便于计算
+		}
+		
+		double travelCost=realCostMeter.doubleValue()-noTravelCost.doubleValue();
+		
+		if(this.getTravelMile()!=null){
+			this.travelPer100km=travelCost*100/this.getTravelMile().doubleValue();
+		}
+	}
+	
+	public static Double addDouble(Double d1,Double d2){
+		if(d2==null||Double.isNaN(d2)){
+			return d1;
+		}
+		if(d1==null||Double.isNaN(d1)){
+			return d2;
+		}
+		else{
+			return d1.doubleValue()+d2.doubleValue();
+		}
+	}
+
+	
+
+	public Double getTravelPer100km() {
+		return travelPer100km;
+	}
+
+	public void setTravelPer100km(Double travelPer100km) {
+		this.travelPer100km = travelPer100km;
+	}
+
+	public Double getStartVolume() {
+		return startVolume;
+	}
+
+	public void setStartVolume(Double startVolume) {
+		this.startVolume = startVolume;
+	}
+
+	public Double getEndVolume() {
+		return endVolume;
+	}
+
+	public void setEndVolume(Double endVolume) {
+		this.endVolume = endVolume;
+	}
+
+	public Double getRealCostMeter() {
+		return realCostMeter;
+	}
+
+	public void setRealCostMeter(Double realCostMeter) {
+		this.realCostMeter = realCostMeter;
+	}
+
+	public String getUnionQuotaPer100km() {
+		return unionQuotaPer100km;
+	}
+
+	public void setUnionQuotaPer100km(String unionQuotaPer100km) {
+		this.unionQuotaPer100km = unionQuotaPer100km;
+	}
+
+	public String getOrgName() {
+		return orgName;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+}

+ 179 - 0
src/main/java/com/hb/proj/model/ERP.java

@@ -0,0 +1,179 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class ERP {
+	
+	private String recordId;
+	
+	private Date  rptMonth;
+	
+	private Date  modifyTime;
+	
+	private String modifier;
+
+	private Double oilCount;
+	private Double oilCountCorrect;
+	
+	private Double coilCount;
+	private Double coilCountCorrect;
+	
+	
+	private Double oilMoney;
+	private Double oilMoneyCorrect;
+	
+	private Double coilMoney;
+	private Double coilMoneyCorrect;
+	
+	private Double oilCountSum;
+	private Double oilMoneySum;
+	
+	private Double coilCountSum;
+	private Double coilMoneySum;
+	
+	private Double oilSumCoal;   //汽油累计折算吨煤
+	
+	private Double coilSumCoal; //柴油累计折算吨煤
+	
+	private Double oilCorrectCoal; //汽油月度修正值折算吨煤
+	
+	private Double coilCorrectCoal;
+	
+	private Double oilCoal; //汽油当月值折算吨煤
+	
+	private Double coilCoal;
+	
+	
+	public Double getOilCount() {
+		return oilCount;
+	}
+	public void setOilCount(Double oilCount) {
+		this.oilCount = oilCount;
+	}
+	public Double getOilCountCorrect() {
+		return oilCountCorrect;
+	}
+	public void setOilCountCorrect(Double oilCountCorrect) {
+		this.oilCountCorrect = oilCountCorrect;
+	}
+	public Double getCoilCount() {
+		return coilCount;
+	}
+	public void setCoilCount(Double coilCount) {
+		this.coilCount = coilCount;
+	}
+	public Double getCoilCountCorrect() {
+		return coilCountCorrect;
+	}
+	public void setCoilCountCorrect(Double coilCountCorrect) {
+		this.coilCountCorrect = coilCountCorrect;
+	}
+	public Double getOilMoney() {
+		return oilMoney;
+	}
+	public void setOilMoney(Double oilMoney) {
+		this.oilMoney = oilMoney;
+	}
+	public Double getOilMoneyCorrect() {
+		return oilMoneyCorrect;
+	}
+	public void setOilMoneyCorrect(Double oilMoneyCorrect) {
+		this.oilMoneyCorrect = oilMoneyCorrect;
+	}
+	public Double getCoilMoney() {
+		return coilMoney;
+	}
+	public void setCoilMoney(Double coilMoney) {
+		this.coilMoney = coilMoney;
+	}
+	public Double getCoilMoneyCorrect() {
+		return coilMoneyCorrect;
+	}
+	public void setCoilMoneyCorrect(Double coilMoneyCorrect) {
+		this.coilMoneyCorrect = coilMoneyCorrect;
+	}
+	public Double getOilCountSum() {
+		return oilCountSum;
+	}
+	public void setOilCountSum(Double oilCountSum) {
+		this.oilCountSum = oilCountSum;
+	}
+	public Double getOilMoneySum() {
+		return oilMoneySum;
+	}
+	public void setOilMoneySum(Double oilMoneySum) {
+		this.oilMoneySum = oilMoneySum;
+	}
+	public Double getCoilCountSum() {
+		return coilCountSum;
+	}
+	public void setCoilCountSum(Double coilCountSum) {
+		this.coilCountSum = coilCountSum;
+	}
+	public Double getCoilMoneySum() {
+		return coilMoneySum;
+	}
+	public void setCoilMoneySum(Double coilMoneySum) {
+		this.coilMoneySum = coilMoneySum;
+	}
+	public String getRecordId() {
+		return recordId;
+	}
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+	public Date getModifyTime() {
+		return modifyTime;
+	}
+	public void setModifyTime(Date modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+	public String getModifier() {
+		return modifier;
+	}
+	public void setModifier(String modifier) {
+		this.modifier = modifier;
+	}
+	public Double getOilSumCoal() {
+		return oilSumCoal;
+	}
+	public void setOilSumCoal(Double oilSumCoal) {
+		this.oilSumCoal = oilSumCoal;
+	}
+	public Double getCoilSumCoal() {
+		return coilSumCoal;
+	}
+	public void setCoilSumCoal(Double coilSumCoal) {
+		this.coilSumCoal = coilSumCoal;
+	}
+	public Double getOilCorrectCoal() {
+		return oilCorrectCoal;
+	}
+	public void setOilCorrectCoal(Double oilCorrectCoal) {
+		this.oilCorrectCoal = oilCorrectCoal;
+	}
+	public Double getCoilCorrectCoal() {
+		return coilCorrectCoal;
+	}
+	public void setCoilCorrectCoal(Double coilCorrectCoal) {
+		this.coilCorrectCoal = coilCorrectCoal;
+	}
+	public Double getOilCoal() {
+		return oilCoal;
+	}
+	public void setOilCoal(Double oilCoal) {
+		this.oilCoal = oilCoal;
+	}
+	public Double getCoilCoal() {
+		return coilCoal;
+	}
+	public void setCoilCoal(Double coilCoal) {
+		this.coilCoal = coilCoal;
+	}
+}

+ 45 - 0
src/main/java/com/hb/proj/model/ERPCalculater.java

@@ -0,0 +1,45 @@
+package com.hb.proj.model;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+
+public class ERPCalculater {
+
+	private static Logger logger=LoggerFactory.getLogger(ERPCalculater.class);
+			
+	/**
+	 * 对erp上报数据标煤折算处理,数据库记录:数量单位是吨,金额是元
+	 * @param erp
+	 */
+	public static void calculate(ERP  erp){
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		if(qc==null){
+			logger.warn("缺少折算系数,取消对ERP数据的换算");
+			return;
+		}
+		
+		if(erp.getOilCountSum()!=null){ // OilCountSum  单位是吨直接乘系数
+			erp.setOilSumCoal(erp.getOilCountSum()*qc.getOilCoalRatio());
+		}
+		if(erp.getCoilCountSum()!=null){
+			erp.setCoilSumCoal(erp.getCoilCountSum()*qc.getCoilCoalRatio());
+		}
+		
+		if(erp.getOilCountCorrect()!=null){ 
+			erp.setOilCorrectCoal(erp.getOilCountCorrect()*qc.getOilCoalRatio());
+		}
+		if(erp.getCoilCountCorrect()!=null){ 
+			erp.setCoilCorrectCoal(erp.getCoilCountCorrect()*qc.getCoilCoalRatio());
+		}
+		if(erp.getOilCount()!=null){
+			erp.setOilCoal(erp.getOilCount()*qc.getOilCoalRatio());
+		}
+		if(erp.getCoilCount()!=null){
+			erp.setCoilCoal(erp.getCoilCount()*qc.getCoilCoalRatio());
+		}
+		
+	}
+}

+ 301 - 0
src/main/java/com/hb/proj/model/EnergyWaterCompareVO.java

@@ -0,0 +1,301 @@
+package com.hb.proj.model;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.utils.DataUtils;
+/**
+ * 用能用水累计同比有两个报表。1:总量、单值;
+ * @author xe
+ *
+ */
+public class EnergyWaterCompareVO {
+
+	private ERP  erpkl;
+	
+	private Wpg   wpg;
+	
+	
+	private Double oilTotal;  //汽油总量 吨
+	
+	private Double coilTotal;  //柴油总量 吨
+	
+    private Double oilCompared;  //汽油同比
+	
+	private Double coilCompared;  //柴油同比
+	
+	private Double waterCompared;  //水量同比
+		
+    private Double powerCompared;  //电量同比
+		
+	private Double ngasCompared;  //天然气同比
+		
+	private Double ygasCompared;  //液化气同比
+	
+	private Double oilPrice;  //汽油单价元
+	
+	private Double coilPrice; 
+	
+	private Double waterPrice; 
+	
+	private Double powerPrice; 
+	
+	private Double ngasPrice; 
+	
+	private Double lgasPrice;
+	
+	private Double coalCompared;  //折算吨煤同比
+	
+	private Double coals; //折算吨煤
+	
+	/**
+	 * 报表1不需要产值
+	 * @param erpkl
+	 * @param wpg
+	 * @param workload
+	 */
+	public EnergyWaterCompareVO (ERP  erpkl,Wpg   wpg){
+		this.erpkl=erpkl;
+		this.wpg=wpg;
+		
+		this.oilTotal=erpkl.getOilCount();  //借用字段存有erp+昆仑卡值
+		this.coilTotal=erpkl.getCoilCount();
+		
+		init();
+	}
+	
+	
+	
+	
+	
+	//计算折算煤,单价,报表1的初始计算
+	public void init(){
+		Double d=null;
+		if(this.erpkl!=null){
+			d=CarRptUtils.addDouble(this.erpkl.getOilCoal(),this.erpkl.getCoilCoal()); //如果是和数据校正中的当月对应,就用oilCoal,用累计就用oilSumCoal
+		}
+		if(this.wpg!=null){
+			d=CarRptUtils.addDouble(d,this.wpg.getNgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getLgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getPowerCoal());
+		}
+		
+		this.coals=DataUtils.round(d, 3);
+		
+		this.oilPrice=getPrice(this.oilTotal,this.erpkl.getOilMoney()); //如果是和数据校正中的当月对应,就用oilMoney,用累计就用oilMoneySum
+		
+		this.coilPrice=getPrice(this.coilTotal,this.erpkl.getCoilMoney());
+		
+		this.waterPrice=getPrice(this.wpg.getWaterCount(),this.wpg.getWaterCost());
+		this.powerPrice=getPrice(this.wpg.getPowerCount(),this.wpg.getPowerCost());
+		this.ngasPrice=getPrice(this.wpg.getNgasCount(),this.wpg.getNgasCost());
+		this.lgasPrice=getPrice(this.wpg.getLgasCount(),this.wpg.getLgasCost());
+	}
+	
+	/**
+	 * 
+	 * @param d1
+	 * @param money  万元,内部计算转换为元
+	 * @return
+	 */
+	private Double getPrice(Double d1,Double money){
+		if(d1==null||d1.isNaN()||money==null||money.isNaN()||money.doubleValue()==0){
+			return null;
+		}
+		return money.doubleValue()*10000/d1.doubleValue();
+	}
+	
+	public void setComparedValue(EnergyWaterCompareVO preVo){
+		if(preVo==null){
+			return;
+		}
+		if(preVo.getErpkl()!=null){
+			if(this.erpkl==null){
+				this.oilCompared=-1.0;
+				this.coilCompared=-1.0;
+			}
+			else{
+				this.oilCompared=getCompareVal(this.oilTotal,preVo.getOilTotal());
+				this.coilCompared=getCompareVal(this.coilTotal,preVo.getCoilTotal());
+			}
+		}
+		
+		if(preVo.getWpg()!=null){
+			if(this.wpg==null){
+				this.waterCompared=-1.0;
+				this.powerCompared=-1.0;
+				this.ngasCompared=-1.0;
+				this.ygasCompared=-1.0;
+			}
+			else{
+				this.waterCompared=getCompareVal(this.wpg.getWaterCount(),preVo.getWpg().getWaterCount());
+				this.powerCompared=getCompareVal(this.wpg.getPowerCount(),preVo.getWpg().getPowerCount());
+				this.ngasCompared=getCompareVal(this.wpg.getNgasCount(),preVo.getWpg().getNgasCount());
+				this.ygasCompared=getCompareVal(this.wpg.getLgasCount(),preVo.getWpg().getLgasCount());
+			}
+		}
+	
+		if(preVo.getCoals()!=null){
+			this.coalCompared=getCompareVal(this.coals,preVo.getCoals());
+		}
+		
+	}
+	
+	private Double getCompareVal(Object d1,Object d2){
+		if(d2==null){
+			return null;
+		}
+		else if(d1==null){
+			return -1.0;
+		}
+		else if(d1 instanceof Double){
+			return (((Double)d1).doubleValue()-((Double)d2).doubleValue())/((Double)d2).doubleValue();
+		}
+		else if(d1 instanceof Integer){
+			return (((Integer)d1).intValue()-((Integer)d2).intValue())/((Integer)d2+0.0);
+		}
+		return null;
+	}
+	
+	public String getCoalCompared() {
+		if(coalCompared==null||coalCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(coalCompared*100, 1)+"%";
+	}
+	
+	public String getOilCompared() {
+		if(oilCompared==null||oilCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(oilCompared*100, 1)+"%";
+	}
+	
+	public String getCoilCompared() {
+		if(coilCompared==null||coilCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(coilCompared*100, 1)+"%";
+	}
+	
+	
+	
+	public String getWaterCompared() {
+		if(waterCompared==null||waterCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(waterCompared*100, 1)+"%";
+	}
+	
+	public String getPowerCompared() {
+		if(powerCompared==null||powerCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(powerCompared*100, 1)+"%";
+	}
+	
+	public String getNgasCompared() {
+		if(ngasCompared==null||ngasCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(ngasCompared*100, 1)+"%";
+	}
+	
+	public String getYgasCompared() {
+		if(ygasCompared==null||ygasCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(ygasCompared*100, 1)+"%";
+	}
+	
+	
+
+	
+
+	public Wpg getWpg() {
+		return wpg;
+	}
+
+	public void setWpg(Wpg wpg) {
+		this.wpg = wpg;
+	}
+
+	
+
+	public Double getCoals() {
+		return coals;
+	}
+
+	public Double getOilPrice() {
+		return DataUtils.round(oilPrice, 2);
+	}
+
+	public void setOilPrice(Double oilPrice) {
+		this.oilPrice = oilPrice;
+	}
+
+	public Double getCoilPrice() {
+		return DataUtils.round(coilPrice, 2);
+	}
+
+	public void setCoilPrice(Double coilPrice) {
+		this.coilPrice = coilPrice;
+	}
+
+	public Double getWaterPrice() {
+		return DataUtils.round(waterPrice, 2);
+	}
+
+	public void setWaterPrice(Double waterPrice) {
+		this.waterPrice = waterPrice;
+	}
+
+	public Double getPowerPrice() {
+		return DataUtils.round(powerPrice, 2);
+	}
+
+	public void setPowerPrice(Double powerPrice) {
+		this.powerPrice = powerPrice;
+	}
+
+	public Double getNgasPrice() {
+		return DataUtils.round(ngasPrice, 2);
+	}
+
+	public void setNgasPrice(Double ngasPrice) {
+		this.ngasPrice = ngasPrice;
+	}
+
+	public Double getLgasPrice() {
+		return DataUtils.round(lgasPrice, 2);
+	}
+
+	public void setLgasPrice(Double lgasPrice) {
+		this.lgasPrice = lgasPrice;
+	}
+
+	public Double getOilTotal() {
+		return oilTotal;
+	}
+
+	public void setOilTotal(Double oilTotal) {
+		this.oilTotal = oilTotal;
+	}
+
+	public Double getCoilTotal() {
+		return coilTotal;
+	}
+
+	public void setCoilTotal(Double coilTotal) {
+		this.coilTotal = coilTotal;
+	}
+
+	public ERP getErpkl() {
+		return erpkl;
+	}
+
+	public void setErpkl(ERP erpkl) {
+		this.erpkl = erpkl;
+	}
+
+	
+	
+}

+ 255 - 0
src/main/java/com/hb/proj/model/EnergyWaterRatioCompareVO.java

@@ -0,0 +1,255 @@
+package com.hb.proj.model;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.utils.DataUtils;
+
+/**
+ * 用能用水累计同比有两个报表。2:能、水和产值等数据的比例的同比;
+ * @author hb
+ *
+ */
+public class EnergyWaterRatioCompareVO {
+
+	private ERP  erpkl;
+	
+	private Wpg   wpg;
+	
+	private Workload workload;
+	
+	private Double oilTotal;  //汽油总量 吨
+	
+	private Double coilTotal;  //柴油总量 吨
+	
+	private Double oilCoilTotal;
+	
+	private Double coals; //折算吨煤
+	
+	private Double checkMile; //考核里程 累计值
+	
+	private Double coalKgIndustryValue; // 千克标煤/万元产值
+	
+	private Double coalKgAddedValue;  //千克标煤/万元增加值
+	
+	private Double waterIndustryValue ; //立方米 /万元产值
+	
+	private Double coalKgWellCount ;  //千克标煤/井次
+	
+	private Double powerBuilderArea; // 千瓦时/平方米 建筑面积
+	
+	private Double oilCost100km ; //百公里耗油=(汽油+柴油)/考核公里
+	
+	public EnergyWaterRatioCompareVO (ERP erpkl, Wpg  wpg, Workload workload,Double checkMile){
+		this.erpkl=erpkl;
+		this.wpg=wpg;
+		this.workload=workload;
+		this.checkMile=checkMile;
+		this.oilTotal=erpkl.getOilCount();  //借用字段存有erp+昆仑卡值
+		this.coilTotal=erpkl.getCoilCount();
+		
+		init();
+	}
+	
+	
+	/**
+	 * 计算综合吨标煤,报表中使用的是千克需要转换,计算指标值
+	 */
+	public void init(){
+		Double d=null;
+		if(this.erpkl!=null){
+			d=CarRptUtils.addDouble(this.erpkl.getOilCoal(),this.erpkl.getCoilCoal());  //如果是和数据校正中的当月对应,就用oilCoal,用累计就用oilSumCoal
+		}
+		if(this.wpg!=null){
+			d=CarRptUtils.addDouble(d,this.wpg.getNgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getLgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getPowerCoal());
+		}
+		
+		this.coals=DataUtils.round(d, 3);
+		this.coals=this.coals!=null?this.coals*1000:null;  //报表中使用的是千克所以*1000
+		this.oilCoilTotal=CarRptUtils.addDouble(this.oilTotal,this.coilTotal);
+		if(this.oilCoilTotal!=null){
+			this.oilCoilTotal=this.oilCoilTotal*1000; //报表中使用的是千克所以*1000
+		}
+		if(this.getWpg()!=null&&this.getWpg().getWaterCount()!=null){
+			this.getWpg().setWaterCount(this.getWpg().getWaterCount()*10000); //报表中使用的是立方米所以*10000
+		}
+		if(this.getWpg()!=null&&this.getWpg().getPowerCount()!=null){
+			this.getWpg().setPowerCount(this.getWpg().getPowerCount()*10000); //报表中使用的是千瓦时所以*10000
+		}
+		
+		if(this.checkMile!=null){
+			this.checkMile=this.checkMile/100;
+		}
+		//指标值计算
+		
+		this.coalKgIndustryValue=this.workload!=null?divideDouble(this.coals,this.workload.getIndustryValue()):null;
+		this.coalKgAddedValue=this.workload!=null?divideDouble(this.coals,this.workload.getAddedValue()):null;
+		
+		if(this.getWpg()!=null&&this.getWpg().getWaterCount()!=null&&this.workload!=null){
+			this.waterIndustryValue=divideDouble(this.getWpg().getWaterCount(),this.workload.getIndustryValue());
+		}
+		this.coalKgWellCount=this.workload!=null?divideDouble(this.coals,getDouble(this.workload.getWellCount())):null;
+		if(this.getWpg()!=null&&this.getWpg().getPowerCount()!=null&&this.getWorkload()!=null){
+			this.powerBuilderArea=divideDouble(this.getWpg().getPowerCount(),this.getWorkload().getBuilderArea());
+		}
+		
+		if(this.oilCoilTotal!=null&&this.checkMile!=null){
+			this.oilCost100km=divideDouble(this.oilCoilTotal,this.checkMile);
+		}
+		
+	}
+	
+	private Double getDouble(Integer val){
+		return val==null?null:(val.intValue()+0.0);
+	}
+	
+	
+	private Double divideDouble(Double d1,Double d2){
+		if(d1==null||d2==null||d2.doubleValue()==0){
+			return null;
+		}
+		return d1.doubleValue()/d2.doubleValue();
+	}
+
+
+	public ERP getErpkl() {
+		return erpkl;
+	}
+
+
+	public void setErpkl(ERP erpkl) {
+		this.erpkl = erpkl;
+	}
+
+
+	public Wpg getWpg() {
+		return wpg;
+	}
+
+
+	public void setWpg(Wpg wpg) {
+		this.wpg = wpg;
+	}
+
+
+	public Workload getWorkload() {
+		return workload;
+	}
+
+
+	public void setWorkload(Workload workload) {
+		this.workload = workload;
+	}
+
+
+	public Double getOilTotal() {
+		return oilTotal;
+	}
+
+
+	public void setOilTotal(Double oilTotal) {
+		this.oilTotal = oilTotal;
+	}
+
+
+	public Double getCoilTotal() {
+		return coilTotal;
+	}
+
+
+	public void setCoilTotal(Double coilTotal) {
+		this.coilTotal = coilTotal;
+	}
+
+
+	public Double getCoals() {
+		return coals;
+	}
+
+
+	public void setCoals(Double coals) {
+		this.coals = coals;
+	}
+
+
+	public Double getCoalKgIndustryValue() {
+		return coalKgIndustryValue;
+	}
+
+
+	public void setCoalKgIndustryValue(Double coalKgIndustryValue) {
+		this.coalKgIndustryValue = coalKgIndustryValue;
+	}
+
+
+	public Double getCoalKgAddedValue() {
+		return coalKgAddedValue;
+	}
+
+
+	public void setCoalKgAddedValue(Double coalKgAddedValue) {
+		this.coalKgAddedValue = coalKgAddedValue;
+	}
+
+
+	public Double getWaterIndustryValue() {
+		return waterIndustryValue;
+	}
+
+
+	public void setWaterIndustryValue(Double waterIndustryValue) {
+		this.waterIndustryValue = waterIndustryValue;
+	}
+
+
+	public Double getCoalKgWellCount() {
+		return coalKgWellCount;
+	}
+
+
+	public void setCoalKgWellCount(Double coalKgWellCount) {
+		this.coalKgWellCount = coalKgWellCount;
+	}
+
+
+	public Double getPowerBuilderArea() {
+		return powerBuilderArea;
+	}
+
+
+	public void setPowerBuilderArea(Double powerBuilderArea) {
+		this.powerBuilderArea = powerBuilderArea;
+	}
+
+
+	public Double getOilCost100km() {
+		return oilCost100km;
+	}
+
+
+	public void setOilCost100km(Double oilCost100km) {
+		this.oilCost100km = oilCost100km;
+	}
+
+
+	
+
+	public Double getCheckMile() {
+		return checkMile;
+	}
+
+
+	public void setCheckMile(Double checkMile) {
+		this.checkMile = checkMile;
+	}
+
+
+	public Double getOilCoilTotal() {
+		return oilCoilTotal;
+	}
+
+
+	public void setOilCoilTotal(Double oilCoilTotal) {
+		this.oilCoilTotal = oilCoilTotal;
+	}
+}

+ 328 - 0
src/main/java/com/hb/proj/model/EnergyWaterSumVO.java

@@ -0,0 +1,328 @@
+package com.hb.proj.model;
+
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.proj.utils.DataUtils;
+
+/**
+ * 用能用水统计汇总报表VO   按月形成一个对象
+ * @author xe
+ *
+ */
+public class EnergyWaterSumVO {
+	
+	/**
+	 * erpKl=ERPKlSumUtil.erpPlusKlMonth  返回的对象
+	 */
+	private ERP  erpKl;  //物资ERP+项目部昆仑卡 
+
+    private Double oilTotal;  //汽油总量 吨
+	
+	private Double coilTotal;  //柴油总量 吨
+	
+	private Wpg   wpg;
+	
+	private Workload  workload;
+	
+	private String rptMonth;
+	
+    private Double oilCompared;  //汽油同比
+	
+	private Double coilCompared;  //柴油同比
+	
+	private Double waterCompared;  //水量同比
+		
+    private Double powerCompared;  //电量同比
+		
+	private Double ngasCompared;  //天然气同比
+		
+	private Double ygasCompared;  //液化气同比
+	
+	private Double wellCountCompared;  //井次同比
+		
+	private Double industryValueCompared;  //工业产值同比
+		
+	private Double addedValueCompared;  //企业增加值同比
+	
+	private Double coalCompared;  //折算吨煤同比
+	
+	private Double coals; //折算吨煤
+	
+	public EnergyWaterSumVO (ERP  erpKl,Wpg   wpg,Workload  workload){
+		this.erpKl=erpKl;
+		this.wpg=wpg;
+		this.workload=workload;
+		if(erpKl!=null){
+			this.oilTotal=erpKl.getOilCount();
+			this.coilTotal=erpKl.getCoilCount();
+		}
+		
+	}
+	
+	/**
+	 *计算油、电、气折标吨煤
+	 */
+	public void initCoal(){
+		Double d=null;
+		if(this.erpKl!=null){
+			d=CarRptUtils.addDouble(this.erpKl.getOilCoal(),this.erpKl.getCoilCoal());
+		}
+		if(this.wpg!=null){
+			d=CarRptUtils.addDouble(d,this.wpg.getNgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getLgasCoal());
+			d=CarRptUtils.addDouble(d,this.wpg.getPowerCoal());
+		}
+		
+		this.coals=DataUtils.round(d, 4);
+	}
+	
+	public void setComparedValue(EnergyWaterSumVO preVo){
+		if(preVo==null){
+			return;
+		}
+		if(preVo.getErpKl()!=null){
+			if(this.erpKl==null){
+				this.oilCompared=-1.0;
+				this.coilCompared=-1.0;
+			}
+			else{
+				this.oilCompared=getCompareVal(this.oilTotal,preVo.getOilTotal());
+				this.coilCompared=getCompareVal(this.coilTotal,preVo.getCoilTotal());
+			}
+		}
+		
+		if(preVo.getWpg()!=null){
+			if(this.wpg==null){
+				this.waterCompared=-1.0;
+				this.powerCompared=-1.0;
+				this.ngasCompared=-1.0;
+				this.ygasCompared=-1.0;
+			}
+			else{
+				this.waterCompared=getCompareVal(this.wpg.getWaterCount(),preVo.getWpg().getWaterCount());
+				this.powerCompared=getCompareVal(this.wpg.getPowerCount(),preVo.getWpg().getPowerCount());
+				this.ngasCompared=getCompareVal(this.wpg.getNgasCount(),preVo.getWpg().getNgasCount());
+				this.ygasCompared=getCompareVal(this.wpg.getLgasCount(),preVo.getWpg().getLgasCount());
+			}
+		}
+		
+		if(preVo.getWorkload()!=null){
+			if(this.workload==null){
+				this.wellCountCompared=-1.0;
+				this.industryValueCompared=-1.0;
+				this.addedValueCompared=-1.0;
+			}
+			else{
+				this.wellCountCompared=getCompareVal(this.workload.getWellCount(),preVo.getWorkload().getWellCount());
+				this.industryValueCompared=getCompareVal(this.workload.getIndustryValue(),preVo.getWorkload().getIndustryValue());
+				this.addedValueCompared=getCompareVal(this.workload.getAddedValue(),preVo.getWorkload().getAddedValue());
+			}
+		}
+		if(preVo.getCoals()!=null&&preVo.getCoals().doubleValue()!=0){
+			this.coalCompared=getCompareVal(this.coals,preVo.getCoals());
+		}
+		
+	}
+	
+	private Double getCompareVal(Object d1,Object d2){
+		if(d2==null){
+			return null;
+		}
+		else if(d1==null){
+			return -1.0;
+		}
+		else if(d1 instanceof Double){
+			return (((Double)d1).doubleValue()-((Double)d2).doubleValue())/((Double)d2).doubleValue();
+		}
+		else if(d1 instanceof Integer){
+			return (((Integer)d1).intValue()-((Integer)d2).intValue())/((Integer)d2+0.0);
+		}
+		return null;
+	}
+	
+	public String getCoalCompared() {
+		if(coalCompared==null||coalCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(coalCompared*100, 1)+"%";
+	}
+	
+	public String getOilCompared() {
+		if(oilCompared==null||oilCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(oilCompared*100, 1)+"%";
+	}
+	
+	public String getCoilCompared() {
+		if(coilCompared==null||coilCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(coilCompared*100, 1)+"%";
+	}
+	
+	public String getWellCountCompared() {
+		if(wellCountCompared==null||wellCountCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(wellCountCompared*100, 1)+"%";
+	}
+	
+	public String getIndustryValueCompared() {
+		if(industryValueCompared==null||industryValueCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(industryValueCompared*100, 1)+"%";
+	}
+	
+	public String getAddedValueCompared() {
+		if(addedValueCompared==null||addedValueCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(addedValueCompared*100, 1)+"%";
+	}
+	
+	public String getWaterCompared() {
+		if(waterCompared==null||waterCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(waterCompared*100, 1)+"%";
+	}
+	
+	public String getPowerCompared() {
+		if(powerCompared==null||powerCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(powerCompared*100, 1)+"%";
+	}
+	
+	public String getNgasCompared() {
+		if(ngasCompared==null||ngasCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(ngasCompared*100, 1)+"%";
+	}
+	
+	public String getYgasCompared() {
+		if(ygasCompared==null||ygasCompared.isNaN()){
+			return null;
+		}
+		return DataUtils.format(ygasCompared*100, 1)+"%";
+	}
+
+	public ERP getErpKl() {
+		return erpKl;
+	}
+
+	public void setErpKl(ERP erpKl) {
+		this.erpKl = erpKl;
+	}
+
+	public Double getOilTotal() {
+		return oilTotal;
+	}
+
+	public void setOilTotal(Double oilTotal) {
+		this.oilTotal = oilTotal;
+	}
+
+	public Double getCoilTotal() {
+		return coilTotal;
+	}
+
+	public void setCoilTotal(Double coilTotal) {
+		this.coilTotal = coilTotal;
+	}
+
+	public Wpg getWpg() {
+		return wpg;
+	}
+
+	public void setWpg(Wpg wpg) {
+		this.wpg = wpg;
+	}
+
+	public Workload getWorkload() {
+		return workload;
+	}
+
+	public void setWorkload(Workload workload) {
+		this.workload = workload;
+	}
+
+	public String getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(String rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	
+
+	public void setOilCompared(Double oilCompared) {
+		this.oilCompared = oilCompared;
+	}
+
+	
+
+	public void setCoilCompared(Double coilCompared) {
+		this.coilCompared = coilCompared;
+	}
+
+	
+
+	public void setWaterCompared(Double waterCompared) {
+		this.waterCompared = waterCompared;
+	}
+
+	
+
+	public void setPowerCompared(Double powerCompared) {
+		this.powerCompared = powerCompared;
+	}
+
+	
+
+	public void setNgasCompared(Double ngasCompared) {
+		this.ngasCompared = ngasCompared;
+	}
+
+	
+
+	public void setYgasCompared(Double ygasCompared) {
+		this.ygasCompared = ygasCompared;
+	}
+
+	
+
+	public void setWellCountCompared(Double wellCountCompared) {
+		this.wellCountCompared = wellCountCompared;
+	}
+
+	
+
+	public void setIndustryValueCompared(Double industryValueCompared) {
+		this.industryValueCompared = industryValueCompared;
+	}
+
+	
+
+	public void setAddedValueCompared(Double addedValueCompared) {
+		this.addedValueCompared = addedValueCompared;
+	}
+
+	
+
+	public void setCoalCompared(Double coalCompared) {
+		this.coalCompared = coalCompared;
+	}
+
+	public Double getCoals() {
+		return coals;
+	}
+
+	public void setCoals(Double coals) {
+		this.coals = coals;
+	}
+	
+}

+ 164 - 0
src/main/java/com/hb/proj/model/EnergyWaterSumVOUtil.java

@@ -0,0 +1,164 @@
+package com.hb.proj.model;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.hb.proj.car.controller.ERPKlSumUtil;
+import com.hb.proj.car.service.CarRptUtils;
+import com.hb.xframework.util.DateUtil;
+
+public class EnergyWaterSumVOUtil {
+
+	/**
+	 * 计算同比值
+	 * @param voIndex
+	 * @param preVoIndex
+	 */
+	public static void caculateCompare(Map<String,EnergyWaterSumVO>  voIndex,Map<String,EnergyWaterSumVO> preVoIndex){
+		String month=null;
+		EnergyWaterSumVO v1=null;
+		for(int i=1;i<=12;i++){
+			month=String.format("%02d",i);
+			v1=voIndex.get(month);
+			if(preVoIndex.get(month)!=null){
+				if(v1==null){
+					v1=new EnergyWaterSumVO(null,null,null);
+					voIndex.put(month, v1);
+				}
+				v1.setComparedValue(preVoIndex.get(month));
+			}
+		}
+	}
+	
+	/**
+	 * 油量各月数据和数据校正中表二中的当月数据对应(单位:万元、吨、万立方米)
+	 * @return
+	 */
+	public static Map<String,ERP>  builderERPKlMonthGroup(List<ERP> erps,List<OtherConsume> kls){
+		Map<String,OtherConsume> klIdx=new HashMap<String,OtherConsume>();
+		Map<String,ERP> erpIdx=new HashMap<String,ERP>();
+		String month=null;
+		
+		for(OtherConsume consume : kls){
+			month=DateUtil.format(consume.getRptMonth(), "MM");
+			klIdx.put(month, consume);
+		}
+		for(ERP erp : erps){
+			month=DateUtil.format(erp.getRptMonth(), "MM");
+			erpIdx.put(month, erp);
+		}
+		for(int m=1;m<=12;m++){
+			month=String.format("%02d", m);
+			erpIdx.put(month, ERPKlSumUtil.erpPlusKlMonth(klIdx.get(month), erpIdx.get(month))); //借用,原始ERP替换为ERP+kl
+		}
+		klIdx.clear();
+		klIdx=null;
+		return erpIdx;
+	}
+	
+	/**
+	 * 水电气各月数据和数据校正中表三中的当月和计数据对应
+	 * @param wpgs
+	 * @param wpgCorrects
+	 * @return
+	 */
+	public static Map<String,Wpg> buildWpgWithCorrect(List<Wpg> wpgs,List<WpgCorrect> wpgCorrects){
+		Map<String,Wpg> wpgIdx=new HashMap<String,Wpg>();
+		Map<String,WpgCorrect> correctIdx=new HashMap<String,WpgCorrect>();
+		String month=null;
+		
+		for(Wpg wpg : wpgs){
+			month=DateUtil.format(wpg.getRptMonth(), "MM");
+			wpgIdx.put(month, wpg);
+		}
+		for(WpgCorrect crt : wpgCorrects){
+			month=DateUtil.format(crt.getRptMonth(), "MM");
+			correctIdx.put(month, crt);
+		}
+		Wpg wpg=null;
+		for(int m=1;m<=12;m++){
+			month=String.format("%02d", m);
+			wpg=wpgIdx.get(month); 
+			if(wpg==null){//可能为空
+				wpg=new Wpg();
+				wpgIdx.put(month, wpg);
+			}
+			ERPKlSumUtil.processWpgSum(wpg, correctIdx.get(month));
+		}
+		correctIdx.clear();
+		correctIdx=null;
+		return wpgIdx;
+	}
+	
+	/**
+	 * 用能用水统计汇总(分月显示12个月)
+	 * @param erps
+	 * @param kls
+	 * @param wpgs
+	 * @param wpgCorrects
+	 * @param workloads
+	 * @return
+	 */
+	public static Map<String,EnergyWaterSumVO> build(List<ERP> erps,List<OtherConsume> kls,List<Wpg> wpgs,List<WpgCorrect> wpgCorrects,List<Workload> workloads){
+		Map<String,EnergyWaterSumVO>  voIdx=new HashMap<String,EnergyWaterSumVO>();
+		String month=null;
+		EnergyWaterSumVO vo=null;
+		
+		Map<String,ERP>   monthErps=builderERPKlMonthGroup(erps,kls); //汽油、柴油
+		Map<String,Wpg>   monthWpgs=buildWpgWithCorrect(wpgs,wpgCorrects) ; //水电气
+		Map<String,Workload> monthWorkloads=new HashMap<String,Workload>(); //工作量
+		for(Workload wk : workloads){
+			month=DateUtil.format(wk.getRptMonth(), "MM");
+			monthWorkloads.put(month, wk);
+		}
+		
+		for(int m=1;m<=12;m++){
+			month=String.format("%02d", m);
+			vo=new EnergyWaterSumVO(monthErps.get(month),monthWpgs.get(month),monthWorkloads.get(month));
+			vo.initCoal();
+			voIdx.put(month, vo);
+		}
+		
+		return voIdx;
+	}
+	
+	
+	/**
+	 * 用于能源台账报表:EnergyCostAccountController
+	 * 来源数据单位:吨,万元,万立方米,万千瓦时。部分单位需要转换
+	 * 汽油、柴油千克、液化气千克
+	 * 汽油、柴油折算吨标煤显示合计值,合计后存储在oilCoal
+	 * @param erps
+	 * @param kls
+	 * @param wpgs
+	 * @param wpgCorrects
+	 * @return
+	 */
+	public static Map<String,EnergyWaterSumVO> buildForCostAccount(List<ERP> erps,List<OtherConsume> kls,List<Wpg> wpgs,List<WpgCorrect> wpgCorrects){
+		Map<String,EnergyWaterSumVO>  voIdx=new HashMap<String,EnergyWaterSumVO>();
+		String month=null;
+		EnergyWaterSumVO vo=null;
+		
+		Map<String,ERP>   monthErps=builderERPKlMonthGroup(erps,kls); //汽油、柴油
+		Map<String,Wpg>   monthWpgs=buildWpgWithCorrect(wpgs,wpgCorrects) ; //水电气
+		
+		for(int m=1;m<=12;m++){
+			month=String.format("%02d", m);
+			vo=new EnergyWaterSumVO(monthErps.get(month),monthWpgs.get(month),null);
+			vo.initCoal();
+			if(vo.getErpKl()!=null){
+				vo.getErpKl().setOilCoal(CarRptUtils.addDouble(vo.getErpKl().getOilCoal(),vo.getErpKl().getCoilCoal()));
+			}
+			vo.setOilTotal(vo.getOilTotal()!=null?(vo.getOilTotal()*1000):null);
+			vo.setCoilTotal(vo.getCoilTotal()!=null?(vo.getCoilTotal()*1000):null);
+			if(vo.getWpg()!=null&&vo.getWpg().getLgasCount()!=null){
+				vo.getWpg().setLgasCount(vo.getWpg().getLgasCount()*1000);
+			}
+			
+			voIdx.put(month, vo);
+		}
+		
+		return voIdx;
+	}
+}

+ 161 - 0
src/main/java/com/hb/proj/model/Menu.java

@@ -0,0 +1,161 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+import com.hb.xframework.annotation.Column;
+import com.hb.xframework.annotation.Table;
+
+
+@Table("T_MENU_DEFINITION")
+public class Menu {
+
+	 @Column(value="MENU_ID",primary=true)
+	 private String menuId;
+	 
+	 
+	 @Column("MENU_NAME")
+	 private String menuName;
+	 
+	 @Column("MENU_ICON")
+	 private String menuIcon;
+	 
+	 @Column("FATHER_MENU_ID")
+	 private String fatherMenuId;
+	 
+	 @Column("MENU_LINK")
+	 private String menuLink;
+	 
+	 @Column(value="CREATOR",update=false)
+	 private String creator;
+	 
+	 @Column(value="CREATE_TIME",update=false)
+	 private Date createTime;
+	 
+	 @Column("DISPLAY_NUM")
+	 private Integer displayNum;
+	 
+	 @Column(insert=false,update=false)
+	 private String fatherMenuName;
+	 
+	 @Column(insert=false,update=false)
+	 private int childCount;
+	 
+	 @Column(insert=false,update=false)
+	 private Boolean  disabled;
+	 
+	 @Column("TARGET_DEPTH")
+	 private String targetDepth;
+	 
+	 @Column("ASSIST_CODE")
+	 private String assistCode;
+
+	public String getMenuId() {
+		return menuId;
+	}
+
+	public void setMenuId(String menuId) {
+		this.menuId = menuId;
+	}
+
+	public String getMenuName() {
+		return menuName;
+	}
+
+	public void setMenuName(String menuName) {
+		this.menuName = menuName;
+	}
+
+	public String getMenuIcon() {
+		return menuIcon;
+	}
+
+	public void setMenuIcon(String menuIcon) {
+		this.menuIcon = menuIcon;
+	}
+
+	public String getFatherMenuId() {
+		return fatherMenuId;
+	}
+
+	public void setFatherMenuId(String fatherMenuId) {
+		this.fatherMenuId = fatherMenuId;
+	}
+
+	public String getMenuLink() {
+		return menuLink;
+	}
+
+	public void setMenuLink(String menuLink) {
+		this.menuLink = menuLink;
+	}
+
+	public String getCreator() {
+		return creator;
+	}
+
+	public void setCreator(String creator) {
+		this.creator = creator;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Integer getDisplayNum() {
+		return displayNum;
+	}
+
+	public void setDisplayNum(Integer displayNum) {
+		this.displayNum = displayNum;
+	}
+
+	
+
+	public String getFatherMenuName() {
+		return fatherMenuName;
+	}
+
+	public void setFatherMenuName(String fatherMenuName) {
+		this.fatherMenuName = fatherMenuName;
+	}
+
+	public int getChildCount() {
+		return childCount;
+	}
+
+	public void setChildCount(int childCount) {
+		this.childCount = childCount;
+	}
+	
+	
+
+	public String getTargetDepth() {
+		return targetDepth;
+	}
+
+	public void setTargetDepth(String targetDepth) {
+		this.targetDepth = targetDepth;
+	}
+
+	public Boolean getDisabled() {
+		return disabled;
+	}
+
+	public void setDisabled(Boolean disabled) {
+		this.disabled = disabled;
+	}
+
+	public String getAssistCode() {
+		return assistCode;
+	}
+
+	public void setAssistCode(String assistCode) {
+		this.assistCode = assistCode;
+	}
+
+	
+}

+ 117 - 0
src/main/java/com/hb/proj/model/OilAddLog.java

@@ -0,0 +1,117 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class OilAddLog {
+
+	private Integer id;
+	
+	private String carNum;
+	
+	private String carId;
+	
+	private Date addTime;
+	
+	private Double addCount;
+	
+	private Double volumeRatio;
+	
+	private Double volumeRatio2;
+	
+	private Double meterVol;
+	
+	private Double meterVol2;
+	
+	private Date modifyTime;
+	
+	private String note;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getCarNum() {
+		return carNum;
+	}
+
+	public void setCarNum(String carNum) {
+		this.carNum = carNum;
+	}
+
+	public Date getAddTime() {
+		return addTime;
+	}
+
+	public void setAddTime(Date addTime) {
+		this.addTime = addTime;
+	}
+
+	public Double getAddCount() {
+		return addCount;
+	}
+
+	public void setAddCount(Double addCount) {
+		this.addCount = addCount;
+	}
+
+	public Double getVolumeRatio() {
+		return volumeRatio;
+	}
+
+	public void setVolumeRatio(Double volumeRatio) {
+		this.volumeRatio = volumeRatio;
+	}
+
+	public Double getVolumeRatio2() {
+		return volumeRatio2;
+	}
+
+	public void setVolumeRatio2(Double volumeRatio2) {
+		this.volumeRatio2 = volumeRatio2;
+	}
+
+	public Date getModifyTime() {
+		return modifyTime;
+	}
+
+	public void setModifyTime(Date modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+
+	public String getNote() {
+		return note;
+	}
+
+	public void setNote(String note) {
+		this.note = note;
+	}
+
+	public String getCarId() {
+		return carId;
+	}
+
+	public void setCarId(String carId) {
+		this.carId = carId;
+	}
+
+	public Double getMeterVol() {
+		return meterVol;
+	}
+
+	public void setMeterVol(Double meterVol) {
+		this.meterVol = meterVol;
+	}
+
+	public Double getMeterVol2() {
+		return meterVol2;
+	}
+
+	public void setMeterVol2(Double meterVol2) {
+		this.meterVol2 = meterVol2;
+	}
+	
+}

+ 87 - 0
src/main/java/com/hb/proj/model/OilChangeBO.java

@@ -0,0 +1,87 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class OilChangeBO {
+
+	private String carId;
+	
+	private String carNum;
+	
+	private Double diffVolume;
+	
+	private Date dataTime;
+	
+	private String boxNum;
+	
+	private String dtuNum;
+	
+	private String mountId;
+	
+	private Integer id;
+	
+
+	public String getCarId() {
+		return carId;
+	}
+
+	public void setCarId(String carId) {
+		this.carId = carId;
+	}
+
+	public String getCarNum() {
+		return carNum;
+	}
+
+	public void setCarNum(String carNum) {
+		this.carNum = carNum;
+	}
+
+	public Double getDiffVolume() {
+		return diffVolume;
+	}
+
+	public void setDiffVolume(Double diffVolume) {
+		this.diffVolume = diffVolume;
+	}
+
+	public Date getDataTime() {
+		return dataTime;
+	}
+
+	public void setDataTime(Date dataTime) {
+		this.dataTime = dataTime;
+	}
+
+	public String getBoxNum() {
+		return boxNum;
+	}
+
+	public void setBoxNum(String boxNum) {
+		this.boxNum = boxNum;
+	}
+
+	public String getDtuNum() {
+		return dtuNum;
+	}
+
+	public void setDtuNum(String dtuNum) {
+		this.dtuNum = dtuNum;
+	}
+
+	public String getMountId() {
+		return mountId;
+	}
+
+	public void setMountId(String mountId) {
+		this.mountId = mountId;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+}

+ 56 - 0
src/main/java/com/hb/proj/model/OilCurrentDTO.java

@@ -0,0 +1,56 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class OilCurrentDTO {
+
+	private String termSn;
+	
+	private String vin;
+	
+	private Date reportTime;
+	
+	private Double curOil;
+	
+	private Double realValue;
+
+	public String getTermSn() {
+		return termSn;
+	}
+
+	public void setTermSn(String termSn) {
+		this.termSn = termSn;
+	}
+
+	public String getVin() {
+		return vin;
+	}
+
+	public void setVin(String vin) {
+		this.vin = vin;
+	}
+
+	public Date getReportTime() {
+		return reportTime;
+	}
+
+	public void setReportTime(Date reportTime) {
+		this.reportTime = reportTime;
+	}
+
+	public Double getCurOil() {
+		return curOil;
+	}
+
+	public void setCurOil(Double curOil) {
+		this.curOil = curOil;
+	}
+
+	public Double getRealValue() {
+		return realValue;
+	}
+
+	public void setRealValue(Double realValue) {
+		this.realValue = realValue;
+	}
+}

+ 261 - 0
src/main/java/com/hb/proj/model/OtherConsume.java

@@ -0,0 +1,261 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+/**
+ * 主要用于报表计算(汽油未区分92,95 只显示两种标号汽油的和重量,明细在OtherConsumeBO)
+ * @author xe
+ *
+ */
+public class OtherConsume {
+	
+	private String recordId;
+	
+	private String modifier;
+	
+	private Date   modifyTime;
+	
+	private String orgId;
+	
+	private  Date  rptMonth;
+
+	private Double oilCount;
+	
+	private Double coilCount;
+	
+	private Double oilCountKg;
+	
+	private Double coilCountKg;
+	
+	private Double oilErpCount;
+	
+	private Double oilKlCount;
+	
+	private Double oilKlMoney;
+	
+	private Double coilErpCount;
+	
+	private Double coilKlCount;
+	
+	private Double coilKlMoney;
+	
+	
+	private Double oilErpCountKg;
+	
+	private Double oilKlCountKg;
+	
+	private Double coilErpCountKg;
+	
+	private Double coilKlCountKg;
+	
+	private Double oilCoal;  //总汽油标煤折算
+	
+	private Double coilCoal;
+	
+	private Double oilKlCoal; //昆仑卡汽油标准煤折算
+	
+	private Double coilKlCoal; //昆仑卡柴油标准煤折算
+	
+	private Double oilOthCoal; //其它汽油标准煤折算
+	
+	private Double coilOthCoal; //其它卡柴油标准煤折算
+
+	public Double getOilCount() {
+		return oilCount;
+	}
+
+	public void setOilCount(Double oilCount) {
+		this.oilCount = oilCount;
+	}
+
+	public Double getCoilCount() {
+		return coilCount;
+	}
+
+	public void setCoilCount(Double coilCount) {
+		this.coilCount = coilCount;
+	}
+
+	public Double getOilCountKg() {
+		return oilCountKg;
+	}
+
+	public void setOilCountKg(Double oilCountKg) {
+		this.oilCountKg = oilCountKg;
+	}
+
+	public Double getCoilCountKg() {
+		return coilCountKg;
+	}
+
+	public void setCoilCountKg(Double coilCountKg) {
+		this.coilCountKg = coilCountKg;
+	}
+
+	public String getOrgId() {
+		return orgId;
+	}
+
+	public void setOrgId(String orgId) {
+		this.orgId = orgId;
+	}
+
+	public Double getOilErpCount() {
+		return oilErpCount;
+	}
+
+	public void setOilErpCount(Double oilErpCount) {
+		this.oilErpCount = oilErpCount;
+	}
+
+	public Double getOilKlCount() {
+		return oilKlCount;
+	}
+
+	public void setOilKlCount(Double oilKlCount) {
+		this.oilKlCount = oilKlCount;
+	}
+
+	public Double getOilKlMoney() {
+		return oilKlMoney;
+	}
+
+	public void setOilKlMoney(Double oilKlMoney) {
+		this.oilKlMoney = oilKlMoney;
+	}
+
+	public Double getCoilErpCount() {
+		return coilErpCount;
+	}
+
+	public void setCoilErpCount(Double coilErpCount) {
+		this.coilErpCount = coilErpCount;
+	}
+
+	public Double getCoilKlCount() {
+		return coilKlCount;
+	}
+
+	public void setCoilKlCount(Double coilKlCount) {
+		this.coilKlCount = coilKlCount;
+	}
+
+	public Double getCoilKlMoney() {
+		return coilKlMoney;
+	}
+
+	public void setCoilKlMoney(Double coilKlMoney) {
+		this.coilKlMoney = coilKlMoney;
+	}
+
+	public Double getOilErpCountKg() {
+		return oilErpCountKg;
+	}
+
+	public void setOilErpCountKg(Double oilErpCountKg) {
+		this.oilErpCountKg = oilErpCountKg;
+	}
+
+	public Double getOilKlCountKg() {
+		return oilKlCountKg;
+	}
+
+	public void setOilKlCountKg(Double oilKlCountKg) {
+		this.oilKlCountKg = oilKlCountKg;
+	}
+
+	public Double getCoilErpCountKg() {
+		return coilErpCountKg;
+	}
+
+	public void setCoilErpCountKg(Double coilErpCountKg) {
+		this.coilErpCountKg = coilErpCountKg;
+	}
+
+	public Double getCoilKlCountKg() {
+		return coilKlCountKg;
+	}
+
+	public void setCoilKlCountKg(Double coilKlCountKg) {
+		this.coilKlCountKg = coilKlCountKg;
+	}
+
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+
+	public String getModifier() {
+		return modifier;
+	}
+
+	public void setModifier(String modifier) {
+		this.modifier = modifier;
+	}
+
+	public Date getModifyTime() {
+		return modifyTime;
+	}
+
+	public void setModifyTime(Date modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+
+	public Double getOilCoal() {
+		return oilCoal;
+	}
+
+	public void setOilCoal(Double oilCoal) {
+		this.oilCoal = oilCoal;
+	}
+
+	public Double getCoilCoal() {
+		return coilCoal;
+	}
+
+	public void setCoilCoal(Double coilCoal) {
+		this.coilCoal = coilCoal;
+	}
+
+	public Double getOilKlCoal() {
+		return oilKlCoal;
+	}
+
+	public void setOilKlCoal(Double oilKlCoal) {
+		this.oilKlCoal = oilKlCoal;
+	}
+
+	public Double getCoilKlCoal() {
+		return coilKlCoal;
+	}
+
+	public void setCoilKlCoal(Double coilKlCoal) {
+		this.coilKlCoal = coilKlCoal;
+	}
+
+	public Double getOilOthCoal() {
+		return oilOthCoal;
+	}
+
+	public void setOilOthCoal(Double oilOthCoal) {
+		this.oilOthCoal = oilOthCoal;
+	}
+
+	public Double getCoilOthCoal() {
+		return coilOthCoal;
+	}
+
+	public void setCoilOthCoal(Double coilOthCoal) {
+		this.coilOthCoal = coilOthCoal;
+	}
+}

+ 246 - 0
src/main/java/com/hb/proj/model/OtherConsumeBO.java

@@ -0,0 +1,246 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+/**
+ * 各项目部上报的其它用油、合计用油(区分了汽油92#、95#)主要用于数据的上报
+ * @author xe
+ *
+ */
+public class OtherConsumeBO {
+
+	private String recordId;
+	
+	private String modifier;
+	
+	private Date   modifyTime;
+	
+	private String orgId;
+	
+	private  Date  rptMonth;
+
+	private Double oilCount;
+	
+	private Double coilCount;
+	
+	private Double oilCountKg;
+	
+	private Double coilCountKg;
+	
+	private Double oilErpCount;
+	
+	private Double oilKlCount;
+	
+	private Double oilKlMoney;
+	
+	private Double coilErpCount;
+	
+	private Double coilKlCount;
+	
+	private Double coilKlMoney;
+	
+	
+	private Double oilErpCountKg;
+	
+	private Double oilKlCountKg;
+	
+	private Double coilErpCountKg;
+	
+	private Double coilKlCountKg;
+	
+	private Double oilCoal;  //总汽油标煤折算
+	
+	private Double coilCoal;
+	
+	private Double oilKlCoal; //昆仑卡汽油标准煤折算
+	
+	private Double coilKlCoal; //昆仑卡柴油标准煤折算
+	
+	private Double oilOthCoal; //其它汽油标准煤折算
+	
+	private Double coilOthCoal; //其它卡柴油标准煤折算
+	
+	private Double oilKl92; //昆仑卡汽油 92#
+	private Double oilKl95; //昆仑卡汽油 95#
+	
+	private Double oilErp92; //ERP汽油 92#
+	private Double oilErp95; //ERP汽油 95#
+	
+	public String getRecordId() {
+		return recordId;
+	}
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+	public String getModifier() {
+		return modifier;
+	}
+	public void setModifier(String modifier) {
+		this.modifier = modifier;
+	}
+	public Date getModifyTime() {
+		return modifyTime;
+	}
+	public void setModifyTime(Date modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+	public String getOrgId() {
+		return orgId;
+	}
+	public void setOrgId(String orgId) {
+		this.orgId = orgId;
+	}
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+	public Double getOilCount() {
+		return oilCount;
+	}
+	public void setOilCount(Double oilCount) {
+		this.oilCount = oilCount;
+	}
+	public Double getCoilCount() {
+		return coilCount;
+	}
+	public void setCoilCount(Double coilCount) {
+		this.coilCount = coilCount;
+	}
+	public Double getOilCountKg() {
+		return oilCountKg;
+	}
+	public void setOilCountKg(Double oilCountKg) {
+		this.oilCountKg = oilCountKg;
+	}
+	public Double getCoilCountKg() {
+		return coilCountKg;
+	}
+	public void setCoilCountKg(Double coilCountKg) {
+		this.coilCountKg = coilCountKg;
+	}
+	public Double getOilErpCount() {
+		return oilErpCount;
+	}
+	public void setOilErpCount(Double oilErpCount) {
+		this.oilErpCount = oilErpCount;
+	}
+	public Double getOilKlCount() {
+		return oilKlCount;
+	}
+	public void setOilKlCount(Double oilKlCount) {
+		this.oilKlCount = oilKlCount;
+	}
+	public Double getOilKlMoney() {
+		return oilKlMoney;
+	}
+	public void setOilKlMoney(Double oilKlMoney) {
+		this.oilKlMoney = oilKlMoney;
+	}
+	public Double getCoilErpCount() {
+		return coilErpCount;
+	}
+	public void setCoilErpCount(Double coilErpCount) {
+		this.coilErpCount = coilErpCount;
+	}
+	public Double getCoilKlCount() {
+		return coilKlCount;
+	}
+	public void setCoilKlCount(Double coilKlCount) {
+		this.coilKlCount = coilKlCount;
+	}
+	public Double getCoilKlMoney() {
+		return coilKlMoney;
+	}
+	public void setCoilKlMoney(Double coilKlMoney) {
+		this.coilKlMoney = coilKlMoney;
+	}
+	public Double getOilErpCountKg() {
+		return oilErpCountKg;
+	}
+	public void setOilErpCountKg(Double oilErpCountKg) {
+		this.oilErpCountKg = oilErpCountKg;
+	}
+	public Double getOilKlCountKg() {
+		return oilKlCountKg;
+	}
+	public void setOilKlCountKg(Double oilKlCountKg) {
+		this.oilKlCountKg = oilKlCountKg;
+	}
+	public Double getCoilErpCountKg() {
+		return coilErpCountKg;
+	}
+	public void setCoilErpCountKg(Double coilErpCountKg) {
+		this.coilErpCountKg = coilErpCountKg;
+	}
+	public Double getCoilKlCountKg() {
+		return coilKlCountKg;
+	}
+	public void setCoilKlCountKg(Double coilKlCountKg) {
+		this.coilKlCountKg = coilKlCountKg;
+	}
+	public Double getOilCoal() {
+		return oilCoal;
+	}
+	public void setOilCoal(Double oilCoal) {
+		this.oilCoal = oilCoal;
+	}
+	public Double getCoilCoal() {
+		return coilCoal;
+	}
+	public void setCoilCoal(Double coilCoal) {
+		this.coilCoal = coilCoal;
+	}
+	public Double getOilKlCoal() {
+		return oilKlCoal;
+	}
+	public void setOilKlCoal(Double oilKlCoal) {
+		this.oilKlCoal = oilKlCoal;
+	}
+	public Double getCoilKlCoal() {
+		return coilKlCoal;
+	}
+	public void setCoilKlCoal(Double coilKlCoal) {
+		this.coilKlCoal = coilKlCoal;
+	}
+	public Double getOilOthCoal() {
+		return oilOthCoal;
+	}
+	public void setOilOthCoal(Double oilOthCoal) {
+		this.oilOthCoal = oilOthCoal;
+	}
+	public Double getCoilOthCoal() {
+		return coilOthCoal;
+	}
+	public void setCoilOthCoal(Double coilOthCoal) {
+		this.coilOthCoal = coilOthCoal;
+	}
+	public Double getOilKl92() {
+		return oilKl92;
+	}
+	public void setOilKl92(Double oilKl92) {
+		this.oilKl92 = oilKl92;
+	}
+	public Double getOilKl95() {
+		return oilKl95;
+	}
+	public void setOilKl95(Double oilKl95) {
+		this.oilKl95 = oilKl95;
+	}
+	public Double getOilErp92() {
+		return oilErp92;
+	}
+	public void setOilErp92(Double oilErp92) {
+		this.oilErp92 = oilErp92;
+	}
+	public Double getOilErp95() {
+		return oilErp95;
+	}
+	public void setOilErp95(Double oilErp95) {
+		this.oilErp95 = oilErp95;
+	}
+	
+	
+
+}

+ 47 - 0
src/main/java/com/hb/proj/model/OtherConsumeWrapVO.java

@@ -0,0 +1,47 @@
+package com.hb.proj.model;
+
+import com.hb.proj.car.service.CarRptUtils;
+
+/**
+ * OtherConsume的包装类
+ * @author xe
+ *
+ */
+public class OtherConsumeWrapVO {
+
+	private OtherConsume  oth;
+	
+	private Double oilSumKg; //汽油合计量(ERP+昆仑卡)
+	
+	private Double coilSumKg; //柴油合计量(ERP+昆仑卡)
+	
+	public OtherConsumeWrapVO(OtherConsume otherConsume){
+		this.oth=otherConsume;
+		this.oilSumKg=CarRptUtils.addDouble(otherConsume.getOilErpCountKg(),otherConsume.getOilKlCountKg());
+		this.coilSumKg=CarRptUtils.addDouble(otherConsume.getCoilErpCountKg(),otherConsume.getCoilKlCountKg());
+	}
+
+	public OtherConsume getOth() {
+		return oth;
+	}
+
+	public void setOth(OtherConsume otherConsume) {
+		this.oth = otherConsume;
+	}
+
+	public Double getOilSumKg() {
+		return oilSumKg;
+	}
+
+	public void setOilSumKg(Double oilSumKg) {
+		this.oilSumKg = oilSumKg;
+	}
+
+	public Double getCoilSumKg() {
+		return coilSumKg;
+	}
+
+	public void setCoilSumKg(Double coilSumKg) {
+		this.coilSumKg = coilSumKg;
+	}
+}

+ 151 - 0
src/main/java/com/hb/proj/model/OtherOilCalculater.java

@@ -0,0 +1,151 @@
+package com.hb.proj.model;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hb.proj.car.quota.QuotaConfig;
+import com.hb.proj.car.quota.QuotaStandardSupport;
+
+/**
+ * 其它用油换算工具
+ * @author hb
+ *
+ */
+public class OtherOilCalculater {
+
+	private static Logger logger=LoggerFactory.getLogger(OtherOilCalculater.class);
+	
+	//获得带权重(92#:95#)的汽油折算系数---加权值
+	public static double getOilWeightRatio(Double oil92,Double oil95){
+		if(oil92==null){
+			oil92=0.0;
+		}
+		if(oil95==null){
+			oil95=0.0;
+		}
+		if(oil92==0&&oil95==0){
+			return 1;
+		}
+		double w92=oil92/(oil92+oil95),w95=oil95/(oil92+oil95);  //计算权重
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		return qc.getOilRatio()*w92+qc.getOilRatio95()*w95;
+	}		
+		
+	/**
+	 * 油耗 升-转kg
+	 * @param othOil
+	 */
+	public static void calculate(OtherConsumeBO othOil){
+		QuotaConfig qc=QuotaStandardSupport.getConfig();
+		if(qc==null){
+			logger.warn("缺少折算系数,取消对其它油耗的换算");
+			return;
+		}
+		 Double w92=addDouble(othOil.getOilKl92(), othOil.getOilErp92());
+		 Double w95=addDouble(othOil.getOilKl95(), othOil.getOilErp95());
+		 Double oilWeightRatio=getOilWeightRatio(w92, w95);
+		 
+		//先清空计算字段数据
+		clearOther(othOil);
+		//其它用油
+		if(othOil.getOilCount()!=null){
+			othOil.setOilCountKg(othOil.getOilCount()*oilWeightRatio);
+		}
+		if(othOil.getCoilCount()!=null){
+			othOil.setCoilCountKg(othOil.getCoilCount()*qc.getCoilRatio());
+		}
+		//汽油92#,95# 升进行合并,重量分别折算后再合并
+		
+		othOil.setOilKlCount(addDouble(othOil.getOilKl92(),othOil.getOilKl95()));
+		othOil.setOilErpCount(addDouble(othOil.getOilErp92(),othOil.getOilErp95()));
+		double oilWeight=0;
+		if(othOil.getOilKl92()!=null){
+			oilWeight+=othOil.getOilKl92()*qc.getOilRatio();
+		}
+		if(othOil.getOilKl95()!=null){
+			oilWeight+=othOil.getOilKl95()*qc.getOilRatio95();
+		}
+		othOil.setOilKlCountKg(oilWeight);
+		//oilWeight要重置否则产生累计效果
+		oilWeight=0;
+		if(othOil.getOilErp92()!=null){
+			oilWeight+=othOil.getOilErp92()*qc.getOilRatio();
+		}
+		if(othOil.getOilErp95()!=null){
+			oilWeight+=othOil.getOilErp95()*qc.getOilRatio95();
+		}
+		othOil.setOilErpCountKg(oilWeight);
+		
+		
+		
+		//项目部合计用油
+		
+		
+		if(othOil.getCoilErpCount()!=null){
+			othOil.setCoilErpCountKg(othOil.getCoilErpCount()*qc.getCoilRatio());
+		}
+		if(othOil.getCoilKlCount()!=null){ 
+			othOil.setCoilKlCountKg(othOil.getCoilKlCount()*qc.getCoilRatio());
+		}
+		
+		//计算汽油、柴油合计折算煤(昆仑卡+ERP)
+		Double oilKg=addDouble(othOil.getOilKlCountKg(),othOil.getOilErpCountKg());
+		if(oilKg!=null){ //kg转吨再折算
+			othOil.setOilCoal(oilKg*qc.getOilCoalRatio()/1000.0);
+		}
+		
+		oilKg=addDouble(othOil.getCoilKlCountKg(),othOil.getCoilErpCountKg());
+		
+		if(oilKg!=null){
+			othOil.setCoilCoal(oilKg*qc.getCoilCoalRatio()/1000.0);
+		}
+		
+		//单独计算昆仑卡油耗折算煤
+		if(othOil.getOilKlCountKg()!=null){  //kg转吨再折算
+			othOil.setOilKlCoal(othOil.getOilKlCountKg()*qc.getOilCoalRatio()/1000.0);
+		}
+		if(othOil.getCoilKlCountKg()!=null){
+			othOil.setCoilKlCoal(othOil.getCoilKlCountKg()*qc.getCoilCoalRatio()/1000.0);
+		}
+		//单独计算其它油耗折算煤
+		if(othOil.getOilCountKg()!=null){  //kg转吨再折算
+			othOil.setOilOthCoal(othOil.getOilCountKg()*qc.getOilCoalRatio()/1000.0);
+		}
+		if(othOil.getCoilCountKg()!=null){
+			othOil.setCoilOthCoal(othOil.getCoilCountKg()*qc.getCoilCoalRatio()/1000.0);
+		}
+	}
+	
+	/**
+	 * 上报数据有些本身来源于库中,特别是需要计算的数据,再次入库时应该重新计算,就需要把这些计算数据先置空
+	 * @param othOil
+	 */
+	public static void clearOther(OtherConsumeBO othOil){
+		//其它用油由升转公斤
+		othOil.setOilCountKg(null);
+		othOil.setCoilCountKg(null);
+		othOil.setOilKlCountKg(null);
+		othOil.setOilErpCountKg(null);
+		othOil.setCoilErpCountKg(null);
+		othOil.setCoilKlCountKg(null);
+		othOil.setOilCoal(null);
+		othOil.setCoilCoal(null);
+		othOil.setOilKlCoal(null);
+		othOil.setCoilKlCoal(null);
+		othOil.setOilOthCoal(null);
+		othOil.setCoilOthCoal(null);
+	}
+	
+	
+	public static Double addDouble(Double d1,Double d2){
+		if(d2==null||Double.isNaN(d2)){
+			return d1!=null?d1.doubleValue():null;
+		}
+		if(d1==null||Double.isNaN(d1)){
+			return d2!=null?d2.doubleValue():null;
+		}
+		else{
+			return d1.doubleValue()+d2.doubleValue();
+		}
+	}
+}

+ 120 - 0
src/main/java/com/hb/proj/model/Quota.java

@@ -0,0 +1,120 @@
+package com.hb.proj.model;
+
+import java.util.Map;
+
+public class Quota {
+
+    private String deviceName;
+	
+	private String deviceModel;
+	
+	private Integer  deviceAge;
+	
+	private String quotaType;
+	
+	private Number quotaCount;
+	
+	private String quotaKey;
+	
+	private String workArea;
+	
+	private Map<Integer,Double> riseMap;
+	
+	public Quota(){
+		
+	}
+	
+	public Quota(String quotaKey,String workArea,String qt,Number qc,String dn){
+		this.quotaKey=quotaKey;
+		this.workArea=workArea;
+		this.quotaType=qt;
+		this.quotaCount=qc;
+		this.deviceName=dn;
+	}
+	
+	
+	public Quota(String dn,String dm,Integer da,String qt,Number qc){
+		this.deviceName=dn;
+		this.deviceModel=dm;
+		this.deviceAge=da;
+		this.quotaType=qt;
+		this.quotaCount=qc;
+	}
+	
+
+	public String getDeviceName() {
+		return deviceName;
+	}
+
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
+	}
+
+	public String getDeviceModel() {
+		return deviceModel;
+	}
+
+	public void setDeviceModel(String deviceModel) {
+		this.deviceModel = deviceModel;
+	}
+
+
+
+	public String getQuotaType() {
+		return quotaType;
+	}
+
+	public void setQuotaType(String quotaType) {
+		this.quotaType = quotaType;
+	}
+
+	
+
+	public Integer getDeviceAge() {
+		return deviceAge;
+	}
+
+	public void setDeviceAge(Integer deviceAge) {
+		this.deviceAge = deviceAge;
+	}
+
+	public Number getQuotaCount() {
+		return quotaCount;
+	}
+
+	public void setQuotaCount(Number quotaCount) {
+		this.quotaCount = quotaCount;
+	}
+
+
+
+	public String getQuotaKey() {
+		return quotaKey;
+	}
+
+
+
+	public void setQuotaKey(String quotaKey) {
+		this.quotaKey = quotaKey;
+	}
+
+
+
+	public String getWorkArea() {
+		return workArea;
+	}
+
+
+
+	public void setWorkArea(String workArea) {
+		this.workArea = workArea;
+	}
+
+	public Map<Integer, Double> getRiseMap() {
+		return riseMap;
+	}
+
+	public void setRiseMap(Map<Integer, Double> riseMap) {
+		this.riseMap = riseMap;
+	}
+}

+ 124 - 0
src/main/java/com/hb/proj/model/QuotaRulePO.java

@@ -0,0 +1,124 @@
+package com.hb.proj.model;
+
+public class QuotaRulePO {
+
+	private String recordId;
+	
+	private String deviceName;
+	
+	private String deviceModel;
+	
+	private String quotaPower;
+	
+	private String oilType;
+	
+	private String workAreaQuota;
+	
+	private String quotaType;
+	
+	private Double quotaCount;
+	
+	private Double workHourQuota;
+	
+	private Double age5Rise;
+	
+	private Double age10Rise;
+	
+	private Double age15Rise;
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+
+	public String getDeviceName() {
+		return deviceName;
+	}
+
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
+	}
+
+	public String getDeviceModel() {
+		return deviceModel;
+	}
+
+	public void setDeviceModel(String deviceModel) {
+		this.deviceModel = deviceModel;
+	}
+
+	public String getQuotaPower() {
+		return quotaPower;
+	}
+
+	public void setQuotaPower(String quotaPower) {
+		this.quotaPower = quotaPower;
+	}
+
+	public String getOilType() {
+		return oilType;
+	}
+
+	public void setOilType(String oilType) {
+		this.oilType = oilType;
+	}
+
+	public String getWorkAreaQuota() {
+		return workAreaQuota;
+	}
+
+	public void setWorkAreaQuota(String workAreaQuota) {
+		this.workAreaQuota = workAreaQuota;
+	}
+
+	public String getQuotaType() {
+		return quotaType;
+	}
+
+	public void setQuotaType(String quotaType) {
+		this.quotaType = quotaType;
+	}
+
+	public Double getQuotaCount() {
+		return quotaCount;
+	}
+
+	public void setQuotaCount(Double quotaCount) {
+		this.quotaCount = quotaCount;
+	}
+
+	public Double getWorkHourQuota() {
+		return workHourQuota;
+	}
+
+	public void setWorkHourQuota(Double workHourQuota) {
+		this.workHourQuota = workHourQuota;
+	}
+
+	public Double getAge5Rise() {
+		return age5Rise;
+	}
+
+	public void setAge5Rise(Double age5Rise) {
+		this.age5Rise = age5Rise;
+	}
+
+	public Double getAge10Rise() {
+		return age10Rise;
+	}
+
+	public void setAge10Rise(Double age10Rise) {
+		this.age10Rise = age10Rise;
+	}
+
+	public Double getAge15Rise() {
+		return age15Rise;
+	}
+
+	public void setAge15Rise(Double age15Rise) {
+		this.age15Rise = age15Rise;
+	}
+}

+ 76 - 0
src/main/java/com/hb/proj/model/Workload.java

@@ -0,0 +1,76 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class Workload {
+
+	private String recordId;  
+
+	private Date rptMonth;
+	
+	private Integer wellCount;
+	
+	private String rptOrg;
+	
+	private Double industryValue;
+	
+	private Double addedValue;
+	
+	private Double builderArea;
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	public Integer getWellCount() {
+		return wellCount;
+	}
+
+	public void setWellCount(Integer wellCount) {
+		this.wellCount = wellCount;
+	}
+
+	public Double getIndustryValue() {
+		return industryValue;
+	}
+
+	public void setIndustryValue(Double industryValue) {
+		this.industryValue = industryValue;
+	}
+
+	public Double getAddedValue() {
+		return addedValue;
+	}
+
+	public void setAddedValue(Double addedValue) {
+		this.addedValue = addedValue;
+	}
+
+	public String getRptOrg() {
+		return rptOrg;
+	}
+
+	public void setRptOrg(String rptOrg) {
+		this.rptOrg = rptOrg;
+	}
+
+	public Double getBuilderArea() {
+		return builderArea;
+	}
+
+	public void setBuilderArea(Double builderArea) {
+		this.builderArea = builderArea;
+	}
+}

+ 101 - 0
src/main/java/com/hb/proj/model/WorkloadPO.java

@@ -0,0 +1,101 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+/**
+ * 用于持久化
+ * @author hb
+ *
+ */
+public class WorkloadPO {
+
+	private String recordId;  
+
+	private Date rptMonth;
+	
+	private Integer wellCount;
+	
+	private String rptOrg;
+	
+	private Double industryValue;
+	
+	private Double addedValue;
+	
+	private Double builderArea;
+	
+	private String modifier;
+	
+	private Date modifyTime;
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	public Integer getWellCount() {
+		return wellCount;
+	}
+
+	public void setWellCount(Integer wellCount) {
+		this.wellCount = wellCount;
+	}
+
+	public String getRptOrg() {
+		return rptOrg;
+	}
+
+	public void setRptOrg(String rptOrg) {
+		this.rptOrg = rptOrg;
+	}
+
+	public Double getIndustryValue() {
+		return industryValue;
+	}
+
+	public void setIndustryValue(Double industryValue) {
+		this.industryValue = industryValue;
+	}
+
+	public Double getAddedValue() {
+		return addedValue;
+	}
+
+	public void setAddedValue(Double addedValue) {
+		this.addedValue = addedValue;
+	}
+
+	public Double getBuilderArea() {
+		return builderArea;
+	}
+
+	public void setBuilderArea(Double builderArea) {
+		this.builderArea = builderArea;
+	}
+
+	public String getModifier() {
+		return modifier;
+	}
+
+	public void setModifier(String modifier) {
+		this.modifier = modifier;
+	}
+
+	public Date getModifyTime() {
+		return modifyTime;
+	}
+
+	public void setModifyTime(Date modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+}

+ 198 - 0
src/main/java/com/hb/proj/model/Wpg.java

@@ -0,0 +1,198 @@
+package com.hb.proj.model;
+
+import java.util.Date;
+
+public class Wpg {
+	
+	private String recordId;  //t_wpg_account表主键
+
+	private Date rptMonth;
+	
+	private String orgId;
+	
+	private String orgName;
+	
+	private Double waterCount;
+	
+	private Double waterCost;
+	
+	private Double powerCount;
+	
+	private Double powerCost;
+	
+	private Double ngasCount;
+	
+	private Double ngasCost;
+	
+	private Double lgasCount;
+	
+	private Double lgasCost;
+	
+	private Double waterCountQuota;
+	
+	private Double powerCountQuota;
+	
+	private Double ngasCountQuota;
+	
+	private Double lgasCountQuota;
+	
+	private Double powerCoal;
+	
+	private Double ngasCoal;
+	
+	private Double lgasCoal;
+
+	public Date getRptMonth() {
+		return rptMonth;
+	}
+
+	public void setRptMonth(Date rptMonth) {
+		this.rptMonth = rptMonth;
+	}
+
+	public String getOrgId() {
+		return orgId;
+	}
+
+	public void setOrgId(String orgId) {
+		this.orgId = orgId;
+	}
+
+	public String getOrgName() {
+		return orgName;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+
+	public Double getWaterCount() {
+		return waterCount;
+	}
+
+	public void setWaterCount(Double waterCount) {
+		this.waterCount = waterCount;
+	}
+
+	public Double getWaterCost() {
+		return waterCost;
+	}
+
+	public void setWaterCost(Double waterCost) {
+		this.waterCost = waterCost;
+	}
+
+	public Double getPowerCount() {
+		return powerCount;
+	}
+
+	public void setPowerCount(Double powerCount) {
+		this.powerCount = powerCount;
+	}
+
+	public Double getPowerCost() {
+		return powerCost;
+	}
+
+	public void setPowerCost(Double powerCost) {
+		this.powerCost = powerCost;
+	}
+
+	public Double getNgasCount() {
+		return ngasCount;
+	}
+
+	public void setNgasCount(Double ngasCount) {
+		this.ngasCount = ngasCount;
+	}
+
+	public Double getNgasCost() {
+		return ngasCost;
+	}
+
+	public void setNgasCost(Double ngasCost) {
+		this.ngasCost = ngasCost;
+	}
+
+	public Double getLgasCount() {
+		return lgasCount;
+	}
+
+	public void setLgasCount(Double lgasCount) {
+		this.lgasCount = lgasCount;
+	}
+
+	public Double getLgasCost() {
+		return lgasCost;
+	}
+
+	public void setLgasCost(Double lgasCost) {
+		this.lgasCost = lgasCost;
+	}
+
+	public Double getWaterCountQuota() {
+		return waterCountQuota;
+	}
+
+	public void setWaterCountQuota(Double waterCountQuota) {
+		this.waterCountQuota = waterCountQuota;
+	}
+
+	public Double getPowerCountQuota() {
+		return powerCountQuota;
+	}
+
+	public void setPowerCountQuota(Double powerCountQuota) {
+		this.powerCountQuota = powerCountQuota;
+	}
+
+	public Double getNgasCountQuota() {
+		return ngasCountQuota;
+	}
+
+	public void setNgasCountQuota(Double ngasCountQuota) {
+		this.ngasCountQuota = ngasCountQuota;
+	}
+
+	public Double getLgasCountQuota() {
+		return lgasCountQuota;
+	}
+
+	public void setLgasCountQuota(Double lgasCountQuota) {
+		this.lgasCountQuota = lgasCountQuota;
+	}
+
+	public Double getPowerCoal() {
+		return powerCoal;
+	}
+
+	public void setPowerCoal(Double powerCoal) {
+		this.powerCoal = powerCoal;
+	}
+
+	public Double getNgasCoal() {
+		return ngasCoal;
+	}
+
+	public void setNgasCoal(Double ngasCoal) {
+		this.ngasCoal = ngasCoal;
+	}
+
+	public Double getLgasCoal() {
+		return lgasCoal;
+	}
+
+	public void setLgasCoal(Double lgasCoal) {
+		this.lgasCoal = lgasCoal;
+	}
+
+	public String getRecordId() {
+		return recordId;
+	}
+
+	public void setRecordId(String recordId) {
+		this.recordId = recordId;
+	}
+	
+	
+}

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