harry il y a 4 ans
commit
93691c1bf4
88 fichiers modifiés avec 9764 ajouts et 0 suppressions
  1. 157 0
      database/pom.xml
  2. 15 0
      database/src/main/java/com/qr/database/DatabaseApplication.java
  3. 20 0
      database/src/main/java/com/qr/database/DatabaseServletInitializer.java
  4. 93 0
      database/src/main/java/com/qr/database/common/BaseController.java
  5. 85 0
      database/src/main/java/com/qr/database/common/Jwt.java
  6. 39 0
      database/src/main/java/com/qr/database/common/RedisType.java
  7. 124 0
      database/src/main/java/com/qr/database/common/RedisUtil.java
  8. 56 0
      database/src/main/java/com/qr/database/common/TokenState.java
  9. 48 0
      database/src/main/java/com/qr/database/common/TokenType.java
  10. 79 0
      database/src/main/java/com/qr/database/config/FreemarkerConfig.java
  11. 19 0
      database/src/main/java/com/qr/database/config/GlobalConstant.java
  12. 119 0
      database/src/main/java/com/qr/database/config/MybatisPlusConfig.java
  13. 38 0
      database/src/main/java/com/qr/database/config/WebMvcConfig.java
  14. 122 0
      database/src/main/java/com/qr/database/config/aop/LoginInterceptor.java
  15. 210 0
      database/src/main/java/com/qr/database/config/properties/DruidProperties.java
  16. 88 0
      database/src/main/java/com/qr/database/config/properties/GlobalProperties.java
  17. 22 0
      database/src/main/java/com/qr/database/controller/IndexController.java
  18. 521 0
      database/src/main/java/com/qr/database/controller/ProductController.java
  19. 419 0
      database/src/main/java/com/qr/database/controller/ShenqianController.java
  20. 180 0
      database/src/main/java/com/qr/database/controller/StandardController.java
  21. 60 0
      database/src/main/java/com/qr/database/controller/WebController.java
  22. 42 0
      database/src/main/java/com/qr/database/controller/common/FileController.java
  23. 21 0
      database/src/main/java/com/qr/database/dao/FlowMapper.java
  24. 16 0
      database/src/main/java/com/qr/database/dao/FlowNodeMapper.java
  25. 16 0
      database/src/main/java/com/qr/database/dao/NodeUserMapper.java
  26. 30 0
      database/src/main/java/com/qr/database/dao/ProductMapper.java
  27. 20 0
      database/src/main/java/com/qr/database/dao/ShenqianLogMapper.java
  28. 27 0
      database/src/main/java/com/qr/database/dao/ShenqianMapper.java
  29. 26 0
      database/src/main/java/com/qr/database/dao/StandardMapper.java
  30. 16 0
      database/src/main/java/com/qr/database/dao/UnitMapper.java
  31. 36 0
      database/src/main/java/com/qr/database/dao/mapping/FlowMapper.xml
  32. 22 0
      database/src/main/java/com/qr/database/dao/mapping/FlowNodeMapper.xml
  33. 23 0
      database/src/main/java/com/qr/database/dao/mapping/NodeUserMapper.xml
  34. 113 0
      database/src/main/java/com/qr/database/dao/mapping/ProductMapper.xml
  35. 35 0
      database/src/main/java/com/qr/database/dao/mapping/ShenqianLogMapper.xml
  36. 111 0
      database/src/main/java/com/qr/database/dao/mapping/ShenqianMapper.xml
  37. 111 0
      database/src/main/java/com/qr/database/dao/mapping/StandardMapper.xml
  38. 21 0
      database/src/main/java/com/qr/database/dao/mapping/UnitMapper.xml
  39. 204 0
      database/src/main/java/com/qr/database/model/Flow.java
  40. 148 0
      database/src/main/java/com/qr/database/model/FlowNode.java
  41. 162 0
      database/src/main/java/com/qr/database/model/NodeUser.java
  42. 702 0
      database/src/main/java/com/qr/database/model/Product.java
  43. 24 0
      database/src/main/java/com/qr/database/model/ProductDel.java
  44. 290 0
      database/src/main/java/com/qr/database/model/ProductExport.java
  45. 358 0
      database/src/main/java/com/qr/database/model/Shenqian.java
  46. 185 0
      database/src/main/java/com/qr/database/model/ShenqianLog.java
  47. 365 0
      database/src/main/java/com/qr/database/model/Standard.java
  48. 131 0
      database/src/main/java/com/qr/database/model/Unit.java
  49. 16 0
      database/src/main/java/com/qr/database/service/IFlowNodeService.java
  50. 23 0
      database/src/main/java/com/qr/database/service/IFlowService.java
  51. 16 0
      database/src/main/java/com/qr/database/service/INodeUserService.java
  52. 37 0
      database/src/main/java/com/qr/database/service/IProductService.java
  53. 19 0
      database/src/main/java/com/qr/database/service/IShenqianLogService.java
  54. 34 0
      database/src/main/java/com/qr/database/service/IShenqianService.java
  55. 27 0
      database/src/main/java/com/qr/database/service/IStandardService.java
  56. 20 0
      database/src/main/java/com/qr/database/service/IUnitService.java
  57. 20 0
      database/src/main/java/com/qr/database/service/impl/FlowNodeServiceImpl.java
  58. 65 0
      database/src/main/java/com/qr/database/service/impl/FlowServiceImpl.java
  59. 20 0
      database/src/main/java/com/qr/database/service/impl/NodeUserServiceImpl.java
  60. 179 0
      database/src/main/java/com/qr/database/service/impl/ProductServiceImpl.java
  61. 26 0
      database/src/main/java/com/qr/database/service/impl/ShenqianLogServiceImpl.java
  62. 203 0
      database/src/main/java/com/qr/database/service/impl/ShenqianServiceImpl.java
  63. 57 0
      database/src/main/java/com/qr/database/service/impl/StandardServiceImpl.java
  64. 34 0
      database/src/main/java/com/qr/database/service/impl/UnitServiceImpl.java
  65. 61 0
      database/src/main/java/com/qr/database/tips/ReturnResult.java
  66. 37 0
      database/src/main/java/com/qr/database/tips/factory/AppPageFactory.java
  67. 78 0
      database/src/main/java/com/qr/database/utils/BeanUtils.java
  68. 31 0
      database/src/main/java/com/qr/database/utils/CommonUtil.java
  69. 520 0
      database/src/main/java/com/qr/database/utils/DateUtil.java
  70. 55 0
      database/src/main/java/com/qr/database/utils/DocUtils.java
  71. 51 0
      database/src/main/java/com/qr/database/utils/DocumentUtil.java
  72. 43 0
      database/src/main/java/com/qr/database/utils/ExcelUtil.java
  73. 122 0
      database/src/main/java/com/qr/database/utils/ExportExcelUtil.java
  74. 105 0
      database/src/main/java/com/qr/database/utils/FileUtil.java
  75. 195 0
      database/src/main/java/com/qr/database/utils/HttpKit.java
  76. 90 0
      database/src/main/java/com/qr/database/utils/PdfUtils.java
  77. 242 0
      database/src/main/java/com/qr/database/utils/PreviewUtil.java
  78. 32 0
      database/src/main/java/com/qr/database/utils/RedisUtils.java
  79. 256 0
      database/src/main/java/com/qr/database/utils/ShenQianPreviewUtil.java
  80. 46 0
      database/src/main/java/com/qr/database/utils/SpringContextHolder.java
  81. 114 0
      database/src/main/java/com/qr/database/utils/WafKit.java
  82. 149 0
      database/src/main/java/com/qr/database/utils/WafRequestWrapper.java
  83. 160 0
      database/src/main/java/com/qr/database/utils/ZipUtil.java
  84. 411 0
      database/src/main/java/com/qr/database/utils/qr/ImgQrTool.java
  85. 62 0
      database/src/main/java/com/qr/database/utils/qr/MatrixToImageConfig.java
  86. 122 0
      database/src/main/java/com/qr/database/utils/qr/MatrixToImageWriter.java
  87. 170 0
      database/src/main/java/com/qr/database/utils/qr/QrImage.java
  88. 47 0
      database/src/main/resources/application.properties

+ 157 - 0
database/pom.xml

@@ -0,0 +1,157 @@
+<?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>
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.1.6.RELEASE</version>
+		<relativePath/>
+	</parent>
+	<groupId>com.qr</groupId>
+	<artifactId>database</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>database</name>
+	<packaging>war</packaging>
+	<description>Demo project for Spring Boot</description>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-freemarker</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.pdfbox</groupId>
+			<artifactId>pdfbox</artifactId>
+			<version>2.0.15</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.pdfbox</groupId>
+			<artifactId>pdfbox-tools</artifactId>
+			<version>2.0.15</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>3.6</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.zxing</groupId>
+			<artifactId>core</artifactId>
+			<version>3.2.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.zxing</groupId>
+			<artifactId>javase</artifactId>
+			<version>3.2.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+			<version>1.2.44</version>
+		</dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.1.6</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-redis</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.mybatis.spring.boot</groupId>
+			<artifactId>mybatis-spring-boot-starter</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.baomidou</groupId>
+			<artifactId>mybatis-plus-boot-starter</artifactId>
+			<version>3.1.2</version>
+		</dependency>
+		<dependency>
+			<groupId>com.oracle</groupId>
+			<artifactId>ojdbc14</artifactId>
+			<version>10.2.0.4.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>cn.afterturn</groupId>
+			<artifactId>easypoi-spring-boot-starter</artifactId>
+			<version>4.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-beanutils</groupId>
+			<artifactId>commons-beanutils</artifactId>
+			<version>1.9.3</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-websocket</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt -->
+		<dependency>
+			<groupId>com.nimbusds</groupId>
+			<artifactId>nimbus-jose-jwt</artifactId>
+			<version>6.5.1</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.aspose.words</groupId>
+			<artifactId>aspose-words-jdk16</artifactId>
+			<version>16.8.0.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/lib/aspose-words-16.8.0-jdk16.jar</systemPath>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<skip>true</skip>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+			</resource>
+			<resource>
+				<directory>src/main/java</directory>
+				<includes>
+					<include>**/*.xml</include>
+				</includes>
+			</resource>
+		</resources>
+	</build>
+
+</project>

+ 15 - 0
database/src/main/java/com/qr/database/DatabaseApplication.java

@@ -0,0 +1,15 @@
+package com.qr.database;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+public class DatabaseApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(DatabaseApplication.class, args);
+	}
+
+}

+ 20 - 0
database/src/main/java/com/qr/database/DatabaseServletInitializer.java

@@ -0,0 +1,20 @@
+package com.qr.database;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+
+/**
+ * Daigou Agent Web程序启动类
+ *
+ * @author fengshuonan
+ * @date 2017年9月29日09:00:42
+ */
+public class DatabaseServletInitializer extends SpringBootServletInitializer {
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+        return builder.sources(DatabaseApplication.class);
+    }
+
+}

+ 93 - 0
database/src/main/java/com/qr/database/common/BaseController.java

@@ -0,0 +1,93 @@
+package com.qr.database.common;
+
+import net.minidev.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+//@Controller
+public class BaseController {
+
+    @Autowired
+    public RedisUtil redisUtil;
+
+    public Long loginUserId;//登录用户id
+
+    public Long companyId;//登录用户所属企业id
+
+    public Short roleId;//用户角色id
+
+    /**
+     * 校验用户是否登录
+     *
+     * @return 是否登录
+     */
+    public boolean checkLogin(HttpServletRequest request) {
+        String authorization = "";
+        Cookie[] cookies = request.getCookies();
+        if (cookies != null) {
+            for (Cookie cookie : cookies) {
+                if (cookie.getName().equals("token")) {
+                    authorization = cookie.getValue();
+                }
+            }
+        }
+        if (authorization == null || "".equals(authorization)) {
+            return false;
+        }
+        Map<String, Object> payload = Jwt.validToken(authorization);
+        String state = (String) payload.get("state");
+        if (TokenState.VALID.getState().equals(state)) {
+            JSONObject data = (JSONObject) payload.get("data");
+            Number type = data.getAsNumber("type");
+            String userId = data.getAsString("uid");
+            String cid = data.getAsString("cid");
+            String rid = data.getAsString("rid");
+            String chk = data.getAsString("chk");//单点登录验证标识
+            if (type == null || chk == null || "".equals(chk)) {
+                return false;
+            }
+            Integer tokenType = type.intValue();
+            if (!tokenType.equals(TokenType.WEB.value())) {
+                return false;
+            }
+            String key = RedisType.TOKEN.value() + userId + tokenType;
+            String refreshKey = RedisType.TOKEN_REFRESH.value() + userId + tokenType;
+            //检查是否过期及单点登录
+            if (!redisUtil.exists(key) || !chk.equals(redisUtil.get(key))) {
+                return false;
+            } else {
+                loginUserId = Long.parseLong(userId);
+                companyId = Long.parseLong(cid);
+                roleId = Short.parseShort(rid);
+                //refresh标识失效但token还未失效时自动延长有效时间
+                if (redisUtil.get(refreshKey) == null) {
+                    redisUtil.set(key, chk, 60L * 60 * 2);//时间和登录时一致
+                    redisUtil.set(refreshKey, "", (60L * 60 * 2 - 60L * 30));
+                }
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 检验用户是否拥有权限
+     *
+     * @param functionId 功能id
+     *                   1:二维码数据库  2:数据评价系统  3:电子签章系统  4:EWIS系统
+     * @return 是否有该功能的权限
+     */
+    public boolean checkFunction(Integer functionId) {
+        Map<Integer, Object> functions = (Map<Integer, Object>) redisUtil.get(RedisType.FUNCTION.value() + loginUserId);
+        if (functions != null && functions.containsKey(functionId.toString())) {
+            return true;
+        }
+        return false;
+    }
+
+}

+ 85 - 0
database/src/main/java/com/qr/database/common/Jwt.java

@@ -0,0 +1,85 @@
+package com.qr.database.common;
+
+import com.nimbusds.jose.*;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.MACVerifier;
+import net.minidev.json.JSONObject;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JWT工具类
+ */
+public class Jwt {
+
+    /**
+     * 密钥
+     */
+    private static final byte[] SECRET = "Finm_Thngf@r0gGuoFengTang_20190612u".getBytes();
+
+    /**
+     * 初始化head部分的数据为
+     * {
+     * "alg":"HS256",
+     * "type":"JWT"
+     * }
+     */
+    private static final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT, null, null, null, null, null, null, null, null, null, null, null);
+
+    /**
+     * 生成token,该方法只在用户登录成功后调用
+     *
+     * @param payload Map集合,可以存储用户id,token生成时间,token过期时间等自定义字段
+     * @return token字符串, 若失败则返回null
+     */
+    public static String createToken(Map<String, Object> payload) throws Exception {
+        String tokenString = null;
+        // 创建一个 JWS object
+        JWSObject jwsObject = new JWSObject(header, new Payload(new JSONObject(payload)));
+        // 将jwsObject 进行HMAC签名
+        jwsObject.sign(new MACSigner(SECRET));
+        tokenString = jwsObject.serialize();
+        return tokenString;
+    }
+
+    /**
+     * 校验token是否合法,返回Map集合,集合中主要包含    state状态码   data鉴权成功后从token中提取的数据
+     * 该方法在过滤器中调用,每次请求API时都校验
+     */
+    public static Map<String, Object> validToken(String token) {
+        Map<String, Object> resultMap = new HashMap<>();
+        try {
+            JWSObject jwsObject = JWSObject.parse(token);
+            Payload payload = jwsObject.getPayload();
+            JWSVerifier verifier = new MACVerifier(SECRET);
+
+            if (jwsObject.verify(verifier)) {
+                JSONObject jsonOBj = payload.toJSONObject();
+                // token校验成功(此时没有校验是否过期)
+                resultMap.put("state", TokenState.VALID.toString());
+                // 若payload包含ext字段,则校验是否过期
+                if (jsonOBj.containsKey("ext")) {
+                    long extTime = Long.valueOf(jsonOBj.get("ext").toString());
+                    long curTime = new Date().getTime();
+                    // 过期了
+                    if (curTime > extTime) {
+                        resultMap.clear();
+                        resultMap.put("state", TokenState.EXPIRED.toString());
+                    }
+                }
+                resultMap.put("data", jsonOBj);
+            } else {
+                // 校验失败
+                resultMap.put("state", TokenState.INVALID.toString());
+            }
+        } catch (Exception e) {
+            // token格式不合法导致的异常
+            resultMap.clear();
+            resultMap.put("state", TokenState.INVALID.toString());
+        }
+        return resultMap;
+    }
+
+}

+ 39 - 0
database/src/main/java/com/qr/database/common/RedisType.java

@@ -0,0 +1,39 @@
+package com.qr.database.common;
+
+/**
+ * redis前缀类型
+ *
+ * @author GuoFeng Tang
+ * @version V1.0
+ */
+public enum RedisType {
+
+    TOKEN("t"),
+    TOKEN_REFRESH("tr"),
+    FUNCTION("fn");
+
+    private String type;
+
+    RedisType(String type) {
+        this.type = type;
+    }
+
+    public String value() {
+        return this.type;
+    }
+
+    public static String getType(String name) {
+        for (RedisType item : RedisType.values()) {
+            if (item.name().equals(name)) {
+                return item.type;
+            }
+        }
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+
+}

+ 124 - 0
database/src/main/java/com/qr/database/common/RedisUtil.java

@@ -0,0 +1,124 @@
+package com.qr.database.common;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <p> redis cache 工具类</p>
+ */
+@Component
+public class RedisUtil {
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 批量删除对应的value
+     *
+     * @param keys
+     */
+    public void remove(final String... keys) {
+        for (String key : keys) {
+            remove(key);
+        }
+    }
+
+    /**
+     * 批量删除key
+     *
+     * @param pattern
+     */
+    public void removePattern(final String pattern) {
+        Set<String> keys = redisTemplate.keys(pattern);
+        if (keys.size() > 0)
+            redisTemplate.delete(keys);
+    }
+
+    /**
+     * 删除对应的value
+     *
+     * @param key
+     */
+    public void remove(final String key) {
+        if (exists(key)) {
+            redisTemplate.delete(key);
+        }
+    }
+
+    /**
+     * 判断缓存中是否有对应的value
+     *
+     * @param key
+     * @return
+     */
+    public boolean exists(final String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    /**
+     * 读取缓存
+     *
+     * @param key
+     * @return
+     */
+    public Object get(final String key) {
+        Object result = null;
+        ValueOperations<String, Object> operations = redisTemplate
+                .opsForValue();
+        result = operations.get(key);
+        return result;
+    }
+
+    /**
+     * 写入缓存
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean set(final String key, Object value) {
+        boolean result = false;
+        try {
+            ValueOperations<String, Object> operations = redisTemplate
+                    .opsForValue();
+            operations.set(key, value);
+            result = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * 写入缓存
+     *
+     * @param key
+     * @param value
+     * @param expireTime 过期时间,单位:秒
+     * @return
+     */
+    public boolean set(final String key, Object value, Long expireTime) {
+        boolean result = false;
+        try {
+            ValueOperations<String, Object> operations = redisTemplate
+                    .opsForValue();
+            operations.set(key, value);
+            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
+            result = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+
+
+}

+ 56 - 0
database/src/main/java/com/qr/database/common/TokenState.java

@@ -0,0 +1,56 @@
+package com.qr.database.common;
+
+/**
+ * 枚举,定义token的三种状态
+ */
+public enum TokenState {
+    /**
+     * 过期
+     */
+    EXPIRED("EXPIRED"),
+    /**
+     * 无效(token不合法)
+     */
+    INVALID("INVALID"),
+    /**
+     * 有效的
+     */
+    VALID("VALID");
+
+    private String state;
+
+    private TokenState(String state) {
+        this.state = state;
+    }
+
+    /**
+     * 根据状态字符串获取token状态枚举对象
+     *
+     * @param tokenState
+     * @return
+     */
+    public static TokenState getTokenState(String tokenState) {
+        TokenState[] states = TokenState.values();
+        TokenState ts = null;
+        for (TokenState state : states) {
+            if (state.toString().equals(tokenState)) {
+                ts = state;
+                break;
+            }
+        }
+        return ts;
+    }
+
+    public String toString() {
+        return this.state;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+}

+ 48 - 0
database/src/main/java/com/qr/database/common/TokenType.java

@@ -0,0 +1,48 @@
+package com.qr.database.common;
+
+/**
+ * token类型
+ *
+ * @author GuoFeng Tang
+ */
+public enum TokenType {
+
+    WEB(1, "WEB前台"),
+    ADMIN(2, "后台管理");
+
+    private Integer type;
+    private String info;
+
+    TokenType(Integer type, String info) {
+        this.type = type;
+        this.info = info;
+    }
+
+    public Integer value() {
+        return this.type;
+    }
+
+    public static Integer getType(String name) {
+        for (TokenType item : TokenType.values()) {
+            if (item.name().equals(name)) {
+                return item.type;
+            }
+        }
+        return null;
+    }
+
+    public static String getInfo(String name) {
+        for (TokenType item : TokenType.values()) {
+            if (item.name().equals(name)) {
+                return item.info;
+            }
+        }
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+
+}

+ 79 - 0
database/src/main/java/com/qr/database/config/FreemarkerConfig.java

@@ -0,0 +1,79 @@
+package com.qr.database.config;
+
+import freemarker.template.Configuration;
+import freemarker.template.TemplateException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.freemarker.FreeMarkerProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
+
+import java.io.IOException;
+import java.util.*;
+
+@Component
+public class FreemarkerConfig {
+
+    private static Logger log = LoggerFactory.getLogger(FreemarkerConfig.class);
+    @Autowired
+    private FreeMarkerProperties properties;
+
+    @Bean
+    public FreeMarkerConfigurer freeMarkerConfigurer(@Value("${auto_import}") String autoImport, @Value("${auto_include}") String autoInclude) throws Exception {
+        FreeMarkerConfigurer config = new FreeMarkerConfigurer();
+        writerProperties(config);
+        Configuration configuration = null;
+        try {
+            configuration = config.createConfiguration();
+        } catch (IOException e) {
+            throw new RuntimeException("freemarker配置bean,IO异常",e);
+        } catch (TemplateException e) {
+            throw new RuntimeException("freemarker配置bean异常",e);
+        }
+        setAutoImport(autoImport,configuration);
+        setAutoInclude(autoInclude,configuration);
+        config.setConfiguration(configuration);
+        return config;
+    }
+
+    private void writerProperties(FreeMarkerConfigurer config) {
+        config.setTemplateLoaderPaths(this.properties.getTemplateLoaderPath());
+        config.setPreferFileSystemAccess(this.properties.isPreferFileSystemAccess());
+        config.setDefaultEncoding(this.properties.getCharsetName());
+        Properties settings = new Properties();
+        settings.putAll(this.properties.getSettings());
+        config.setFreemarkerSettings(settings);
+    }
+
+    private void setAutoImport(String autoImport,Configuration configuration) throws Exception {
+        if("_".equals(autoImport.trim())) {
+            return;
+        }
+        String[] imports = autoImport.split(";");
+        Map<String,String> importMap = new HashMap<String,String>(imports.length);
+        for (String s : imports) {
+            String[] keyValue = s.split("as");
+            if (keyValue.length != 2) {
+                log.error("freemarker配置auto_import格式不正确 ");
+                throw new RuntimeException("freemarker配置auto_import格式不正确");
+            }
+            importMap.put(keyValue[1].trim(),keyValue[0].trim());
+        }
+        configuration.setAutoImports(importMap);
+    }
+
+    private void setAutoInclude(final String autoInclude,Configuration configuration) {
+        if ("_".equals(autoInclude.trim())) {
+            return;
+        }
+        String[] includes = autoInclude.split(";");
+        for (String s : includes) {
+            System.out.println(s);
+        }
+        List list = new ArrayList<String>(Arrays.asList(includes));
+        configuration.setAutoIncludes(list);
+    }
+}

+ 19 - 0
database/src/main/java/com/qr/database/config/GlobalConstant.java

@@ -0,0 +1,19 @@
+package com.qr.database.config;
+
+public class GlobalConstant {
+    
+    public static String OK_NEWS = "ok_news";
+    public static String FALL_NEWS = "fall_news";
+    public static String RS = String.valueOf((char)30);
+    public static String GS = String.valueOf((char)29);
+    public static String EOT = String.valueOf((char)4);
+    public static String UNIT_FLAG = "[A-Za-z]+";
+    public static String SURVEY_REPORT_REGEX= "^BJ\\d{2}-H\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String OUTGOING_REPORT_REGEX= "^BJ\\d{2}-[A-GI-Z]\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String THIRDPARTY_SIZE_REPORT_REGEX= "^BJ\\d{2}-CC\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String THIRDPARTY_PER_REPORT_REGEX= "^BJ\\d{2}-FY\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String INTO_SIZE_REPORT_REGEX= "^BJ\\d{2}-RE\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String INTO_PER_REPORT_REGEX= "^BJ\\d{2}-RC\\d{5}-[A-Za-z]+\\d{4}-\\d+$";
+    public static String CERTIFICATION= "^HGZ-[A-Za-z]+\\d{4}-\\d+-\\d+$";
+    public static String PREVIEW_FINISH= "PREVIEW_FINISH";
+}

+ 119 - 0
database/src/main/java/com/qr/database/config/MybatisPlusConfig.java

@@ -0,0 +1,119 @@
+package com.qr.database.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.qr.database.config.properties.DruidProperties;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Mybatis配置
+ *
+ * @author ntelligent
+ */
+@Configuration
+@MapperScan(basePackages = {"com.qr.database.dao"})
+public class MybatisPlusConfig {
+
+    @Autowired
+    private DruidProperties druidProperties;
+
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
+
+    @Bean
+    public OracleKeyGenerator oracleKeyGenerator(){
+        return new OracleKeyGenerator();
+    }
+
+//    @Bean
+//    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
+//    {
+//        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
+//        ObjectMapper om = new ObjectMapper();
+//        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+//        jackson2JsonRedisSerializer.setObjectMapper(om);
+//        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
+//        template.setConnectionFactory(redisConnectionFactory);
+//        template.setKeySerializer(jackson2JsonRedisSerializer);
+//        template.setValueSerializer(jackson2JsonRedisSerializer);
+//        template.setHashKeySerializer(jackson2JsonRedisSerializer);
+//        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+//        template.afterPropertiesSet();
+//        return template;
+//    }
+
+    /**
+     * redisTemplate
+     */
+    @Bean
+    @ConditionalOnMissingBean(name = "redisTemplate")
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(factory);
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        ObjectMapper om = new ObjectMapper();
+        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+        jackson2JsonRedisSerializer.setObjectMapper(om);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        // key采用String的序列化方式
+        template.setKeySerializer(stringRedisSerializer);
+        // hash的key也采用String的序列化方式
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value序列化方式采用jackson
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        // hash的value序列化方式采用jackson
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        template.afterPropertiesSet();
+        return template;
+    }
+
+    @Bean
+    public DruidDataSource dataSourceGuns() {
+        DruidDataSource dataSource = new DruidDataSource();
+        druidProperties.config(dataSource);
+        return dataSource;
+    }
+
+//    @Bean
+//    public Connector connector() {
+//        Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
+//        connector.setScheme("http");
+//        connector.setPort(9132);
+//        connector.setSecure(false);
+//        connector.setRedirectPort(9032);
+//        return connector;
+//    }
+//
+//    @Bean
+//    public EmbeddedServletContainerFactory servletContainer() {
+//        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
+//            @Override
+//            protected void postProcessContext(Context context) {
+//                SecurityConstraint constraint = new SecurityConstraint();
+//                constraint.setUserConstraint("CONFIDENTIAL");
+//                SecurityCollection collection = new SecurityCollection();
+//                collection.addPattern("/*");
+//                constraint.addCollection(collection);
+//                context.addConstraint(constraint);
+//            }
+//        };
+//        tomcat.addAdditionalTomcatConnectors(connector());
+//        return tomcat;
+//    }
+}

+ 38 - 0
database/src/main/java/com/qr/database/config/WebMvcConfig.java

@@ -0,0 +1,38 @@
+package com.qr.database.config;
+
+import com.qr.database.config.aop.LoginInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class WebMvcConfig extends WebMvcConfigurerAdapter {
+
+    @Autowired
+    private LoginInterceptor loginInterceptor;
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
+    }
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+//        registry.addMapping("/qr/**").allowedOrigins("*").allowedHeaders("Origin, Content-Type, Accept, Authorization");
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+//        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
+        registry.addInterceptor(loginInterceptor).addPathPatterns("/qr/**");
+//        registry.addInterceptor(permissionInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login/**");
+    }
+
+//    @Bean
+//    public ServerEndpointExporter serverEndpointExporter() {
+//        return new ServerEndpointExporter();
+//    }
+}

+ 122 - 0
database/src/main/java/com/qr/database/config/aop/LoginInterceptor.java

@@ -0,0 +1,122 @@
+package com.qr.database.config.aop;
+
+import com.qr.database.common.*;
+import net.minidev.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+@Component
+public class LoginInterceptor extends HandlerInterceptorAdapter {
+
+    private Logger log = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    public RedisUtil redisUtil;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
+                             Object arg2) throws Exception {
+        request.setAttribute("attrUserId","4");
+        request.setAttribute("attrCompanyId","1");
+        request.setAttribute("attrRoleId","1");
+        return true;
+//        request.setAttribute("attrUserId","2");
+//        request.setAttribute("attrCompanyId","1");
+//        request.setAttribute("attrRoleId","1");
+
+//        boolean b = checkLogin(request);
+//        if (b) {
+//            boolean b1 = checkFunction(1, request.getAttribute("attrUserId"));
+//            if (!b1) {
+//                request.setAttribute("isAudit", 2);
+//                request.getRequestDispatcher("/").forward(request,response);
+//            }
+//            return b1;
+//        }
+//        request.setAttribute("isAudit", 1);
+//        request.getRequestDispatcher("/").forward(request,response);
+//        return false;
+    }
+
+    /**
+     * 校验用户是否登录
+     *
+     * @return 是否登录
+     */
+    public boolean checkLogin(HttpServletRequest request) {
+        String authorization = "";
+        Cookie[] cookies = request.getCookies();
+        if (cookies != null) {
+            for (Cookie cookie : cookies) {
+                if (cookie.getName().equals("token")) {
+                    authorization = cookie.getValue();
+                }
+            }
+        }
+        if (authorization == null || "".equals(authorization)) {
+            return false;
+        }
+        Map<String, Object> payload = Jwt.validToken(authorization);
+        String state = (String) payload.get("state");
+        if (TokenState.VALID.getState().equals(state)) {
+            JSONObject data = (JSONObject) payload.get("data");
+            Number type = data.getAsNumber("type");
+            String userId = data.getAsString("uid");
+            String cid = data.getAsString("cid");
+            String rid = data.getAsString("rid");
+            String chk = data.getAsString("chk");//单点登录验证标识
+            if (type == null || chk == null || "".equals(chk)) {
+                return false;
+            }
+            Integer tokenType = type.intValue();
+            if (!tokenType.equals(TokenType.WEB.value())) {
+                return false;
+            }
+            String key = RedisType.TOKEN.value() + userId + tokenType;
+            String refreshKey = RedisType.TOKEN_REFRESH.value() + userId + tokenType;
+            //检查是否过期及单点登录
+            if (!redisUtil.exists(key) || !chk.equals(redisUtil.get(key))) {
+                return false;
+            } else {
+                request.setAttribute("attrUserId",Long.parseLong(userId));
+                request.setAttribute("attrCompanyId",Long.parseLong(cid));
+                request.setAttribute("attrRoleId",Short.parseShort(rid));
+//                loginUserId = Long.parseLong(userId);
+//                companyId = Long.parseLong(cid);
+//                roleId = Short.parseShort(rid);
+                //refresh标识失效但token还未失效时自动延长有效时间
+                if (redisUtil.get(refreshKey) == null) {
+                    redisUtil.set(key, chk, 60L * 60 * 2);//时间和登录时一致
+                    redisUtil.set(refreshKey, "", (60L * 60 * 2 - 60L * 30));
+                }
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 检验用户是否拥有权限
+     *
+     * @param functionId 功能id
+     *                   1:二维码数据库  2:数据评价系统  3:电子签章系统  4:EWIS系统
+     * @return 是否有该功能的权限
+     */
+    public boolean checkFunction(Integer functionId, Object loginUserId) {
+        Map<Integer, Object> functions = (Map<Integer, Object>) redisUtil.get(RedisType.FUNCTION.value() + loginUserId);
+        if (functions != null && functions.containsKey(functionId.toString())) {
+            return true;
+        }
+        return false;
+    }
+
+}

+ 210 - 0
database/src/main/java/com/qr/database/config/properties/DruidProperties.java

@@ -0,0 +1,210 @@
+package com.qr.database.config.properties;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.sql.SQLException;
+
+@Component
+@ConfigurationProperties(prefix = "spring.datasource")
+public class DruidProperties {
+
+    private String url = "";
+
+    private String username = "root";
+
+    private String password = "root";
+
+    private String driverClassName = "com.mysql.jdbc.Driver";
+
+    private Integer initialSize = 10;
+
+    private Integer minIdle = 5;
+
+    private Integer maxActive = 100;
+
+    private Integer maxWait = 60000;
+
+    private Integer timeBetweenEvictionpadsMillis = 60000;
+
+    private Integer minEvictableIdleTimeMillis = 300000;
+
+    private String validationQuery = "SELECT 'x' FROM DUAL";
+
+    private Boolean testWhileIdle = true;
+
+    private Boolean testOnBorrow = false;
+
+    private Boolean testOnReturn = false;
+
+    private Boolean poolPreparedStatements = true;
+
+    private Integer maxPoolPreparedStatementPerConnectionSize = 20;
+
+    private String filters = "stat";
+
+    public void config(DruidDataSource dataSource) {
+        dataSource.setUrl(url);
+        dataSource.setUsername(username);
+        dataSource.setPassword(password);
+        dataSource.setDriverClassName(driverClassName);
+        dataSource.setInitialSize(initialSize);
+        dataSource.setMinIdle(minIdle);
+        dataSource.setMaxActive(maxActive);
+        dataSource.setMaxWait(maxWait);
+
+        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionpadsMillis);
+
+        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        dataSource.setValidationQuery(validationQuery);
+        dataSource.setTestWhileIdle(testWhileIdle);
+        dataSource.setTestOnBorrow(testOnBorrow);
+        dataSource.setTestOnReturn(testOnReturn);
+
+        dataSource.setPoolPreparedStatements(poolPreparedStatements);
+        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+
+        try {
+            dataSource.setFilters(filters);
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getDriverClassName() {
+        return driverClassName;
+    }
+
+    public void setDriverClassName(String driverClassName) {
+        this.driverClassName = driverClassName;
+    }
+
+    public Integer getInitialSize() {
+        return initialSize;
+    }
+
+    public void setInitialSize(Integer initialSize) {
+        this.initialSize = initialSize;
+    }
+
+    public Integer getMinIdle() {
+        return minIdle;
+    }
+
+    public void setMinIdle(Integer minIdle) {
+        this.minIdle = minIdle;
+    }
+
+    public Integer getMaxActive() {
+        return maxActive;
+    }
+
+    public void setMaxActive(Integer maxActive) {
+        this.maxActive = maxActive;
+    }
+
+    public Integer getMaxWait() {
+        return maxWait;
+    }
+
+    public void setMaxWait(Integer maxWait) {
+        this.maxWait = maxWait;
+    }
+
+    public Integer getTimeBetweenEvictionpadsMillis() {
+        return timeBetweenEvictionpadsMillis;
+    }
+
+    public void setTimeBetweenEvictionpadsMillis(Integer timeBetweenEvictionpadsMillis) {
+        this.timeBetweenEvictionpadsMillis = timeBetweenEvictionpadsMillis;
+    }
+
+    public Integer getMinEvictableIdleTimeMillis() {
+        return minEvictableIdleTimeMillis;
+    }
+
+    public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+    }
+
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+
+    public void setValidationQuery(String validationQuery) {
+        this.validationQuery = validationQuery;
+    }
+
+    public Boolean getTestWhileIdle() {
+        return testWhileIdle;
+    }
+
+    public void setTestWhileIdle(Boolean testWhileIdle) {
+        this.testWhileIdle = testWhileIdle;
+    }
+
+    public Boolean getTestOnBorrow() {
+        return testOnBorrow;
+    }
+
+    public void setTestOnBorrow(Boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+    }
+
+    public Boolean getTestOnReturn() {
+        return testOnReturn;
+    }
+
+    public void setTestOnReturn(Boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+    }
+
+    public Boolean getPoolPreparedStatements() {
+        return poolPreparedStatements;
+    }
+
+    public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
+        this.poolPreparedStatements = poolPreparedStatements;
+    }
+
+    public Integer getMaxPoolPreparedStatementPerConnectionSize() {
+        return maxPoolPreparedStatementPerConnectionSize;
+    }
+
+    public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
+        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
+    }
+
+    public String getFilters() {
+        return filters;
+    }
+
+    public void setFilters(String filters) {
+        this.filters = filters;
+    }
+}

+ 88 - 0
database/src/main/java/com/qr/database/config/properties/GlobalProperties.java

@@ -0,0 +1,88 @@
+package com.qr.database.config.properties;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+
+@Component
+@ConfigurationProperties(prefix = GlobalProperties.PREFIX)
+public class GlobalProperties {
+
+    public static final String PREFIX = "qr";
+
+    private Boolean kaptchaOpen = false;
+
+    private Boolean swaggerOpen = false;
+
+    private static String fileUploadPath;
+
+    private static Boolean haveCreatePath = false;
+
+    private Boolean springSessionOpen = false;
+
+    private Integer sessionInvalidateTime = 30 * 60;
+
+    private Integer sessionValidationInterval = 15 * 60;
+
+    public static String getFileUploadPath() {
+        if (StringUtils.isBlank(fileUploadPath)) {
+            return System.getProperty("java.io.tmpdir");
+        } else {
+            if (!fileUploadPath.endsWith(File.separator)) {
+                fileUploadPath = fileUploadPath + File.separator;
+            }
+            if (!haveCreatePath) {
+                File file = new File(fileUploadPath);
+                file.mkdirs();
+                haveCreatePath = true;
+            }
+            return fileUploadPath;
+        }
+    }
+
+    public void setFileUploadPath(String fileUploadPath) {
+        this.fileUploadPath = fileUploadPath;
+    }
+
+    public Boolean getKaptchaOpen() {
+        return kaptchaOpen;
+    }
+
+    public void setKaptchaOpen(Boolean kaptchaOpen) {
+        this.kaptchaOpen = kaptchaOpen;
+    }
+
+    public Boolean getSwaggerOpen() {
+        return swaggerOpen;
+    }
+
+    public void setSwaggerOpen(Boolean swaggerOpen) {
+        this.swaggerOpen = swaggerOpen;
+    }
+
+    public Boolean getSpringSessionOpen() {
+        return springSessionOpen;
+    }
+
+    public void setSpringSessionOpen(Boolean springSessionOpen) {
+        this.springSessionOpen = springSessionOpen;
+    }
+
+    public Integer getSessionInvalidateTime() {
+        return sessionInvalidateTime;
+    }
+
+    public void setSessionInvalidateTime(Integer sessionInvalidateTime) {
+        this.sessionInvalidateTime = sessionInvalidateTime;
+    }
+
+    public Integer getSessionValidationInterval() {
+        return sessionValidationInterval;
+    }
+
+    public void setSessionValidationInterval(Integer sessionValidationInterval) {
+        this.sessionValidationInterval = sessionValidationInterval;
+    }
+}

+ 22 - 0
database/src/main/java/com/qr/database/controller/IndexController.java

@@ -0,0 +1,22 @@
+package com.qr.database.controller;
+
+import com.qr.database.service.IStandardService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+public class IndexController {
+
+    @Autowired
+    IStandardService standardService;
+
+    @RequestMapping("/")
+    public ModelAndView index(ModelAndView modelAndView) {
+        modelAndView.setViewName("validateErr");
+        return modelAndView;
+    }
+
+}

+ 521 - 0
database/src/main/java/com/qr/database/controller/ProductController.java

@@ -0,0 +1,521 @@
+package com.qr.database.controller;
+
+import cn.afterturn.easypoi.entity.ImageEntity;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.google.common.collect.Lists;
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.model.Product;
+import com.qr.database.model.ProductDel;
+import com.qr.database.model.ProductExport;
+import com.qr.database.service.IFlowService;
+import com.qr.database.service.IProductService;
+import com.qr.database.service.IUnitService;
+import com.qr.database.tips.ReturnResult;
+import com.qr.database.utils.*;
+import com.qr.database.utils.qr.ImgQrTool;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotNull;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+@Controller
+@RequestMapping("/qr/product")
+public class ProductController {
+
+    private static Logger log = LoggerFactory.getLogger(ProductController.class);
+
+    @Autowired
+    private IProductService productService;
+    @Autowired
+    private IUnitService unitService;
+    @Autowired
+    private IFlowService flowService;
+    @Autowired
+    private ExportExcelUtil exportExcelUtil;
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @RequestMapping("/imports")
+    @ResponseBody
+    public ReturnResult imports(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, @RequestAttribute("attrCompanyId") Long companyId) throws Exception {
+        List<Product> imports = ExcelUtil.imports(picture.getInputStream(), Product.class);
+        Iterator<Product> iterator = imports.iterator();
+        Date date = new Date();
+        int ok = 0;
+        int fall = 0;
+        LinkedList<Product> standards = new LinkedList<>();
+        LinkedList<Long> okList = new LinkedList<>();
+        String uuid = CommonUtil.getUUID();
+        HashMap<String, Object> stringIntegerHashMap = new HashMap<>();
+        Map<String, String> list = unitService.flagAndUnitCode();
+        while (iterator.hasNext()) {
+            Product next = iterator.next();
+            next.setStatus(1);
+            next.setCreateTime(date);
+            next.setCompanyId(companyId);
+            boolean add = productService.add(next, list);
+            if (add) {
+                ok++;
+                okList.add(next.getId());
+            } else {
+                fall++;
+                standards.add(next);
+            }
+        }
+        if (ok >= 1) {
+            redisTemplate.opsForValue().set(GlobalConstant.OK_NEWS + uuid, okList, 8, TimeUnit.HOURS);
+        }
+        if (fall >= 1) {
+            redisTemplate.opsForValue().set(GlobalConstant.FALL_NEWS + uuid, standards, 8, TimeUnit.HOURS);
+        }
+        stringIntegerHashMap.put("ok", ok);
+        stringIntegerHashMap.put("fall", fall);
+        stringIntegerHashMap.put("id", uuid);
+        stringIntegerHashMap.put("flag", "product");
+        return ReturnResult.success(stringIntegerHashMap);
+    }
+
+    @RequestMapping(value = "/fall/{id}")
+    public String export(@PathVariable("id") String id, ModelMap modelMap) {
+        Object o = redisTemplate.opsForValue().get(GlobalConstant.FALL_NEWS + id);
+        LinkedList<Product> list = null;
+        if (o != null) {
+            list = (LinkedList) o;
+        } else {
+            list = new LinkedList<>();
+        }
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        stringObjectHashMap.put("maplist", list);
+        return exportExcelUtil.export(modelMap, "product.xlsx", "产品导入出错数据", stringObjectHashMap);
+    }
+
+    @RequestMapping(value = "/ok/{id}")
+    public void export(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
+        Object o = redisTemplate.opsForValue().get(GlobalConstant.OK_NEWS + id);
+        List<Map<String, Object>> parms = new LinkedList<Map<String, Object>>();
+        if (o != null) {
+            List<Map<String, Object>> id1 = productService.listMaps(new QueryWrapper<Product>().select("BATCH_NO \"batchNo\"", "QR_DATA \"qrData\"").in("ID", (LinkedList) o));
+            for (Map<String, Object> map : id1) {
+                HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+                stringObjectHashMap.put("fileName", map.get("batchNo") + ".png");
+                stringObjectHashMap.put("data", ImgQrTool.Base64ToImage(String.valueOf(map.get("qrData"))));
+                parms.add(stringObjectHashMap);
+            }
+        }
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String("产品二维码.zip".getBytes(), "iso-8859-1"));
+        ZipUtil.batchDataToZIP(parms, response.getOutputStream());
+    }
+
+    @RequestMapping("/deli")
+    public ModelAndView deli(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, ModelAndView modelAndView) throws Exception {
+        List<ProductDel> imports = ExcelUtil.imports(picture.getInputStream(), ProductDel.class);
+        Iterator<ProductDel> iterator = imports.iterator();
+        while (iterator.hasNext()) {
+            ProductDel next = iterator.next();
+            if (StringUtils.isBlank(next.getBatchNo())) {
+                iterator.remove();
+                continue;
+            }
+        }
+        modelAndView.setViewName("productImportDel");
+        modelAndView.addObject("param", imports);
+        return modelAndView;
+    }
+
+    @RequestMapping("/exporti")
+    public ModelAndView exporti(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, ModelAndView modelAndView) throws Exception {
+        List<ProductDel> imports = ExcelUtil.imports(picture.getInputStream(), ProductDel.class);
+        Iterator<ProductDel> iterator = imports.iterator();
+        while (iterator.hasNext()) {
+            ProductDel next = iterator.next();
+            if (StringUtils.isBlank(next.getBatchNo())) {
+                iterator.remove();
+                continue;
+            }
+        }
+        modelAndView.setViewName("productImportExport");
+        modelAndView.addObject("param", imports);
+        return modelAndView;
+    }
+
+    @RequestMapping("/del")
+    @ResponseBody
+    public ReturnResult del(@RequestParam("pDel") List<String> pDel, @RequestParam("delDoc") List<Integer> delDoc, @RequestParam("delType") Integer delType) {
+        List<Product> batch_no = productService.list(new QueryWrapper<Product>().in("BATCH_NO", pDel));
+        for (Product product : batch_no) {
+            productService.del(product, delDoc, delType);
+        }
+        return ReturnResult.success();
+    }
+
+    @RequestMapping("/exportAll")
+    public void exportAll(@RequestParam("batchNo") List<String> batchNo, @RequestParam("docType") List<Integer> docType, HttpServletResponse response) throws IOException {
+        List<ProductExport> list = productService.selectListByBatchNo(batchNo);
+        List<Map<String, Object>> parms = new LinkedList<>();
+        for (Integer d : docType) {
+            if (d == 1) {
+                HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+                stringObjectHashMap.put("maplist", list);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ExportExcelUtil.export(stringObjectHashMap, "product.xlsx", baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品表格.xlsx");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            } else if (d == 2) {
+                List<Map<String, Object>> parms1 = new LinkedList<>();
+                for (ProductExport product : list) {
+                    String surveyReport = product.getSurveyReport();
+                    if (StringUtils.isNotBlank(surveyReport)) {
+                        parms1.add(ZipUtil.getZipMap(surveyReport));
+                    }
+                    String outgoingReport = product.getOutgoingReport();
+                    if (StringUtils.isNotBlank(outgoingReport)) {
+                        parms1.add(ZipUtil.getZipMap(outgoingReport));
+                    }
+                    String intoPerReport = product.getIntoPerReport();
+                    if (StringUtils.isNotBlank(intoPerReport)) {
+                        parms1.add(ZipUtil.getZipMap(intoPerReport));
+                    }
+                    String intoSizeReport = product.getIntoSizeReport();
+                    if (StringUtils.isNotBlank(intoSizeReport)) {
+                        parms1.add(ZipUtil.getZipMap(intoSizeReport));
+                    }
+                    String thirdpartyPerReport = product.getThirdpartyPerReport();
+                    if (StringUtils.isNotBlank(thirdpartyPerReport)) {
+                        parms1.add(ZipUtil.getZipMap(thirdpartyPerReport));
+                    }
+                    String thirdpartySizeReport = product.getThirdpartySizeReport();
+                    if (StringUtils.isNotBlank(thirdpartySizeReport)) {
+                        parms1.add(ZipUtil.getZipMap(thirdpartySizeReport));
+                    }
+                    String certification = product.getCertification();
+                    if (StringUtils.isNotBlank(certification)) {
+                        parms1.add(ZipUtil.getZipMap(certification));
+                    }
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ZipUtil.batchFileToZIP(parms1, baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品文档.zip");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            } else if (d == 3) {
+                List<Map<String, Object>> parms1 = new LinkedList<>();
+                for (ProductExport product : list) {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    Map<String, Object> map = BeanUtils.convert2Map(product);
+                    ImageEntity image = new ImageEntity();
+                    image.setHeight(150);
+                    image.setWidth(120);
+                    image.setData(ImgQrTool.Base64ToImage(String.valueOf(map.get("qrData"))));
+                    image.setType(ImageEntity.Data);
+                    map.put("qrDataImg", image);
+                    String certification = product.getCertification();
+                    map.put("certificationName", certification == null ? " " : certification.substring(11));
+                    ExportExcelUtil.exportDocx(map, "sendVerification.docx", baos);
+                    HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                    stringObjectHashMap1.put("fileName", "送验单-" + product.getBatchMarking() + product.getBatchNo() + ".docx");
+                    stringObjectHashMap1.put("data", baos.toByteArray());
+                    baos.close();
+                    parms1.add(stringObjectHashMap1);
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ZipUtil.batchDataToZIP(parms1, baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品送验单.zip");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            } else if (d == 4) {
+                List<Map<String, Object>> parms1 = new LinkedList<>();
+                for (ProductExport product : list) {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    Map<String, Object> map = BeanUtils.convert2Map(product);
+                    ImageEntity image = new ImageEntity();
+                    image.setHeight(150);
+                    image.setWidth(120);
+                    image.setData(ImgQrTool.Base64ToImage(String.valueOf(map.get("qrData"))));
+                    image.setType(ImageEntity.Data);
+                    map.put("qrDataImg", image);
+                    String certification = product.getCertification();
+                    map.put("certificationName", certification == null ? " " : certification.substring(11));
+                    ExportExcelUtil.exportDocx(map, "stockOut.docx", baos);
+                    HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                    stringObjectHashMap1.put("fileName", "出库单-" + product.getBatchMarking() + product.getBatchNo() + ".docx");
+                    stringObjectHashMap1.put("data", baos.toByteArray());
+                    baos.close();
+                    parms1.add(stringObjectHashMap1);
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ZipUtil.batchDataToZIP(parms1, baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品出库单.zip");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            } else if (d == 5) {
+                List<Map<String, Object>> parms1 = new LinkedList<>();
+                for (ProductExport product : list) {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    Map<String, Object> map = BeanUtils.convert2Map(product);
+                    ImageEntity image = new ImageEntity();
+                    image.setHeight(150);
+                    image.setWidth(120);
+                    image.setData(ImgQrTool.Base64ToImage(String.valueOf(map.get("qrData"))));
+                    image.setType(ImageEntity.Data);
+                    map.put("qrDataImg", image);
+                    ExportExcelUtil.exportDocx(map, "godownEntry.docx", baos);
+                    HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                    stringObjectHashMap1.put("fileName", "入库单-" + product.getBatchMarking() + product.getBatchNo() + ".docx");
+                    stringObjectHashMap1.put("data", baos.toByteArray());
+                    baos.close();
+                    parms1.add(stringObjectHashMap1);
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ZipUtil.batchDataToZIP(parms1, baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品入库单.zip");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            } else if (d == 6) {
+                List<Map<String, Object>> parms1 = new LinkedList<Map<String, Object>>();
+                for (ProductExport product : list) {
+                    HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+                    stringObjectHashMap.put("fileName", product.getBatchNo() + ".png");
+                    stringObjectHashMap.put("data", ImgQrTool.Base64ToImage(String.valueOf(product.getQrData())));
+                    parms1.add(stringObjectHashMap);
+                }
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ZipUtil.batchDataToZIP(parms1, baos);
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                parms.add(stringObjectHashMap1);
+                stringObjectHashMap1.put("fileName", "产品二维码.zip");
+                stringObjectHashMap1.put("data", baos.toByteArray());
+                baos.close();
+            }
+        }
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String("产品数据.zip".getBytes(), "iso-8859-1"));
+        ZipUtil.batchDataToZIP(parms, response.getOutputStream());
+    }
+
+    @RequestMapping("/importDoc")
+    @ResponseBody
+    @Transactional
+    public ReturnResult importDoc(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, @RequestAttribute("attrUserId") Long userId) throws Exception {
+        String fileName = picture.getOriginalFilename().substring(0, picture.getOriginalFilename().lastIndexOf("."));
+        String originalFilename = picture.getOriginalFilename();
+        if (originalFilename.startsWith("HGZ")) {
+            originalFilename = originalFilename.substring(4, originalFilename.lastIndexOf("-"));
+        } else {
+            originalFilename = originalFilename.substring(originalFilename.indexOf("-", 5) + 1, originalFilename.lastIndexOf("."));
+        }
+        if (StringUtils.isNotBlank(originalFilename)) {
+            String fileSavePath = GlobalProperties.getFileUploadPath() + "productDoc" + File.separator;
+            String upload = FileUtil.upload(picture, fileSavePath, picture.getOriginalFilename());
+            if (upload == null) {
+                return ReturnResult.fail(480, "文件上传失败");
+            }
+            String filePathName = "productDoc" + File.separator + picture.getOriginalFilename();
+            Product product = new Product();
+            Product batch_no1 = productService.getOne(new QueryWrapper<Product>().eq("BATCH_NO", originalFilename).eq("STATUS", 1));
+            int docType = 0;
+            if (Pattern.matches(GlobalConstant.SURVEY_REPORT_REGEX, fileName)) {
+                product.setSurveyReport(filePathName);
+                product.setSurveyReportUserId(userId);
+                product.setSurveyReportTime(new Date());
+                docType = 1;
+            } else if (Pattern.matches(GlobalConstant.OUTGOING_REPORT_REGEX, fileName)) {
+                product.setOutgoingReport(filePathName);
+                product.setOutgoingReportUserId(userId);
+                product.setOutgoingReportTime(new Date());
+                docType = 2;
+            } else if (Pattern.matches(GlobalConstant.THIRDPARTY_SIZE_REPORT_REGEX, fileName)) {
+                product.setThirdpartySizeReport(filePathName);
+                product.setThirdpartySizeReportUserId(userId);
+                product.setThirdpartySizeReportTime(new Date());
+                docType = 3;
+            } else if (Pattern.matches(GlobalConstant.THIRDPARTY_PER_REPORT_REGEX, fileName)) {
+                product.setThirdpartyPerReport(filePathName);
+                product.setThirdpartyPerReportUserId(userId);
+                product.setThirdpartyPerReportTime(new Date());
+                docType = 4;
+            } else if (Pattern.matches(GlobalConstant.INTO_SIZE_REPORT_REGEX, fileName)) {
+                product.setIntoSizeReport(filePathName);
+                product.setIntoSizeReportUserId(userId);
+                product.setIntoSizeReportTime(new Date());
+                docType = 5;
+            } else if (Pattern.matches(GlobalConstant.INTO_PER_REPORT_REGEX, fileName)) {
+                product.setIntoPerReport(filePathName);
+                product.setIntoPerReportUserId(userId);
+                product.setIntoPerReportTime(new Date());
+                docType = 6;
+            } else if (Pattern.matches(GlobalConstant.CERTIFICATION, fileName)) {
+                product.setCertification(filePathName);
+                product.setCertificationUserId(userId);
+                product.setCertificationTime(new Date());
+                docType = 7;
+            } else {
+                FileUtil.deleteFile(filePathName);
+                return ReturnResult.fail("命名不正确");
+            }
+            boolean batch_no = product.update(new UpdateWrapper<Product>().eq("BATCH_NO", originalFilename).eq("STATUS", 1));
+            if (batch_no) {
+                productService.shenqianErrUpdate(originalFilename);
+                productService.delFile(batch_no1, Lists.newArrayList(docType));
+                return ReturnResult.success();
+            }
+            FileUtil.deleteFile(filePathName);
+        }
+        return ReturnResult.fail("批号不正确");
+    }
+
+    /**
+     * 子合格证上传
+     *
+     * @param picture
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping("/importSubCertification")
+    @ResponseBody
+    @Transactional
+    public ReturnResult importSubCertification(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, @RequestAttribute("attrUserId") Long userId) throws Exception {
+        String fileName = picture.getOriginalFilename().substring(0, picture.getOriginalFilename().lastIndexOf("."));
+        String originalFilename = picture.getOriginalFilename();
+        originalFilename = originalFilename.substring(4, originalFilename.lastIndexOf("-"));
+        Product product = new Product();
+        if (StringUtils.isNotBlank(originalFilename)) {
+            String fileSavePath = GlobalProperties.getFileUploadPath() + "productDoc" + File.separator + "sub" + File.separator;
+            String upload = FileUtil.upload(picture, fileSavePath, picture.getOriginalFilename());
+            if (upload == null) {
+                return ReturnResult.fail(480, "文件上传失败");
+            }
+            String filePathName = "productDoc" + File.separator + "sub" + File.separator + picture.getOriginalFilename();
+            if (Pattern.matches(GlobalConstant.CERTIFICATION, fileName)) {
+                product.setSubCertification(filePathName);
+                product.setSubCertificationUserId(userId);
+                product.setSubCertificationTime(new Date());
+            } else {
+                FileUtil.deleteFile(filePathName);
+                return ReturnResult.fail("命名不正确");
+            }
+            Product batch_no1 = productService.getOne(new QueryWrapper<Product>().eq("BATCH_NO", originalFilename).eq("STATUS", 1));
+            boolean batch_no = product.update(new UpdateWrapper<Product>().eq("BATCH_NO", originalFilename).eq("STATUS", 1));
+            if (batch_no) {
+                productService.shenqianErrUpdate(originalFilename);
+                productService.delFile(batch_no1, Lists.newArrayList(8));
+                return ReturnResult.success();
+            }
+            FileUtil.deleteFile(filePathName);
+        }
+        return ReturnResult.fail("批号不正确");
+    }
+
+    @RequestMapping("/detail/{id}")
+    public ModelAndView detail(@PathVariable("id") String id, ModelAndView modelAndView) {
+        Product detail = productService.detail(id);
+        modelAndView.addObject("product", detail);
+        modelAndView.setViewName("productDetail");
+        return modelAndView;
+    }
+
+    @RequestMapping("/saveData")
+    @ResponseBody
+    public ReturnResult saveData(Product detail) {
+        Long shipmentsAmount = detail.getShipmentsAmount();
+        if (shipmentsAmount != null) {
+            detail.setShipmentsAmount(detail.getProductionAmount() - shipmentsAmount);
+        }
+        detail.updateById();
+        return ReturnResult.success();
+    }
+
+    @RequestMapping("/preview/{id}/{docType}")
+    @ResponseBody
+    public ReturnResult preview(@PathVariable("id") String id, @PathVariable("docType") Integer docType) {
+        Product byId = productService.getById(id);
+        if (byId != null) {
+            String uuid = CommonUtil.getUUID();
+            ReturnResult returnResult = new ReturnResult(300, "1", uuid);
+            redisTemplate.opsForValue().set(uuid, returnResult, 10, TimeUnit.MINUTES);
+            PreviewUtil previewUtil = new PreviewUtil(uuid, byId, docType);
+            previewUtil.start();
+            return returnResult;
+        }
+        return ReturnResult.fail("数据不存在");
+    }
+
+    @RequestMapping("/previewGet/{id}")
+    @ResponseBody
+    public ReturnResult previewGet(@PathVariable("id") String id) {
+        try {
+            Object o = redisTemplate.opsForValue().get(id);
+            if (o != null) {
+                return (ReturnResult) o;
+            }
+            return new ReturnResult(303, "");
+        } catch (Exception e) {
+            log.warn(e.getMessage(), e);
+            return new ReturnResult(400, "连接失败,请稍后再试");
+        }
+    }
+
+    @RequestMapping("/previewDel/{id}")
+    @ResponseBody
+    public ReturnResult previewDel(@PathVariable("id") String id) {
+        redisTemplate.delete(id);
+        return ReturnResult.success();
+    }
+
+    /**
+     * 产品详情文件预览生成完成
+     *
+     * @param id
+     * @return
+     */
+    @RequestMapping("/previewFinish/{id}")
+    public ModelAndView previewFinish(@PathVariable("id") String id, ModelAndView modelAndView) {
+        modelAndView.addObject("param", redisTemplate.opsForValue().get(id));
+        modelAndView.setViewName("productDocPreview");
+        new Thread() {
+            @Override
+            public void run() {
+                redisTemplate.delete(id);
+            }
+        }.start();
+        return modelAndView;
+    }
+
+    @RequestMapping("/startShenQian")
+    public ModelAndView startShenQian(ModelAndView modelAndView, @RequestParam("batchNos") List<String> batchNos) {
+        modelAndView.setViewName("productStartShenQian");
+        Map<String, Object> flowSelect = flowService.getFlowSelect(null);
+        modelAndView.addObject("param", batchNos);
+        modelAndView.addObject("flowSelect", flowSelect);
+        return modelAndView;
+    }
+}

+ 419 - 0
database/src/main/java/com/qr/database/controller/ShenqianController.java

@@ -0,0 +1,419 @@
+package com.qr.database.controller;
+
+import cn.afterturn.easypoi.entity.ImageEntity;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.model.*;
+import com.qr.database.service.*;
+import com.qr.database.tips.ReturnResult;
+import com.qr.database.tips.factory.AppPageFactory;
+import com.qr.database.utils.*;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static oracle.net.aso.C01.o;
+
+@Controller
+@RequestMapping("/qr/shenqian")
+public class ShenqianController {
+
+    @Autowired
+    private IShenqianService shenqianService;
+    @Autowired
+    private IProductService productService;
+    @Autowired
+    private IFlowNodeService flowNodeService;
+    @Autowired
+    private IShenqianLogService shenqianLogService;
+    @Autowired
+    private IFlowService flowService;
+    @Autowired
+    private ExportExcelUtil exportExcelUtil;
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @RequestMapping("/start")
+    @ResponseBody
+    public ReturnResult start (@RequestParam("batchNos") List<String> batchNos, String note, String flowId,
+                               @RequestAttribute("attrUserId") Long userId,@RequestAttribute("attrCompanyId") Long companyId) {
+        String userName = shenqianService.getUserNameById(userId, null);
+        int ok = 0;
+        int fail = 0;
+        Iterator<String> iterator = batchNos.iterator();
+        while (iterator.hasNext()) {
+            String batchNo = iterator.next();
+            boolean start = shenqianService.start(batchNo, note, flowId, userId, companyId, userName);
+            if (start) {
+                ok ++;
+                iterator.remove();
+            } else {
+                fail ++;
+            }
+        }
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        stringObjectHashMap.put("ok", ok);
+        stringObjectHashMap.put("fall", fail);
+        stringObjectHashMap.put("batchNos", batchNos);
+        return ReturnResult.success(stringObjectHashMap);
+    }
+
+    @RequestMapping("/restart")
+    @ResponseBody
+    public ReturnResult restart(String note, String flowId, String id,
+                               @RequestAttribute("attrUserId") Long userId,@RequestAttribute("attrCompanyId") Long companyId) {
+        String userName = shenqianService.getUserNameById(userId, null);
+        return shenqianService.restart(id, flowId, note, userId, userName);
+    }
+
+    @RequestMapping("/restartPage")
+    public ModelAndView restartPage(String id,ModelAndView modelAndView,
+                                @RequestAttribute("attrUserId") Long userId,@RequestAttribute("attrCompanyId") Long companyId) {
+        List<ShenqianLog> list = shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).orderByAsc("ORDER_NUMBER"));
+        Map<String, Object> flowSelect = flowService.getFlowSelect(null);
+        Shenqian byId = shenqianService.getById(id);
+        Product byId1 = productService.getById(byId.getProductId());
+        modelAndView.addObject("shenqianLog", list);
+        modelAndView.addObject("param", byId1.getBatchNo());
+        modelAndView.addObject("id", id);
+        modelAndView.addObject("flowSelect", flowSelect);
+        modelAndView.setViewName("productReStartShenQian");
+        return modelAndView;
+    }
+
+    @RequestMapping("/list")
+    public ModelAndView list(ModelAndView modelAndView, BindingResult result, Shenqian shenqian, Integer all,
+                             @RequestAttribute("attrUserId") Long userId, @RequestAttribute("attrCompanyId") Long companyId, @RequestAttribute("attrRoleId") Long roleId) {
+        int count = shenqianService.count(new QueryWrapper<Shenqian>().eq("APPROVAL_USER_ID", userId).eq("FLAG", 1));
+        if (all== null || all==1) {
+            shenqian.setUserId(userId);
+            modelAndView.addObject("count", shenqianService.count(new QueryWrapper<Shenqian>().eq("USER_ID", userId).eq("FLAG", 1)));
+            modelAndView.addObject("waitCount", count);
+        } else if (all == 2) {
+            shenqian.setApprovalUserId(userId);
+            modelAndView.addObject("count", count);
+        } else {
+            modelAndView.addObject("count", shenqianService.count(new QueryWrapper<Shenqian>().eq("FLAG", 1)));
+            modelAndView.addObject("waitCount", count);
+        }
+        Page<Shenqian> page = new AppPageFactory<Shenqian>().defaultPage();
+        page.setRecords((List) shenqianService.listShenqian(page, shenqian));
+        modelAndView.addObject("page", page);
+        modelAndView.addObject("pages", page.getPages());
+        modelAndView.addObject("param", shenqian);
+        modelAndView.addObject("roleId", roleId);
+        List<String> node_name = (List)flowNodeService.listObjs(new QueryWrapper<FlowNode>().select("NODE_NAME"));
+        modelAndView.addObject("nodeNames", new HashSet<String>(node_name));
+        modelAndView.setViewName("shenqianList");
+        return modelAndView;
+    }
+
+    @RequestMapping("/awaitList")
+    public ModelAndView awaitList(ModelAndView modelAndView, BindingResult result, Shenqian shenqian,
+                             @RequestAttribute("attrUserId") Long userId, @RequestAttribute("attrCompanyId") Long companyId, @RequestAttribute("attrRoleId") Long roleId) {
+        int count = shenqianService.count(new QueryWrapper<Shenqian>().eq("APPROVAL_USER_ID", userId).eq("FLAG", 1));
+        shenqian.setApprovalUserId(userId);
+        modelAndView.addObject("count", count);
+
+        Page<Shenqian> page = new AppPageFactory<Shenqian>().defaultPage();
+        page.setRecords((List) shenqianService.listShenqian(page, shenqian));
+        modelAndView.addObject("page", page);
+        modelAndView.addObject("pages", page.getPages());
+        modelAndView.addObject("param", shenqian);
+        modelAndView.addObject("roleId", roleId);
+        List<String> node_name = (List)flowNodeService.listObjs(new QueryWrapper<FlowNode>().select("NODE_NAME"));
+        modelAndView.addObject("nodeNames", new HashSet<String>(node_name));
+        modelAndView.setViewName("shenqianAwaitList");
+        return modelAndView;
+    }
+
+    @RequestMapping("/allList")
+    public ModelAndView allList(ModelAndView modelAndView, BindingResult result, Shenqian shenqian,
+                                  @RequestAttribute("attrUserId") Long userId, @RequestAttribute("attrCompanyId") Long companyId) {
+        int count = shenqianService.count(new QueryWrapper<Shenqian>().eq("APPROVAL_USER_ID", userId).eq("FLAG", 1));
+        modelAndView.addObject("count", shenqianService.count(new QueryWrapper<Shenqian>().eq("FLAG", 1)));
+        modelAndView.addObject("waitCount", count);
+        shenqian.setCompanyId(companyId);
+        Page<Shenqian> page = new AppPageFactory<Shenqian>().defaultPage();
+        page.setRecords((List) shenqianService.listShenqian(page, shenqian));
+        modelAndView.addObject("page", page);
+        modelAndView.addObject("pages", page.getPages());
+        modelAndView.addObject("param", shenqian);
+        List<String> node_name = (List)flowNodeService.listObjs(new QueryWrapper<FlowNode>().select("NODE_NAME"));
+        modelAndView.addObject("nodeNames", new HashSet<String>(node_name));
+        modelAndView.setViewName("shenqianAllList");
+        return modelAndView;
+    }
+
+    @RequestMapping("/detail/{id}")
+    public ModelAndView detail(@PathVariable String id, ModelAndView modelAndView) {
+        Shenqian byId = shenqianService.getById(id);
+        if (byId != null) {
+            List<ShenqianLog> list = shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).orderByAsc("ORDER_NUMBER"));
+            byId.setShenqianLogList(list);
+            Product detail = productService.detail(String.valueOf(byId.getProductId()));
+            modelAndView.addObject("product", detail);
+        }
+        modelAndView.addObject("shenqian", byId);
+        modelAndView.setViewName("shenqianDetail");
+        return modelAndView;
+    }
+
+    @RequestMapping("/awaitDetail/{id}")
+    public ModelAndView awaitDetail(@PathVariable String id, @RequestAttribute("attrUserId") Long userId, @RequestAttribute("attrRoleId") Long roleId, ModelAndView modelAndView) {
+        Shenqian byId = shenqianService.getById(id);
+        if (byId != null) {
+            List<ShenqianLog> list = shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).orderByAsc("ORDER_NUMBER"));
+            byId.setShenqianLogList(list);
+            Product detail = productService.detail(String.valueOf(byId.getProductId()));
+            modelAndView.addObject("product", detail);
+        }
+        Shenqian last = shenqianService.last(id, null, userId);
+        Shenqian next = shenqianService.next(id, null, userId);
+
+        modelAndView.addObject("last", last);
+        modelAndView.addObject("next", next);
+        modelAndView.addObject("shenqian", byId);
+        modelAndView.addObject("userId", userId);
+        modelAndView.setViewName("shenqianAwaitDetail");
+        return modelAndView;
+    }
+
+    @RequestMapping("/audit")
+    @ResponseBody
+    public ReturnResult audit(String id, String note, boolean audit,@RequestAttribute("attrUserId") Long userId) {
+        Shenqian byId = shenqianService.getById(id);
+        if (byId != null) {
+            Date date = new Date();
+            Shenqian shenqian = new Shenqian();
+            ShenqianLog shenqianLog = new ShenqianLog();
+            shenqianLog.setNote(note);
+            shenqianLog.setCreateTime(date);
+            Long step = byId.getStep();
+            Map<String, Object> map = null;
+            if (audit) {
+                ShenqianLog one = shenqianLogService.getOne(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).eq("ORDER_NUMBER", step + 1));
+                if (one !=null) {
+                    shenqian.setStep(step+1);
+                    shenqian.setApprovalUserId(one.getApprovalUserId());
+                } else {
+                    shenqian.setStatus(4);
+                    shenqian.setDocPath("shenqianDoc"+File.separator+byId.getOrderId()+".docx");
+                    map = new HashMap<>();
+                    map.put("fileName", "shenqianDoc"+File.separator+byId.getOrderId()+".docx");
+                    Standard standard = productService.shenqianDoc(byId.getProductId());
+                    map.put("shipmentsAmount", standard.getShipmentsAmount());
+                    map.put("name", standard.getName());
+                    map.put("batchMarking", standard.getBatchMarking());
+                    map.put("unit", standard.getUnit());
+                    map.put("year", DateUtil.getYear(date));
+                    map.put("month", DateUtil.getMonth(date));
+                    map.put("day", DateUtil.getDay(date));
+                    List<String> strings = shenqianLogService.shenqianDocApprovalUser(byId.getId());
+                    int size = strings.size();
+                    for (int i=0; i<5;i++) {
+                        if (size>i) {
+                            ImageEntity image = new ImageEntity();
+                            image.setHeight(100);
+                            image.setWidth(100);
+                            image.setUrl(strings.get(i));
+                            image.setType(ImageEntity.URL);
+                            map.put("img"+i, image);
+                        } else {
+                            map.put("img"+i, " ");
+                        }
+                    }
+                }
+                boolean update = shenqian.update(new QueryWrapper<Shenqian>().eq("ID", id).eq("STATUS", 1).eq("APPROVAL_USER_ID", userId));
+                if (update) {
+                    shenqianLog.setStatus("通过");
+                    shenqianLog.update(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).eq("ORDER_NUMBER", step));
+                    if (map != null) {
+                        DocumentUtil.export(map, "shenqian.docx");
+                    }
+                    return ReturnResult.success();
+                }
+                return ReturnResult.fail("审签单状态不正确");
+            } else {
+                shenqian.setStatus(2);
+                boolean update = shenqian.update(new QueryWrapper<Shenqian>().eq("ID", id).eq("STATUS", 1).eq("APPROVAL_USER_ID", userId));
+                if (update) {
+                    shenqianLog.setStatus("驳回");
+                    shenqianLog.update(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).eq("ORDER_NUMBER", step));
+                    return ReturnResult.success();
+                }
+                return ReturnResult.fail("审签单状态不正确");
+            }
+        }
+        return ReturnResult.fail("审签单不存在");
+    }
+
+    @RequestMapping("/del")
+    @ResponseBody
+    public ReturnResult del(String id, @RequestAttribute("attrUserId") Long userId) {
+        Shenqian shenqian = new Shenqian();
+        shenqian.setFlag(2);
+        boolean update = shenqian.update(new UpdateWrapper<Shenqian>().eq("ID", id).eq("STATUS", 3));
+        if (update) {
+            return ReturnResult.success();
+        }
+        return ReturnResult.fail("审签单状态不正确");
+    }
+
+    @RequestMapping("/preview/{id}/{docType}")
+    @ResponseBody
+    public ReturnResult preview(@PathVariable("id") String id, @PathVariable("docType") Integer docType, @RequestAttribute("attrUserId") Long userId) {
+        Shenqian byId = shenqianService.getById(id);
+        if (byId !=null) {
+            String uuid = CommonUtil.getUUID();
+            ReturnResult returnResult = new ReturnResult(300, "1", uuid);
+            redisTemplate.opsForValue().set(uuid, returnResult, 10, TimeUnit.MINUTES);
+            Product byId1 = productService.getById(byId.getProductId());
+            Shenqian last = shenqianService.last(id, null, userId);
+            Shenqian next = shenqianService.next(id, null, userId);
+            HashMap<String, Object> stringLongHashMap = new HashMap<>();
+            stringLongHashMap.put("status", byId.getStatus());
+            stringLongHashMap.put("id", byId.getId());
+            stringLongHashMap.put("userId", userId);
+            stringLongHashMap.put("approvalUserId", byId.getApprovalUserId());
+            stringLongHashMap.put("last", last==null?null:last.getId());
+            stringLongHashMap.put("next", next==null?null:next.getId());
+            ShenQianPreviewUtil previewUtil = new ShenQianPreviewUtil(uuid, stringLongHashMap, byId1, docType);
+            previewUtil.start();
+            return returnResult;
+        }
+        return ReturnResult.fail("数据不存在");
+    }
+
+    @RequestMapping("/previewFinish/{id}")
+    public ModelAndView previewFinish(@PathVariable("id") String id, ModelAndView modelAndView) {
+        LinkedHashMap map = (LinkedHashMap)redisTemplate.opsForValue().get(id);
+        Object shenqian = map.remove("shenqian");
+        modelAndView.addObject("param", map);
+        modelAndView.addObject("shenqian", shenqian);
+        modelAndView.setViewName("shenqianDocPreview");
+        new Thread(){
+            @Override
+            public void run() {
+                redisTemplate.delete(id);
+            }
+        }.start();
+        return modelAndView;
+    }
+
+    @RequestMapping(value = "/exportLog/{id}")
+    public String export(ModelMap modelMap, @PathVariable String id) {
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        stringObjectHashMap.put("maplist", shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).orderByAsc("ORDER_NUMBER")));
+        return exportExcelUtil.export(modelMap,"shenqianLog.xlsx","审批记录"+ DateUtil.getAllTime(), stringObjectHashMap);
+    }
+
+    @RequestMapping(value = "/finishExport")
+    public void finishExport(@RequestParam("ids") List<String> ids, HttpServletResponse response) throws IOException {
+        Collection<Shenqian> shenqians = shenqianService.listByIds(ids);
+        List<Map<String, Object>> parms1 = new LinkedList<>();
+        for (Shenqian s:shenqians) {
+            String docPath = s.getDocPath();
+            if (StringUtils.isNotBlank(docPath)) {
+                parms1.add(ZipUtil.getZipMap(docPath));
+            }
+            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+            stringObjectHashMap.put("maplist", shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", s.getId()).orderByAsc("ORDER_NUMBER")));
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ExportExcelUtil.export(stringObjectHashMap, "shenqianLog.xlsx", baos);
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            parms1.add(stringObjectHashMap1);
+            stringObjectHashMap1.put("fileName", s.getOrderId()+".xlsx");
+            stringObjectHashMap1.put("data", baos.toByteArray());
+            baos.close();
+        }
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String("审签记录.zip".getBytes(), "iso-8859-1"));
+        ZipUtil.batchAllToZIP(parms1, response.getOutputStream());
+    }
+
+    @RequestMapping(value = "/allExport/{id}")
+    public void allExport(@PathVariable String id, HttpServletResponse response) throws IOException {
+        List<Map<String, Object>> parms1 = new LinkedList<>();
+        Shenqian byId = shenqianService.getById(id);
+        if (byId != null) {
+            String docPath = byId.getDocPath();
+            if (StringUtils.isNotBlank(docPath)) {
+                parms1.add(ZipUtil.getZipMap(docPath));
+            }
+            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+            stringObjectHashMap.put("maplist", shenqianLogService.list(new QueryWrapper<ShenqianLog>().eq("SHENQIAN_ID", byId.getId()).orderByAsc("ORDER_NUMBER")));
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ExportExcelUtil.export(stringObjectHashMap, "shenqianLog.xlsx", baos);
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            parms1.add(stringObjectHashMap1);
+            stringObjectHashMap1.put("fileName", byId.getOrderId()+".xlsx");
+            stringObjectHashMap1.put("data", baos.toByteArray());
+            baos.close();
+            Product product = productService.getById(byId.getProductId());
+            String surveyReport = product.getSurveyReport();
+            if (StringUtils.isNotBlank(surveyReport)) {
+                parms1.add(ZipUtil.getZipMap(surveyReport));
+            }
+            String outgoingReport = product.getOutgoingReport();
+            if (StringUtils.isNotBlank(outgoingReport)) {
+                parms1.add(ZipUtil.getZipMap(outgoingReport));
+            }
+            String intoPerReport = product.getIntoPerReport();
+            if (StringUtils.isNotBlank(intoPerReport)) {
+                parms1.add(ZipUtil.getZipMap(intoPerReport));
+            }
+            String intoSizeReport = product.getIntoSizeReport();
+            if (StringUtils.isNotBlank(intoSizeReport)) {
+                parms1.add(ZipUtil.getZipMap(intoSizeReport));
+            }
+            String thirdpartyPerReport = product.getThirdpartyPerReport();
+            if (StringUtils.isNotBlank(thirdpartyPerReport)) {
+                parms1.add(ZipUtil.getZipMap(thirdpartyPerReport));
+            }
+            String thirdpartySizeReport = product.getThirdpartySizeReport();
+            if (StringUtils.isNotBlank(thirdpartySizeReport)) {
+                parms1.add(ZipUtil.getZipMap(thirdpartySizeReport));
+            }
+            String certification = product.getCertification();
+            if (StringUtils.isNotBlank(certification)) {
+                parms1.add(ZipUtil.getZipMap(certification));
+            }
+            String subCertification = product.getSubCertification();
+            if (StringUtils.isNotBlank(subCertification)) {
+                HashMap<String, Object> subCertificationMap = new HashMap<>();
+                File file = new File(GlobalProperties.getFileUploadPath() + subCertification);
+                subCertificationMap.put("fileName", "子合格证-"+file.getName());
+                subCertificationMap.put("file", new FileInputStream(file));
+                parms1.add(subCertificationMap);
+            }
+        }
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String("审签单文档.zip".getBytes(), "iso-8859-1"));
+        ZipUtil.batchAllToZIP(parms1, response.getOutputStream());
+    }
+
+    @Scheduled(cron = "0 */5 * * * ?")
+    public void report() {
+        List<Shenqian> status = shenqianService.list(new QueryWrapper<Shenqian>().eq("STATUS", 1));
+        for (Shenqian s:status) {
+            String userName = shenqianService.getUserNameById(s.getApprovalUserId(), 0);
+            if (userName == null) {
+                shenqianService.errUpdate(s);
+            }
+        }
+    }
+}

+ 180 - 0
database/src/main/java/com/qr/database/controller/StandardController.java

@@ -0,0 +1,180 @@
+package com.qr.database.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.model.Product;
+import com.qr.database.model.Standard;
+import com.qr.database.service.IProductService;
+import com.qr.database.service.IStandardService;
+import com.qr.database.tips.ReturnResult;
+import com.qr.database.tips.factory.AppPageFactory;
+import com.qr.database.utils.*;
+import com.qr.database.utils.qr.ImgQrTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotNull;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@Controller
+@RequestMapping("/qr/standard")
+public class StandardController {
+
+    private static Logger log = LoggerFactory.getLogger(StandardController.class);
+    @Autowired
+    private IStandardService standardService;
+    @Autowired
+    private IProductService productService;
+    @Autowired
+    private ExportExcelUtil exportExcelUtil;
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @RequestMapping("/list")
+    public ModelAndView list(ModelAndView modelAndView, Standard standard, @RequestAttribute("attrCompanyId") Long companyId) {
+        Integer isStandard = standard.getIsStandard();
+        standard.setCompanyId(companyId);
+        if (isStandard == null || isStandard != 2) {
+            Page<Product> page = new AppPageFactory<Product>().defaultPage();
+            page.setRecords((List) standardService.listProduct(page, standard));
+            modelAndView.addObject("count", productService.count());
+            modelAndView.addObject("page", page);
+            modelAndView.addObject("pages", page.getPages());
+        } else {
+            Page<Standard> page = new AppPageFactory<Standard>().defaultPage();
+            page.setRecords((List) standardService.list(page, standard));
+            modelAndView.addObject("count", standardService.count());
+            modelAndView.addObject("page", page);
+            modelAndView.addObject("pages", page.getPages());
+        }
+        modelAndView.addObject("isStandard", standard.getIsStandard());
+        modelAndView.addObject("param", standard);
+        modelAndView.setViewName("standardList");
+        return modelAndView;
+    }
+
+    @RequestMapping("/imports")
+    @ResponseBody
+    public ReturnResult imports(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture, @RequestAttribute("attrCompanyId") Long companyId) throws Exception {
+        List<Standard> imports = ExcelUtil.imports(picture.getInputStream(), Standard.class);
+        Iterator<Standard> iterator = imports.iterator();
+        Date date = new Date();
+        int ok = 0;
+        int fall = 0;
+        LinkedList<Standard> standards = new LinkedList<>();
+        LinkedList<String> okList = new LinkedList<>();
+        String uuid = CommonUtil.getUUID();
+        HashMap<String, Object> stringIntegerHashMap = new HashMap<>();
+        while (iterator.hasNext()) {
+            Standard next = iterator.next();
+            next.setCreateTime(date);
+            next.setCompanyId(companyId);
+            boolean add = standardService.add(next);
+            if (add) {
+                ok++;
+                okList.add(next.getGroupItemCode());
+            } else {
+                fall++;
+                standards.add(next);
+            }
+        }
+        if (ok >= 1) {
+            redisTemplate.opsForValue().set(GlobalConstant.OK_NEWS + uuid, okList, 8, TimeUnit.HOURS);
+        }
+        if (fall >= 1) {
+            redisTemplate.opsForValue().set(GlobalConstant.FALL_NEWS + uuid, standards, 8, TimeUnit.HOURS);
+        }
+        stringIntegerHashMap.put("ok", ok);
+        stringIntegerHashMap.put("fall", fall);
+        stringIntegerHashMap.put("id", uuid);
+        stringIntegerHashMap.put("flag", "standard");
+        return ReturnResult.success(stringIntegerHashMap);
+    }
+
+    @RequestMapping(value = "/fall/{id}")
+    public String export(@PathVariable("id") String id, ModelMap modelMap) {
+        Object o = redisTemplate.opsForValue().get(GlobalConstant.FALL_NEWS + id);
+        LinkedList<Standard> list = null;
+        if (o != null) {
+            list = (LinkedList) o;
+        } else {
+            list = new LinkedList<>();
+        }
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        stringObjectHashMap.put("maplist", list);
+        return exportExcelUtil.export(modelMap, "standard.xlsx", "标准导入出错数据", stringObjectHashMap);
+    }
+
+    @RequestMapping(value = "/ok/{id}")
+    public void export(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
+        Object o = redisTemplate.opsForValue().get(GlobalConstant.OK_NEWS + id);
+        List<Map<String, Object>> parms = new LinkedList<Map<String, Object>>();
+        if (o != null) {
+            List<Map<String, Object>> id1 = standardService.listMaps(new QueryWrapper<Standard>().select("GROUP_ITEM_CODE \"groupItemCode\"", "QR_DATA as \"qrData\"").in("GROUP_ITEM_CODE", (LinkedList) o));
+            for (Map<String, Object> map : id1) {
+                HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+                stringObjectHashMap.put("fileName", map.get("groupItemCode") + ".png");
+                stringObjectHashMap.put("data", ImgQrTool.Base64ToImage(String.valueOf(map.get("qrData"))));
+                parms.add(stringObjectHashMap);
+            }
+        }
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String("标准二维码.zip".getBytes(), "iso-8859-1"));
+        ZipUtil.batchDataToZIP(parms, response.getOutputStream());
+    }
+
+    @RequestMapping("/importDoc")
+    @ResponseBody
+    public ReturnResult importDoc(@NotNull(message = "上传文件不能为空") @RequestPart(value = "file", required = false) MultipartFile picture) throws Exception {
+        String fileSavePath = GlobalProperties.getFileUploadPath() + "standardDoc" + File.separator;
+        String upload = FileUtil.upload(picture, fileSavePath, picture.getOriginalFilename());
+        if (upload == null) {
+            return ReturnResult.fail(480, "文件上传失败");
+        }
+        return ReturnResult.success();
+    }
+
+    @RequestMapping("/detail/{id}")
+    public ModelAndView detail(@PathVariable("id") String id, ModelAndView modelAndView) {
+        Standard byId = standardService.getById(id);
+        modelAndView.addObject("standard", byId==null?new Standard():byId);
+        modelAndView.setViewName("standardDetail");
+        return modelAndView;
+    }
+
+    @RequestMapping("/ewmDetail")
+    public ModelAndView ewmDetail(String qrId, ModelAndView modelAndView) {
+        String[] split = qrId.split(GlobalConstant.GS);
+        try {
+            if (split.length==4) {
+                Product product = productService.ewmDetail(split[1].substring(1), split[2].substring(1), split[3].substring(1, split[3].length() - 2));
+                modelAndView.addObject("product", product);
+                modelAndView.setViewName("productDetail");
+                return modelAndView;
+            } else if (split.length==2) {
+                Standard byId = standardService.getOne(new QueryWrapper<Standard>().eq("GROUP_ITEM_CODE", split[1].substring(1, split[1].length() - 2)));
+                modelAndView.addObject("standard", byId==null?new Standard():byId);
+                modelAndView.setViewName("standardDetail");
+                return modelAndView;
+            }
+        } catch (RuntimeException e) {
+            log.warn(qrId+"-"+e.getMessage());
+        }
+        modelAndView.addObject("standard", new Standard());
+        modelAndView.setViewName("standardDetail");
+        return modelAndView;
+    }
+}

+ 60 - 0
database/src/main/java/com/qr/database/controller/WebController.java

@@ -0,0 +1,60 @@
+package com.qr.database.controller;
+
+import com.qr.database.tips.ReturnResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.stereotype.Controller;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+//@DependsOn("springContextHolder")
+//@ServerEndpoint(value = "/qr/web/{token}")
+//@Controller
+public class WebController {
+
+    private static Logger log = LoggerFactory.getLogger(WebController.class);
+    private static CopyOnWriteArraySet<WebController> webSocketSet = new CopyOnWriteArraySet<WebController>();
+
+    private Session session;
+
+    @OnOpen
+    public void onOpen(Session session, @PathParam("token") String token) throws Exception {
+        this.session = session;
+        webSocketSet.add(this);
+        try {
+            sendMessage(ReturnResult.SUCCESS_MSG);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    @OnClose
+    public void onClose(Session session, @PathParam("token") String token) throws Exception {
+        webSocketSet.remove(this);
+    }
+
+    @OnMessage
+    public void onMessage(String message, Session session) throws IOException, EncodeException {
+//        session.getBasicRemote().sendObject(ReturnResult.success());
+//        log.warn(message);
+//        ConcurrentHashMap<String, Session> all = webService.all();
+//        for (Map.Entry<String, Session> map:all.entrySet()) {
+//            sendMessage(map.getValue(), ReturnResult.success(message));
+//        }
+    }
+
+    @OnError
+    public void onError(Session session, Throwable error) {
+        webSocketSet.remove(this);
+    }
+
+    private void sendMessage(String obj) throws IOException {
+        this.session.getBasicRemote().sendText(obj);
+    }
+
+}

+ 42 - 0
database/src/main/java/com/qr/database/controller/common/FileController.java

@@ -0,0 +1,42 @@
+package com.qr.database.controller.common;
+
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.tips.ReturnResult;
+import com.qr.database.utils.FileUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+
+@Controller
+@RequestMapping("/qr/file")
+public class FileController {
+
+    private static Logger log = LoggerFactory.getLogger(FileController.class);
+
+    @RequestMapping("/upload")
+    @ResponseBody
+    public ReturnResult upload(@RequestPart(value = "file", required = false) MultipartFile picture) {
+        System.out.println(1111);
+        return ReturnResult.success();
+    }
+
+    @RequestMapping({"/{pictureId:.+}", "/{dir}/{pictureId:.+}","/{dir}/{subdir}/{pictureId:.+}"})
+    public void renderPicture(@PathVariable("pictureId") String pictureId, @PathVariable(name="dir",required=false) String dir, @PathVariable(name="subdir",required=false) String subdir, HttpServletResponse response) {
+        String path = GlobalProperties.getFileUploadPath() + (dir==null?"":dir + File.separator) + (subdir == null?"":subdir+File.separator) + pictureId;
+        try {
+            byte[] bytes = FileUtil.toByteArray(path);
+            response.setHeader("Content-Disposition", "attachment;filename=" + new String(pictureId.getBytes(), "iso-8859-1"));
+            response.getOutputStream().write(bytes);
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+        }
+    }
+}

+ 21 - 0
database/src/main/java/com/qr/database/dao/FlowMapper.java

@@ -0,0 +1,21 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.Flow;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 二维码数据库审签流程表 Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface FlowMapper extends BaseMapper<Flow> {
+
+    List<Flow> getFlow(@Param("flowId") Long flowId);
+}

+ 16 - 0
database/src/main/java/com/qr/database/dao/FlowNodeMapper.java

@@ -0,0 +1,16 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.FlowNode;
+
+/**
+ * <p>
+ * 二维码数据库流程节点表 Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface FlowNodeMapper extends BaseMapper<FlowNode> {
+
+}

+ 16 - 0
database/src/main/java/com/qr/database/dao/NodeUserMapper.java

@@ -0,0 +1,16 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.NodeUser;
+
+/**
+ * <p>
+ * 节点审批人表 Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface NodeUserMapper extends BaseMapper<NodeUser> {
+
+}

+ 30 - 0
database/src/main/java/com/qr/database/dao/ProductMapper.java

@@ -0,0 +1,30 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.Product;
+import com.qr.database.model.ProductExport;
+import com.qr.database.model.Standard;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface ProductMapper extends BaseMapper<Product> {
+
+    List<ProductExport> selectListByBatchNo(@Param("batchNo") List<String> batchNo);
+
+    Product detail(@Param("id") String id);
+
+    Standard shenqianDoc(@Param("productId") Long productId);
+
+    int shenqianErrUpdate(@Param("batchNo") String batchNo);
+
+    Product ewmDetail(@Param("unitCode") String unitCode, @Param("groupItemCode") String groupItemCode, @Param("no") String no);
+}

+ 20 - 0
database/src/main/java/com/qr/database/dao/ShenqianLogMapper.java

@@ -0,0 +1,20 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.ShenqianLog;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface ShenqianLogMapper extends BaseMapper<ShenqianLog> {
+
+    List<String> shenqianDocApprovalUser(@Param("shenqianId") Long shenqianId);
+}

+ 27 - 0
database/src/main/java/com/qr/database/dao/ShenqianMapper.java

@@ -0,0 +1,27 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qr.database.model.Shenqian;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 审签 Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface ShenqianMapper extends BaseMapper<Shenqian> {
+
+    String getUserNameById(@Param("userId") Long userId, @Param("status") Integer status);
+
+    List<Shenqian> listShenqian(@Param("page") Page<Shenqian> page, @Param("a") Shenqian shenqian);
+
+    Shenqian last(@Param("id") String id, @Param("userId") Long userId, @Param("approvalUserId") Long approvalUserId);
+
+    Shenqian next(@Param("id") String id, @Param("userId") Long userId, @Param("approvalUserId") Long approvalUserId);
+}

+ 26 - 0
database/src/main/java/com/qr/database/dao/StandardMapper.java

@@ -0,0 +1,26 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qr.database.model.Product;
+import com.qr.database.model.Standard;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface StandardMapper extends BaseMapper<Standard> {
+
+    List<Standard> list(@Param("page") Page<Standard> page, @Param("a") Standard standard);
+
+    List<Standard> listProduct(@Param("page") Page<Product> page, @Param("a") Standard standard);
+}

+ 16 - 0
database/src/main/java/com/qr/database/dao/UnitMapper.java

@@ -0,0 +1,16 @@
+package com.qr.database.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qr.database.model.Unit;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface UnitMapper extends BaseMapper<Unit> {
+
+}

+ 36 - 0
database/src/main/java/com/qr/database/dao/mapping/FlowMapper.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.FlowMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.Flow">
+        <id column="FLOW_ID" property="flowId" />
+        <result column="FLOW_NAME" property="flowName" />
+        <result column="STATUS" property="status" />
+        <result column="CREATOR_ID" property="creatorId" />
+        <result column="COMPANY_ID" property="companyId" />
+        <result column="MODIFIER_ID" property="modifierId" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="UPDATE_TIME" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        FLOW_ID AS flowId, FLOW_NAME AS flowName, STATUS AS status, CREATOR_ID AS creatorId, COMPANY_ID AS companyId, MODIFIER_ID AS modifierId, CREATE_TIME AS createTime, UPDATE_TIME AS updateTime
+    </sql>
+
+    <select id="getFlow" resultType="com.qr.database.model.Flow">
+        select a.FLOW_ID AS flowId, a.FLOW_NAME AS flowName,b.NODE_NAME,c.APPROVAL_TYPE,c.USER_ID,d.NICKNAME from QR_FLOW a
+        left join QR_FLOW_NODE b on a.FLOW_ID=b.FLOW_ID
+        left join QR_NODE_USER c on b.NODE_ID=c.NODE_ID
+        left join T_USER d on c.USER_ID=d.USER_ID and d.STATUS=0
+        <where>
+            a.STATUS = 0
+            and b.NODE_NAME is not null
+            <if test="flowId !=null">
+                and a.FLOW_ID=#{flowId}
+            </if>
+        </where>
+        order by a.FLOW_ID desc,b.NODE_ORDER,c.USER_ORDER
+    </select>
+</mapper>

+ 22 - 0
database/src/main/java/com/qr/database/dao/mapping/FlowNodeMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.FlowNodeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.FlowNode">
+        <result column="NODE_ID" property="nodeId" />
+        <result column="FLOW_ID" property="flowId" />
+        <result column="NODE_NAME" property="nodeName" />
+        <result column="NODE_ORDER" property="nodeOrder" />
+        <result column="CREATOR_ID" property="creatorId" />
+        <result column="MODIFIER_ID" property="modifierId" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="UPDATE_TIME" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        NODE_ID AS nodeId, FLOW_ID AS flowId, NODE_NAME AS nodeName, NODE_ORDER AS nodeOrder, CREATOR_ID AS creatorId, MODIFIER_ID AS modifierId, CREATE_TIME AS createTime, UPDATE_TIME AS updateTime
+    </sql>
+
+</mapper>

+ 23 - 0
database/src/main/java/com/qr/database/dao/mapping/NodeUserMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.NodeUserMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.NodeUser">
+        <result column="ID" property="id" />
+        <result column="NODE_ID" property="nodeId" />
+        <result column="USER_ID" property="userId" />
+        <result column="APPROVAL_TYPE" property="approvalType" />
+        <result column="USER_ORDER" property="userOrder" />
+        <result column="CREATOR_ID" property="creatorId" />
+        <result column="MODIFIER_ID" property="modifierId" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="UPDATE_TIME" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID AS id, NODE_ID AS nodeId, USER_ID AS userId, APPROVAL_TYPE AS approvalType, USER_ORDER AS userOrder, CREATOR_ID AS creatorId, MODIFIER_ID AS modifierId, CREATE_TIME AS createTime, UPDATE_TIME AS updateTime
+    </sql>
+
+</mapper>

Fichier diff supprimé car celui-ci est trop grand
+ 113 - 0
database/src/main/java/com/qr/database/dao/mapping/ProductMapper.xml


+ 35 - 0
database/src/main/java/com/qr/database/dao/mapping/ShenqianLogMapper.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.ShenqianLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.ShenqianLog">
+        <id column="ID" property="id" />
+        <result column="SHENQIAN_ID" property="shenqianId" />
+        <result column="ORDER_NUMBER" property="orderNumber" />
+        <result column="FLOW_ID" property="flowId" />
+        <result column="NODE_NAME" property="nodeName" />
+        <result column="APPROVAL_TYPE" property="approvalType" />
+        <result column="APPROVAL_USER_ID" property="approvalUserId" />
+        <result column="STATUS" property="status" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="NOTE" property="note" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID AS id, SHENQIAN_ID AS shenqianId, ORDER_NUMBER AS orderNumber, FLOW_ID AS flowId, NODE_NAME AS nodeName, APPROVAL_TYPE AS approvalType, APPROVAL_USER_ID AS approvalUserId, STATUS AS status, CREATE_TIME AS createTime, NOTE AS note
+    </sql>
+
+    <select id="shenqianDocApprovalUser" resultType="string">
+        select DISTINCT aa.imgUrl from (
+        select NVL(b.img_url,c.img_url) imgUrl,a.ORDER_NUMBER from QR_SHENQIAN_LOG a
+        left join T_USER_SIGNATURE b on a.APPROVAL_USER_ID=b.user_id and a.APPROVAL_TYPE=2
+        left join T_USER_STAMPER c on a.APPROVAL_USER_ID=c.user_id and a.APPROVAL_TYPE=1
+        where a.SHENQIAN_ID=#{shenqianId}
+        and a.APPROVAL_TYPE in (1,2)
+        order by a.ORDER_NUMBER
+        ) aa
+        where aa.imgUrl is not null
+    </select>
+</mapper>

+ 111 - 0
database/src/main/java/com/qr/database/dao/mapping/ShenqianMapper.xml

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.ShenqianMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.Shenqian">
+        <id column="ID" property="id" />
+        <result column="PRODUCT_ID" property="productId" />
+        <result column="FLOW_ID" property="flowId" />
+        <result column="ORDER_ID" property="orderId" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="STATUS" property="status" />
+        <result column="STEP" property="step" />
+        <result column="USER_ID" property="userId" />
+        <result column="COMPANY_ID" property="companyId" />
+        <result column="DOC_PATH" property="docPath" />
+        <result column="APPROVAL_USER_ID" property="approvalUserId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID AS id, PRODUCT_ID AS productId, FLOW_ID AS flowId, ORDER_ID AS orderId, CREATE_TIME AS createTime, STATUS AS status, STEP AS step, USER_ID AS userId, COMPANY_ID AS companyId, DOC_PATH AS docPath, APPROVAL_USER_ID AS approvalUserId
+    </sql>
+
+    <select id="getUserNameById" resultType="string">
+        select NICKNAME from T_USER where USER_ID=#{userId}
+        <if test="status !=null">
+            and STATUS=#{status}
+        </if>
+    </select>
+
+    <select id="listShenqian" resultType="com.qr.database.model.Shenqian">
+        select a.ID,a.ORDER_ID,a.CREATE_TIME,b.NODE_NAME,b.APPROVAL_USER_NAME,a.STATUS from QR_SHENQIAN a
+        left join QR_SHENQIAN_LOG b on a.ID=b.SHENQIAN_ID and a.STEP=b.ORDER_NUMBER
+        left join QR_PRODUCT c on a.PRODUCT_ID=c.ID
+        left join QR_STANDARD d on c.BATCH_MARKING=d.BATCH_MARKING
+        left join QR_UNIT e on c.FLAG=e.FLAG
+        <where>
+            a.FLAG=1
+            <if test="a.userId !=null">
+                and a.USER_ID=#{a.userId}
+            </if>
+            <if test="a.approvalUserId !=null">
+                and a.APPROVAL_USER_ID=#{a.approvalUserId}
+            </if>
+            <if test="a.batchMarking !=null and a.batchMarking !=''">
+                and c.BATCH_MARKING=#{a.batchMarking}
+            </if>
+            <if test="a.name !=null and a.name !=''">
+                and d.NAME like '%'||#{a.name}||'%'
+            </if>
+            <if test="a.standardNumber !=null and a.standardNumber !=''">
+                and d.STANDARD_NUMBER=#{a.standardNumber}
+            </if>
+            <if test="a.groupItemCode !=null and a.groupItemCode !=''">
+                and d.GROUP_ITEM_CODE=#{a.groupItemCode}
+            </if>
+            <if test="a.unit != null and a.unit !=''">
+                and e.NAME = #{a.unit}
+            </if>
+            <if test="a.status !=null">
+                and a.STATUS=#{a.status}
+            </if>
+            <if test="a.nodeName !=null and a.nodeName !=''">
+                and b.NODE_NAME=#{a.nodeName}
+            </if>
+            <if test="a.orderId !=null and a.orderId !=''">
+                and b.ORDER_ID=#{a.orderId}
+            </if>
+            <if test="a.companyId !=null">
+                and a.COMPANY_ID = #{a.companyId}
+            </if>
+            <if test="a.startCreateTime !=null">
+                and a.CREATE_TIME >= #{a.startCreateTime}
+            </if>
+            <if test="a.endCreateTime !=null">
+                and a.CREATE_TIME &lt;= #{a.endCreateTime}
+            </if>
+            <if test="a.productType !=null and a.productType !=1 and a.productType !=2">
+                and c.ID = -1
+            </if>
+        </where>
+        order by a.ID desc
+    </select>
+
+    <select id="last" resultType="com.qr.database.model.Shenqian">
+        select ID AS id, PRODUCT_ID AS productId, FLOW_ID AS flowId, ORDER_ID AS orderId, CREATE_TIME AS createTime, STATUS AS status, STEP AS step, USER_ID AS userId, COMPANY_ID AS companyId, DOC_PATH AS docPath, APPROVAL_USER_ID AS approvalUserId from QR_SHENQIAN
+        where ID=(select min(c.ID) from (select ID,USER_ID,APPROVAL_USER_ID from QR_SHENQIAN ORDER BY ID) c
+        where c.ID>#{id}
+        <if test="userId !=null">
+            and c.USER_ID = #{userId}
+        </if>
+        <if test="approvalUserId !=null">
+            and c.APPROVAL_USER_ID = #{approvalUserId}
+        </if>
+        )
+    </select>
+
+    <select id="next" resultType="com.qr.database.model.Shenqian">
+        select ID AS id, PRODUCT_ID AS productId, FLOW_ID AS flowId, ORDER_ID AS orderId, CREATE_TIME AS createTime, STATUS AS status, STEP AS step, USER_ID AS userId, COMPANY_ID AS companyId, DOC_PATH AS docPath, APPROVAL_USER_ID AS approvalUserId from QR_SHENQIAN
+        where ID=(select max(c.ID) from (select ID,USER_ID,APPROVAL_USER_ID from QR_SHENQIAN ORDER BY ID) c
+        where c.ID&lt;#{id}
+        <if test="userId !=null">
+            and c.USER_ID = #{userId}
+        </if>
+        <if test="approvalUserId !=null">
+            and c.APPROVAL_USER_ID = #{approvalUserId}
+        </if>
+        )
+    </select>
+</mapper>

+ 111 - 0
database/src/main/java/com/qr/database/dao/mapping/StandardMapper.xml

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.StandardMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.Standard">
+        <id column="ID" property="id" />
+        <result column="GROUP_ITEM_CODE" property="groupItemCode" />
+        <result column="BATCH_MARKING" property="batchMarking" />
+        <result column="YEAR" property="year" />
+        <result column="NAME" property="name" />
+        <result column="STANDARD_NUMBER" property="standardNumber" />
+        <result column="SPECIFICATION" property="specification" />
+        <result column="FINISH" property="finish" />
+        <result column="MATERIALS" property="materials" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="QR_DATA" property="qrData" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID AS id, GROUP_ITEM_CODE AS groupItemCode, BATCH_MARKING AS batchMarking, YEAR AS year, NAME AS name, STANDARD_NUMBER AS standardNumber, SPECIFICATION AS specification, FINISH AS finish, MATERIALS AS materials, CREATE_TIME AS createTime, QR_DATA AS qrData
+    </sql>
+
+    <select id="list" parameterType="com.baomidou.mybatisplus.extension.plugins.pagination.Page" resultType="com.qr.database.model.Standard">
+        select a.ID AS id, a.GROUP_ITEM_CODE AS groupItemCode, a.BATCH_MARKING AS batchMarking, a.YEAR AS year, a.NAME AS name, a.STANDARD_NUMBER AS standardNumber, a.SPECIFICATION AS specification, a.FINISH AS finish, a.MATERIALS AS materials, a.CREATE_TIME AS createTime from QR_STANDARD a
+        <where>
+            <if test="a.batchMarking !=null and a.batchMarking !=''">
+                a.BATCH_MARKING = #{a.batchMarking}
+            </if>
+            <if test="a.standardNumber !=null and a.standardNumber !=''">
+                and a.STANDARD_NUMBER = #{a.standardNumber}
+            </if>
+            <if test="a.groupItemCode !=null and a.groupItemCode !=''">
+                and a.GROUP_ITEM_CODE = #{a.groupItemCode}
+            </if>
+            <if test="a.companyId !=null">
+                and a.COMPANY_ID = #{a.companyId}
+            </if>
+            <if test="a.name !=null and a.name !=''">
+                and a.NAME like '%'||#{a.name}||'%'
+            </if>
+            <if test="a.startCreateTime !=null">
+                and a.CREATE_TIME >= #{a.startCreateTime}
+            </if>
+            <if test="a.endCreateTime !=null">
+                and a.CREATE_TIME &lt;= #{a.endCreateTime}
+            </if>
+            <if test="a.productType !=null and a.productType !=1 and a.productType !=2">
+                and a.ID = -1
+            </if>
+        </where>
+    </select>
+
+    <select id="listProduct" parameterType="com.baomidou.mybatisplus.extension.plugins.pagination.Page" resultType="com.qr.database.model.Standard">
+        select b.ID AS id, a.GROUP_ITEM_CODE AS groupItemCode, a.BATCH_MARKING AS batchMarking, a.YEAR AS year, a.NAME AS name, a.STANDARD_NUMBER AS standardNumber, a.SPECIFICATION AS specification, a.FINISH AS finish, a.MATERIALS AS materials, a.CREATE_TIME AS createTime,
+        b.BATCH_NO batchNo,b.PRODUCTION_AMOUNT productionAmount,b.SHIPMENTS_AMOUNT shipmentsAmount,c.NAME unit,d.minCount from QR_PRODUCT b
+        left join ( select least((3-aa.ce-aa.isi-aa.ip), (2-aa.ce-aa.tp),(2-aa.ce-aa.ts)) minCount,aa.ID from
+        (select  ID,NVL2(THIRDPARTY_SIZE_REPORT,1,0) ts,NVL2(THIRDPARTY_PER_REPORT,1,0) tp,NVL2(INTO_SIZE_REPORT,1,0) isi,NVL2(INTO_PER_REPORT,1,0) ip,NVL2(CERTIFICATION,1,0) ce from QR_PRODUCT ) aa
+        ) d on d.ID = b.ID
+        left join QR_STANDARD a on b.BATCH_MARKING=a.BATCH_MARKING
+        left join QR_UNIT c on b.FLAG=c.FLAG
+        <where>
+            b.STATUS=1
+            <if test="a.batchMarking !=null and a.batchMarking !=''">
+                and a.BATCH_MARKING = #{a.batchMarking}
+            </if>
+            <if test="a.standardNumber !=null and a.standardNumber !=''">
+                and a.STANDARD_NUMBER = #{a.standardNumber}
+            </if>
+            <if test="a.groupItemCode !=null and a.groupItemCode !=''">
+                and a.GROUP_ITEM_CODE = #{a.groupItemCode}
+            </if>
+            <if test="a.companyId !=null">
+                and a.COMPANY_ID = #{a.companyId}
+            </if>
+            <if test="a.name !=null and a.name !=''">
+                and a.NAME like '%'||#{a.name}||'%'
+            </if>
+            <if test="a.startCreateTime !=null">
+                and a.CREATE_TIME >= #{a.startCreateTime}
+            </if>
+            <if test="a.endCreateTime !=null">
+                and a.CREATE_TIME &lt;= #{a.endCreateTime}
+            </if>
+            <if test="a.productType !=null and a.productType !=1 and a.productType !=2">
+                and a.ID = -1
+            </if>
+            <if test="a.unit != null and a.unit !=''">
+                and c.NAME = #{a.unit}
+            </if>
+            <if test="a.fileType !=null">
+                <choose>
+                    <when test="a.fileType==1">and b.SURVEY_REPORT is not null</when>
+                    <when test="a.fileType==2">and b.OUTGOING_REPORT is not null</when>
+                    <when test="a.fileType==3">and b.THIRDPARTY_SIZE_REPORT is not null</when>
+                    <when test="a.fileType==4">and b.THIRDPARTY_PER_REPORT is not null</when>
+                    <when test="a.fileType==5">and b.INTO_SIZE_REPORT is not null</when>
+                    <when test="a.fileType==6">and b.INTO_PER_REPORT is not null</when>
+                    <when test="a.fileType==7">and b.CERTIFICATION is not null</when>
+                </choose>
+            </if>
+            <if test="a.isFull != null">
+                <choose>
+                    <when test="a.isFull==1">and d.minCount=0</when>
+                    <when test="a.isFull==2">and d.minCount>=1</when>
+                </choose>
+            </if>
+        </where>
+    </select>
+</mapper>

+ 21 - 0
database/src/main/java/com/qr/database/dao/mapping/UnitMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qr.database.dao.UnitMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qr.database.model.Unit">
+        <id column="ID" property="id" />
+        <result column="TYPE" property="type" />
+        <result column="NAME" property="name" />
+        <result column="ADDR" property="addr" />
+        <result column="FLAG" property="flag" />
+        <result column="UNIT_CODE" property="unitCode" />
+        <result column="NOTE" property="note" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID AS id, TYPE AS type, NAME AS name, ADDR AS addr, FLAG AS flag, UNIT_CODE AS unitCode, NOTE AS note
+    </sql>
+
+</mapper>

+ 204 - 0
database/src/main/java/com/qr/database/model/Flow.java

@@ -0,0 +1,204 @@
+package com.qr.database.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 二维码数据库审签流程表
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@TableName("QR_FLOW")
+public class Flow extends Model<Flow> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 流程id
+     */
+    @TableId("FLOW_ID")
+    private Long flowId;
+    /**
+     * 流程名称
+     */
+    @TableField("FLOW_NAME")
+    private String flowName;
+    /**
+     * 状态 0:正常 1:删除
+     */
+    @TableField("STATUS")
+    private Integer status;
+    /**
+     * 创建者用户id
+     */
+    @TableField("CREATOR_ID")
+    private Long creatorId;
+    /**
+     * 企业id
+     */
+    @TableField("COMPANY_ID")
+    private Long companyId;
+    /**
+     * 修改者用户id
+     */
+    @TableField("MODIFIER_ID")
+    private Long modifierId;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @TableField("UPDATE_TIME")
+    private Date updateTime;
+    /**
+     * 审批内容  1:盖章  2:签字
+     */
+    @TableField(exist = false)
+    private Integer approvalType;
+    /**
+     * 审批人id
+     */
+    @TableField(exist = false)
+    private Long userId;
+    /**
+     * 节点名称
+     */
+    @TableField(exist = false)
+    private String nodeName;
+    /**
+     * 昵称
+     */
+    @TableField(exist = false)
+    private String nickname;
+
+    public Integer getApprovalType() {
+        return approvalType;
+    }
+
+    public void setApprovalType(Integer approvalType) {
+        this.approvalType = approvalType;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public void setNodeName(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    public String getNickname() {
+        return nickname;
+    }
+
+    public void setNickname(String nickname) {
+        this.nickname = nickname;
+    }
+
+    public Long getFlowId() {
+        return flowId;
+    }
+
+    public void setFlowId(Long flowId) {
+        this.flowId = flowId;
+    }
+
+    public String getFlowName() {
+        return flowName;
+    }
+
+    public void setFlowName(String flowName) {
+        this.flowName = flowName;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public Long getCreatorId() {
+        return creatorId;
+    }
+
+    public void setCreatorId(Long creatorId) {
+        this.creatorId = creatorId;
+    }
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public Long getModifierId() {
+        return modifierId;
+    }
+
+    public void setModifierId(Long modifierId) {
+        this.modifierId = modifierId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.flowId;
+    }
+
+    @Override
+    public String toString() {
+        return "Flow{" +
+                "flowId=" + flowId +
+                ", flowName='" + flowName + '\'' +
+                ", status=" + status +
+                ", creatorId=" + creatorId +
+                ", companyId=" + companyId +
+                ", modifierId=" + modifierId +
+                ", createTime=" + createTime +
+                ", updateTime=" + updateTime +
+                ", approvalType=" + approvalType +
+                ", userId=" + userId +
+                ", nodeName='" + nodeName + '\'' +
+                ", nickname='" + nickname + '\'' +
+                '}';
+    }
+}

+ 148 - 0
database/src/main/java/com/qr/database/model/FlowNode.java

@@ -0,0 +1,148 @@
+package com.qr.database.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 二维码数据库流程节点表
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@TableName("QR_FLOW_NODE")
+public class FlowNode extends Model<FlowNode> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 节点id
+     */
+    @TableField("NODE_ID")
+    private Long nodeId;
+    /**
+     * 流程id
+     */
+    @TableField("FLOW_ID")
+    private Long flowId;
+    /**
+     * 节点名称
+     */
+    @TableField("NODE_NAME")
+    private String nodeName;
+    /**
+     * 节点序号
+     */
+    @TableField("NODE_ORDER")
+    private Integer nodeOrder;
+    /**
+     * 创建者用户id
+     */
+    @TableField("CREATOR_ID")
+    private Long creatorId;
+    /**
+     * 修改者用户id
+     */
+    @TableField("MODIFIER_ID")
+    private Long modifierId;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @TableField("UPDATE_TIME")
+    private Date updateTime;
+
+
+    public Long getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(Long nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public Long getFlowId() {
+        return flowId;
+    }
+
+    public void setFlowId(Long flowId) {
+        this.flowId = flowId;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public void setNodeName(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    public Integer getNodeOrder() {
+        return nodeOrder;
+    }
+
+    public void setNodeOrder(Integer nodeOrder) {
+        this.nodeOrder = nodeOrder;
+    }
+
+    public Long getCreatorId() {
+        return creatorId;
+    }
+
+    public void setCreatorId(Long creatorId) {
+        this.creatorId = creatorId;
+    }
+
+    public Long getModifierId() {
+        return modifierId;
+    }
+
+    public void setModifierId(Long modifierId) {
+        this.modifierId = modifierId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.nodeId;
+    }
+
+    @Override
+    public String toString() {
+        return "FlowNode{" +
+        "nodeId=" + nodeId +
+        ", flowId=" + flowId +
+        ", nodeName=" + nodeName +
+        ", nodeOrder=" + nodeOrder +
+        ", creatorId=" + creatorId +
+        ", modifierId=" + modifierId +
+        ", createTime=" + createTime +
+        ", updateTime=" + updateTime +
+        "}";
+    }
+}

+ 162 - 0
database/src/main/java/com/qr/database/model/NodeUser.java

@@ -0,0 +1,162 @@
+package com.qr.database.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 节点审批人表
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@TableName("QR_NODE_USER")
+public class NodeUser extends Model<NodeUser> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @TableField("ID")
+    private Long id;
+    /**
+     * 节点id
+     */
+    @TableField("NODE_ID")
+    private Long nodeId;
+    /**
+     * 审批人id
+     */
+    @TableField("USER_ID")
+    private Long userId;
+    /**
+     * 审批内容  1:盖章  2:签字
+     */
+    @TableField("APPROVAL_TYPE")
+    private Integer approvalType;
+    /**
+     * 审批人序号
+     */
+    @TableField("USER_ORDER")
+    private Integer userOrder;
+    /**
+     * 创建者用户id
+     */
+    @TableField("CREATOR_ID")
+    private Long creatorId;
+    /**
+     * 修改者用户id
+     */
+    @TableField("MODIFIER_ID")
+    private Long modifierId;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @TableField("UPDATE_TIME")
+    private Date updateTime;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(Long nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Integer getApprovalType() {
+        return approvalType;
+    }
+
+    public void setApprovalType(Integer approvalType) {
+        this.approvalType = approvalType;
+    }
+
+    public Integer getUserOrder() {
+        return userOrder;
+    }
+
+    public void setUserOrder(Integer userOrder) {
+        this.userOrder = userOrder;
+    }
+
+    public Long getCreatorId() {
+        return creatorId;
+    }
+
+    public void setCreatorId(Long creatorId) {
+        this.creatorId = creatorId;
+    }
+
+    public Long getModifierId() {
+        return modifierId;
+    }
+
+    public void setModifierId(Long modifierId) {
+        this.modifierId = modifierId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "NodeUser{" +
+        "id=" + id +
+        ", nodeId=" + nodeId +
+        ", userId=" + userId +
+        ", approvalType=" + approvalType +
+        ", userOrder=" + userOrder +
+        ", creatorId=" + creatorId +
+        ", modifierId=" + modifierId +
+        ", createTime=" + createTime +
+        ", updateTime=" + updateTime +
+        "}";
+    }
+}

+ 702 - 0
database/src/main/java/com/qr/database/model/Product.java

@@ -0,0 +1,702 @@
+package com.qr.database.model;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@TableName("QR_PRODUCT")
+@KeySequence("QR_PRODUCT_SEQ")
+public class Product extends Model<Product> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.INPUT)
+    private Long id;
+    /**
+     * 批次标记
+     */
+    @Excel(name = "批次标记")
+    @TableField("BATCH_MARKING")
+    private String batchMarking;
+    /**
+     * 批号
+     */
+    @Excel(name = "批号")
+    @TableField("BATCH_NO")
+    private String batchNo;
+    /**
+     * 单位标记
+     */
+    @TableField("FLAG")
+    private String flag;
+    /**
+     * 序号
+     */
+    @TableField("NO")
+    private String no;
+    /**
+     * 投产批量
+     */
+    @Excel(name = "投产批量")
+    @TableField("PRODUCTION_AMOUNT")
+    private Long productionAmount;
+    /**
+     * 本次发货数量
+     */
+    @Excel(name = "本次发货数量")
+    @TableField("SHIPMENTS_AMOUNT")
+    private Long shipmentsAmount;
+    /**
+     * 二维码
+     */
+    @TableField("QR_DATA")
+    private String qrData;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    private Date createTime;
+    /**
+     * 鉴定报告
+     */
+    @TableField("SURVEY_REPORT")
+    private String surveyReport;
+    @TableField("SURVEY_REPORT_TIME")
+    private Date surveyReportTime;
+    @TableField("SURVEY_REPORT_USER_ID")
+    private Long surveyReportUserId;
+    /**
+     * 上传人姓名
+     */
+    @TableField(exist = false)
+    private String surveyReportUserName;
+    /**
+     * 鉴定报告上传人部门
+     */
+    @TableField(exist = false)
+    private String surveyReportUserDep;
+    /**
+     * 出厂报告
+     */
+    @TableField("OUTGOING_REPORT")
+    private String outgoingReport;
+    @TableField("OUTGOING_REPORT_TIME")
+    private Date outgoingReportTime;
+    @TableField("OUTGOING_REPORT_USER_ID")
+    private Long outgoingReportUserId;
+    @TableField(exist = false)
+    private String outgoingReportName;
+    @TableField(exist = false)
+    private String outgoingReportDep;
+    /**
+     * 第三方尺寸复验报告
+     */
+    @TableField("THIRDPARTY_SIZE_REPORT")
+    private String thirdpartySizeReport;
+    @TableField("THIRDPARTY_SIZE_REPORT_TIME")
+    private Date thirdpartySizeReportTime;
+    @TableField("THIRDPARTY_SIZE_REPORT_USER_ID")
+    private Long thirdpartySizeReportUserId;
+    @TableField(exist = false)
+    private String thirdpartySizeReportName;
+    @TableField(exist = false)
+    private String thirdpartySizeReportDep;
+    /**
+     * 第三方性能报告
+     */
+    @TableField("THIRDPARTY_PER_REPORT")
+    private String thirdpartyPerReport;
+    @TableField("THIRDPARTY_PER_REPORT_TIME")
+    private Date thirdpartyPerReportTime;
+    @TableField("THIRDPARTY_PER_REPORT_USER_ID")
+    private Long thirdpartyPerReportUserId;
+    @TableField(exist = false)
+    private String thirdpartyPerReportName;
+    @TableField(exist = false)
+    private String thirdpartyPerReportDep;
+    /**
+     * 入厂尺寸复验报告
+     */
+    @TableField("INTO_SIZE_REPORT")
+    private String intoSizeReport;
+    @TableField("INTO_SIZE_REPORT_TIME")
+    private Date intoSizeReportTime;
+    @TableField("INTO_SIZE_REPORT_USER_ID")
+    private Long intoSizeReportUserId;
+    @TableField(exist = false)
+    private String intoSizeReportName;
+    @TableField(exist = false)
+    private String intoSizeReportDep;
+    /**
+     * 入厂性能复验报告
+     */
+    @TableField("INTO_PER_REPORT")
+    private String intoPerReport;
+    @TableField("INTO_PER_REPORT_TIME")
+    private Date intoPerReportTime;
+    @TableField("INTO_PER_REPORT_USER_ID")
+    private Long intoPerReportUserId;
+    @TableField(exist = false)
+    private String intoPerReportName;
+    @TableField(exist = false)
+    private String intoPerReportDep;
+    /**
+     * 合格证
+     */
+    @TableField("CERTIFICATION")
+    private String certification;
+    @TableField("CERTIFICATION_TIME")
+    private Date certificationTime;
+    @TableField("CERTIFICATION_USER_ID")
+    private Long certificationUserId;
+    @TableField(exist = false)
+    private String certificationName;
+    @TableField(exist = false)
+    private String certificationDep;
+    /**
+     * 子合格证
+     */
+    @TableField("SUB_CERTIFICATION")
+    private String subCertification;
+    @TableField("SUB_CERTIFICATION_TIME")
+    private Date subCertificationTime;
+    @TableField("SUB_CERTIFICATION_USER_ID")
+    private Long subCertificationUserId;
+    @TableField(exist = false)
+    private String subCertificationName;
+    @TableField(exist = false)
+    private String subCertificationDep;
+    /**
+     * 企业ID
+     */
+    @TableField("COMPANY_ID")
+    private Long companyId;
+    /**
+     * 集团物品码
+     */
+    @Excel(name = "集团物品码")
+    @TableField(exist = false)
+    private String groupItemCode;
+    /**
+     * 物品名称
+     */
+    @Excel(name = "物品名称")
+    @TableField(exist = false)
+    private String name;
+    /**
+     * 材料
+     */
+    @Excel(name = "材料")
+    @TableField(exist = false)
+    private String materials;
+    /**
+     * 表面处理
+     */
+    @Excel(name = "表面处理")
+    @TableField(exist = false)
+    private String finish;
+    /**
+     * 标准号
+     */
+    @Excel(name = "标准号")
+    @TableField(exist = false)
+    private String standardNumber;
+    /**
+     * 年代
+     */
+    @Excel(name = "年代")
+    @TableField(exist = false)
+    private String year;
+    /**
+     * 1=正常,2=删除
+     */
+    @TableField("STATUS")
+    private Integer status;
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getSubCertification() {
+        return subCertification;
+    }
+
+    public void setSubCertification(String subCertification) {
+        this.subCertification = subCertification;
+    }
+
+    public Date getSubCertificationTime() {
+        return subCertificationTime;
+    }
+
+    public void setSubCertificationTime(Date subCertificationTime) {
+        this.subCertificationTime = subCertificationTime;
+    }
+
+    public Long getSubCertificationUserId() {
+        return subCertificationUserId;
+    }
+
+    public void setSubCertificationUserId(Long subCertificationUserId) {
+        this.subCertificationUserId = subCertificationUserId;
+    }
+
+    public String getSubCertificationName() {
+        return subCertificationName;
+    }
+
+    public void setSubCertificationName(String subCertificationName) {
+        this.subCertificationName = subCertificationName;
+    }
+
+    public String getSubCertificationDep() {
+        return subCertificationDep;
+    }
+
+    public void setSubCertificationDep(String subCertificationDep) {
+        this.subCertificationDep = subCertificationDep;
+    }
+
+    public String getSurveyReportUserName() {
+        return surveyReportUserName;
+    }
+
+    public void setSurveyReportUserName(String surveyReportUserName) {
+        this.surveyReportUserName = surveyReportUserName;
+    }
+
+    public String getSurveyReportUserDep() {
+        return surveyReportUserDep;
+    }
+
+    public void setSurveyReportUserDep(String surveyReportUserDep) {
+        this.surveyReportUserDep = surveyReportUserDep;
+    }
+
+    public String getOutgoingReportName() {
+        return outgoingReportName;
+    }
+
+    public void setOutgoingReportName(String outgoingReportName) {
+        this.outgoingReportName = outgoingReportName;
+    }
+
+    public String getOutgoingReportDep() {
+        return outgoingReportDep;
+    }
+
+    public void setOutgoingReportDep(String outgoingReportDep) {
+        this.outgoingReportDep = outgoingReportDep;
+    }
+
+    public String getThirdpartySizeReportName() {
+        return thirdpartySizeReportName;
+    }
+
+    public void setThirdpartySizeReportName(String thirdpartySizeReportName) {
+        this.thirdpartySizeReportName = thirdpartySizeReportName;
+    }
+
+    public String getThirdpartySizeReportDep() {
+        return thirdpartySizeReportDep;
+    }
+
+    public void setThirdpartySizeReportDep(String thirdpartySizeReportDep) {
+        this.thirdpartySizeReportDep = thirdpartySizeReportDep;
+    }
+
+    public String getThirdpartyPerReportName() {
+        return thirdpartyPerReportName;
+    }
+
+    public void setThirdpartyPerReportName(String thirdpartyPerReportName) {
+        this.thirdpartyPerReportName = thirdpartyPerReportName;
+    }
+
+    public String getThirdpartyPerReportDep() {
+        return thirdpartyPerReportDep;
+    }
+
+    public void setThirdpartyPerReportDep(String thirdpartyPerReportDep) {
+        this.thirdpartyPerReportDep = thirdpartyPerReportDep;
+    }
+
+    public String getIntoSizeReportName() {
+        return intoSizeReportName;
+    }
+
+    public void setIntoSizeReportName(String intoSizeReportName) {
+        this.intoSizeReportName = intoSizeReportName;
+    }
+
+    public String getIntoSizeReportDep() {
+        return intoSizeReportDep;
+    }
+
+    public void setIntoSizeReportDep(String intoSizeReportDep) {
+        this.intoSizeReportDep = intoSizeReportDep;
+    }
+
+    public String getIntoPerReportName() {
+        return intoPerReportName;
+    }
+
+    public void setIntoPerReportName(String intoPerReportName) {
+        this.intoPerReportName = intoPerReportName;
+    }
+
+    public String getIntoPerReportDep() {
+        return intoPerReportDep;
+    }
+
+    public void setIntoPerReportDep(String intoPerReportDep) {
+        this.intoPerReportDep = intoPerReportDep;
+    }
+
+    public String getCertificationName() {
+        return certificationName;
+    }
+
+    public void setCertificationName(String certificationName) {
+        this.certificationName = certificationName;
+    }
+
+    public String getCertificationDep() {
+        return certificationDep;
+    }
+
+    public void setCertificationDep(String certificationDep) {
+        this.certificationDep = certificationDep;
+    }
+
+    public String getGroupItemCode() {
+        return groupItemCode;
+    }
+
+    public void setGroupItemCode(String groupItemCode) {
+        this.groupItemCode = groupItemCode;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getMaterials() {
+        return materials;
+    }
+
+    public void setMaterials(String materials) {
+        this.materials = materials;
+    }
+
+    public String getFinish() {
+        return finish;
+    }
+
+    public void setFinish(String finish) {
+        this.finish = finish;
+    }
+
+    public String getStandardNumber() {
+        return standardNumber;
+    }
+
+    public void setStandardNumber(String standardNumber) {
+        this.standardNumber = standardNumber;
+    }
+
+    public String getYear() {
+        return year;
+    }
+
+    public void setYear(String year) {
+        this.year = year;
+    }
+
+    public Date getSurveyReportTime() {
+        return surveyReportTime;
+    }
+
+    public void setSurveyReportTime(Date surveyReportTime) {
+        this.surveyReportTime = surveyReportTime;
+    }
+
+    public Long getSurveyReportUserId() {
+        return surveyReportUserId;
+    }
+
+    public void setSurveyReportUserId(Long surveyReportUserId) {
+        this.surveyReportUserId = surveyReportUserId;
+    }
+
+    public Date getOutgoingReportTime() {
+        return outgoingReportTime;
+    }
+
+    public void setOutgoingReportTime(Date outgoingReportTime) {
+        this.outgoingReportTime = outgoingReportTime;
+    }
+
+    public Date getThirdpartySizeReportTime() {
+        return thirdpartySizeReportTime;
+    }
+
+    public void setThirdpartySizeReportTime(Date thirdpartySizeReportTime) {
+        this.thirdpartySizeReportTime = thirdpartySizeReportTime;
+    }
+
+    public Date getThirdpartyPerReportTime() {
+        return thirdpartyPerReportTime;
+    }
+
+    public void setThirdpartyPerReportTime(Date thirdpartyPerReportTime) {
+        this.thirdpartyPerReportTime = thirdpartyPerReportTime;
+    }
+
+    public Date getIntoSizeReportTime() {
+        return intoSizeReportTime;
+    }
+
+    public void setIntoSizeReportTime(Date intoSizeReportTime) {
+        this.intoSizeReportTime = intoSizeReportTime;
+    }
+
+    public Date getIntoPerReportTime() {
+        return intoPerReportTime;
+    }
+
+    public void setIntoPerReportTime(Date intoPerReportTime) {
+        this.intoPerReportTime = intoPerReportTime;
+    }
+
+    public Date getCertificationTime() {
+        return certificationTime;
+    }
+
+    public void setCertificationTime(Date certificationTime) {
+        this.certificationTime = certificationTime;
+    }
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public String getSurveyReport() {
+        return surveyReport;
+    }
+
+    public void setSurveyReport(String surveyReport) {
+        this.surveyReport = surveyReport;
+    }
+
+    public String getOutgoingReport() {
+        return outgoingReport;
+    }
+
+    public void setOutgoingReport(String outgoingReport) {
+        this.outgoingReport = outgoingReport;
+    }
+
+    public String getThirdpartySizeReport() {
+        return thirdpartySizeReport;
+    }
+
+    public void setThirdpartySizeReport(String thirdpartySizeReport) {
+        this.thirdpartySizeReport = thirdpartySizeReport;
+    }
+
+    public String getThirdpartyPerReport() {
+        return thirdpartyPerReport;
+    }
+
+    public void setThirdpartyPerReport(String thirdpartyPerReport) {
+        this.thirdpartyPerReport = thirdpartyPerReport;
+    }
+
+    public String getIntoSizeReport() {
+        return intoSizeReport;
+    }
+
+    public void setIntoSizeReport(String intoSizeReport) {
+        this.intoSizeReport = intoSizeReport;
+    }
+
+    public String getIntoPerReport() {
+        return intoPerReport;
+    }
+
+    public void setIntoPerReport(String intoPerReport) {
+        this.intoPerReport = intoPerReport;
+    }
+
+    public String getCertification() {
+        return certification;
+    }
+
+    public void setCertification(String certification) {
+        this.certification = certification;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getBatchMarking() {
+        return batchMarking;
+    }
+
+    public void setBatchMarking(String batchMarking) {
+        this.batchMarking = batchMarking;
+    }
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    public String getNo() {
+        return no;
+    }
+
+    public void setNo(String no) {
+        this.no = no;
+    }
+
+    public Long getProductionAmount() {
+        return productionAmount;
+    }
+
+    public void setProductionAmount(Long productionAmount) {
+        this.productionAmount = productionAmount;
+    }
+
+    public Long getShipmentsAmount() {
+        return shipmentsAmount;
+    }
+
+    public void setShipmentsAmount(Long shipmentsAmount) {
+        this.shipmentsAmount = shipmentsAmount;
+    }
+
+    public String getQrData() {
+        return qrData;
+    }
+
+    public void setQrData(String qrData) {
+        this.qrData = qrData;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Long getOutgoingReportUserId() {
+        return outgoingReportUserId;
+    }
+
+    public void setOutgoingReportUserId(Long outgoingReportUserId) {
+        this.outgoingReportUserId = outgoingReportUserId;
+    }
+
+    public Long getThirdpartySizeReportUserId() {
+        return thirdpartySizeReportUserId;
+    }
+
+    public void setThirdpartySizeReportUserId(Long thirdpartySizeReportUserId) {
+        this.thirdpartySizeReportUserId = thirdpartySizeReportUserId;
+    }
+
+    public Long getThirdpartyPerReportUserId() {
+        return thirdpartyPerReportUserId;
+    }
+
+    public void setThirdpartyPerReportUserId(Long thirdpartyPerReportUserId) {
+        this.thirdpartyPerReportUserId = thirdpartyPerReportUserId;
+    }
+
+    public Long getIntoSizeReportUserId() {
+        return intoSizeReportUserId;
+    }
+
+    public void setIntoSizeReportUserId(Long intoSizeReportUserId) {
+        this.intoSizeReportUserId = intoSizeReportUserId;
+    }
+
+    public Long getIntoPerReportUserId() {
+        return intoPerReportUserId;
+    }
+
+    public void setIntoPerReportUserId(Long intoPerReportUserId) {
+        this.intoPerReportUserId = intoPerReportUserId;
+    }
+
+    public Long getCertificationUserId() {
+        return certificationUserId;
+    }
+
+    public void setCertificationUserId(Long certificationUserId) {
+        this.certificationUserId = certificationUserId;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "Product{" +
+        "id=" + id +
+        ", batchMarking=" + batchMarking +
+        ", batchNo=" + batchNo +
+        ", flag=" + flag +
+        ", no=" + no +
+        ", productionAmount=" + productionAmount +
+        ", shipmentsAmount=" + shipmentsAmount +
+        ", qrData=" + qrData +
+        ", createTime=" + createTime +
+        "}";
+    }
+}

+ 24 - 0
database/src/main/java/com/qr/database/model/ProductDel.java

@@ -0,0 +1,24 @@
+package com.qr.database.model;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+
+public class ProductDel {
+
+    @Excel(name = "批号")
+    private String batchNo;
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    @Override
+    public String toString() {
+        return "ProductDel{" +
+                "batchNo='" + batchNo + '\'' +
+                '}';
+    }
+}

+ 290 - 0
database/src/main/java/com/qr/database/model/ProductExport.java

@@ -0,0 +1,290 @@
+package com.qr.database.model;
+
+import cn.afterturn.easypoi.entity.ImageEntity;
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.TableField;
+
+public class ProductExport {
+    /**
+     * 承制单位代码
+     */
+    @TableField("UNIT_CODE")
+    private String unitCode;
+    /**
+     * 集团物品码
+     */
+    @Excel(name = "集团物品码")
+    @TableField("GROUP_ITEM_CODE")
+    private String groupItemCode;
+    /**
+     * 序号
+     */
+    @TableField("NO")
+    private String no;
+    /**
+     * 物品名称
+     */
+    @Excel(name = "物品名称")
+    @TableField("NAME")
+    private String name;
+    /**
+     * 批次标记
+     */
+    @Excel(name = "图号")
+    @TableField("BATCH_MARKING")
+    private String batchMarking;
+    /**
+     * 批号
+     */
+    @Excel(name = "批号")
+    @TableField("BATCH_NO")
+    private String batchNo;
+    /**
+     * 标准号
+     */
+    @Excel(name = "标准号")
+    @TableField("STANDARD_NUMBER")
+    private String standardNumber;
+    /**
+     * 规格
+     */
+    @Excel(name = "规格")
+    @TableField("SPECIFICATION")
+    private String specification;
+    /**
+     * 表面处理
+     */
+    @Excel(name = "表面处理")
+    @TableField("FINISH")
+    private String finish;
+    /**
+     * 材料
+     */
+    @Excel(name = "材料")
+    @TableField("MATERIALS")
+    private String materials;
+    /**
+     * 单位名称
+     */
+    private String unitName;
+    /**
+     * 鉴定报告
+     */
+    @TableField("SURVEY_REPORT")
+    private String surveyReport;
+    /**
+     * 出厂报告
+     */
+    @TableField("OUTGOING_REPORT")
+    private String outgoingReport;
+    /**
+     * 第三方尺寸复验报告
+     */
+    @TableField("THIRDPARTY_SIZE_REPORT")
+    private String thirdpartySizeReport;
+    /**
+     * 第三方性能报告
+     */
+    @TableField("THIRDPARTY_PER_REPORT")
+    private String thirdpartyPerReport;
+    /**
+     * 入厂尺寸复验报告
+     */
+    @TableField("INTO_SIZE_REPORT")
+    private String intoSizeReport;
+    /**
+     * 入厂性能复验报告
+     */
+    @TableField("INTO_PER_REPORT")
+    private String intoPerReport;
+    /**
+     * 合格证
+     */
+    @TableField("CERTIFICATION")
+    private String certification;
+    /**
+     * 投产批量
+     */
+    @Excel(name = "投产批量")
+    @TableField("PRODUCTION_AMOUNT")
+    private Long productionAmount;
+    /**
+     * 本次发货数量
+     */
+    @Excel(name = "本次发货数量")
+    @TableField("SHIPMENTS_AMOUNT")
+    private Long shipmentsAmount;
+    /**
+     * 二维码
+     */
+    @TableField("QR_DATA")
+    private String qrData;
+
+    public String getUnitCode() {
+        return unitCode;
+    }
+
+    public void setUnitCode(String unitCode) {
+        this.unitCode = unitCode;
+    }
+
+    public String getGroupItemCode() {
+        return groupItemCode;
+    }
+
+    public void setGroupItemCode(String groupItemCode) {
+        this.groupItemCode = groupItemCode;
+    }
+
+    public String getNo() {
+        return no;
+    }
+
+    public void setNo(String no) {
+        this.no = no;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBatchMarking() {
+        return batchMarking;
+    }
+
+    public void setBatchMarking(String batchMarking) {
+        this.batchMarking = batchMarking;
+    }
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public String getStandardNumber() {
+        return standardNumber;
+    }
+
+    public void setStandardNumber(String standardNumber) {
+        this.standardNumber = standardNumber;
+    }
+
+    public String getSpecification() {
+        return specification;
+    }
+
+    public void setSpecification(String specification) {
+        this.specification = specification;
+    }
+
+    public String getFinish() {
+        return finish;
+    }
+
+    public void setFinish(String finish) {
+        this.finish = finish;
+    }
+
+    public String getMaterials() {
+        return materials;
+    }
+
+    public void setMaterials(String materials) {
+        this.materials = materials;
+    }
+
+    public String getUnitName() {
+        return unitName;
+    }
+
+    public void setUnitName(String unitName) {
+        this.unitName = unitName;
+    }
+
+    public String getSurveyReport() {
+        return surveyReport;
+    }
+
+    public void setSurveyReport(String surveyReport) {
+        this.surveyReport = surveyReport;
+    }
+
+    public String getOutgoingReport() {
+        return outgoingReport;
+    }
+
+    public void setOutgoingReport(String outgoingReport) {
+        this.outgoingReport = outgoingReport;
+    }
+
+    public String getThirdpartySizeReport() {
+        return thirdpartySizeReport;
+    }
+
+    public void setThirdpartySizeReport(String thirdpartySizeReport) {
+        this.thirdpartySizeReport = thirdpartySizeReport;
+    }
+
+    public String getThirdpartyPerReport() {
+        return thirdpartyPerReport;
+    }
+
+    public void setThirdpartyPerReport(String thirdpartyPerReport) {
+        this.thirdpartyPerReport = thirdpartyPerReport;
+    }
+
+    public String getIntoSizeReport() {
+        return intoSizeReport;
+    }
+
+    public void setIntoSizeReport(String intoSizeReport) {
+        this.intoSizeReport = intoSizeReport;
+    }
+
+    public String getIntoPerReport() {
+        return intoPerReport;
+    }
+
+    public void setIntoPerReport(String intoPerReport) {
+        this.intoPerReport = intoPerReport;
+    }
+
+    public String getCertification() {
+        return certification;
+    }
+
+    public void setCertification(String certification) {
+        this.certification = certification;
+    }
+
+    public Long getProductionAmount() {
+        return productionAmount;
+    }
+
+    public void setProductionAmount(Long productionAmount) {
+        this.productionAmount = productionAmount;
+    }
+
+    public Long getShipmentsAmount() {
+        return shipmentsAmount;
+    }
+
+    public void setShipmentsAmount(Long shipmentsAmount) {
+        this.shipmentsAmount = shipmentsAmount;
+    }
+
+    public String getQrData() {
+        return qrData;
+    }
+
+    public void setQrData(String qrData) {
+        this.qrData = qrData;
+    }
+}

+ 358 - 0
database/src/main/java/com/qr/database/model/Shenqian.java

@@ -0,0 +1,358 @@
+package com.qr.database.model;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 审签
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@TableName("QR_SHENQIAN")
+@KeySequence("QR_SHENQIAN_SEQ")
+public class Shenqian extends Model<Shenqian> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.INPUT)
+    private Long id;
+    /**
+     * 产品ID
+     */
+    @TableField("PRODUCT_ID")
+    private Long productId;
+    /**
+     * 流程ID
+     */
+    @TableField("FLOW_ID")
+    private Long flowId;
+    /**
+     * 审签单号
+     */
+    @TableField("ORDER_ID")
+    private String orderId;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+    /**
+     * 1=审签中,2=驳回。3=异常,4=完成
+     */
+    @TableField("STATUS")
+    private Integer status;
+    /**
+     * 审签步骤ID
+     */
+    @TableField("STEP")
+    private Long step;
+    /**
+     * 用户id
+     */
+    @TableField("USER_ID")
+    private Long userId;
+    /**
+     * 企业id
+     */
+    @TableField("COMPANY_ID")
+    private Long companyId;
+    @TableField("DOC_PATH")
+    private String docPath;
+    /**
+     * 审签人ID
+     */
+    @TableField("APPROVAL_USER_ID")
+    private Long approvalUserId;
+    /**
+     * 1=正常,2=删除
+     */
+    @TableField("FLAG")
+    private Integer flag;
+    /**
+     * 批次标记
+     */
+    @TableField(exist = false)
+    private String batchMarking;
+    /**
+     * 物品名称
+     */
+    @TableField(exist = false)
+    private String name;
+    /**
+     * 标准号
+     */
+    @TableField(exist = false)
+    private String standardNumber;
+    /**
+     * 集团物品码
+     */
+    @TableField(exist = false)
+    private String groupItemCode;
+    /**
+     * 生产单位
+     */
+    @TableField(exist = false)
+    private String unit;
+    /**
+     * 节点名称
+     */
+    @TableField(exist = false)
+    private String nodeName;
+
+    @TableField(exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date startCreateTime;
+
+    @TableField(exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endCreateTime;
+
+    @TableField(exist = false)
+    private String createTimeRange;
+
+    /**
+     * 产品类型
+     * 1全部</
+     * 2紧固件<
+     * 3管内径<
+     * 4电线电缆
+     * 5电连接器
+     * 6金属材料
+     * 7锻、铸件
+     */
+    @TableField(exist = false)
+    private Integer productType;
+    /**
+     * 审批人姓名
+     */
+    @TableField(exist = false)
+    private String approvalUserName;
+
+    @TableField(exist = false)
+    private List<ShenqianLog> ShenqianLogList;
+
+    public List<ShenqianLog> getShenqianLogList() {
+        return ShenqianLogList;
+    }
+
+    public void setShenqianLogList(List<ShenqianLog> shenqianLogList) {
+        ShenqianLogList = shenqianLogList;
+    }
+
+    public String getCreateTimeRange() {
+        return createTimeRange;
+    }
+
+    public void setCreateTimeRange(String createTimeRange) {
+        this.createTimeRange = createTimeRange;
+    }
+
+    public String getApprovalUserName() {
+        return approvalUserName;
+    }
+
+    public void setApprovalUserName(String approvalUserName) {
+        this.approvalUserName = approvalUserName;
+    }
+
+    public String getBatchMarking() {
+        return batchMarking;
+    }
+
+    public void setBatchMarking(String batchMarking) {
+        this.batchMarking = batchMarking;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStandardNumber() {
+        return standardNumber;
+    }
+
+    public void setStandardNumber(String standardNumber) {
+        this.standardNumber = standardNumber;
+    }
+
+    public String getGroupItemCode() {
+        return groupItemCode;
+    }
+
+    public void setGroupItemCode(String groupItemCode) {
+        this.groupItemCode = groupItemCode;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public void setNodeName(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    public Date getStartCreateTime() {
+        return startCreateTime;
+    }
+
+    public void setStartCreateTime(Date startCreateTime) {
+        this.startCreateTime = startCreateTime;
+    }
+
+    public Date getEndCreateTime() {
+        return endCreateTime;
+    }
+
+    public void setEndCreateTime(Date endCreateTime) {
+        this.endCreateTime = endCreateTime;
+    }
+
+    public Integer getProductType() {
+        return productType;
+    }
+
+    public void setProductType(Integer productType) {
+        this.productType = productType;
+    }
+
+    public Integer getFlag() {
+        return flag;
+    }
+
+    public void setFlag(Integer flag) {
+        this.flag = flag;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getProductId() {
+        return productId;
+    }
+
+    public void setProductId(Long productId) {
+        this.productId = productId;
+    }
+
+    public Long getFlowId() {
+        return flowId;
+    }
+
+    public void setFlowId(Long flowId) {
+        this.flowId = flowId;
+    }
+
+    public String getOrderId() {
+        return orderId;
+    }
+
+    public void setOrderId(String orderId) {
+        this.orderId = orderId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public Long getStep() {
+        return step;
+    }
+
+    public void setStep(Long step) {
+        this.step = step;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public String getDocPath() {
+        return docPath;
+    }
+
+    public void setDocPath(String docPath) {
+        this.docPath = docPath;
+    }
+
+    public Long getApprovalUserId() {
+        return approvalUserId;
+    }
+
+    public void setApprovalUserId(Long approvalUserId) {
+        this.approvalUserId = approvalUserId;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "Shenqian{" +
+        "id=" + id +
+        ", productId=" + productId +
+        ", flowId=" + flowId +
+        ", orderId=" + orderId +
+        ", createTime=" + createTime +
+        ", status=" + status +
+        ", step=" + step +
+        ", userId=" + userId +
+        ", companyId=" + companyId +
+        ", docPath=" + docPath +
+        ", approvalUserId=" + approvalUserId +
+        "}";
+    }
+}

+ 185 - 0
database/src/main/java/com/qr/database/model/ShenqianLog.java

@@ -0,0 +1,185 @@
+package com.qr.database.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@TableName("QR_SHENQIAN_LOG")
+@KeySequence("QR_SHENQIAN_LOG_SEQ")
+public class ShenqianLog extends Model<ShenqianLog> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.INPUT)
+    private Long id;
+    /**
+     * 审签ID
+     */
+    @TableField("SHENQIAN_ID")
+    private Long shenqianId;
+    /**
+     * 序号
+     */
+    @TableField("ORDER_NUMBER")
+    private Long orderNumber;
+    /**
+     * 流程ID
+     */
+    @TableField("FLOW_ID")
+    private Long flowId;
+    /**
+     * 节点名称
+     */
+    @TableField("NODE_NAME")
+    private String nodeName;
+    /**
+     * 审批内容  1:盖章  2:签字
+     */
+    @TableField("APPROVAL_TYPE")
+    private Integer approvalType;
+    /**
+     * 审批人id
+     */
+    @TableField("APPROVAL_USER_ID")
+    private Long approvalUserId;
+    /**
+     * 审批人姓名
+     */
+    @TableField("APPROVAL_USER_NAME")
+    private String approvalUserName;
+    /**
+     * 审批状态
+     */
+    @TableField("STATUS")
+    private String status;
+    /**
+     * 审批时间
+     */
+    @TableField("CREATE_TIME")
+    private Date createTime;
+    /**
+     * 备注
+     */
+    @TableField("NOTE")
+    private String note;
+
+    public String getApprovalUserName() {
+        return approvalUserName;
+    }
+
+    public void setApprovalUserName(String approvalUserName) {
+        this.approvalUserName = approvalUserName;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getShenqianId() {
+        return shenqianId;
+    }
+
+    public void setShenqianId(Long shenqianId) {
+        this.shenqianId = shenqianId;
+    }
+
+    public Long getOrderNumber() {
+        return orderNumber;
+    }
+
+    public void setOrderNumber(Long orderNumber) {
+        this.orderNumber = orderNumber;
+    }
+
+    public Long getFlowId() {
+        return flowId;
+    }
+
+    public void setFlowId(Long flowId) {
+        this.flowId = flowId;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public void setNodeName(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    public Integer getApprovalType() {
+        return approvalType;
+    }
+
+    public void setApprovalType(Integer approvalType) {
+        this.approvalType = approvalType;
+    }
+
+    public Long getApprovalUserId() {
+        return approvalUserId;
+    }
+
+    public void setApprovalUserId(Long approvalUserId) {
+        this.approvalUserId = approvalUserId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getNote() {
+        return note;
+    }
+
+    public void setNote(String note) {
+        this.note = note;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "ShenqianLog{" +
+        "id=" + id +
+        ", shenqianId=" + shenqianId +
+        ", orderNumber=" + orderNumber +
+        ", flowId=" + flowId +
+        ", nodeName=" + nodeName +
+        ", approvalType=" + approvalType +
+        ", approvalUserId=" + approvalUserId +
+        ", status=" + status +
+        ", createTime=" + createTime +
+        ", note=" + note +
+        "}";
+    }
+}

+ 365 - 0
database/src/main/java/com/qr/database/model/Standard.java

@@ -0,0 +1,365 @@
+package com.qr.database.model;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@TableName("QR_STANDARD")
+@KeySequence("QR_STANDARD_SEQ")
+public class Standard extends Model<Standard> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.INPUT)
+    private Long id;
+    /**
+     * 集团物品码
+     */
+    @Excel(name = "集团物品码")
+    @TableField("GROUP_ITEM_CODE")
+    private String groupItemCode;
+    /**
+     * 批次标记
+     */
+    @Excel(name = "图号")
+    @TableField("BATCH_MARKING")
+    private String batchMarking;
+    /**
+     * 年代
+     */
+    @Excel(name = "年代")
+    @TableField("YEAR")
+    private String year;
+    /**
+     * 物品名称
+     */
+    @Excel(name = "物品名称")
+    @TableField("NAME")
+    private String name;
+    /**
+     * 标准号
+     */
+    @Excel(name = "标准号")
+    @TableField("STANDARD_NUMBER")
+    private String standardNumber;
+    /**
+     * 规格
+     */
+    @Excel(name = "规格")
+    @TableField("SPECIFICATION")
+    private String specification;
+    /**
+     * 表面处理
+     */
+    @Excel(name = "表面处理")
+    @TableField("FINISH")
+    private String finish;
+    /**
+     * 材料
+     */
+    @Excel(name = "材料")
+    @TableField("MATERIALS")
+    private String materials;
+    /**
+     * 创建时间
+     */
+    @TableField("CREATE_TIME")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+    /**
+     * 二维码
+     */
+    @TableField("QR_DATA")
+    private String qrData;
+    /**
+     * 企业ID
+     */
+    @TableField("COMPANY_ID")
+    private Long companyId;
+    /**
+     * 生产单位
+     */
+    @TableField(exist = false)
+    private String unit;
+
+    @TableField(exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date startCreateTime;
+
+    @TableField(exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endCreateTime;
+    /**
+     * 1=鉴定报告,2=出厂报告,3=第三方尺寸复验报告,4=第三方性能报告,5=入厂尺寸复验报告,6=入厂性能复验报告,7=合格证
+     */
+    @TableField(exist = false)
+    private Integer fileType;
+    /**
+     * 1=完整,2=不完整
+     */
+    @TableField(exist = false)
+    private Integer isFull;
+    /**
+     * 1=产品,2=标准
+     */
+    @TableField(exist = false)
+    private Integer isStandard;
+
+    @TableField(exist = false)
+    private String createTimeRange;
+    /**
+     * 产品类型
+     * 1全部</
+     * 2紧固件<
+     * 3管内径<
+     * 4电线电缆
+     * 5电连接器
+     * 6金属材料
+     * 7锻、铸件
+     */
+    @TableField(exist = false)
+    private Integer productType;
+    /**
+     * 批号
+     */
+    @TableField(exist = false)
+    private String batchNo;
+    /**
+     * 投产批量
+     */
+    @TableField(exist = false)
+    private Long productionAmount;
+    /**
+     * 本次发货数量
+     */
+    @TableField(exist = false)
+    private Long shipmentsAmount;
+    @TableField(exist = false)
+    private Integer minCount;
+
+    public Integer getMinCount() {
+        return minCount;
+    }
+
+    public void setMinCount(Integer minCount) {
+        this.minCount = minCount;
+    }
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public Long getProductionAmount() {
+        return productionAmount;
+    }
+
+    public void setProductionAmount(Long productionAmount) {
+        this.productionAmount = productionAmount;
+    }
+
+    public Long getShipmentsAmount() {
+        return shipmentsAmount;
+    }
+
+    public void setShipmentsAmount(Long shipmentsAmount) {
+        this.shipmentsAmount = shipmentsAmount;
+    }
+
+    public Integer getProductType() {
+        return productType;
+    }
+
+    public void setProductType(Integer productType) {
+        this.productType = productType;
+    }
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public String getCreateTimeRange() {
+        return createTimeRange;
+    }
+
+    public void setCreateTimeRange(String createTimeRange) {
+        this.createTimeRange = createTimeRange;
+    }
+
+    public Integer getIsStandard() {
+        return isStandard;
+    }
+
+    public void setIsStandard(Integer isStandard) {
+        this.isStandard = isStandard;
+    }
+
+    public Integer getFileType() {
+        return fileType;
+    }
+
+    public void setFileType(Integer fileType) {
+        this.fileType = fileType;
+    }
+
+    public Integer getIsFull() {
+        return isFull;
+    }
+
+    public void setIsFull(Integer isFull) {
+        this.isFull = isFull;
+    }
+
+    public Date getStartCreateTime() {
+        return startCreateTime;
+    }
+
+    public void setStartCreateTime(Date startCreateTime) {
+        this.startCreateTime = startCreateTime;
+    }
+
+    public Date getEndCreateTime() {
+        return endCreateTime;
+    }
+
+    public void setEndCreateTime(Date endCreateTime) {
+        this.endCreateTime = endCreateTime;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getGroupItemCode() {
+        return groupItemCode;
+    }
+
+    public void setGroupItemCode(String groupItemCode) {
+        this.groupItemCode = groupItemCode;
+    }
+
+    public String getBatchMarking() {
+        return batchMarking;
+    }
+
+    public void setBatchMarking(String batchMarking) {
+        this.batchMarking = batchMarking;
+    }
+
+    public String getYear() {
+        return year;
+    }
+
+    public void setYear(String year) {
+        this.year = year;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStandardNumber() {
+        return standardNumber;
+    }
+
+    public void setStandardNumber(String standardNumber) {
+        this.standardNumber = standardNumber;
+    }
+
+    public String getSpecification() {
+        return specification;
+    }
+
+    public void setSpecification(String specification) {
+        this.specification = specification;
+    }
+
+    public String getFinish() {
+        return finish;
+    }
+
+    public void setFinish(String finish) {
+        this.finish = finish;
+    }
+
+    public String getMaterials() {
+        return materials;
+    }
+
+    public void setMaterials(String materials) {
+        this.materials = materials;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getQrData() {
+        return qrData;
+    }
+
+    public void setQrData(String qrData) {
+        this.qrData = qrData;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "Standard{" +
+        "id=" + id +
+        ", groupItemCode=" + groupItemCode +
+        ", batchMarking=" + batchMarking +
+        ", year=" + year +
+        ", name=" + name +
+        ", standardNumber=" + standardNumber +
+        ", specification=" + specification +
+        ", finish=" + finish +
+        ", materials=" + materials +
+        ", createTime=" + createTime +
+        ", qrData=" + qrData +
+        "}";
+    }
+}

+ 131 - 0
database/src/main/java/com/qr/database/model/Unit.java

@@ -0,0 +1,131 @@
+package com.qr.database.model;
+
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@TableName("QR_UNIT")
+public class Unit extends Model<Unit> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("ID")
+    private Long id;
+    /**
+     * 单位类型
+     */
+    @TableField("TYPE")
+    private String type;
+    /**
+     * 单位名称
+     */
+    @TableField("NAME")
+    private String name;
+    /**
+     * 单位地址
+     */
+    @TableField("ADDR")
+    private String addr;
+    /**
+     * 标志
+     */
+    @TableField("FLAG")
+    private String flag;
+    /**
+     * 承制单位代码
+     */
+    @TableField("UNIT_CODE")
+    private String unitCode;
+    /**
+     * 备注
+     */
+    @TableField("NOTE")
+    private String note;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getAddr() {
+        return addr;
+    }
+
+    public void setAddr(String addr) {
+        this.addr = addr;
+    }
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    public String getUnitCode() {
+        return unitCode;
+    }
+
+    public void setUnitCode(String unitCode) {
+        this.unitCode = unitCode;
+    }
+
+    public String getNote() {
+        return note;
+    }
+
+    public void setNote(String note) {
+        this.note = note;
+    }
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+    @Override
+    public String toString() {
+        return "Unit{" +
+        "id=" + id +
+        ", type=" + type +
+        ", name=" + name +
+        ", addr=" + addr +
+        ", flag=" + flag +
+        ", unitCode=" + unitCode +
+        ", note=" + note +
+        "}";
+    }
+}

+ 16 - 0
database/src/main/java/com/qr/database/service/IFlowNodeService.java

@@ -0,0 +1,16 @@
+package com.qr.database.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.FlowNode;
+
+/**
+ * <p>
+ * 二维码数据库流程节点表 服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface IFlowNodeService extends IService<FlowNode> {
+
+}

+ 23 - 0
database/src/main/java/com/qr/database/service/IFlowService.java

@@ -0,0 +1,23 @@
+package com.qr.database.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.Flow;
+import org.hibernate.validator.constraints.EAN;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 二维码数据库审签流程表 服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface IFlowService extends IService<Flow> {
+
+    public List<Flow> getFlow(Long flowId);
+
+    public Map<String, Object> getFlowSelect(Long flowId);
+}

+ 16 - 0
database/src/main/java/com/qr/database/service/INodeUserService.java

@@ -0,0 +1,16 @@
+package com.qr.database.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.NodeUser;
+
+/**
+ * <p>
+ * 节点审批人表 服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface INodeUserService extends IService<NodeUser> {
+
+}

+ 37 - 0
database/src/main/java/com/qr/database/service/IProductService.java

@@ -0,0 +1,37 @@
+package com.qr.database.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.Product;
+import com.qr.database.model.ProductExport;
+import com.qr.database.model.Standard;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface IProductService extends IService<Product> {
+
+    boolean add(Product next, Map<String, String> map);
+
+    boolean del(Product product, List<Integer> delDoc, Integer delType);
+
+    List<ProductExport> selectListByBatchNo(List<String> batchNo);
+
+    Product detail(String id);
+
+    Standard shenqianDoc(Long productId);
+
+    void shenqianErrUpdate(String originalFilename);
+
+    void delFile(Product product, List<Integer> delDoc);
+
+    Product ewmDetail(String unitCode, String groupItemCode, String no);
+}

+ 19 - 0
database/src/main/java/com/qr/database/service/IShenqianLogService.java

@@ -0,0 +1,19 @@
+package com.qr.database.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.ShenqianLog;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface IShenqianLogService extends IService<ShenqianLog> {
+
+    List<String> shenqianDocApprovalUser(Long shenqianId);
+}

+ 34 - 0
database/src/main/java/com/qr/database/service/IShenqianService.java

@@ -0,0 +1,34 @@
+package com.qr.database.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.Shenqian;
+import com.qr.database.tips.ReturnResult;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 审签 服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+public interface IShenqianService extends IService<Shenqian> {
+
+    boolean start(String batchNo, String note, String flowId, Long userId, Long companyId, String userName);
+
+    String getUserNameById(Long userId, Integer status);
+
+    List<Shenqian> listShenqian(Page<Shenqian> page, Shenqian shenqian);
+
+    ReturnResult restart(String id, String flowId, String note, Long userId, String userName);
+
+    Shenqian last(String id, Long userId, Long approvalUserId);
+
+    Shenqian next(String id, Long userId, Long approvalUserId);
+
+    void errUpdate(Shenqian s);
+}

+ 27 - 0
database/src/main/java/com/qr/database/service/IStandardService.java

@@ -0,0 +1,27 @@
+package com.qr.database.service;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.Product;
+import com.qr.database.model.Standard;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface IStandardService extends IService<Standard> {
+
+    List<Standard> list(Page<Standard> page, Standard standard);
+
+    boolean add(Standard next);
+
+    List<Standard> listProduct(Page<Product> page, Standard standard);
+}

+ 20 - 0
database/src/main/java/com/qr/database/service/IUnitService.java

@@ -0,0 +1,20 @@
+package com.qr.database.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qr.database.model.Unit;
+
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+public interface IUnitService extends IService<Unit> {
+
+    Map<String, String> flagAndUnitCode();
+}

+ 20 - 0
database/src/main/java/com/qr/database/service/impl/FlowNodeServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.FlowNodeMapper;
+import com.qr.database.model.FlowNode;
+import com.qr.database.service.IFlowNodeService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 二维码数据库流程节点表 服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@Service
+public class FlowNodeServiceImpl extends ServiceImpl<FlowNodeMapper, FlowNode> implements IFlowNodeService {
+
+}

+ 65 - 0
database/src/main/java/com/qr/database/service/impl/FlowServiceImpl.java

@@ -0,0 +1,65 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.FlowMapper;
+import com.qr.database.model.Flow;
+import com.qr.database.service.IFlowService;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * <p>
+ * 二维码数据库审签流程表 服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@Service
+public class FlowServiceImpl extends ServiceImpl<FlowMapper, Flow> implements IFlowService {
+
+    @Override
+    public List<Flow> getFlow(Long flowId) {
+        return this.baseMapper.getFlow(flowId);
+    }
+
+    @Override
+    public Map<String, Object> getFlowSelect(Long flowId) {
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        LinkedHashMap<String, String> select = new LinkedHashMap();
+        LinkedHashMap<String, Map<String, List<Flow>>> table = new LinkedHashMap();
+        List<Flow> flow = getFlow(flowId);
+        for (Flow f: flow) {
+            String flowId1 = String.valueOf(f.getFlowId());
+            select.put(flowId1, f.getFlowName());
+            Map<String, List<Flow>> o = table.get(flowId1);
+            String nodeName = f.getNodeName();
+            if (o == null) {
+                Map<String, List<Flow>> stringMapLinkedHashMap = new LinkedHashMap<>();
+                table.put(flowId1,stringMapLinkedHashMap);
+                List<Flow> stringObjectLinkedHashMap = new LinkedList<Flow>();
+                stringMapLinkedHashMap.put(nodeName,stringObjectLinkedHashMap);
+                stringObjectLinkedHashMap.add(f);
+            } else {
+                List<Flow> flows = o.get(nodeName);
+                if (flows == null) {
+                    flows = new LinkedList<Flow>();
+                    o.put(nodeName,flows);
+                }
+                flows.add(f);
+            }
+        }
+        stringObjectHashMap.put("select", select);
+        stringObjectHashMap.put("table", table);
+        return stringObjectHashMap;
+    }
+
+    public static void main(String[] args) {
+        LinkedHashMap linkedHashMap = new LinkedHashMap();
+        linkedHashMap.put("qwe","123");
+        linkedHashMap.put("qaz","edc");
+        linkedHashMap.put("qwe","123");
+        System.out.println(linkedHashMap);
+    }
+}

+ 20 - 0
database/src/main/java/com/qr/database/service/impl/NodeUserServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.NodeUserMapper;
+import com.qr.database.model.NodeUser;
+import com.qr.database.service.INodeUserService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 节点审批人表 服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@Service
+public class NodeUserServiceImpl extends ServiceImpl<NodeUserMapper, NodeUser> implements INodeUserService {
+
+}

+ 179 - 0
database/src/main/java/com/qr/database/service/impl/ProductServiceImpl.java

@@ -0,0 +1,179 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.dao.ProductMapper;
+import com.qr.database.dao.StandardMapper;
+import com.qr.database.model.Product;
+import com.qr.database.model.ProductExport;
+import com.qr.database.model.Standard;
+import com.qr.database.service.IProductService;
+import com.qr.database.utils.FileUtil;
+import com.qr.database.utils.qr.ImgQrTool;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.swing.plaf.TableHeaderUI;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@Service
+public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
+
+    private static String prefix = "D>"+ GlobalConstant.RS+"21"+GlobalConstant.GS+"M";
+    private static String suffix = GlobalConstant.RS+GlobalConstant.EOT;
+    private static Logger log = LoggerFactory.getLogger(ProductServiceImpl.class);
+
+    @Autowired
+    private StandardMapper standardMapper;
+
+    @Override
+    public boolean add(Product next, Map<String, String> map) {
+        try {
+            String batchNo = next.getBatchNo();
+            if (StringUtils.isBlank(batchNo)) {
+                return false;
+            }
+            Pattern compile = Pattern.compile(GlobalConstant.UNIT_FLAG);
+            Matcher matcher = compile.matcher(batchNo);
+            if (!matcher.find()) {
+                return false;
+            }
+            String group = matcher.group();
+            next.setFlag(group);
+            next.setNo(batchNo.replaceFirst(group,""));
+            String s = map.get(group);
+            if (s == null) {
+                return false;
+            }
+            Standard batch_marking = standardMapper.selectOne(new QueryWrapper<Standard>().eq("BATCH_MARKING", next.getBatchMarking()));
+            if (batch_marking == null) {
+                return false;
+            }
+            next.setQrData(ImgQrTool.createSimpleQr(prefix+ s +GlobalConstant.GS+"W"+batch_marking.getGroupItemCode()+GlobalConstant.GS+"S"+next.getNo()+suffix, 150,150));
+            return next.insert();
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return false;
+        }
+    }
+
+    @Override
+    @Transactional
+    public boolean del(Product product, List<Integer> delDoc, Integer delType) {
+        if (delType==2) {
+            Product product1 = new Product();
+            product1.setStatus(2);
+            product1.setId(product.getId());
+            if (product1.updateById()) {
+                delFile(product, delDoc);
+                shenqianErrUpdate(product.getBatchNo());
+                return true;
+            }
+            return false;
+        } else if (delType==1) {
+            if (delDoc == null || delDoc.size()==0) {
+                return true;
+            }
+            Product product1 = new Product();
+            product1.setId(product.getId());
+            boolean isUpdate = false;
+            for (Integer f:delDoc) {
+                if (f==1) {
+                    product1.setSurveyReport("");
+                    isUpdate = true;
+                } else if (f==2) {
+                    product1.setOutgoingReport("");
+                    isUpdate = true;
+                } else if (f==3) {
+                    product1.setThirdpartySizeReport("");
+                    isUpdate = true;
+                } else if (f==4) {
+                    product1.setThirdpartyPerReport("");
+                    isUpdate = true;
+                } else if (f==5) {
+                    product1.setIntoSizeReport("");
+                    isUpdate = true;
+                } else if (f==6) {
+                    product1.setIntoPerReport("");
+                    isUpdate = true;
+                } else if (f==7) {
+                    product1.setCertification("");
+                    isUpdate = true;
+                } else if (f==8) {
+                    product1.setSubCertification("");
+                    isUpdate = true;
+                }
+            }
+            if (isUpdate && product1.updateById()) {
+                delFile(product, delDoc);
+                shenqianErrUpdate(product.getBatchNo());
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<ProductExport> selectListByBatchNo(List<String> batchNo) {
+        return this.baseMapper.selectListByBatchNo(batchNo);
+    }
+
+    @Override
+    public Product detail(String id) {
+        return this.baseMapper.detail(id);
+    }
+
+    @Override
+    public Standard shenqianDoc(Long productId) {
+        return this.baseMapper.shenqianDoc(productId);
+    }
+
+    @Override
+    public void shenqianErrUpdate(String batchNo) {
+        this.baseMapper.shenqianErrUpdate(batchNo);
+    }
+
+    public void delFile(Product product, List<Integer> delDoc) {
+        for (Integer f:delDoc) {
+            if (f==1) {
+                FileUtil.deleteFile(product.getSurveyReport());
+            } else if (f==2) {
+                FileUtil.deleteFile(product.getOutgoingReport());
+            } else if (f==3) {
+                FileUtil.deleteFile(product.getThirdpartySizeReport());
+            } else if (f==4) {
+                FileUtil.deleteFile(product.getThirdpartyPerReport());
+            } else if (f==5) {
+                FileUtil.deleteFile(product.getIntoSizeReport());
+            } else if (f==6) {
+                FileUtil.deleteFile(product.getIntoPerReport());
+            } else if (f==7) {
+                FileUtil.deleteFile(product.getCertification());
+            } else if (f==8) {
+                FileUtil.deleteFile(product.getSubCertification());
+            }
+        }
+    }
+
+    @Override
+    public Product ewmDetail(String unitCode, String groupItemCode, String no) {
+        return this.baseMapper.ewmDetail(unitCode, groupItemCode, no);
+    }
+
+}

+ 26 - 0
database/src/main/java/com/qr/database/service/impl/ShenqianLogServiceImpl.java

@@ -0,0 +1,26 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.ShenqianLogMapper;
+import com.qr.database.model.ShenqianLog;
+import com.qr.database.service.IShenqianLogService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@Service
+public class ShenqianLogServiceImpl extends ServiceImpl<ShenqianLogMapper, ShenqianLog> implements IShenqianLogService {
+
+    @Override
+    public List<String> shenqianDocApprovalUser(Long shenqianId) {
+        return this.baseMapper.shenqianDocApprovalUser(shenqianId);
+    }
+}

+ 203 - 0
database/src/main/java/com/qr/database/service/impl/ShenqianServiceImpl.java

@@ -0,0 +1,203 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.ProductMapper;
+import com.qr.database.dao.ShenqianMapper;
+import com.qr.database.model.Flow;
+import com.qr.database.model.Product;
+import com.qr.database.model.Shenqian;
+import com.qr.database.model.ShenqianLog;
+import com.qr.database.service.IFlowService;
+import com.qr.database.service.IShenqianLogService;
+import com.qr.database.service.IShenqianService;
+import com.qr.database.tips.ReturnResult;
+import com.qr.database.utils.CommonUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * 审签 服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-08
+ */
+@Service
+public class ShenqianServiceImpl extends ServiceImpl<ShenqianMapper, Shenqian> implements IShenqianService {
+
+    @Autowired
+    private ProductMapper productMapper;
+    @Autowired
+    private IFlowService flowService;
+    @Autowired
+    private IShenqianLogService shenqianLogService;
+
+    @Override
+    @Transactional
+    public boolean start(String batchNo, String note, String flowId, Long userId, Long companyId, String userName) {
+        try {
+            Product product = productMapper.selectOne(new QueryWrapper<Product>().eq("BATCH_NO", batchNo));
+            if (product == null) {
+                return false;
+            }
+            List<Flow> flow = flowService.getFlow(Long.valueOf(flowId));
+            if (flow.size()<=0) {
+                return false;
+            }
+            Shenqian shenqian = new Shenqian();
+            shenqian.setProductId(product.getId());
+            shenqian.setFlowId(Long.valueOf(flowId));
+            shenqian.setOrderId(CommonUtil.getShenqianId());
+            shenqian.setCreateTime(new Date());
+            shenqian.setUserId(userId);
+            shenqian.setCompanyId(companyId);
+            shenqian.setStatus(1);
+            shenqian.setStep(1L);
+            shenqian.setFlag(1);
+            LinkedList<ShenqianLog> shenqianLogs = new LinkedList<>();
+            for (long i = 1; i <= flow.size(); i++) {
+                Flow flow1 = flow.get((int) (i - 1));
+                ShenqianLog shenqianLog = new ShenqianLog();
+                shenqianLog.setOrderNumber(i);
+                shenqianLog.setFlowId(Long.valueOf(flowId));
+                shenqianLog.setNodeName(flow1.getNodeName());
+                shenqianLog.setApprovalType(flow1.getApprovalType());
+                Long userId1 = flow1.getUserId();
+                if (userId1 == null) {
+                    return false;
+                }
+                if (i==1) {
+                    shenqian.setApprovalUserId(userId1);
+                }
+                shenqianLog.setApprovalUserId(userId1);
+                shenqianLog.setApprovalUserName(flow1.getNickname());
+                shenqianLogs.add(shenqianLog);
+            }
+            if (shenqian.insert()) {
+                for (ShenqianLog s: shenqianLogs) {
+                    s.setShenqianId(shenqian.getId());
+                }
+                ShenqianLog shenqianLog = new ShenqianLog();
+                shenqianLog.setOrderNumber(0l);
+                shenqianLog.setShenqianId(shenqian.getId());
+                shenqianLog.setFlowId(Long.valueOf(flowId));
+                shenqianLog.setNodeName("发起");
+                shenqianLog.setApprovalUserId(userId);
+                shenqianLog.setApprovalUserName(userName);
+                shenqianLog.setCreateTime(new Date());
+                shenqianLog.setStatus("发起审批");
+                shenqianLog.setNote(note);
+                shenqianLogs.addFirst(shenqianLog);
+                boolean b = shenqianLogService.saveBatch(shenqianLogs);
+                if (b) {
+                    return true;
+                }
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            }
+        } catch (Exception e) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+        }
+        return false;
+    }
+
+
+    @Override
+    public String getUserNameById(Long userId, Integer status) {
+        return this.baseMapper.getUserNameById(userId, status);
+    }
+
+    @Override
+    public List<Shenqian> listShenqian(Page<Shenqian> page, Shenqian shenqian) {
+        return this.baseMapper.listShenqian(page, shenqian);
+    }
+
+    @Override
+    @Transactional
+    public ReturnResult restart(String id, String flowId, String note, Long userId, String userName) {
+        Shenqian byId = this.getById(id);
+        if (byId != null) {
+            List<Flow> flow = flowService.getFlow(Long.valueOf(flowId));
+            if (flow.size()<=0) {
+                return ReturnResult.fail("流程不存在");
+            }
+            LinkedList<ShenqianLog> shenqianLogs = new LinkedList<>();
+            Iterator<Flow> iterator = flow.iterator();
+            long i = byId.getStep()+1;
+            Shenqian shenqian = new Shenqian();
+            shenqian.setStatus(1);
+            shenqian.setStep(i+1);
+            ShenqianLog shenqianLog1 = new ShenqianLog();
+            shenqianLog1.setOrderNumber(i);
+            shenqianLog1.setShenqianId(byId.getId());
+            shenqianLog1.setFlowId(Long.valueOf(flowId));
+            shenqianLog1.setNodeName("重新发起");
+            shenqianLog1.setApprovalUserId(userId);
+            shenqianLog1.setApprovalUserName(userName);
+            shenqianLog1.setCreateTime(new Date());
+            shenqianLog1.setStatus("重新发起审批");
+            shenqianLog1.setNote(note);
+            shenqianLogs.add(shenqianLog1);
+            while (iterator.hasNext()) {
+                Flow next = iterator.next();
+                if (i==byId.getStep()+1) {
+                    shenqian.setApprovalUserId(next.getUserId());
+                }
+                i++;
+                ShenqianLog shenqianLog = new ShenqianLog();
+                shenqianLog.setOrderNumber(i);
+                shenqianLog.setFlowId(Long.valueOf(flowId));
+                shenqianLog.setNodeName(next.getNodeName());
+                shenqianLog.setApprovalType(next.getApprovalType());
+                Long userId1 = next.getUserId();
+                if (userId1 == null) {
+                    return ReturnResult.fail("流程中审批人不存在");
+                }
+                shenqianLog.setApprovalUserId(userId1);
+                shenqianLog.setApprovalUserName(next.getNickname());
+                shenqianLog.setShenqianId(byId.getId());
+                shenqianLogs.add(shenqianLog);
+            }
+            boolean update = shenqian.update(new UpdateWrapper<Shenqian>().eq("ID", id).eq("FLAG",1).in("STATUS", 2, 3).eq("USER_ID", userId));
+            if (update) {
+                shenqianLogService.remove(new UpdateWrapper<ShenqianLog>().eq("SHENQIAN_ID", id).isNull("CREATE_TIME"));
+                shenqianLogService.saveBatch(shenqianLogs);
+                return ReturnResult.success();
+            }
+            return ReturnResult.fail("审签单状态不正确");
+        }
+        return ReturnResult.fail("审签单不存在");
+    }
+
+    @Override
+    public Shenqian last(String id, Long userId, Long approvalUserId) {
+        return this.baseMapper.last(id, userId, approvalUserId);
+    }
+
+    @Override
+    public Shenqian next(String id, Long userId, Long approvalUserId) {
+        return this.baseMapper.next(id, userId, approvalUserId);
+    }
+
+    @Override
+    public void errUpdate(Shenqian s) {
+        Shenqian shenqian = new Shenqian();
+        shenqian.setStatus(3);
+        boolean status1 = shenqian.update(new UpdateWrapper<Shenqian>().eq("STATUS", 1));
+        if (status1) {
+            ShenqianLog shenqianLog = new ShenqianLog();
+            shenqianLog.setStatus("异常");
+            shenqianLog.update(new UpdateWrapper<ShenqianLog>().eq("SHENQIAN_ID", s.getId()).eq("ORDER_NUMBER",s.getStep()).eq("APPROVAL_USER_ID", s.getApprovalUserId()));
+        }
+    }
+}

+ 57 - 0
database/src/main/java/com/qr/database/service/impl/StandardServiceImpl.java

@@ -0,0 +1,57 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.dao.StandardMapper;
+import com.qr.database.model.Product;
+import com.qr.database.model.Standard;
+import com.qr.database.service.IStandardService;
+import com.qr.database.utils.qr.ImgQrTool;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@Service
+public class StandardServiceImpl extends ServiceImpl<StandardMapper, Standard> implements IStandardService {
+
+    private static String prefix = "D>"+ GlobalConstant.RS+"21"+GlobalConstant.GS+"W";
+    private static String suffix = GlobalConstant.RS+GlobalConstant.EOT;
+
+    @Override
+    public List<Standard> list(Page<Standard> page, Standard standard) {
+        return this.baseMapper.list(page, standard);
+    }
+
+    @Override
+    public boolean add(Standard next) {
+        String groupItemCode = next.getGroupItemCode();
+        if (StringUtils.isBlank(groupItemCode)) {
+            return false;
+        }
+        Integer group_item_code = this.baseMapper.selectCount(new QueryWrapper<Standard>().eq("GROUP_ITEM_CODE", groupItemCode));
+        if (group_item_code>=1) {
+            return next.update(new UpdateWrapper<Standard>().eq("GROUP_ITEM_CODE", groupItemCode));
+        }
+        next.setQrData(ImgQrTool.createSimpleQr(prefix+ groupItemCode +suffix, 150,150));
+        return next.insert();
+    }
+
+    @Override
+    public List<Standard> listProduct(Page<Product> page, Standard standard) {
+        return this.baseMapper.listProduct(page, standard);
+    }
+}

+ 34 - 0
database/src/main/java/com/qr/database/service/impl/UnitServiceImpl.java

@@ -0,0 +1,34 @@
+package com.qr.database.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qr.database.dao.UnitMapper;
+import com.qr.database.model.Unit;
+import com.qr.database.service.IUnitService;
+import org.omg.PortableServer.THREAD_POLICY_ID;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author stylefeng123
+ * @since 2019-07-02
+ */
+@Service
+public class UnitServiceImpl extends ServiceImpl<UnitMapper, Unit> implements IUnitService {
+
+    @Override
+    public Map<String, String> flagAndUnitCode() {
+        List<Unit> list = this.list();
+        Map<String, String> stringStringHashMap = new HashMap<>();
+        for (Unit u:list) {
+            stringStringHashMap.put(u.getFlag(), u.getUnitCode());
+        }
+        return stringStringHashMap;
+    }
+}

+ 61 - 0
database/src/main/java/com/qr/database/tips/ReturnResult.java

@@ -0,0 +1,61 @@
+package com.qr.database.tips;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ReturnResult implements Serializable {
+    public static final int SUCCESS_STATUS = 200;
+    public static final int DEFAULT_FAIL_STATUS = 400;
+    public static final String SUCCESS_MSG = "success";
+
+    private Integer code = 400;
+    private String message = "客户端请求的参数错误";
+    /**
+     * 返回结果集
+     */
+    private Object data;
+
+    public ReturnResult() {}
+
+    public ReturnResult(Integer code, String message, Object data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public ReturnResult(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public static ReturnResult success(Object data) {
+        return new ReturnResult(SUCCESS_STATUS, SUCCESS_MSG, data);
+    }
+
+    public static ReturnResult success() {
+        return new ReturnResult(SUCCESS_STATUS, SUCCESS_MSG);
+    }
+
+    public static ReturnResult fail() {
+        return new ReturnResult();
+    }
+
+    public static ReturnResult fail(String msg) {
+        return new ReturnResult(DEFAULT_FAIL_STATUS, msg);
+    }
+
+    public static ReturnResult fail(Integer code, String msg) {
+        return new ReturnResult(code, msg);
+    }
+
+    @Override
+    public String toString() {
+        return "{" +
+                "\"code\":" + code +
+                ", \"message\":\"" + message +
+                "\", \"data\":\"" + data +
+                "\"}";
+    }
+}

+ 37 - 0
database/src/main/java/com/qr/database/tips/factory/AppPageFactory.java

@@ -0,0 +1,37 @@
+package com.qr.database.tips.factory;
+
+
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qr.database.utils.HttpKit;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+
+public class AppPageFactory<T> {
+
+    public Page<T> defaultPage() {
+        HttpServletRequest request = HttpKit.getRequest();
+        String offset = request.getParameter("page");
+        String limit = request.getParameter("pageSize");
+        String sort = request.getParameter("sort");
+        String order = request.getParameter("order");
+        if (StringUtils.isBlank(sort)) {
+            Page<T> page = new Page<>(StringUtils.isBlank(offset) ? 1:Integer.valueOf(offset), StringUtils.isBlank(limit) ? 15:Integer.valueOf(limit), true);
+            return page;
+        } else {
+            Page<T> page = new Page<>(StringUtils.isBlank(offset) ? 1:Integer.valueOf(offset), StringUtils.isBlank(limit) ? 15:Integer.valueOf(limit), true);
+            if ("asc".equalsIgnoreCase(order)) {
+                ArrayList<OrderItem> objects = new ArrayList<>();
+                objects.add(OrderItem.asc(sort));
+                page.setOrders(objects);
+            } else {
+                ArrayList<OrderItem> objects = new ArrayList<>();
+                objects.add(OrderItem.desc(sort));
+                page.setOrders(objects);
+            }
+            return page;
+        }
+    }
+}

+ 78 - 0
database/src/main/java/com/qr/database/utils/BeanUtils.java

@@ -0,0 +1,78 @@
+package com.qr.database.utils;
+
+import com.qr.database.model.ProductExport;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ *
+ * @author tomsonqiang
+ * @version 1.0.0 2018-05-25
+ * bean和map的转化
+ */
+
+public class BeanUtils {
+    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
+        if (map == null)
+            return null;
+        Object obj = beanClass.newInstance();
+        org.apache.commons.beanutils.BeanUtils.populate(obj, map);
+        return obj;
+    }
+
+    public static Map<?, ?> objectToMap(Object obj) {
+        if(obj == null)
+            return null;
+        return checkNull((Map)new org.apache.commons.beanutils.BeanMap(obj));
+    }
+
+    public static Map<String, Object> checkNull(Map<String, Object> maps) {
+        for (Map.Entry<String, Object> map : maps.entrySet()) {
+            if (map.getValue() == null) {
+                map.setValue(" ");
+            }
+        }
+        return maps;
+    }
+
+    public static Map<String, Object> convert2Map(Object bean) {
+        Class type = bean.getClass();
+        Map<String, Object> returnMap = new HashMap();
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(type);
+            PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
+            for (int i = 0; i< propertyDescriptors.length; i++) {
+                PropertyDescriptor descriptor = propertyDescriptors[i];
+                String propertyName = descriptor.getName();
+                if (!propertyName.equals("class")) {
+                    Method readMethod = descriptor.getReadMethod();
+                    Object result = readMethod.invoke(bean, new Object[0]);
+                    if (result != null) {
+                        returnMap.put(propertyName, result);
+                    } else {
+                        returnMap.put(propertyName, " ");
+                    }
+                }
+            }
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (IntrospectionException e) {
+            e.printStackTrace();
+        }
+        return returnMap;
+    }
+
+}

+ 31 - 0
database/src/main/java/com/qr/database/utils/CommonUtil.java

@@ -0,0 +1,31 @@
+package com.qr.database.utils;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+import java.util.UUID;
+
+public class CommonUtil {
+
+    public static String getUUID() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    /*将偶数替换成**/
+    public static String evenReplase(String str) {
+        StringBuilder builder = new StringBuilder();
+        int length = str.length();
+        for (int i = 0; i < length; i += 2) {
+            builder.append(str.charAt(i)).append("*");
+        }
+        builder.replace(length, length + 1, "");
+        return builder.toString();
+    }
+
+    public static String phoneHandle(String phone) {
+        return new StringBuilder(phone).replace(3, 7, "****").toString();
+    }
+
+    public static String getShenqianId() {
+        return "SQ" + System.currentTimeMillis() + RandomStringUtils.randomNumeric(3);
+    }
+}

+ 520 - 0
database/src/main/java/com/qr/database/utils/DateUtil.java

@@ -0,0 +1,520 @@
+/**
+ * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.qr.database.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class DateUtil {
+
+
+    /**
+     * 获取YYYY格式
+     *
+     * @return
+     */
+    public static String getYear() {
+        return formatDate(new Date(), "yyyy");
+    }
+
+    /**
+     * 获取YYYY格式
+     *
+     * @return
+     */
+    public static String getYear(Date date) {
+        return formatDate(date, "yyyy");
+    }
+
+    /**
+     * 获取YYYY-MM-DD格式
+     *
+     * @return
+     */
+    public static String getDay() {
+        return formatDate(new Date(), "yyyy-MM-dd");
+    }
+
+    /**
+     * 获取YYYY-MM-DD格式
+     *
+     * @return
+     */
+    public static String getDay(Date date) {
+        return formatDate(date, "dd");
+    }
+
+    /**
+     * 获取YYYYMMDD格式
+     *
+     * @return
+     */
+    public static String getDays() {
+        return formatDate(new Date(), "yyyyMMdd");
+    }
+
+    /**
+     * 获取yyyy-MMD格式
+     *
+     * @return
+     */
+    public static String getMonth(Date date) {
+        return formatDate(date, "MM");
+    }
+
+    /**
+     * 获取YYYYMMDD格式
+     *
+     * @return
+     */
+    public static String getDays(Date date) {
+        return formatDate(date, "yyyyMMdd");
+    }
+
+    /**
+     * 获取YYYY-MM-DD HH:mm:ss格式
+     *
+     * @return
+     */
+    public static String getTime() {
+        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
+    }
+
+    /**
+     * 获取YYYY-MM-DD HH:mm:ss.SSS格式
+     *
+     * @return
+     */
+    public static String getMsTime() {
+        return formatDate(new Date(), "yyyy-MM-dd HHmmss.SSS");
+    }
+
+    /**
+     * 获取YYYYMMDDHHmmss格式
+     *
+     * @return
+     */
+    public static String getAllTime() {
+        return formatDate(new Date(), "yyyyMMddHHmmss");
+    }
+
+    /**
+     * 获取YYYY-MM-DD HH:mm:ss格式
+     *
+     * @return
+     */
+    public static String getTime(Date date) {
+        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    public static String getChineseDay(Date date) {
+        return formatDate(date, "yyyy年MM月dd日");
+    }
+
+    public static String formatDate(Date date, String pattern) {
+        String formatDate = null;
+        if (StringUtils.isNotBlank(pattern)) {
+            formatDate = DateFormatUtils.format(date, pattern);
+        } else {
+            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
+        }
+        return formatDate;
+    }
+
+    /**
+     * @param s
+     * @param e
+     * @return boolean
+     * @throws
+     * @Title: compareDate
+     * @Description:(日期比较,如果s>=e 返回true 否则返回false)
+     * @author luguosui
+     */
+    public static boolean compareDate(String s, String e) {
+        if (parseDate(s) == null || parseDate(e) == null) {
+            return false;
+        }
+        return parseDate(s).getTime() >= parseDate(e).getTime();
+    }
+
+    /**
+     * 格式化日期
+     *
+     * @return
+     */
+    public static Date parseDate(String date) {
+        return parse(date, "yyyy-MM-dd");
+    }
+
+    /**
+     * 格式化日期
+     *
+     * @return
+     */
+    public static Date parseTime(String date) {
+        return parse(date, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    /**
+     * 格式化日期
+     *
+     * @return
+     */
+    public static Date parse(String date, String pattern) {
+        try {
+            return DateUtils.parseDate(date, pattern);
+        } catch (ParseException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 格式化日期
+     *
+     * @return
+     */
+    public static String format(Date date, String pattern) {
+        return DateFormatUtils.format(date, pattern);
+    }
+
+    /**
+     * 把日期转换为Timestamp
+     *
+     * @param date
+     * @return
+     */
+    public static Timestamp format(Date date) {
+        return new Timestamp(date.getTime());
+    }
+
+    /**
+     * 校验日期是否合法
+     *
+     * @return
+     */
+    public static boolean isValidDate(String s) {
+        return parse(s, "yyyy-MM-dd HH:mm:ss") != null;
+    }
+
+    /**
+     * 校验日期是否合法
+     *
+     * @return
+     */
+    public static boolean isValidDate(String s, String pattern) {
+        return parse(s, pattern) != null;
+    }
+
+    public static int getDiffYear(String startTime, String endTime) {
+        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
+                    startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
+            return years;
+        } catch (Exception e) {
+            // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
+            return 0;
+        }
+    }
+
+    /**
+     * <li>功能描述:时间相减得到天数
+     *
+     * @param beginDateStr
+     * @param endDateStr
+     * @return long
+     * @author Administrator
+     */
+    public static long getDaySub(String beginDateStr, String endDateStr) {
+        long day = 0;
+        SimpleDateFormat format = new SimpleDateFormat(
+                "yyyy-MM-dd");
+        Date beginDate = null;
+        Date endDate = null;
+
+        try {
+            beginDate = format.parse(beginDateStr);
+            endDate = format.parse(endDateStr);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
+        // System.out.println("相隔的天数="+day);
+
+        return day;
+    }
+
+    /**
+     * 得到n天之后的日期
+     *
+     * @param days
+     * @return
+     */
+    public static String getAfterDayDate(String days) {
+        int daysInt = Integer.parseInt(days);
+
+        Calendar canlendar = Calendar.getInstance(); // java.util包
+        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
+        Date date = canlendar.getTime();
+
+        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String dateStr = sdfd.format(date);
+
+        return dateStr;
+    }
+
+    /**
+     * 得到n天之后是周几
+     *
+     * @param days
+     * @return
+     */
+    public static String getAfterDayWeek(String days) {
+        int daysInt = Integer.parseInt(days);
+
+        Calendar canlendar = Calendar.getInstance(); // java.util包
+        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
+        Date date = canlendar.getTime();
+
+        SimpleDateFormat sdf = new SimpleDateFormat("E");
+        String dateStr = sdf.format(date);
+
+        return dateStr;
+    }
+
+    /**
+     * 更具开始时间分割月
+     *
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public static Map<String, Map<String, Date>> getMonthStartAndEndTime(Date startTime, Date endTime) {
+        Map<String, Map<String, Date>> stringMapHashMap = new LinkedHashMap<>();
+        Long parseStart = parse(getMonth(startTime), "yyyy-MM").getTime();
+        Long parseEnd = parse(getMonth(endTime), "yyyy-MM").getTime();
+        Long time = endTime.getTime();
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(parseStart);
+        int i = 1;
+        while (time >= (parseStart = cal.getTimeInMillis())) {
+            HashMap<String, Date> stringDateHashMap = new HashMap<>();
+            if (i == 1) {
+                stringDateHashMap.put("startTime", startTime);
+            } else {
+                stringDateHashMap.put("startTime", cal.getTime());
+            }
+            cal.add(Calendar.MONTH, 1);
+            cal.add(Calendar.DATE, -1);
+            if (parseEnd.equals(parseStart)) {
+                stringDateHashMap.put("endTime", endTime);
+            } else {
+                stringDateHashMap.put("endTime", cal.getTime());
+            }
+            cal.add(Calendar.DATE, 1);
+            stringMapHashMap.put(getMonth(new Date(parseStart)), stringDateHashMap);
+            i++;
+        }
+        return stringMapHashMap;
+    }
+
+    /**
+     * 更具开始时间分割周
+     *
+     * @return
+     */
+    public static Map<String, Map<String, Date>> getWeekStartAndEndTime(Date startTime, Date endTime) {
+        Calendar cal = Calendar.getInstance();
+        cal.setFirstDayOfWeek(Calendar.MONDAY);
+        cal.setTime(startTime);
+        int start = cal.get(Calendar.WEEK_OF_YEAR);
+        cal.setTime(endTime);
+        int end = cal.get(Calendar.WEEK_OF_YEAR);
+        Map<String, Map<String, Date>> stringMapHashMap = new LinkedHashMap<>();
+        SimpleDateFormat simple = new SimpleDateFormat("yyyy-");
+        for (int i = start; i <= end; i++) {
+            cal.set(Calendar.WEEK_OF_YEAR, i);
+            String format = simple.format(cal.getTime()) + (i <= 9 ? "0" + i : i);
+            HashMap<String, Date> stringDateHashMap = new HashMap<>();
+            if (start == i) {
+                if (start == end) {
+                    stringDateHashMap.put("startTime", startTime);
+                    stringDateHashMap.put("endTime", endTime);
+                } else {
+                    stringDateHashMap.put("startTime", startTime);
+                    cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+                    stringDateHashMap.put("endTime", cal.getTime());
+                }
+            } else if (end == i) {
+                cal.set(Calendar.DAY_OF_WEEK, Calendar.MONTH);
+                stringDateHashMap.put("startTime", cal.getTime());
+                stringDateHashMap.put("endTime", endTime);
+            } else {
+                cal.set(Calendar.DAY_OF_WEEK, Calendar.MONTH);
+                stringDateHashMap.put("startTime", cal.getTime());
+                cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+                stringDateHashMap.put("endTime", cal.getTime());
+            }
+            stringMapHashMap.put(format, stringDateHashMap);
+        }
+        return stringMapHashMap;
+    }
+
+    /**
+     * 更具开始时间分割日
+     *
+     * @return
+     */
+    public static Map<String, Map<String, Date>> getDayStartAndEndTime(Date startTime, Date endTime) {
+        Map<String, Map<String, Date>> stringMapHashMap = new LinkedHashMap<>();
+        Integer dayMun = getDayMun(startTime, endTime);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(startTime);
+        for (int i = 0; i < dayMun; i++) {
+            HashMap<String, Date> stringDateHashMap = new HashMap<>();
+            if (i == 0) {
+                stringDateHashMap.put("startTime", startTime);
+            } else {
+                cal.add(Calendar.SECOND, 1);
+                stringDateHashMap.put("startTime", cal.getTime());
+            }
+            if (i == (dayMun - 1)) {
+                stringDateHashMap.put("endTime", endTime);
+            } else {
+                cal.set(Calendar.HOUR_OF_DAY, 23);
+                cal.set(Calendar.MINUTE, 59);
+                cal.set(Calendar.SECOND, 59);
+                stringDateHashMap.put("endTime", cal.getTime());
+            }
+            stringMapHashMap.put(getDay(cal.getTime()), stringDateHashMap);
+        }
+        return stringMapHashMap;
+    }
+
+    /**
+     * 获取开始时间到结束时间的天数
+     *
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public static Integer getDayMun(Date startTime, Date endTime) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            startTime = sdf.parse(sdf.format(startTime));
+            endTime = sdf.parse(sdf.format(endTime));
+        } catch (ParseException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        long days = (endTime.getTime() - startTime.getTime()) / (1000 * 3600 * 24);
+        return (int) days + 1;
+    }
+
+    /**
+     * 获取 yyyy-ww
+     *
+     * @param startTime
+     * @return
+     */
+    public static String getWeek(Date startTime) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(startTime);
+        cal.setFirstDayOfWeek(Calendar.MONDAY);
+        int weekYear = cal.get(Calendar.WEEK_OF_YEAR);
+        return cal.get(Calendar.YEAR) + "-" + (weekYear <= 9 ? "0" + weekYear : weekYear);
+    }
+
+    public static List<String> getFiveYear() {
+        List<String> list = new ArrayList<>();
+        String year = getYear();
+        list.add(year);
+        Integer integer = Integer.valueOf(year);
+        for (int i = 1; i < 6; i++) {
+            list.add(String.valueOf(integer-i));
+        }
+        return list;
+    }
+
+    public static Map<String,String> startEndToDay() throws ParseException {
+        Map<String,String> map = new HashMap<>();
+        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
+        Calendar calendar = Calendar.getInstance();
+        calendar.setFirstDayOfWeek(Calendar.MONDAY);
+        calendar.add(Calendar.DAY_OF_WEEK, -1);
+        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        map.put("startDay", sf.format(calendar.getTime()));
+        calendar.add(Calendar.DAY_OF_WEEK, 6);
+        map.put("endDay", sf.format(calendar.getTime()));
+        return map;
+    }
+
+    public static Map<String,Object> getLastWeekTime() {
+        Map<String,Object> map = new HashMap<>();
+        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
+        Calendar calendar = Calendar.getInstance();
+        calendar.setFirstDayOfWeek(Calendar.MONDAY);
+        calendar.add(Calendar.WEEK_OF_YEAR, -1);
+        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        int i = calendar.get(Calendar.WEEK_OF_YEAR);
+        map.put("week", i);
+        map.put("weekTime", calendar.get(Calendar.YEAR)+"-"+(i<=9?"0"+i:i));
+        map.put("startDay", calendar.get(Calendar.DAY_OF_MONTH));
+        map.put("startMonth", calendar.get(Calendar.MONTH)+1);
+        map.put("startTime", sf.format(calendar.getTime()));
+        calendar.add(Calendar.DAY_OF_WEEK, 6);
+        map.put("year", calendar.get(Calendar.YEAR));
+        map.put("endDay", calendar.get(Calendar.DAY_OF_MONTH));
+        map.put("endMonth", calendar.get(Calendar.MONTH)+1);
+        map.put("endTime", sf.format(calendar.getTime()));
+        return map;
+    }
+
+    public static Map<? extends String, ?> getLastMonthTime() throws ParseException {
+        Map<String,Object> map = new HashMap<>();
+        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
+        SimpleDateFormat sfm=new SimpleDateFormat("yyyy-MM");
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.MONTH, -1);
+        calendar.set(Calendar.DAY_OF_MONTH,1);
+        map.put("startTime", sf.format(calendar.getTime()));
+        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+        map.put("year", calendar.get(Calendar.YEAR));
+        map.put("endDay", calendar.get(Calendar.DAY_OF_MONTH));
+        map.put("endMonth", calendar.get(Calendar.MONTH)+1);
+        map.put("endTime", sf.format(calendar.getTime()));
+        map.put("monthTime", sfm.format(calendar.getTime()));
+        calendar.add(Calendar.MONTH, -1);
+        map.put("onMonthTime", sfm.format(calendar.getTime()));
+        calendar.add(Calendar.MONTH, 1);
+        calendar.add(Calendar.YEAR, -1);
+        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+        map.put("oldYear", calendar.get(Calendar.YEAR));
+        map.put("oldMonth", calendar.get(Calendar.MONTH)+1);
+        map.put("oldDay", calendar.get(Calendar.DAY_OF_MONTH));
+        map.put("oldTime", sf.format(calendar.getTime()));
+        map.put("oldMonthTime", sfm.format(calendar.getTime()));
+        return map;
+    }
+
+}

+ 55 - 0
database/src/main/java/com/qr/database/utils/DocUtils.java

@@ -0,0 +1,55 @@
+package com.qr.database.utils;
+
+import com.aspose.words.Document;
+import com.aspose.words.License;
+import com.aspose.words.SaveFormat;
+import com.qr.database.config.FreemarkerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+
+public class DocUtils {
+
+    private static Logger log = LoggerFactory.getLogger(DocUtils.class);
+
+    static {
+        try {
+            ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            InputStream license = new FileInputStream(loader.getResource("license.xml").getPath());
+            License aposeLic = new License();
+            aposeLic.setLicense(license);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    public static byte [] docToPdf(String fileInput) {
+        Document doc = null;
+        ByteArrayOutputStream byteArrayOutputStream = null;
+        try {
+            doc = new Document(fileInput);
+            byteArrayOutputStream = new ByteArrayOutputStream();
+            doc.save(byteArrayOutputStream, SaveFormat.PDF);
+            return byteArrayOutputStream.toByteArray();
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (byteArrayOutputStream !=null) {
+                try {
+                    byteArrayOutputStream.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+            if (doc != null) {
+                try {
+                    doc.deepClone();
+                } catch (Exception e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        return new byte[]{};
+    }
+}

+ 51 - 0
database/src/main/java/com/qr/database/utils/DocumentUtil.java

@@ -0,0 +1,51 @@
+package com.qr.database.utils;
+
+import cn.afterturn.easypoi.word.WordExportUtil;
+import com.qr.database.config.properties.GlobalProperties;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+
+public class DocumentUtil {
+    private static final Logger log = LoggerFactory.getLogger(DocumentUtil.class);
+
+    public static boolean export(Map<String, Object> map, String name) {
+        Object fileName = map.get("fileName");
+        if (fileName != null) {
+            XWPFDocument xwpfDocument = null;
+            FileOutputStream fileOutputStream = null;
+            try {
+                xwpfDocument = WordExportUtil.exportWord07(GlobalProperties.getFileUploadPath() + "export" + File.separator + name, map);
+                if (xwpfDocument != null) {
+                    fileOutputStream = new FileOutputStream(GlobalProperties.getFileUploadPath() + fileName);
+                    xwpfDocument.write(fileOutputStream);
+                    return true;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            } finally {
+                if (fileOutputStream != null) {
+                    try {
+                        fileOutputStream.close();
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                    }
+                }
+                if (xwpfDocument != null) {
+                    try {
+                        xwpfDocument.close();
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+}

+ 43 - 0
database/src/main/java/com/qr/database/utils/ExcelUtil.java

@@ -0,0 +1,43 @@
+package com.qr.database.utils;
+
+import cn.afterturn.easypoi.excel.ExcelImportUtil;
+import cn.afterturn.easypoi.excel.entity.ImportParams;
+import org.apache.poi.util.IOUtils;
+
+import java.io.InputStream;
+import java.util.List;
+
+public class ExcelUtil {
+
+    /**
+     * 导入
+     * @param inputStream
+     * @param entity
+     * @param params
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public static <T> List<T> imports(InputStream inputStream, Class<T> entity, ImportParams params) throws Exception {
+        List<T> objects = null;
+        try{
+            objects = ExcelImportUtil.importExcel(inputStream, entity, params);
+        } finally {
+            IOUtils.closeQuietly(inputStream);
+        }
+        return objects;
+    }
+
+    /**
+     * 导入
+     * @param inputStream
+     * @param entity
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public static <T> List<T> imports(InputStream inputStream, Class<T> entity) throws Exception {
+        return imports(inputStream, entity, new ImportParams());
+    }
+
+}

+ 122 - 0
database/src/main/java/com/qr/database/utils/ExportExcelUtil.java

@@ -0,0 +1,122 @@
+package com.qr.database.utils;
+
+import cn.afterturn.easypoi.entity.vo.TemplateExcelConstants;
+import cn.afterturn.easypoi.excel.ExcelExportUtil;
+import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
+import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
+import cn.afterturn.easypoi.word.WordExportUtil;
+import com.qr.database.config.properties.GlobalProperties;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.ui.ModelMap;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class ExportExcelUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(ExportExcelUtil.class);
+
+    public static String export(ModelMap modelMap, String templateFileName, String exportFileName, Map<String, Object> map) {
+        TemplateExportParams params = new TemplateExportParams(gh(templateFileName), true);
+        modelMap.put(TemplateExcelConstants.FILE_NAME, exportFileName);
+        modelMap.put(TemplateExcelConstants.PARAMS, params);
+        modelMap.put(TemplateExcelConstants.MAP_DATA, map);
+        return TemplateExcelConstants.EASYPOI_TEMPLATE_EXCEL_VIEW;
+    }
+
+    private static String gh(String fileName) {
+        return GlobalProperties.getFileUploadPath() + "export" + File.separator + fileName;
+    }
+
+    public static boolean export(Map<String, Object> map, String name) {
+        Object fileName = map.get("fileName");
+        if (fileName != null) {
+            Workbook xwpfDocument = null;
+            FileOutputStream fileOutputStream = null;
+            try {
+                TemplateExportParams params = new TemplateExportParams(gh(name), true);
+                xwpfDocument = ExcelExportUtil.exportExcel(params, map);
+                if (xwpfDocument != null) {
+                    fileOutputStream = new FileOutputStream(GlobalProperties.getFileUploadPath() + fileName);
+                    xwpfDocument.write(fileOutputStream);
+                    return true;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            } finally {
+                if (fileOutputStream != null) {
+                    try {
+                        fileOutputStream.close();
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                    }
+                }
+                if (xwpfDocument != null) {
+                    try {
+                        xwpfDocument.close();
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean export(Map<String, Object> map, String name,OutputStream outputStream) {
+        Workbook xwpfDocument = null;
+        try {
+            TemplateExportParams params = new TemplateExportParams(gh(name), true);
+            xwpfDocument = ExcelExportUtil.exportExcel(params, map);
+            if (xwpfDocument != null) {
+                xwpfDocument.write(outputStream);
+                return true;
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (xwpfDocument != null) {
+                try {
+                    xwpfDocument.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean exportDocx(Map<String, Object> map, String name,OutputStream outputStream) {
+        XWPFDocument xwpfDocument = null;
+        try {
+            System.out.println(map);
+            xwpfDocument = WordExportUtil.exportWord07(GlobalProperties.getFileUploadPath() + "export" + File.separator + name, map);
+            if (xwpfDocument != null) {
+                xwpfDocument.write(outputStream);
+                return true;
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (xwpfDocument != null) {
+                try {
+                    xwpfDocument.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        return false;
+    }
+}

+ 105 - 0
database/src/main/java/com/qr/database/utils/FileUtil.java

@@ -0,0 +1,105 @@
+package com.qr.database.utils;
+
+import com.qr.database.config.properties.GlobalProperties;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+public class FileUtil {
+
+    private static Logger log = LoggerFactory.getLogger(FileUtil.class);
+
+    /**
+     * NIO way
+     */
+    public static byte[] toByteArray(String filename) {
+
+        File f = new File(filename);
+        if (!f.exists()) {
+            log.error("文件未找到!" + filename);
+            throw new RuntimeException("文件未找到!");
+        }
+        FileChannel channel = null;
+        FileInputStream fs = null;
+        try {
+            fs = new FileInputStream(f);
+            channel = fs.getChannel();
+            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
+            while ((channel.read(byteBuffer)) > 0) {
+                // do nothing
+                // System.out.println("reading");
+            }
+            return byteBuffer.array();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                channel.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+            try {
+                fs.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * 删除目录
+     *
+     * @author harry
+     * @Date 2017/10/30 下午4:15
+     */
+    public static boolean deleteDir(File dir) {
+        if (dir.isDirectory()) {
+            String[] children = dir.list();
+            for (int i = 0; i < children.length; i++) {
+                boolean success = deleteDir(new File(dir, children[i]));
+                if (!success) {
+                    return false;
+                }
+            }
+        }
+        return dir.delete();
+    }
+
+    public static boolean deleteFile(String filePath) {
+        if (StringUtils.isNotBlank(filePath)) {
+            return deleteDir(new File(GlobalProperties.getFileUploadPath()+filePath));
+        }
+        return false;
+    }
+
+    /**
+     * 上传文件
+     *
+     * @param picture
+     * @param fileSavePath
+     */
+    public static String upload(MultipartFile picture, String fileSavePath, String fileName) {
+        File file = new File(fileSavePath);
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        File file1 = new File(file, fileName);
+//        if (file1.exists()) {
+//            return "";
+//        }
+        try {
+            picture.transferTo(file1);
+        } catch (IOException e) {
+            log.error(e.getMessage(),e);
+            return null;
+        }
+        return fileName;
+    }
+}

+ 195 - 0
database/src/main/java/com/qr/database/utils/HttpKit.java

@@ -0,0 +1,195 @@
+/**
+ * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.qr.database.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HttpKit {
+
+    public static String getIp(){
+       return HttpKit.getRequest().getRemoteHost();
+    }
+
+    /**
+     * 获取所有请求的值
+     */
+    public static Map<String, String> getRequestParameters() {
+        HashMap<String, String> values = new HashMap<>();
+        HttpServletRequest request = HttpKit.getRequest();
+        Enumeration enums = request.getParameterNames();
+        while ( enums.hasMoreElements()){
+            String paramName = (String) enums.nextElement();
+            String paramValue = request.getParameter(paramName);
+            values.put(paramName, paramValue);
+        }
+        return values;
+    }
+
+    /**
+     * 获取 HttpServletRequest
+     */
+    public static HttpServletResponse getResponse() {
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        return response;
+    }
+
+    /**
+     * 获取 包装防Xss Sql注入的 HttpServletRequest
+     * @return request
+     */
+    public static HttpServletRequest getRequest() {
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        return new WafRequestWrapper(request);
+    }
+
+    /**
+     * 向指定URL发送GET方法的请求
+     *
+     * @param url 发送请求的URL
+     * @param param 请求参数
+     * @return URL 所代表远程资源的响应结果
+     */
+    public static String sendGet(String url, Map<String, String> param) {
+        String result = "";
+        BufferedReader in = null;
+        try {
+            StringBuffer query = new StringBuffer();
+
+            for (Map.Entry<String, String> kv : param.entrySet()) {
+                query.append(URLEncoder.encode(kv.getKey(), "UTF-8") + "=");
+                query.append(URLEncoder.encode(kv.getValue(), "UTF-8") + "&");
+            }
+            if (query.lastIndexOf("&") > 0) {
+                query.deleteCharAt(query.length() - 1);
+            }
+
+            String urlNameString = url + "?" + query.toString();
+            URL realUrl = new URL(urlNameString);
+            // 打开和URL之间的连接
+            URLConnection connection = realUrl.openConnection();
+            // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-file", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 建立实际的连接
+            connection.connect();
+            // 获取所有响应头字段
+            Map<String, List<String>> map = connection.getHeaderFields();
+            // 遍历所有的响应头字段
+            for (String key : map.keySet()) {
+                System.out.println(key + "--->" + map.get(key));
+            }
+            // 定义 BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            System.out.println("发送GET请求出现异常!" + e);
+            e.printStackTrace();
+        }
+        // 使用finally块来关闭输入流
+        finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (Exception e2) {
+                e2.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求
+     *
+     * @param url 发送请求的 URL
+     * @param param  请求参数
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendPost(String url, Map<String, String> param) {
+        PrintWriter out = null;
+        BufferedReader in = null;
+        String result = "";
+        try {
+            String para = "";
+            for (String key : param.keySet()) {
+                para += (key + "=" + param.get(key) + "&");
+            }
+            if (para.lastIndexOf("&") > 0) {
+                para = para.substring(0, para.length() - 1);
+            }
+            String urlNameString = url + "?" + para;
+            URL realUrl = new URL(urlNameString);
+            // 打开和URL之间的连接
+            URLConnection conn = realUrl.openConnection();
+            // 设置通用的请求属性
+            conn.setRequestProperty("accept", "*/*");
+            conn.setRequestProperty("connection", "Keep-Alive");
+            conn.setRequestProperty("user-file", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 发送POST请求必须设置如下两行
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            // 获取URLConnection对象对应的输出流
+            out = new PrintWriter(conn.getOutputStream());
+            // 发送请求参数
+            out.print(param);
+            // flush输出流的缓冲
+            out.flush();
+            // 定义BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            System.out.println("发送 POST 请求出现异常!" + e);
+            e.printStackTrace();
+        }
+        // 使用finally块来关闭输出流、输入流
+        finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+}

+ 90 - 0
database/src/main/java/com/qr/database/utils/PdfUtils.java

@@ -0,0 +1,90 @@
+package com.qr.database.utils;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.ImageType;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.misc.BASE64Encoder;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PdfUtils {
+
+    private static Logger log = LoggerFactory.getLogger(PdfUtils.class);
+
+    public static List<String> toImg(String pdfFilePath) {
+        try {
+            PDDocument doc = PDDocument.load(new File(pdfFilePath));
+            return toImg(doc);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return new ArrayList<String>(0);
+    }
+
+    public static List<String> toImg(byte [] data) {
+        try {
+            PDDocument doc = PDDocument.load(data);
+            return toImg(doc);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return new ArrayList<String>(1);
+    }
+
+    private static List<String> toImg(PDDocument doc) {
+        List<String> strings = null;
+        try {
+            int pageCount = doc.getNumberOfPages();
+            PDFRenderer pdfRenderer = new PDFRenderer(doc);
+            BASE64Encoder encoder = new BASE64Encoder();
+            strings = new ArrayList<>(pageCount);
+            for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
+                BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 85, ImageType.RGB);
+                ByteArrayOutputStream baos = null;
+                try {
+                    baos = new ByteArrayOutputStream();//io流
+                    ImageIO.write(image, "png", baos);//写入流中
+                    byte[] bytes = baos.toByteArray();//转换成字节
+                    String png_base64 =  encoder.encodeBuffer(bytes).trim();//转换成base64串
+                    png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
+                    strings.add(png_base64);
+                } catch (Exception e) {
+                    log.error(e.getMessage(), e);
+                } finally {
+                    if (baos != null) {
+                        baos.close();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (doc != null) {
+                try {
+                    doc.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        return strings;
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        List<String> strings = toImg("C:\\Users\\hasee\\Documents\\WeChat Files\\li1210451792\\FileStorage\\File\\2019-07\\滴滴出行行程报销单_201907052050581.pdf");
+        for (String s:strings) {
+            System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+            Thread.sleep(1000);
+            System.out.println(s);
+        }
+        System.out.println(strings.size());
+    }
+}

+ 242 - 0
database/src/main/java/com/qr/database/utils/PreviewUtil.java

@@ -0,0 +1,242 @@
+package com.qr.database.utils;
+
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.model.Product;
+import com.qr.database.tips.ReturnResult;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class PreviewUtil extends Thread {
+    private static Logger log = LoggerFactory.getLogger(PreviewUtil.class);
+    private String id;
+    private Product product;
+    private Integer docType;
+
+    public PreviewUtil(String id, Product product, Integer docType) {
+        super();
+        this.id = id;
+        this.product = product;
+        this.docType = docType;
+    }
+
+    @Override
+    public void run() {
+        try {
+            LinkedHashMap<String, Map<String, Object>> stringObjectHashMap = new LinkedHashMap<>();
+            String surveyReport = product.getSurveyReport();
+            if (StringUtils.isNotBlank(surveyReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——鉴定报告:" + surveyReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "2"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(surveyReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + surveyReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + surveyReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "8"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", surveyReport);
+                if (docType == 1) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "13"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String outgoingReport = product.getOutgoingReport();
+            if (StringUtils.isNotBlank(outgoingReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——出厂报告:" + outgoingReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "14"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(outgoingReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + outgoingReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + outgoingReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "20"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", outgoingReport);
+                if (docType == 2) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "25"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String thirdpartySizeReport = product.getThirdpartySizeReport();
+            if (StringUtils.isNotBlank(thirdpartySizeReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——第三方尺寸复验报告:" + thirdpartySizeReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "26"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(thirdpartySizeReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + thirdpartySizeReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + thirdpartySizeReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "32"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", thirdpartySizeReport);
+                if (docType == 3) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "37"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String thirdpartyPerReport = product.getThirdpartyPerReport();
+            if (StringUtils.isNotBlank(thirdpartyPerReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——第三方性能报告:" + thirdpartyPerReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "38"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(thirdpartyPerReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + thirdpartyPerReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + thirdpartyPerReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "43"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", thirdpartyPerReport);
+                if (docType == 4) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "49"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String intoSizeReport = product.getIntoSizeReport();
+            if (StringUtils.isNotBlank(intoSizeReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——入厂尺寸复验报告:" + intoSizeReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "50"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(intoSizeReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + intoSizeReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + intoSizeReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "56"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", intoSizeReport);
+                if (docType == 5) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "61"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String intoPerReport = product.getIntoPerReport();
+            if (StringUtils.isNotBlank(intoPerReport)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——入厂性能复验报告:" + intoPerReport.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "62"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(intoPerReport)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + intoPerReport));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + intoPerReport);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "68"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", intoPerReport);
+                if (docType == 6) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "73"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String certification = product.getCertification();
+            if (StringUtils.isNotBlank(certification)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——合格证:" + certification.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "74"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(certification)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + certification));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + certification);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "80"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", certification);
+                if (docType == 7) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "85"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            String subCertification = product.getSubCertification();
+            if (StringUtils.isNotBlank(subCertification)) {
+                HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+                stringObjectHashMap.put(product.getBatchNo() + "——子合格证:" + subCertification.substring(11), stringObjectHashMap1);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "86"), 8, TimeUnit.MINUTES)) {
+                    return;
+                }
+                if (isPdf(subCertification)) {
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + subCertification));
+                } else {
+                    byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + subCertification);
+                    if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "92"), 8, TimeUnit.MINUTES)) {
+                        return;
+                    }
+                    stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+                }
+                stringObjectHashMap1.put("download", subCertification);
+                if (docType == 8) {
+                    stringObjectHashMap1.put("activate", true);
+                }
+            }
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "97"), 8, TimeUnit.MINUTES)) {
+                return;
+            }
+            RedisUtils.set(GlobalConstant.PREVIEW_FINISH + id, stringObjectHashMap, 5, TimeUnit.MINUTES);
+            RedisUtils.setIfPresent(id, new ReturnResult(200, "100", GlobalConstant.PREVIEW_FINISH + id), 4, TimeUnit.MINUTES);
+        } catch (Exception e) {
+            log.warn(e.getMessage(), e);
+            RedisUtils.setIfPresent(id, new ReturnResult(400, "生成预览失败,请稍后再试"), 4, TimeUnit.MINUTES);
+        }
+    }
+
+    public static boolean isPdf(String pdfFilePath) {
+        if (pdfFilePath.lastIndexOf(".") <= 0) {
+            return false;
+        }
+        if ("pdf".equalsIgnoreCase(pdfFilePath.substring(pdfFilePath.lastIndexOf(".") + 1))) {
+            return true;
+        }
+        return false;
+    }
+}

+ 32 - 0
database/src/main/java/com/qr/database/utils/RedisUtils.java

@@ -0,0 +1,32 @@
+package com.qr.database.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class RedisUtils {
+
+    private static RedisTemplate<String, Object> redisTemplate;
+
+    @Autowired
+    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
+        RedisUtils.redisTemplate = redisTemplate;
+    }
+
+    public static boolean setIfPresent(String k, Object v, long var3, TimeUnit var5) {
+//        Object o = redisTemplate.opsForValue().get(k);
+//        if (o != null) {
+//            redisTemplate.opsForValue().set(k,v, var3, var5);
+//            return true;
+//        }
+//        return false;
+        return redisTemplate.opsForValue().setIfPresent(k, v, var3, var5);
+    }
+
+    public static void set(String k, Object v, long var3, TimeUnit var5) {
+        redisTemplate.opsForValue().set(k, v, var3, var5);
+    }
+}

+ 256 - 0
database/src/main/java/com/qr/database/utils/ShenQianPreviewUtil.java

@@ -0,0 +1,256 @@
+package com.qr.database.utils;
+
+import com.qr.database.config.GlobalConstant;
+import com.qr.database.config.properties.GlobalProperties;
+import com.qr.database.model.Product;
+import com.qr.database.model.Shenqian;
+import com.qr.database.tips.ReturnResult;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class ShenQianPreviewUtil extends Thread {
+
+    private String id;
+    private Map<String, Object> shenqian;
+    private Product product;
+    private Integer docType;
+
+    public ShenQianPreviewUtil(String id, Map<String, Object> shenqian, Product product, Integer docType) {
+        super();
+        this.id = id;
+        this.shenqian = shenqian;
+        this.product = product;
+        this.docType = docType;
+    }
+
+    @Override
+    public void run() {
+        if (product==null) {
+            RedisUtils.setIfPresent(id, new ReturnResult(400, "数据不存在"), 8, TimeUnit.MINUTES);
+            return;
+        }
+        LinkedHashMap<String, Object> stringObjectHashMap = new LinkedHashMap<>();
+        String surveyReport = product.getSurveyReport();
+        if (StringUtils.isNotBlank(surveyReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——鉴定报告:"+surveyReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "2"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(surveyReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + surveyReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + surveyReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "8"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", surveyReport);
+            stringObjectHashMap1.put("docType", 1);
+            if (docType==1) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "13"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String outgoingReport = product.getOutgoingReport();
+        if (StringUtils.isNotBlank(outgoingReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——出厂报告:"+outgoingReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "14"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(outgoingReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + outgoingReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + outgoingReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "20"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", outgoingReport);
+            stringObjectHashMap1.put("docType", 2);
+            if (docType==2) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "25"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String thirdpartySizeReport = product.getThirdpartySizeReport();
+        if (StringUtils.isNotBlank(thirdpartySizeReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——第三方尺寸复验报告:"+thirdpartySizeReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "26"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(thirdpartySizeReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + thirdpartySizeReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + thirdpartySizeReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "32"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", thirdpartySizeReport);
+            stringObjectHashMap1.put("docType", 3);
+            if (docType==3) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "37"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String thirdpartyPerReport = product.getThirdpartyPerReport();
+        if (StringUtils.isNotBlank(thirdpartyPerReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——第三方性能报告:"+thirdpartyPerReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "38"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(thirdpartyPerReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + thirdpartyPerReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + thirdpartyPerReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "43"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", thirdpartyPerReport);
+            stringObjectHashMap1.put("docType", 4);
+            if (docType==4) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "49"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String intoSizeReport = product.getIntoSizeReport();
+        if (StringUtils.isNotBlank(intoSizeReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——入厂尺寸复验报告:"+intoSizeReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "50"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(intoSizeReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + intoSizeReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + intoSizeReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "56"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", intoSizeReport);
+            stringObjectHashMap1.put("docType", 5);
+            if (docType==5) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "61"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String intoPerReport = product.getIntoPerReport();
+        if (StringUtils.isNotBlank(intoPerReport)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——入厂性能复验报告:"+intoPerReport.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "62"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(intoPerReport)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + intoPerReport));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + intoPerReport);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "68"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", intoPerReport);
+            stringObjectHashMap1.put("docType", 6);
+            if (docType==6) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "73"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String certification = product.getCertification();
+        if (StringUtils.isNotBlank(certification)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——合格证:"+certification.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "74"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(certification)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + certification));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + certification);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "80"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", certification);
+            stringObjectHashMap1.put("docType", 7);
+            if (docType==7) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "85"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        String subCertification = product.getSubCertification();
+        if (StringUtils.isNotBlank(subCertification)) {
+            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+            stringObjectHashMap.put(product.getBatchNo()+"——子合格证:"+subCertification.substring(11), stringObjectHashMap1);
+            if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "86"), 8, TimeUnit.MINUTES)) {
+                return ;
+            }
+            if (isPdf(subCertification)) {
+                stringObjectHashMap1.put("img", PdfUtils.toImg(GlobalProperties.getFileUploadPath() + subCertification));
+            } else {
+                byte[] bytes = DocUtils.docToPdf(GlobalProperties.getFileUploadPath() + subCertification);
+                if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "92"), 8, TimeUnit.MINUTES)) {
+                    return ;
+                }
+                stringObjectHashMap1.put("img", PdfUtils.toImg(bytes));
+            }
+            stringObjectHashMap1.put("download", subCertification);
+            stringObjectHashMap1.put("docType", 8);
+            if (docType==8) {
+                stringObjectHashMap1.put("activate", true);
+            }
+        }
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "97"), 8, TimeUnit.MINUTES)) {
+            return ;
+        }
+        stringObjectHashMap.put("shenqian", shenqian);
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(300, "98"), 7, TimeUnit.MINUTES)) {
+            return ;
+        }
+        RedisUtils.set(GlobalConstant.PREVIEW_FINISH+id, stringObjectHashMap, 5, TimeUnit.MINUTES);
+        if (!RedisUtils.setIfPresent(id, new ReturnResult(200, "100", GlobalConstant.PREVIEW_FINISH+id), 4, TimeUnit.MINUTES)) {
+            return ;
+        }
+    }
+
+    public static boolean isPdf(String pdfFilePath) {
+        if (pdfFilePath.lastIndexOf(".")<=0) {
+            return false;
+        }
+        if ("pdf".equalsIgnoreCase(pdfFilePath.substring(pdfFilePath.lastIndexOf(".")+1))) {
+            return true;
+        }
+        return false;
+    }
+}

+ 46 - 0
database/src/main/java/com/qr/database/utils/SpringContextHolder.java

@@ -0,0 +1,46 @@
+package com.qr.database.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean
+ *
+ * @author harry
+ * @date 2016年11月27日 下午3:32:11
+ */
+@Component
+public class SpringContextHolder implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        assertApplicationContext();
+        return applicationContext;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String beanName) {
+        assertApplicationContext();
+        return (T) applicationContext.getBean(beanName);
+    }
+
+    public static <T> T getBean(Class<T> requiredType) {
+        assertApplicationContext();
+        return applicationContext.getBean(requiredType);
+    }
+
+    private static void assertApplicationContext() {
+        if (SpringContextHolder.applicationContext == null) {
+            throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
+        }
+    }
+
+}

+ 114 - 0
database/src/main/java/com/qr/database/utils/WafKit.java

@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2011-2014, hubin (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.qr.database.utils;
+
+import java.util.regex.Pattern;
+
+/**
+ * Web防火墙工具类
+ * <p>
+ * @author   hubin
+ * @Date	 2014-5-8 	 
+ */
+public class WafKit {
+
+	/**
+	 * @Description 过滤XSS脚本内容
+	 * @param value
+	 * 				待处理内容
+	 * @return
+	 */
+	public static String stripXSS(String value) {
+		String rlt = null;
+
+		if (null != value) {
+			// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
+			// avoid encoded attacks.
+			// value = ESAPI.encoder().canonicalize(value);
+
+			// Avoid null characters
+			rlt = value.replaceAll("", "");
+
+			// Avoid anything between script tags
+			Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid anything in a src='...' type of expression
+			/*scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");*/
+
+			// Remove any lonesome </script> tag
+			scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Remove any lonesome <script ...> tag
+			scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid eval(...) expressions
+			scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid expression(...) expressions
+			scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid javascript:... expressions
+			scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid vbscript:... expressions
+			scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			// Avoid onload= expressions
+			scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+		}
+		
+		return rlt;
+	}
+
+	/**
+	 * @Description 过滤SQL注入内容
+	 * @param value
+	 * 				待处理内容
+	 * @return
+	 */
+	public static String stripSqlInjection(String value) {
+		return (null == value) ? null : value.replaceAll("('.+--)|(--)|(%7C)", ""); //value.replaceAll("('.+--)|(--)|(\\|)|(%7C)", "");
+	}
+
+	/**
+	 * @Description 过滤SQL/XSS注入内容
+	 * @param value
+	 * 				待处理内容
+	 * @return
+	 */
+	public static String stripSqlXSS(String value) {
+		return stripXSS(stripSqlInjection(value));
+	}
+
+}

+ 149 - 0
database/src/main/java/com/qr/database/utils/WafRequestWrapper.java

@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2011-2014, hubin (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.qr.database.utils;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Request请求过滤包装
+ * <p>
+ * @author   hubin
+ * @Date	 2014-5-8 	 
+ */
+public class WafRequestWrapper extends HttpServletRequestWrapper {
+
+	private boolean filterXSS = true;
+
+	private boolean filterSQL = true;
+
+
+	public WafRequestWrapper(HttpServletRequest request, boolean filterXSS, boolean filterSQL) {
+		super(request);
+		this.filterXSS = filterXSS;
+		this.filterSQL = filterSQL;
+	}
+
+
+	public WafRequestWrapper(HttpServletRequest request) {
+		this(request, true, true);
+	}
+
+
+	/**
+	 * @Description 数组参数过滤
+	 * @param parameter
+	 * 				过滤参数
+	 * @return
+	 */
+	@Override
+	public String[] getParameterValues(String parameter) {
+		String[] values = super.getParameterValues(parameter);
+		if ( values == null ) {
+			return null;
+		}
+
+		int count = values.length;
+		String[] encodedValues = new String[count];
+		for ( int i = 0 ; i < count ; i++ ) {
+			encodedValues[i] = filterParamString(values[i]);
+		}
+
+		return encodedValues;
+	}
+
+	@Override
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public Map getParameterMap() {
+		Map<String, String[]> primary = super.getParameterMap();
+		Map<String, String[]> result = new HashMap<String, String[]>(primary.size());
+		for ( Map.Entry<String, String[]> entry : primary.entrySet() ) {
+			result.put(entry.getKey(), filterEntryString(entry.getValue()));
+		}
+		return result;
+
+	}
+	
+	protected String[] filterEntryString(String[] rawValue) {
+		for ( int i = 0 ; i < rawValue.length ; i++ ) {
+			rawValue[i] = filterParamString(rawValue[i]);
+		}
+		return rawValue;
+	}
+
+	/**
+	 * @Description 参数过滤
+	 * @param parameter
+	 * 				过滤参数
+	 * @return
+	 */
+	@Override
+	public String getParameter(String parameter) {
+		return filterParamString(super.getParameter(parameter));
+	}
+
+
+	/**
+	 * @Description 请求头过滤 
+	 * @param name
+	 * 				过滤内容
+	 * @return
+	 */
+	@Override
+	public String getHeader(String name) {
+		return filterParamString(super.getHeader(name));
+	}
+
+
+	/**
+	 * @Description Cookie内容过滤
+	 * @return
+	 */
+	@Override
+	public Cookie[] getCookies() {
+		Cookie[] existingCookies = super.getCookies();
+		if (existingCookies != null) {
+			for (int i = 0 ; i < existingCookies.length ; ++i) {
+				Cookie cookie = existingCookies[i];
+				cookie.setValue(filterParamString(cookie.getValue()));
+			}
+		}
+		return existingCookies;
+	}
+
+	/**
+	 * @Description 过滤字符串内容
+	 * @param rawValue
+	 * 				待处理内容
+	 * @return
+	 */
+	protected String filterParamString(String rawValue) {
+		if (null == rawValue) {
+			return null;
+		}
+		String tmpStr = rawValue;
+		if (this.filterXSS) {
+			tmpStr = WafKit.stripXSS(rawValue);
+		}
+		if (this.filterSQL) {
+			tmpStr = WafKit.stripSqlInjection(tmpStr);
+		}
+		return tmpStr;
+	}
+}

+ 160 - 0
database/src/main/java/com/qr/database/utils/ZipUtil.java

@@ -0,0 +1,160 @@
+package com.qr.database.utils;
+
+import com.qr.database.config.properties.GlobalProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @Description: ZipUtil
+ * @Author: harry
+ * @CreateDate: 2018/10/19 17:47
+ * @UpdateUser:
+ * @UpdateDate: 2018/10/19 17:47
+ * @UpdateRemark:
+ * @Version: 1.0
+ */
+public class ZipUtil {
+
+    private static Logger log = LoggerFactory.getLogger(ZipUtil.class);
+
+    public static ByteArrayInputStream toByteArrayInputStream(ByteArrayOutputStream out) {
+        return new ByteArrayInputStream(out.toByteArray());
+    }
+
+    /**
+     * 文件批量压缩
+     *
+     * @param parms
+     */
+    public static void batchFileToZIP(List<Map<String, Object>> parms, OutputStream OutPutStream) {
+        ZipOutputStream zipOut = new ZipOutputStream(OutPutStream);
+        InputStream inputStream = null;
+        try {
+            for (Map<String, Object> value : parms) {
+                inputStream = (InputStream) value.get("file");
+                // 使用指定名称创建新的 ZIP 条目 (通俗点就是文件名)
+                ZipEntry zipEntry = new ZipEntry(String.valueOf(value.get("fileName")));
+                // 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
+                zipOut.putNextEntry(zipEntry);
+                byte[] b = new byte[1024];
+                int length = 0;
+                while ((length = inputStream.read(b)) != -1) {
+                    zipOut.write(b, 0, length);
+                }
+                inputStream.close();
+                zipEntry.clone();
+                zipOut.closeEntry();
+            }
+        } catch (FileNotFoundException e) {
+            log.error(e.getMessage(), e);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            try {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+                zipOut.close();
+            } catch (IOException e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+    }
+
+    public static void batchDataToZIP(List<Map<String, Object>> parms, OutputStream OutPutStream) {
+        ZipOutputStream zipOut = new ZipOutputStream(OutPutStream);
+        try {
+            for (Map<String, Object> value : parms) {
+                byte[] inputStream = (byte[]) value.get("data");
+                // 使用指定名称创建新的 ZIP 条目 (通俗点就是文件名)
+                ZipEntry zipEntry = new ZipEntry(String.valueOf(value.get("fileName")));
+                // 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
+                zipOut.putNextEntry(zipEntry);
+                zipOut.write(inputStream);
+                zipEntry.clone();
+                zipOut.closeEntry();
+            }
+        } catch (FileNotFoundException e) {
+            log.error(e.getMessage(), e);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            try {
+                zipOut.close();
+            } catch (IOException e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+    }
+
+    public static void batchAllToZIP(List<Map<String, Object>> parms, OutputStream OutPutStream) {
+        ZipOutputStream zipOut = new ZipOutputStream(OutPutStream);
+        InputStream input = null;
+        try {
+            for (Map<String, Object> value : parms) {
+                Object data = value.get("data");
+                ZipEntry zipEntry = null;
+                try {
+                    if (data != null) {
+                            byte[] inputStream = (byte[]) data;
+                            // 使用指定名称创建新的 ZIP 条目 (通俗点就是文件名)
+                            zipEntry = new ZipEntry(String.valueOf(value.get("fileName")));
+                            // 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
+                            zipOut.putNextEntry(zipEntry);
+                            zipOut.write(inputStream);
+                    } else if (value.get("file") != null) {
+                        input = (InputStream) value.get("file");
+                        // 使用指定名称创建新的 ZIP 条目 (通俗点就是文件名)
+                        zipEntry = new ZipEntry(String.valueOf(value.get("fileName")));
+                        // 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
+                        zipOut.putNextEntry(zipEntry);
+                        byte[] b = new byte[1024];
+                        int length = 0;
+                        while ((length = input.read(b)) != -1) {
+                            zipOut.write(b, 0, length);
+                        }
+                    }
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                } finally {
+                    if (input != null) {
+                        input.close();
+                    }
+                    if (zipEntry != null) {
+                        zipEntry.clone();
+                    }
+                    if (zipOut != null) {
+                        zipOut.closeEntry();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }finally {
+            try {
+                if (input != null) {
+                    input.close();
+                }
+                zipOut.close();
+            } catch (IOException e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+    }
+
+    public static Map<String, Object> getZipMap(String filePath) throws FileNotFoundException {
+        HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
+        File file = new File(GlobalProperties.getFileUploadPath() + filePath);
+        stringObjectHashMap1.put("fileName", file.getName());
+        stringObjectHashMap1.put("file", new FileInputStream(file));
+        return stringObjectHashMap1;
+    }
+
+}

+ 411 - 0
database/src/main/java/com/qr/database/utils/qr/ImgQrTool.java

@@ -0,0 +1,411 @@
+package com.qr.database.utils.qr;
+
+import com.google.zxing.*;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 内嵌图片的二维码生成器
+ *
+ * @author lichunxi
+ */
+public class ImgQrTool {
+
+    private static Logger log = LoggerFactory.getLogger(ImgQrTool.class);
+
+    // 镶嵌的图片宽度的一般
+    private static final int IMAGE_WIDTH = 80;
+    private static final int IMAGE_HEIGHT = 80;
+    private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
+    private static final int FRAME_WIDTH = 2;
+
+    // 二维码写码器
+    private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
+
+    /**
+     * 生成带图片的二维码
+     *
+     * @param content       二维码的内容
+     * @param width         宽度
+     * @param height        高度
+     * @param srcImagePath  被镶嵌的图片的地址
+     * @param destImagePath 生成二维码图片的地址
+     * @author fengshuonan
+     * @since 2.3.0
+     */
+    public static void encode(String content, int width, int height, String srcImagePath, String destImagePath) {
+        try {
+            ImageIO.write(genBarcode(content, width, height, srcImagePath), "jpg", new File(destImagePath));
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (WriterException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 生成带图片的二维码
+     *
+     * @param content       二维码的内容
+     * @param width         宽度
+     * @param height        高度
+     * @param srcImagePath  被镶嵌的图片的地址
+     * @author fengshuonan
+     * @since 2.3.0
+     */
+    public static void encode(String content, int width, int height, String srcImagePath, OutputStream outputStream) {
+        try {
+            ImageIO.write(genBarcode(content, width, height, srcImagePath), "jpg", outputStream);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (WriterException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 创建不带参数的二维码
+     *
+     * @author fengshuonan
+     * @since 2.3.0
+     */
+    public static void createSimpleQr(String content, int width, int height, String destImagePath) {
+
+        FileOutputStream output = null;
+
+        try {
+            String format = "png";// 图像类型
+            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
+            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+            hints.put(EncodeHintType.MARGIN, 0);
+            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
+            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩阵
+            File dest = new File(destImagePath);
+            output = new FileOutputStream(dest);
+            MatrixToImageWriter.writeToStream(bitMatrix, format, output);// 输出图像
+        } catch (Exception e) {
+            log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
+        } finally {
+            try {
+                output.close();
+            } catch (IOException e) {
+                log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
+            }
+        }
+    }
+
+    public static String createSimpleQr(String content, int width, int height) {
+        ByteArrayOutputStream output = null;
+        BASE64Encoder encoder = new BASE64Encoder();
+        try {
+            String format = "png";// 图像类型
+            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
+            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+            hints.put(EncodeHintType.MARGIN, 0);
+            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
+            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩阵
+            output = new ByteArrayOutputStream();
+            MatrixToImageWriter.writeToStream(bitMatrix, format, output);// 输出图像
+            String png_base64 =  encoder.encodeBuffer(output.toByteArray()).trim();//转换成base64串
+            png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
+            return png_base64;
+        } catch (Exception e) {
+            log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
+        } finally {
+            try {
+                output.close();
+            } catch (IOException e) {
+                log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
+            }
+        }
+        return null;
+    }
+
+    private static BufferedImage genBarcode(String content, int width, int height, String srcImagePath)
+            throws WriterException, IOException {
+        // 读取源图像
+        BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true);
+        int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
+        for (int i = 0; i < scaleImage.getWidth(); i++) {
+            for (int j = 0; j < scaleImage.getHeight(); j++) {
+                srcPixels[i][j] = scaleImage.getRGB(i, j);
+            }
+        }
+
+        Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
+        hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
+        hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+        hint.put(EncodeHintType.MARGIN, 1);// 二维码整体白框
+
+        // 生成二维码
+        BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint);
+
+        // 二维矩阵转为一维像素数组
+        int halfW = matrix.getWidth() / 2;
+        int halfH = matrix.getHeight() / 2;
+        int[] pixels = new int[width * height];
+
+        for (int y = 0; y < matrix.getHeight(); y++) {
+            for (int x = 0; x < matrix.getWidth(); x++) {
+                // 读取图片
+                if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH
+                        && y < halfH + IMAGE_HALF_WIDTH) {
+                    pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
+                }
+                // 在图片四周形成边框
+                else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
+                        && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
+                        || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
+                        && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
+                        && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
+                        || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
+                        && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
+                        && y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH)
+                        || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
+                        && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH
+                        && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
+                    pixels[y * width + x] = 0xfffffff;
+                } else {
+                    // 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
+                    pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff;
+                }
+            }
+        }
+
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        image.getRaster().setDataElements(0, 0, width, height, pixels);
+
+        return image;
+    }
+
+    /**
+     * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
+     *
+     * @param srcImageFile 源文件地址
+     * @param height       目标高度
+     * @param width        目标宽度
+     * @param hasFiller    比例不对时是否需要补白:true为补白; false为不补白;
+     * @throws IOException
+     */
+    private static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller)
+            throws IOException {
+        double ratio = 0.0; // 缩放比例
+        File file = new File(srcImageFile);
+        BufferedImage srcImage = ImageIO.read(file);
+        Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
+        // 计算比例
+        if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
+            if (srcImage.getHeight() > srcImage.getWidth()) {
+                ratio = (new Integer(height)).doubleValue() / srcImage.getHeight();
+            } else {
+                ratio = (new Integer(width)).doubleValue() / srcImage.getWidth();
+            }
+            AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
+            destImage = op.filter(srcImage, null);
+        }
+        if (hasFiller) {// 补白
+            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            Graphics2D graphic = image.createGraphics();
+            graphic.setColor(Color.white);
+            graphic.fillRect(0, 0, width, height);
+            if (width == destImage.getWidth(null))
+                graphic.drawImage(destImage, 0, (height - destImage.getHeight(null)) / 2, destImage.getWidth(null),
+                        destImage.getHeight(null), Color.white, null);
+            else
+                graphic.drawImage(destImage, (width - destImage.getWidth(null)) / 2, 0, destImage.getWidth(null),
+                        destImage.getHeight(null), Color.white, null);
+            graphic.dispose();
+            destImage = image;
+        }
+        return (BufferedImage) destImage;
+    }
+
+    /**
+     * 生成上方带文字的二维码
+     */
+    public static void createQrWithFontsAbove(QrImage para) {
+        try {
+            // 首先生成二维码图片
+            BufferedImage qrImage = genBarcode(para.getQrContent(), para.getQrWidth(), para.getQrHeight(), para.getQrIconFilePath());
+
+            int qrImageWidth = qrImage.getWidth();
+            int qrImageHeight = qrImage.getHeight();
+
+            String[] splitStrLines = null;
+            splitStrLines = splitStrLines(para.getWordContent(), qrImageWidth / para.getWordSize());
+            int fontsImageHeight = splitStrLines.length * para.getWordSize() + 10; //防止文字遮挡
+
+            //创建顶部文字的图片
+            BufferedImage imageWithFonts = new BufferedImage(qrImageWidth, fontsImageHeight, BufferedImage.TYPE_4BYTE_ABGR);
+            Graphics fontsImageGraphics = imageWithFonts.getGraphics();
+            fontsImageGraphics.fillRect(0, 0, qrImageWidth, fontsImageHeight);
+            fontsImageGraphics.setColor(Color.black);
+            fontsImageGraphics.setFont(new Font("宋体", Font.PLAIN, para.getWordSize()));
+
+            //文字长度大于一行的长度,进行分行
+            if (para.getWordContent().length() > qrImageWidth / para.getWordSize()) {//每行限制的文字个数
+                for (int i = 0; i < splitStrLines.length; i++) {
+                    fontsImageGraphics.drawString(splitStrLines[i], 0, para.getWordSize() * (i + 1));
+                }
+            } else {
+                fontsImageGraphics.drawString(
+                        para.getWordContent(),
+                        ((qrImageWidth / para.getWordSize() - para.getWordContent().length()) / 2) * para.getWordSize() + 20, //总长度减去字长度除以2为向右偏移长度
+                        para.getWordSize());
+            }
+
+            // 从图片中读取RGB
+            int[] ImageArrayFonts = new int[qrImageWidth * fontsImageHeight];
+            ImageArrayFonts = imageWithFonts.getRGB(0, 0, qrImageWidth, fontsImageHeight, ImageArrayFonts, 0, qrImageWidth);
+
+            int[] ImageArrayQr = new int[qrImageWidth * qrImageHeight];
+            ImageArrayQr = qrImage.getRGB(0, 0, qrImageWidth, qrImageHeight, ImageArrayQr, 0, qrImageWidth);
+
+            // 生成新图片
+            BufferedImage ImageNew = new BufferedImage(qrImageWidth, qrImageHeight + fontsImageHeight, BufferedImage.TYPE_INT_RGB);
+            ImageNew.setRGB(0, 0, qrImageWidth, fontsImageHeight, ImageArrayFonts, 0, qrImageWidth);// 设置上半部分的RGB
+            ImageNew.setRGB(0, fontsImageHeight, qrImageWidth, qrImageHeight, ImageArrayQr, 0, qrImageWidth);// 设置下半部分的RGB
+
+            File outFile = new File(para.getFileOutputPath());
+            ImageIO.write(ImageNew, "jpg", outFile);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 一行字符串拆分成多行
+     */
+    private static String[] splitStrLines(String str, int len) {
+        int blocks = str.length() / len + 1;
+        String[] strs = new String[blocks];
+        for (int i = 0; i < blocks; i++) {
+            if ((i + 1) * len > str.length()) {
+                strs[i] = str.substring(i * len);
+            } else {
+                strs[i] = str.substring(i * len, (i + 1) * len);
+            }
+        }
+        return strs;
+    }
+
+    /**
+     * base64字符串转换成图片
+     * @param imgStr		base64字符串
+     * @param imgFilePath	图片存放路径
+     * @return
+     *
+     * @author ZHANGJL
+     */
+    public static boolean Base64ToImage(String imgStr,String imgFilePath) {
+
+        if (StringUtils.isBlank(imgStr)) // 图像数据为空
+            return false;
+
+        BASE64Decoder decoder = new BASE64Decoder();
+        OutputStream out = null;
+        try {
+            // Base64解码
+            byte[] b = decoder.decodeBuffer(imgStr);
+            for (int i = 0; i < b.length; ++i) {
+                if (b[i] < 0) {// 调整异常数据
+                    b[i] += 256;
+                }
+            }
+            out = new FileOutputStream(imgFilePath);
+            out.write(b);
+            out.flush();
+
+            return true;
+        } catch (Exception e) {
+            return false;
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+    }
+
+    public static byte [] Base64ToImage(String imgStr) {
+
+        if (StringUtils.isBlank(imgStr)) // 图像数据为空
+            return null;
+
+        BASE64Decoder decoder = new BASE64Decoder();
+        try {
+            // Base64解码
+            byte[] b = decoder.decodeBuffer(imgStr);
+            for (int i = 0; i < b.length; ++i) {
+                if (b[i] < 0) {// 调整异常数据
+                    b[i] += 256;
+                }
+            }
+            return b;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+//        for (int i = 1; i <= 1; i++) {
+//            QrImage para = new QrImage.Builder()
+//                    .setFileOutputPath("D:\\二维码\\test\\" + i + ".jpg")
+//                    .setQrContent("http://www.baidu.com?a=" + "123")
+//                    .setQrHeight(300)
+//                    .setQrWidth(300)
+//                    .setQrIconFilePath("D:\\二维码\\中间图标\\1.png")
+//                    .setTopWrodHeight(100)
+//                    .setWordContent("test" + 1)
+//                    .setWordSize(18).build();
+//            ImgQrTool.createQrWithFontsAbove(para);
+//        }
+        String content = null;
+        BufferedImage image;
+        BASE64Decoder decoder = new BASE64Decoder();
+        byte[] b=null;
+        try {
+            b = decoder.decodeBuffer("iVBORw0KGgoAAAANSUhEUgAAAJYAAACWAQAAAAAUekxPAAAA9ElEQVR42r2WwQ0FIQhESSjAkmzdkiiAhM+AZnf/3SFmw74TjDgqgpi1RE2euMw0IgzMwWb+kZghzW/EUuuieEzGisR0lq27TCor7TWW/O/HXdazVvLP7/zdZVHhI7Io7ZzCZGTT2fpK7RVfBIE5Wi5g+zhzWI62Vy2oYSwtXTisxk0gv7UYDObHvaSZlfb3WbkXZs170iEGg8XZanRfTuYcllZdbn2cOzgMB8v2xLWNCYW1l+hrcZiccroQbQ3us/0WGKvt8/0Gucv2nRxlosidyHrEXueNxcq9kMPDKGxrH7grxvLnDXKX7bdAXVPpJYkp7Afo7iz8eo9KnAAAAABJRU5ErkJggg==");//baseStr转byte[]
+            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(b);//byte[] 转BufferedImage
+            image = ImageIO.read(byteArrayInputStream);
+            LuminanceSource source = new BufferedImageLuminanceSource(image);
+            Binarizer binarizer = new HybridBinarizer(source);
+            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
+            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
+            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
+            //精度
+            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
+            //复杂模式
+            hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
+            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
+            System.out.println(111);
+            System.out.println("图片中内容:  ");
+            System.out.println("content: " + result.getText());
+            content = result.getText();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (NotFoundException e) {
+            e.printStackTrace();
+        }
+
+    }
+}

+ 62 - 0
database/src/main/java/com/qr/database/utils/qr/MatrixToImageConfig.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.qr.database.utils.qr;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Encapsulates custom configuration used in methods of {@link MatrixToImageWriter}.
+ */
+public final class MatrixToImageConfig {
+
+  public static final int BLACK = 0xFF000000;
+  public static final int WHITE = 0xFFFFFFFF;
+  
+  private final int onColor;
+  private final int offColor;
+
+  /**
+   * Creates a default config with on color {@link #BLACK} and off color {@link #WHITE}, generating normal
+   * black-on-white barcodes.
+   */
+  public MatrixToImageConfig() {
+    this(BLACK, WHITE);
+  }
+
+  /**
+   * @param onColor pixel on color, specified as an ARGB value as an int
+   * @param offColor pixel off color, specified as an ARGB value as an int
+   */
+  public MatrixToImageConfig(int onColor, int offColor) {
+    this.onColor = onColor;
+    this.offColor = offColor;
+  }
+
+  public int getPixelOnColor() {
+    return onColor;
+  }
+
+  public int getPixelOffColor() {
+    return offColor;
+  }
+
+  int getBufferedImageColorModel() {
+    // Use faster BINARY if colors match default
+    return onColor == BLACK && offColor == WHITE ? BufferedImage.TYPE_BYTE_BINARY : BufferedImage.TYPE_INT_RGB;
+  }
+
+}

+ 122 - 0
database/src/main/java/com/qr/database/utils/qr/MatrixToImageWriter.java

@@ -0,0 +1,122 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.qr.database.utils.qr;
+
+import com.google.zxing.common.BitMatrix;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Path;
+
+/**
+ * Writes a {@link BitMatrix} to {@link BufferedImage},
+ * file or stream. Provided here instead of core since it depends on
+ * Java SE libraries.
+ *
+ * @author Sean Owen
+ */
+public final class MatrixToImageWriter {
+
+  private static final MatrixToImageConfig DEFAULT_CONFIG = new MatrixToImageConfig();
+
+  private MatrixToImageWriter() {}
+
+  /**
+   * Renders a {@link BitMatrix} as an image, where "false" bits are rendered
+   * as white, and "true" bits are rendered as black.
+   */
+  public static BufferedImage toBufferedImage(BitMatrix matrix) {
+    return toBufferedImage(matrix, DEFAULT_CONFIG);
+  }
+
+  /**
+   * As {@link #toBufferedImage(BitMatrix)}, but allows customization of the output.
+   */
+  public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
+    int width = matrix.getWidth();
+    int height = matrix.getHeight();
+    BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
+    int onColor = config.getPixelOnColor();
+    int offColor = config.getPixelOffColor();
+    for (int x = 0; x < width; x++) {
+      for (int y = 0; y < height; y++) {
+        image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
+      }
+    }
+    return image;
+  }
+
+  /**
+   * @deprecated use {@link #writeToPath(BitMatrix, String, Path)}
+   */
+  @Deprecated
+  public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
+    writeToPath(matrix, format, file.toPath());
+  }
+
+  /**
+   * Writes a {@link BitMatrix} to a file.
+   *
+   * @see #toBufferedImage(BitMatrix)
+   */
+  public static void writeToPath(BitMatrix matrix, String format, Path file) throws IOException {
+    writeToPath(matrix, format, file, DEFAULT_CONFIG);
+  }
+
+  /**
+   * @deprecated use {@link #writeToPath(BitMatrix, String, Path, MatrixToImageConfig)}
+   */
+  @Deprecated
+  public static void writeToFile(BitMatrix matrix, String format, File file, MatrixToImageConfig config) 
+      throws IOException {
+    writeToPath(matrix, format, file.toPath(), config);
+  }
+
+  /**
+   * As {@link #writeToFile(BitMatrix, String, File)}, but allows customization of the output.
+   */
+  public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config)
+      throws IOException {
+    BufferedImage image = toBufferedImage(matrix, config);
+    if (!ImageIO.write(image, format, file.toFile())) {
+      throw new IOException("Could not write an image of format " + format + " to " + file);
+    }
+  }
+
+  /**
+   * Writes a {@link BitMatrix} to a stream.
+   *
+   * @see #toBufferedImage(BitMatrix)
+   */
+  public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
+    writeToStream(matrix, format, stream, DEFAULT_CONFIG);
+  }
+
+  /**
+   * As {@link #writeToStream(BitMatrix, String, OutputStream)}, but allows customization of the output.
+   */
+  public static void writeToStream(BitMatrix matrix, String format, OutputStream stream, MatrixToImageConfig config) 
+      throws IOException {  
+    BufferedImage image = toBufferedImage(matrix, config);
+    if (!ImageIO.write(image, format, stream)) {
+      throw new IOException("Could not write an image of format " + format);
+    }
+  }
+
+}

+ 170 - 0
database/src/main/java/com/qr/database/utils/qr/QrImage.java

@@ -0,0 +1,170 @@
+package com.qr.database.utils.qr;
+
+/**
+ * 二维码图片对象
+ *
+ * @author fengshuonan
+ * @date 2016年12月8日 上午11:37:09
+ */
+public class QrImage {
+
+    /**
+     * 二维码的内容
+     */
+    private String qrContent;
+
+    /**
+     * 二维码的宽度
+     */
+    private int qrWidth;
+
+    /**
+     * 二维码的高度
+     */
+    private int qrHeight;
+
+    /**
+     * 二维码中间图标的文件路径
+     */
+    private String qrIconFilePath;
+
+    /**
+     * 二维码中间小图标的边长
+     */
+    private int qrIconWidth;
+
+    /**
+     * 顶部文字的高度
+     */
+    private int topWrodHeight;
+
+    /**
+     * 文字的大小
+     */
+    private int wordSize;
+
+    /**
+     * 文字的内容
+     */
+    private String wordContent;
+
+    /**
+     * 文件的输出路径
+     */
+    private String fileOutputPath;
+
+    public static class Builder {
+        private String qrContent;
+        private int qrWidth;
+        private int qrHeight;
+        private String qrIconFilePath;
+        private int topWrodHeight;
+        private int wordSize;
+        private String wordContent;
+        private String fileOutputPath;
+        private int qrIconWidth;
+
+        public Builder() {
+        }
+
+        public Builder setQrContent(String qrContent) {
+            this.qrContent = qrContent;
+            return this;
+        }
+
+        public Builder setQrWidth(int qrWidth) {
+            this.qrWidth = qrWidth;
+            return this;
+        }
+
+        public Builder setQrHeight(int qrHeight) {
+            this.qrHeight = qrHeight;
+            return this;
+        }
+
+        public Builder setQrIconFilePath(String qrIconFilePath) {
+            this.qrIconFilePath = qrIconFilePath;
+            return this;
+        }
+
+        public Builder setTopWrodHeight(int topWrodHeight) {
+            this.topWrodHeight = topWrodHeight;
+            return this;
+        }
+
+        public Builder setWordSize(int wordSize) {
+            this.wordSize = wordSize;
+            return this;
+        }
+
+        public Builder setWordContent(String wordContent) {
+            this.wordContent = wordContent;
+            return this;
+        }
+
+        public Builder setFileOutputPath(String fileOutputPath) {
+            this.fileOutputPath = fileOutputPath;
+            return this;
+        }
+
+        public Builder setQrIconWidth(int qrIconWidth) {
+            this.qrIconWidth = qrIconWidth;
+            return this;
+        }
+
+        public QrImage build() {
+            return new QrImage(this.qrContent, this.qrWidth, this.qrHeight, this.qrIconFilePath, this.qrIconWidth,
+                    this.topWrodHeight, this.wordSize, this.wordContent, this.fileOutputPath);
+        }
+    }
+
+    public QrImage(String qrContent, int qrWidth, int qrHeight, String qrIconFilePath, int qrIconWidth,
+                   int topWrodHeight, int wordSize, String wordContent, String fileOutputPath) {
+        super();
+        this.qrContent = qrContent;
+        this.qrWidth = qrWidth;
+        this.qrHeight = qrHeight;
+        this.qrIconFilePath = qrIconFilePath;
+        this.qrIconWidth = qrIconWidth;
+        this.topWrodHeight = topWrodHeight;
+        this.wordSize = wordSize;
+        this.wordContent = wordContent;
+        this.fileOutputPath = fileOutputPath;
+    }
+
+    public String getQrContent() {
+        return qrContent;
+    }
+
+    public int getQrWidth() {
+        return qrWidth;
+    }
+
+    public int getQrHeight() {
+        return qrHeight;
+    }
+
+    public String getQrIconFilePath() {
+        return qrIconFilePath;
+    }
+
+    public int getTopWrodHeight() {
+        return topWrodHeight;
+    }
+
+    public int getWordSize() {
+        return wordSize;
+    }
+
+    public String getWordContent() {
+        return wordContent;
+    }
+
+    public String getFileOutputPath() {
+        return fileOutputPath;
+    }
+
+    public int getQrIconWidth() {
+        return qrIconWidth;
+    }
+}

+ 47 - 0
database/src/main/resources/application.properties

@@ -0,0 +1,47 @@
+server.port=8081
+
+spring.freemarker.template-loader-path=classpath:/templates/
+spring.freemarker.cache=false
+spring.freemarker.charset=UTF-8
+spring.freemarker.check-template-location=true
+spring.freemarker.content-type=text/html
+spring.freemarker.expose-request-attributes=true
+spring.freemarker.expose-session-attributes=true
+spring.freemarker.request-context-attribute=request
+spring.freemarker.suffix=.ftl
+spring.freemarker.settings.number_format=#
+auto_import=macros.ftl as m;uploadProgressBar.ftl as u;previewProgressBar.ftl as p
+auto_include=
+
+spring.mvc.static-path-pattern=/static/**
+spring.resources.static-locations=classpath:/static/
+
+spring.servlet.multipart.max-file-size=200MB
+spring.servlet.multipart.max-request-size=500MB
+
+qr.file-upload-path=D:/IDEA/daigou/qr_code_database/file
+#qr.file-upload-path=/data/database/
+
+mybatis-plus.mapper-locations=classpath*:com/qr/**/mapping/*.xml
+spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
+spring.datasource.url=jdbc:oracle:thin:@192.168.134.136:1521:ORCLE
+spring.datasource.username=datamanage
+spring.datasource.password=123456
+spring.redis.host=10.168.1.134
+spring.redis.port=6379
+spring.redis.password=
+
+#spring.datasource.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
+#spring.datasource.username=datamanage
+#spring.datasource.password=dTmMt201906012
+#spring.redis.host=127.0.0.1
+#spring.redis.port=6379
+#spring.redis.password=
+#39.105.90.156
+#CentOS 7.6
+#Óû§£ºroot
+#ÃÜÂ룺Seraph20190713
+#/usr/local/tomcat
+logging.file=/data/log/database/database.log
+logging.level.root: info
+logging.level.com.qr.database: debug