Kaynağa Gözat

压缩图片

Levi 3 yıl önce
ebeveyn
işleme
ee91cc4ee9

+ 19 - 0
pom.xml

@@ -49,6 +49,25 @@
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>redis.clients</groupId>
+                    <artifactId>jedis</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>lettuce-core</artifactId>
+                    <groupId>io.lettuce</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>

+ 36 - 0
src/main/java/com/ebei/screen/common/aspect/RedisAspect.java

@@ -0,0 +1,36 @@
+package com.ebei.screen.common.aspect;
+
+import com.ebei.screen.common.exception.MyException;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Redis切面处理类
+ *
+ * @author Levi
+ */
+@Slf4j
+@Aspect
+@Configuration
+public class RedisAspect {
+    @Value("${spring.redis.open}")
+    private boolean open;
+
+    @Around("execution(* com.ebei.screen.common.util.RedisUtils.*(..))")
+    public Object around(ProceedingJoinPoint point) throws Throwable {
+        Object result = null;
+        if (open) {
+            try {
+                result = point.proceed();
+            } catch (Exception e) {
+                log.error("redis error", e);
+                throw new MyException("Redis服务异常");
+            }
+        }
+        return result;
+    }
+}

+ 34 - 0
src/main/java/com/ebei/screen/common/config/RedisConfig.java

@@ -0,0 +1,34 @@
+package com.ebei.screen.common.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.core.ValueOperations;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis配置
+ */
+@Configuration
+public class RedisConfig {
+    @Autowired
+    private RedisConnectionFactory factory;
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate() {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        redisTemplate.setValueSerializer(new StringRedisSerializer());
+        redisTemplate.setConnectionFactory(factory);
+        return redisTemplate;
+    }
+
+    @Bean
+    public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
+        return redisTemplate.opsForValue();
+    }
+}

+ 14 - 0
src/main/java/com/ebei/screen/common/task/ScreenTask.java

@@ -60,4 +60,18 @@ public class ScreenTask {
         }
     }
 
+    /**
+     * 每小时第19分钟初始化一次异常数据
+     */
+    @Scheduled(cron = "0 19 * ? * *")
+    public void excelExportTask() {
+        try {
+            log.info("开始初始化报表异常数据 开始时间:{}", DateUtil.now());
+            parkSystemService.excelExportTask();
+            log.info("初始化报表异常数据结束 结束时间:{}", DateUtil.now());
+        } catch (Exception e) {
+            log.info("定时任务执行出现错误:{}", e);
+        }
+    }
+
 }

+ 36 - 10
src/main/java/com/ebei/screen/common/util/ParkUtils.java

@@ -46,6 +46,7 @@ import java.util.stream.Collectors;
 public class ParkUtils {
 
     private static MongoTemplate mongoTemplate;
+    private static RedisUtils redisUtils;
 
     private static final String pno = "JYTDSY";
     private static final String secret = "d52ee6b8a5ed4060a1d1654a3d31e247";
@@ -60,6 +61,10 @@ public class ParkUtils {
         ParkUtils.mongoTemplate = mongoTemplate;
     }
 
+    @Autowired
+    public void setRedisUtils(RedisUtils redisUtils) {
+        ParkUtils.redisUtils = redisUtils;
+    }
 
     public static List<Map> getEmptyTemplate() {
         List<Map> dayList = new ArrayList<>();
@@ -410,19 +415,40 @@ public class ParkUtils {
     /**
      * 获取附件图片字节数组
      *
-     * @param photo
-     * @param flag  是否开启压缩 true开启
+     * @param photos     图片集合
+     * @param flag       是否开启压缩 true开启
+     * @param needResult 是否需要返回map true需要
      * @return
      */
-    public static byte[] getExcelPhotoUrl(Object photo, boolean flag) {
+    public static Map<String, byte[]> getExcelPhotoUrl(List<String> photos, boolean flag, boolean needResult) {
         try {
-            String url = (String) photo;
-            String imgUrlById = getImgUrlById(url);
-            if (flag) {
-                return StringUtils.isNotBlank(imgUrlById) ? imageSet(Base64.getDecoder().decode(imgUrlById)) : null;
-            } else {
-                return StringUtils.isNotBlank(imgUrlById) ? Base64.getDecoder().decode(imgUrlById) : null;
+            Map<String, byte[]> result = new HashMap<>(16);
+            List<Map<String, String>> redis = new ArrayList<>();
+            if (CollUtil.isNotEmpty(photos)) {
+                photos.forEach(url -> {
+                    try {
+                        String imgUrlById = redisUtils.get(url);
+                        if (StringUtils.isBlank(imgUrlById)) {
+                            imgUrlById = getImgUrlById(url);
+                            if (StringUtils.isNotBlank(imgUrlById)) {
+                                redis.add(Levi.by("key", url).set("value", imgUrlById));
+                            }
+                        }
+                        if (needResult) {
+                            if (flag) {
+                                result.put(url, StringUtils.isNotBlank(imgUrlById) ? imageSet(Base64.getDecoder().decode(imgUrlById)) : null);
+                            } else {
+                                result.put(url, StringUtils.isNotBlank(imgUrlById) ? Base64.getDecoder().decode(imgUrlById) : null);
+                            }
+                        }
+                    } catch (Exception e) {
+                        log.info("提取excel图片出现异常", e);
+                    }
+                });
             }
+            redisUtils.batchSetRedis(redis, 36 * 60 * 60);
+            log.info("=============================redis批量存储成功{}条============================", redis.size());
+            return result;
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -466,7 +492,7 @@ public class ParkUtils {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ImageIO.write(bf, "jpeg", out);
         byte[] re = out.toByteArray();
-        log.info("【图片剪切】| 图片原大小={}kb | 压缩后大小={}kb", (data.length / 1024), (re.length / 1024));
+        // log.info("【图片剪切】| 图片原大小={}kb | 压缩后大小={}kb", (data.length / 1024), (re.length / 1024));
         return re;
     }
 

+ 170 - 0
src/main/java/com/ebei/screen/common/util/RedisUtils.java

@@ -0,0 +1,170 @@
+package com.ebei.screen.common.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis工具类
+ *
+ * @author Levi
+ */
+@Component
+public class RedisUtils {
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+    @Autowired
+    private ValueOperations<String, String> valueOperations;
+
+    /**
+     * 默认过期时长24小时
+     */
+    public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
+
+    /**
+     * 永不过期
+     */
+    public final static long NOT_EXPIRE = -1;
+
+    /**
+     * 存值(指定过期时常)
+     *
+     * @param key    key值
+     * @param value  value值
+     * @param expire 过期时长
+     */
+    public void set(String key, Object value, long expire) {
+        valueOperations.set(key, toJson(value));
+        if (expire != NOT_EXPIRE) {
+            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 批量插入数据到redis
+     *
+     * @param dataList
+     * @param expire
+     */
+    public void batchSetRedis(List<Map<String, String>> dataList, long expire) {
+        //使用pipeline方式
+        redisTemplate.executePipelined((RedisCallback<List<Object>>) connection -> {
+            for (Map<String, String> map : dataList) {
+                StringRedisSerializer keySerializer = (StringRedisSerializer) redisTemplate.getKeySerializer();
+                StringRedisSerializer valueSerializer = (StringRedisSerializer) redisTemplate.getValueSerializer();
+                connection.setEx(keySerializer.serialize(map.get("key")), expire, valueSerializer.serialize(map.get("value")));
+            }
+            return null;
+        });
+    }
+
+    /**
+     * 存值(默认24小时过期)
+     *
+     * @param key   key值
+     * @param value value值
+     */
+    public void set(String key, Object value) {
+        set(key, value, DEFAULT_EXPIRE);
+    }
+
+    /**
+     * 取值(指定value要转成的对象&更新过期时间)
+     *
+     * @param key    key值
+     * @param clazz  要将value值转成指定类型对象
+     * @param expire 更新过期时间
+     * @return
+     */
+    public <T> T get(String key, Class<T> clazz, long expire) {
+        String value = valueOperations.get(key);
+        // 如果key值不是永不过期
+        if (expire != NOT_EXPIRE) {
+            // 更新该key值的过期时间为指定过期时间
+            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+        }
+        // 按照指定类型将redis中的JSON数据转换成对象返回
+        return value == null ? null : fromJson(value, clazz);
+    }
+
+    /**
+     * 取值(指定value要转成的对象&默认永不过期)
+     *
+     * @param key   key值
+     * @param clazz 要将value值转成指定类型对象
+     * @param <T>
+     * @return
+     */
+    public <T> T get(String key, Class<T> clazz) {
+        return get(key, clazz, NOT_EXPIRE);
+    }
+
+    /**
+     * 取值(直接返回&更新过期时间)
+     *
+     * @param key    key值
+     * @param expire 更新过期时间
+     * @return
+     */
+    public String get(String key, long expire) {
+        String value = valueOperations.get(key);
+        if (expire != NOT_EXPIRE) {
+            // 更新该key值的过期时间为指定过期时间
+            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+        }
+        return value;
+    }
+
+    /**
+     * 取值(根据key取值)
+     *
+     * @param key key值
+     * @return
+     */
+    public String get(String key) {
+        return get(key, NOT_EXPIRE);
+    }
+
+    /**
+     * 删除(根据key删除)
+     *
+     * @param key key值
+     */
+    public void delete(String key) {
+        redisTemplate.delete(key);
+    }
+
+    /**
+     * 对象转JSON字符串
+     *
+     * @param object 要转成json的对象
+     * @return
+     */
+    public String toJson(Object object) {
+        if (object instanceof Integer || object instanceof Long || object instanceof Float ||
+                object instanceof Double || object instanceof Boolean || object instanceof String) {
+            return String.valueOf(object);
+        }
+        return JSON.toJSONString(object);
+    }
+
+    /**
+     * JSON字符串转指定的对象
+     *
+     * @param json  JSON字符串
+     * @param clazz 要转成的对象
+     * @return
+     */
+    public <T> T fromJson(String json, Class<T> clazz) {
+        return JSONObject.parseObject(json, clazz);
+    }
+}

+ 7 - 0
src/main/java/com/ebei/screen/service/ParkSystemService.java

@@ -230,4 +230,11 @@ public interface ParkSystemService {
      * @param response
      */
     void exportException(ExceptionTrendReq params, HttpServletResponse response);
+
+    /**
+     * 每小时第15分钟初始化一次异常数据
+     *
+     * @return
+     */
+    void excelExportTask();
 }

+ 53 - 10
src/main/java/com/ebei/screen/service/impl/ParkSystemServiceImpl.java

@@ -887,17 +887,19 @@ public class ParkSystemServiceImpl implements ParkSystemService {
                 JSONObject data = obj != null ? obj.getJSONObject("data") : new JSONObject();
                 JSONArray dataList = data != null ? data.getJSONArray(paramsCode) : new JSONArray();
                 List<Map> objects = dataList != null ? dataList.toJavaList(Map.class) : new ArrayList<>();
-                List<Map> maps = ParkUtils.sortDateList(objects, ParkType.EXCEPTION.getSort(), true);
-                if (CollUtil.isNotEmpty(maps)) {
-                    maps.forEach(x -> x.put("photoUrl", ParkUtils.getExcelPhotoUrl(x.get("imageUrl") == null ? (x.get("outCarPhoto") == null ? x.get("inCarPhoto") : x.get("outCarPhoto")) : x.get("imageUrl"), paramsCode.equals("noCard"))));
+                if (CollUtil.isNotEmpty(objects)) {
+                    List<Map> maps = ParkUtils.sortDateList(objects, ParkType.EXCEPTION.getSort(), true);
+                    List<String> photos = maps.stream().map(x -> (x.get("imageUrl") == null ? (x.get("outCarPhoto") == null ? x.get("inCarPhoto") : x.get("outCarPhoto")) : x.get("imageUrl")).toString()).collect(Collectors.toList());
+                    Map<String, byte[]> dictMaps = ParkUtils.getExcelPhotoUrl(photos, paramsCode.equals("noCard"), true);
+                    maps.forEach(x -> x.put("photoUrl", dictMaps.get((x.get("imageUrl") == null ? (x.get("outCarPhoto") == null ? x.get("inCarPhoto") : x.get("outCarPhoto")) : x.get("imageUrl")).toString())));
+                    InputStream inputStream = ResourceUtil.getStream("temp/exception.xlsx");
+                    File ex = File.createTempFile("exception", ".xlsx");
+                    FileUtil.writeFromStream(inputStream, ex);
+                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+                    EasyExcel.write(outputStream).withTemplate(ex).sheet("异常信息").doFill(maps);
+                    excelNames.add(fileName);
+                    streams.add(outputStream);
                 }
-                InputStream inputStream = ResourceUtil.getStream("temp/exception.xlsx");
-                File ex = File.createTempFile("exception", ".xlsx");
-                FileUtil.writeFromStream(inputStream, ex);
-                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-                EasyExcel.write(outputStream).withTemplate(ex).sheet("异常信息").doFill(maps);
-                excelNames.add(fileName);
-                streams.add(outputStream);
             } catch (Exception e) {
                 log.info("异常信息报表导出出现异常:{}", e);
             } finally {
@@ -912,6 +914,47 @@ public class ParkSystemServiceImpl implements ParkSystemService {
         }
     }
 
+    /**
+     * 每小时第15分钟初始化一次异常数据
+     *
+     * @return
+     */
+    @Override
+    public void excelExportTask() {
+        List<String> codeList = ParkExceptionType.codeList();
+        List<String> parkCodeList = ParkUtils.getParkCodeList();
+        // String format = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
+        String format = "20210708";
+        CountDownLatch countDownLatch = new CountDownLatch(parkCodeList.size());
+        parkCodeList.forEach(code -> RunnableUtils.start(() -> {
+            try {
+                JSONObject obj = mongoTemplate.findById(code + "_" + format, JSONObject.class, ParkType.EXCEPTION.getCode());
+                if (obj == null) {
+                    return;
+                }
+                JSONObject data = obj != null ? obj.getJSONObject("data") : new JSONObject();
+                codeList.forEach(paramsCode -> {
+                    JSONArray dataList = data != null ? data.getJSONArray(paramsCode) : new JSONArray();
+                    List<Map> objects = dataList != null ? dataList.toJavaList(Map.class) : new ArrayList<>();
+                    if (CollUtil.isNotEmpty(objects)) {
+                        List<Map> maps = ParkUtils.sortDateList(objects, ParkType.EXCEPTION.getSort(), true);
+                        List<String> photos = maps.stream().map(x -> (x.get("imageUrl") == null ? (x.get("outCarPhoto") == null ? x.get("inCarPhoto") : x.get("outCarPhoto")) : x.get("imageUrl")).toString()).collect(Collectors.toList());
+                        ParkUtils.getExcelPhotoUrl(photos, paramsCode.equals("noCard"), false);
+                    }
+                });
+            } catch (Exception e) {
+                log.info("定时初始化Excel数据出现异常:{}", e);
+            } finally {
+                countDownLatch.countDown();
+            }
+        }));
+        try {
+            countDownLatch.await();
+        } catch (Exception e) {
+            log.info("定时初始化Excel数据出现异常:{}", e);
+        }
+    }
+
     /**
      * 不同收费方式停车统计
      *

+ 13 - 0
src/main/resources/application-dev.yml

@@ -10,6 +10,19 @@ spring:
       database: eaglescreen
       host: 127.0.0.1
       port: 27017
+  redis:
+    host: 172.18.0.23
+    port: 6379
+    database: 0
+    password: Ebe1tech/Passw0rd
+    timeout: 10000ms
+    open: true
+    jedis:
+      pool:
+        max-active: 1024
+        max-idle: 200
+        min-idle: 0
+        max-wait: 10000
 energy:
   # 多个用逗号分隔开
   grpId: 197069285991913100

BIN
src/main/resources/temp/exception.xlsx