From d81324fa771b7427e75f148f0ed3a415b3a88a81 Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 13 Dec 2023 10:39:36 +0800 Subject: [PATCH 1/3] update --- .../thirdparty/zhongdianlian/service/impl/ZDLServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/zhongdianlian/service/impl/ZDLServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/zhongdianlian/service/impl/ZDLServiceImpl.java index 86104af10..a2035ea0a 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/zhongdianlian/service/impl/ZDLServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/zhongdianlian/service/impl/ZDLServiceImpl.java @@ -120,7 +120,7 @@ public class ZDLServiceImpl implements ZDLService { // 组装中电联平台所需要的数据格式 ZDLStationInfo info = ZDLStationInfo.builder() .stationId(String.valueOf(dto.getStationId())) - .operatorId(operatorId) + .operatorId(Constants.OPERATORID_JIANG_SU) // .equipmentOwnerId(Constants.OPERATORID_JIANG_SU) .stationName(pileStationInfo.getStationName()) .countryCode(pileStationInfo.getCountryCode()) @@ -226,7 +226,7 @@ public class ZDLServiceImpl implements ZDLService { for (ThirdPartyStationInfoVO pileStationInfo : pageInfo.getList()) { ZDLStationInfo stationInfo = new ZDLStationInfo(); stationInfo.setStationId(String.valueOf(pileStationInfo.getId())); - stationInfo.setOperatorId(dto.getOperatorId()); // 组织机构代码 + stationInfo.setOperatorId(Constants.OPERATORID_JIANG_SU); // 组织机构代码 String organizationCode = pileStationInfo.getOrganizationCode(); if (StringUtils.isNotBlank(organizationCode) && organizationCode.length() == 18) { String equipmentOwnerId = StringUtils.substring(organizationCode, organizationCode.length() - 10, organizationCode.length() - 1); From f3c0874e7dcb638c2fe618759eff767a8f84d469 Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 13 Dec 2023 10:43:50 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=20=E8=BD=A6=E4=BD=8D?= =?UTF-8?q?=E7=9B=B8=E6=9C=BA=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0=E5=88=B0?= =?UTF-8?q?OSS=E6=9C=8D=E5=8A=A1=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/file/AliyunOssUploadUtils.java | 36 ++++++ .../jsowell/common/util/file/ImageUtils.java | 44 ++++++- .../camera/service/CameraService.java | 114 +++++++++++++----- jsowell-ui/src/views/pile/camera/index.vue | 30 ++--- 4 files changed, 177 insertions(+), 47 deletions(-) diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/file/AliyunOssUploadUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/file/AliyunOssUploadUtils.java index b52db113d..892343f6d 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/file/AliyunOssUploadUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/file/AliyunOssUploadUtils.java @@ -2,12 +2,15 @@ package com.jsowell.common.util.file; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.ObjectMetadata; import com.jsowell.common.config.AliyunOssConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.time.LocalDateTime; import java.time.ZoneOffset; @@ -62,4 +65,37 @@ public class AliyunOssUploadUtils { } return aliyunOssConfig.getUrl() + "/" + filePathName; } + + /** + * 上传到阿里云(车位相机用) + * @param compressedImageBytes + * @param fileName 文件名 (车位号 + 时间戳).jpg + * @return + */ + public static String upload2OSS(byte[] compressedImageBytes, String fileName) { + // 生成 OSSClient + OSS ossClient = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret()); + + // 创建对象元数据,默认是可读的 + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(compressedImageBytes.length); // 设置内容长度 + + // 创建输入流 + InputStream inputStream = new ByteArrayInputStream(compressedImageBytes); + + //获取当前时间 + LocalDateTime currentDate = LocalDateTime.now(); + String dir_name = currentDate.getYear() + "/" + currentDate.getMonthValue() + "/" + currentDate.getDayOfMonth() + "/"; + + // 随机数 + String randomNumber = Long.toHexString(currentDate.toEpochSecond(ZoneOffset.UTC)) + "-"; + + // 文件路径名称 + String filePathName = aliyunOssConfig.getFilehost() + "/" + dir_name + randomNumber + fileName; + ossClient.putObject(aliyunOssConfig.getBucketName(), filePathName, inputStream, metadata); + + // 关闭 OSS 客户端 + ossClient.shutdown(); + return aliyunOssConfig.getUrl() + "/" + filePathName; + } } \ No newline at end of file diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/file/ImageUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/file/ImageUtils.java index d48583bb4..21468c208 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/file/ImageUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/file/ImageUtils.java @@ -7,9 +7,12 @@ import org.apache.poi.util.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.InputStream; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import java.awt.image.BufferedImage; +import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.Arrays; @@ -76,4 +79,39 @@ public class ImageUtils { IOUtils.closeQuietly(in); } } + + /** + * 图像压缩方法 + * @param originalImage 源图像 + * @param quality 压缩质量 + * @return + */ + public static BufferedImage compressImage(BufferedImage originalImage, double quality) { + BufferedImage compressedImage = null; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + try { + // 设置压缩参数 + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality((float) quality); + + // 压缩图像 + writer.setOutput(ImageIO.createImageOutputStream(outputStream)); + writer.write(null, new IIOImage(originalImage, null, null), param); + + // 读取压缩后的图像 + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + compressedImage = ImageIO.read(inputStream); + + // 关闭流 + outputStream.close(); + inputStream.close(); + writer.dispose(); + } catch (IOException e) { + e.printStackTrace(); + } + return compressedImage; + } } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/camera/service/CameraService.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/camera/service/CameraService.java index cfb4e3d7c..910d500f7 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/camera/service/CameraService.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/camera/service/CameraService.java @@ -1,18 +1,32 @@ package com.jsowell.thirdparty.camera.service; -import cn.hutool.core.codec.Base64; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.jsowell.common.constant.CacheConstants; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.ObjectMetadata; +import com.jsowell.common.config.AliyunOssConfig; import com.jsowell.common.core.redis.RedisCache; -import com.jsowell.common.util.DateUtils; import com.jsowell.common.util.StringUtils; +import com.jsowell.common.util.file.AliyunOssUploadUtils; +import com.jsowell.common.util.file.ImageUtils; import com.jsowell.pile.domain.PileCameraInfo; import com.jsowell.pile.dto.camera.CameraIdentifyResultsDTO; import com.jsowell.pile.service.IPileCameraInfoService; import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Base64; +import javax.imageio.ImageIO; import java.util.List; @@ -24,6 +38,7 @@ import java.util.List; */ @Service public class CameraService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private RedisCache redisCache; @@ -89,10 +104,17 @@ public class CameraService { return false; } // Base64解密 - String plateNumber = Base64.decodeStr(plate.getPlate()); - String zoneName = Base64.decodeStr(parking.getZoneName()); + String plateNumber = cn.hutool.core.codec.Base64.decodeStr(plate.getPlate()); + String zoneName = cn.hutool.core.codec.Base64.decodeStr(parking.getZoneName()); for (CameraIdentifyResultsDTO.BgImg bgImg : bgImgList) { + // 上传到阿里云OSS,获取图片上传成功后的地址 + String fileName = zoneName + "-" + System.currentTimeMillis() / 1000 + ".jpg"; + String url = saveImage(bgImg.getImage(), fileName); + if (StringUtils.isBlank(url)) { + logger.error("车位号:{} 图片上传失败", zoneName); + continue; + } PileCameraInfo pileCameraInfo = PileCameraInfo.builder() .deviceName(deviceInfo.getDevName()) .deviceIp(deviceInfo.getIp()) @@ -103,7 +125,7 @@ public class CameraService { .zoneName(zoneName) .color(plate.getColor()) .plateType(plate.getType()) - .image(bgImg.getImage()) + .image(url) .build(); // 插入数据库 @@ -114,34 +136,68 @@ public class CameraService { } + /** + * 保存图像 + * @param base64Image 图像的Base64编码 + * @param fileName 文件名 + * @return + */ + private String saveImage(String base64Image, String fileName) { + try { + // 将Base64编码的字符串解码为字节数组 + byte[] imageBytes = Base64.getDecoder().decode(base64Image); + + // 将字节数组转换为 BufferedImage + ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); + BufferedImage originalImage = ImageIO.read(inputStream); + + // 对图像进行压缩 + double quality = 0.5; // 压缩质量 + BufferedImage compressedImage = ImageUtils.compressImage(originalImage, quality); + + // 将压缩后的图片转换为字节数组 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ImageIO.write(compressedImage, "jpg", outputStream); + byte[] compressedImageBytes = outputStream.toByteArray(); + + // 上传图片到OSS + String url = AliyunOssUploadUtils.upload2OSS(compressedImageBytes, fileName); + if (StringUtils.isNotBlank(url)) { + return url; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } /** * 将车辆图片信息存入缓存 * @param jsonObject */ - private boolean saveCarPicture2Redis(JSONObject jsonObject, String parkingState) { - // 获取车牌号 - String plateNumber = jsonObject.getJSONObject("plate").getString("plate"); - if (StringUtils.isBlank(plateNumber)) { - return false; - } - // 获取背景图片 - JSONArray bgImgs = jsonObject.getJSONArray("bg_img"); - List bgImgList = bgImgs.toList(CameraIdentifyResultsDTO.BgImg.class); - if (CollectionUtils.isEmpty(bgImgList)) { - return false; - } - for (CameraIdentifyResultsDTO.BgImg bgImg : bgImgList) { - String image = bgImg.getImage(); // 图片的 base64 编码 - // String key = bgImg.getKey(); // 索引id - // key: 前缀 + 车牌号 + 日期 + 入场/出场状态 - String redisKey = CacheConstants.CAMERA_IMAGE_BY_PLATE_NUMBER + plateNumber + "_" + DateUtils.getDate() + "_" + parkingState; - // 存入缓存 - // TODO 暂时永久保存 - redisCache.setCacheObject(redisKey, image); - } - return true; - } + // private boolean saveCarPicture2Redis(JSONObject jsonObject, String parkingState) { + // // 获取车牌号 + // String plateNumber = jsonObject.getJSONObject("plate").getString("plate"); + // if (StringUtils.isBlank(plateNumber)) { + // return false; + // } + // // 获取背景图片 + // JSONArray bgImgs = jsonObject.getJSONArray("bg_img"); + // List bgImgList = bgImgs.toList(CameraIdentifyResultsDTO.BgImg.class); + // if (CollectionUtils.isEmpty(bgImgList)) { + // return false; + // } + // for (CameraIdentifyResultsDTO.BgImg bgImg : bgImgList) { + // String image = bgImg.getImage(); // 图片的 base64 编码 + // // String key = bgImg.getKey(); // 索引id + // // key: 前缀 + 车牌号 + 日期 + 入场/出场状态 + // String redisKey = CacheConstants.CAMERA_IMAGE_BY_PLATE_NUMBER + plateNumber + "_" + DateUtils.getDate() + "_" + parkingState; + // // 存入缓存 + // // 暂时永久保存 + // redisCache.setCacheObject(redisKey, image); + // } + // return true; + // } } diff --git a/jsowell-ui/src/views/pile/camera/index.vue b/jsowell-ui/src/views/pile/camera/index.vue index 67f3b3e16..28e331189 100644 --- a/jsowell-ui/src/views/pile/camera/index.vue +++ b/jsowell-ui/src/views/pile/camera/index.vue @@ -5,11 +5,11 @@ - - - - + + + + + @@ -17,19 +17,19 @@ - - - - - - + + + + + + + - - - + + + 搜索 重置 From f1a530599688a9642d00e74aedafffc4becdb0da Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 13 Dec 2023 14:54:32 +0800 Subject: [PATCH 3/3] =?UTF-8?q?update=20=20=E5=90=8E=E7=AE=A1=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA=E7=85=A7=E7=89=87=E9=A1=B5=E9=9D=A2=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jsowell-ui/src/views/pile/camera/index.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jsowell-ui/src/views/pile/camera/index.vue b/jsowell-ui/src/views/pile/camera/index.vue index 28e331189..8af03b8cd 100644 --- a/jsowell-ui/src/views/pile/camera/index.vue +++ b/jsowell-ui/src/views/pile/camera/index.vue @@ -91,8 +91,9 @@