被检设备上传图片功能

This commit is contained in:
caozehui
2026-07-09 16:35:32 +08:00
parent 78b52fa336
commit ca9885c5dc
9 changed files with 372 additions and 9 deletions

View File

@@ -23,6 +23,7 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -69,10 +70,10 @@ public class PqDevController extends BaseController {
} }
@OperateInfo(operateType = OperateType.ADD) @OperateInfo(operateType = OperateType.ADD)
@PostMapping("/add") @PostMapping(value = "/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation("新增被检设备") @ApiOperation("新增被检设备")
@ApiImplicitParam(name = "pqDevParam", value = "被检设备", required = true) @ApiImplicitParam(name = "pqDevParam", value = "被检设备", required = true)
public HttpResult<Boolean> add(@RequestBody @Validated PqDevParam pqDevParam) { public HttpResult<Boolean> add(@ModelAttribute @Validated PqDevParam pqDevParam) {
String methodDescribe = getMethodDescribe("add"); String methodDescribe = getMethodDescribe("add");
LogUtil.njcnDebug(log, "{},新增数据为:{}", methodDescribe, pqDevParam); LogUtil.njcnDebug(log, "{},新增数据为:{}", methodDescribe, pqDevParam);
boolean result = pqDevService.addPqDev(pqDevParam); boolean result = pqDevService.addPqDev(pqDevParam);
@@ -84,10 +85,10 @@ public class PqDevController extends BaseController {
} }
@OperateInfo(operateType = OperateType.UPDATE) @OperateInfo(operateType = OperateType.UPDATE)
@PostMapping("/update") @PostMapping(value = "/update", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation("修改被检设备") @ApiOperation("修改被检设备")
@ApiImplicitParam(name = "updateParam", value = "被检设备", required = true) @ApiImplicitParam(name = "updateParam", value = "被检设备", required = true)
public HttpResult<Boolean> update(@RequestBody @Validated PqDevParam.UpdateParam updateParam) { public HttpResult<Boolean> update(@ModelAttribute @Validated PqDevParam.UpdateParam updateParam) {
String methodDescribe = getMethodDescribe("update"); String methodDescribe = getMethodDescribe("update");
LogUtil.njcnDebug(log, "{},修改数据为:{}", methodDescribe, updateParam); LogUtil.njcnDebug(log, "{},修改数据为:{}", methodDescribe, updateParam);
boolean result = pqDevService.updatePqDev(updateParam); boolean result = pqDevService.updatePqDev(updateParam);
@@ -98,6 +99,14 @@ public class PqDevController extends BaseController {
} }
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DOWNLOAD)
@GetMapping("/image/download")
@ApiOperation("下载设备图片")
@ApiImplicitParam(name = "id", value = "被检设备id", required = true)
public void downloadImage(@RequestParam("id") String id, HttpServletResponse response) {
pqDevService.downloadImage(id, response);
}
@OperateInfo(operateType = OperateType.DELETE) @OperateInfo(operateType = OperateType.DELETE)
@PostMapping("/delete") @PostMapping("/delete")
@ApiOperation("删除被检设备") @ApiOperation("删除被检设备")

View File

@@ -86,8 +86,45 @@
WHERE id = #{planId} WHERE id = #{planId}
</select> </select>
<sql id="DevColumnsNoImage">
dev.Id,
dev.Name,
dev.Pattern,
dev.Dev_Type,
dev.Manufacturer,
dev.Create_Date,
dev.Create_Id,
dev.Hardware_Version,
dev.Software_Version,
dev.Protocol,
dev.IP,
dev.Port,
dev.Encryption_Flag,
dev.Series,
dev.Dev_Key,
dev.Sample_Id,
dev.Arrived_Date,
dev.City_Name,
dev.Gd_Name,
dev.Sub_Name,
dev.Report_Path,
dev.Plan_Id,
dev.Factor_Flag,
dev.Preinvestment_Plan,
dev.Delegate,
dev.Inspect_Channel,
dev.Inspect_Date,
dev.Harm_Sys_Id,
dev.Import_Flag,
dev.State,
dev.Create_By,
dev.Create_Time,
dev.Update_By,
dev.Update_Time
</sql>
<select id="selectByQueryParam" resultType="com.njcn.gather.device.pojo.vo.PqDevVO"> <select id="selectByQueryParam" resultType="com.njcn.gather.device.pojo.vo.PqDevVO">
SELECT dev.*,dev_sub.* FROM pq_dev dev SELECT <include refid="DevColumnsNoImage"/>, dev_sub.* FROM pq_dev dev
left JOIN pq_dev_sub dev_sub ON dev.Id = dev_sub.Dev_Id left JOIN pq_dev_sub dev_sub ON dev.Id = dev_sub.Dev_Id
<where> <where>
dev.state = 1 dev.state = 1
@@ -124,7 +161,7 @@
</select> </select>
<select id="listByDevIds" resultType="com.njcn.gather.device.pojo.vo.PqDevVO"> <select id="listByDevIds" resultType="com.njcn.gather.device.pojo.vo.PqDevVO">
SELECT dev.*, dev_sub.* SELECT <include refid="DevColumnsNoImage"/>, dev_sub.*
FROM pq_dev dev FROM pq_dev dev
left JOIN pq_dev_sub dev_sub ON dev.Id = dev_sub.Dev_Id left JOIN pq_dev_sub dev_sub ON dev.Id = dev_sub.Dev_Id
WHERE dev.state = 1 WHERE dev.state = 1

View File

@@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.Range;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.*; import javax.validation.constraints.*;
@@ -136,6 +137,9 @@ public class PqDevParam {
@ApiModelProperty("是否为导入设备") @ApiModelProperty("是否为导入设备")
private Integer importFlag; private Integer importFlag;
@ApiModelProperty("设备图片")
private MultipartFile image;
/** /**
* 更新操作实体 * 更新操作实体
*/ */

View File

@@ -3,6 +3,7 @@ package com.njcn.gather.device.pojo.po;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -184,6 +185,9 @@ public class PqDev extends BaseEntity implements Serializable {
*/ */
private Integer importFlag; private Integer importFlag;
@JsonIgnore
private byte[] image;
/** /**
* 状态0-删除 1-正常 * 状态0-删除 1-正常
*/ */

View File

@@ -122,4 +122,10 @@ public class PqDevVO extends PqDev {
* 检测点结果 * 检测点结果
*/ */
private List<Integer> monitorResults; private List<Integer> monitorResults;
private Boolean hasImage;
private String imageBase64;
private String imageContentType;
} }

View File

@@ -96,6 +96,14 @@ public interface IPqDevService extends IService<PqDev> {
*/ */
PqDevVO getPqDevById(String id); PqDevVO getPqDevById(String id);
/**
* 下载设备图片
*
* @param id 设备id
* @param response 响应
*/
void downloadImage(String id, HttpServletResponse response);
/** /**
* 获取装置信息和装置下监测点信息 * 获取装置信息和装置下监测点信息
* *

View File

@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
@@ -37,6 +38,7 @@ import com.njcn.gather.device.pojo.po.PqDevSub;
import com.njcn.gather.device.pojo.vo.*; import com.njcn.gather.device.pojo.vo.*;
import com.njcn.gather.device.service.IPqDevService; import com.njcn.gather.device.service.IPqDevService;
import com.njcn.gather.device.service.IPqDevSubService; import com.njcn.gather.device.service.IPqDevSubService;
import com.njcn.gather.device.util.PqDevImageSupport;
import com.njcn.gather.monitor.pojo.po.PqMonitor; import com.njcn.gather.monitor.pojo.po.PqMonitor;
import com.njcn.gather.monitor.pojo.vo.PqMonitorExcel; import com.njcn.gather.monitor.pojo.vo.PqMonitorExcel;
import com.njcn.gather.monitor.service.IPqMonitorService; import com.njcn.gather.monitor.service.IPqMonitorService;
@@ -71,6 +73,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -138,7 +141,8 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
this.checkRepeat(pqDevParam, false); this.checkRepeat(pqDevParam, false);
PqDev pqDev = new PqDev(); PqDev pqDev = new PqDev();
BeanUtil.copyProperties(pqDevParam, pqDev); BeanUtil.copyProperties(pqDevParam, pqDev, CopyOptions.create().setIgnoreProperties("image"));
fillImage(pqDev, pqDevParam);
String currrentScene = sysTestConfigService.getCurrrentScene(); String currrentScene = sysTestConfigService.getCurrrentScene();
this.checkParams(pqDev, currrentScene); this.checkParams(pqDev, currrentScene);
@@ -169,6 +173,19 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
return this.save(pqDev); return this.save(pqDev);
} }
private void fillImage(PqDev pqDev, PqDevParam pqDevParam) {
try {
byte[] image = PqDevImageSupport.processUpload(pqDevParam.getImage());
if (image != null) {
pqDev.setImage(image);
}
} catch (IllegalArgumentException e) {
throw new BusinessException(CommonResponseEnum.FAIL, e.getMessage());
} catch (IOException e) {
throw new BusinessException(CommonResponseEnum.FAIL, "图片处理失败");
}
}
/** /**
* 校验参数 * 校验参数
* *
@@ -211,7 +228,8 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
this.checkRepeat(updateParam, true); this.checkRepeat(updateParam, true);
PqDev pqDev = new PqDev(); PqDev pqDev = new PqDev();
BeanUtil.copyProperties(updateParam, pqDev); BeanUtil.copyProperties(updateParam, pqDev, CopyOptions.create().setIgnoreProperties("image"));
fillImage(pqDev, updateParam);
String currrentScene = sysTestConfigService.getCurrrentScene(); String currrentScene = sysTestConfigService.getCurrrentScene();
this.checkParams(pqDev, currrentScene); this.checkParams(pqDev, currrentScene);
@@ -278,6 +296,8 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
@Override @Override
public List<Map<String, Object>> listUnbound(String pattern) { public List<Map<String, Object>> listUnbound(String pattern) {
List<PqDev> pqDevList = this.lambdaQuery() List<PqDev> pqDevList = this.lambdaQuery()
.select(PqDev::getId, PqDev::getName, PqDev::getDevType, PqDev::getManufacturer,
PqDev::getCityName, PqDev::getGdName, PqDev::getSubName)
.eq(PqDev::getPattern, pattern) .eq(PqDev::getPattern, pattern)
.eq(PqDev::getState, DataStateEnum.ENABLE.getCode()) .eq(PqDev::getState, DataStateEnum.ENABLE.getCode())
.isNull(PqDev::getPlanId) .isNull(PqDev::getPlanId)
@@ -392,6 +412,10 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
@Override @Override
public PqDevVO getPqDevById(String id) { public PqDevVO getPqDevById(String id) {
PqDevVO pqDevVO = this.baseMapper.selectByDevId(id); PqDevVO pqDevVO = this.baseMapper.selectByDevId(id);
if (ObjectUtil.isNull(pqDevVO)) {
return null;
}
setImageEchoFields(pqDevVO);
if (StrUtil.isNotBlank(pqDevVO.getSeries())) { if (StrUtil.isNotBlank(pqDevVO.getSeries())) {
pqDevVO.setSeries(EncryptionUtil.decoderString(1, pqDevVO.getSeries())); pqDevVO.setSeries(EncryptionUtil.decoderString(1, pqDevVO.getSeries()));
} }
@@ -420,6 +444,37 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
return pqDevVO; return pqDevVO;
} }
@Override
public void downloadImage(String id, HttpServletResponse response) {
PqDev pqDev = this.getById(id);
if (ObjectUtil.isNull(pqDev) || pqDev.getImage() == null || pqDev.getImage().length == 0) {
throw new BusinessException(CommonResponseEnum.FAIL, "设备图片不存在");
}
String contentType = PqDevImageSupport.detectContentType(pqDev.getImage());
String filename = "device-image-" + id + "." + PqDevImageSupport.getExtension(contentType);
response.setContentType(contentType);
response.setContentLength(pqDev.getImage().length);
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
try {
response.getOutputStream().write(pqDev.getImage());
response.flushBuffer();
} catch (IOException e) {
throw new BusinessException(CommonResponseEnum.FAIL, "设备图片下载失败");
}
}
private void setImageEchoFields(PqDevVO pqDevVO) {
try {
PqDevImageSupport.ImageEchoPayload payload = PqDevImageSupport.buildEchoPayload(pqDevVO.getImage());
pqDevVO.setHasImage(payload.isHasImage());
pqDevVO.setImageBase64(payload.getImageBase64());
pqDevVO.setImageContentType(payload.getImageContentType());
pqDevVO.setImage(null);
} catch (IllegalArgumentException e) {
throw new BusinessException(CommonResponseEnum.FAIL, e.getMessage());
}
}
/** /**
* 获取查询条件wrapper * 获取查询条件wrapper
@@ -429,6 +484,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
*/ */
private Wrapper getQueryWrapper(PqDevParam.QueryParam queryParam) { private Wrapper getQueryWrapper(PqDevParam.QueryParam queryParam) {
QueryWrapper<PqDev> queryWrapper = new QueryWrapper<>(); QueryWrapper<PqDev> queryWrapper = new QueryWrapper<>();
queryWrapper.select("pq_dev.Id");
if (ObjectUtil.isNotNull(queryParam)) { if (ObjectUtil.isNotNull(queryParam)) {
queryWrapper queryWrapper
.like(StrUtil.isNotBlank(queryParam.getName()), "pq_dev.name", queryParam.getName()) .like(StrUtil.isNotBlank(queryParam.getName()), "pq_dev.name", queryParam.getName())
@@ -1659,7 +1715,10 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
@Override @Override
public Map<String, List<String>> listSelectOptions(String pattern) { public Map<String, List<String>> listSelectOptions(String pattern) {
List<PqDev> pqDevList = this.lambdaQuery().eq(PqDev::getPattern, pattern) List<PqDev> pqDevList = this.lambdaQuery()
.select(PqDev::getCityName, PqDev::getGdName, PqDev::getSubName,
PqDev::getHardwareVersion, PqDev::getSoftwareVersion)
.eq(PqDev::getPattern, pattern)
.eq(PqDev::getState, DataStateEnum.ENABLE.getCode()) .eq(PqDev::getState, DataStateEnum.ENABLE.getCode())
.list(); .list();
String[] devKeyArray = new String[]{"cityName", "gdName", "subName", "hardwareVersion", "softwareVersion"}; String[] devKeyArray = new String[]{"cityName", "gdName", "subName", "hardwareVersion", "softwareVersion"};

View File

@@ -0,0 +1,181 @@
package com.njcn.gather.device.util;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Iterator;
import java.util.Locale;
public final class PqDevImageSupport {
private static final long MAX_FILE_SIZE = 10L * 1024L * 1024L;
private static final int MAX_EDGE = 1600;
private static final float JPEG_QUALITY = 0.82f;
private PqDevImageSupport() {
}
public static ImageEchoPayload buildEchoPayload(byte[] imageBytes) {
if (imageBytes == null || imageBytes.length == 0) {
return new ImageEchoPayload(false, null, null);
}
return new ImageEchoPayload(true, Base64.getEncoder().encodeToString(imageBytes), detectContentType(imageBytes));
}
public static String detectContentType(byte[] imageBytes) {
if (imageBytes == null || imageBytes.length < 4) {
throw new IllegalArgumentException("图片内容无效");
}
if (isPng(imageBytes)) {
return "image/png";
}
if (isJpeg(imageBytes)) {
return "image/jpeg";
}
throw new IllegalArgumentException("仅支持 JPG、PNG 图片");
}
public static byte[] processUpload(MultipartFile image) throws IOException {
if (image == null || image.isEmpty()) {
return null;
}
if (image.getSize() > MAX_FILE_SIZE) {
throw new IllegalArgumentException("图片大小不能超过 10MB");
}
String normalizedName = normalize(image.getOriginalFilename());
String normalizedContentType = normalize(image.getContentType());
boolean allowedType = normalizedContentType.equals("image/jpeg")
|| normalizedContentType.equals("image/png")
|| normalizedName.endsWith(".jpg")
|| normalizedName.endsWith(".jpeg")
|| normalizedName.endsWith(".png");
if (!allowedType) {
throw new IllegalArgumentException("仅支持 JPG、PNG 图片");
}
byte[] originalBytes = image.getBytes();
String contentType = detectContentType(originalBytes);
BufferedImage source;
try (InputStream inputStream = image.getInputStream()) {
source = ImageIO.read(inputStream);
}
if (source == null) {
throw new IllegalArgumentException("图片内容无效");
}
BufferedImage target = scaleIfNeeded(source);
if ("image/png".equals(contentType)) {
return writePng(target);
}
return writeJpeg(target);
}
public static String getExtension(String contentType) {
return "image/png".equals(contentType) ? "png" : "jpg";
}
private static BufferedImage scaleIfNeeded(BufferedImage source) {
int width = source.getWidth();
int height = source.getHeight();
int max = Math.max(width, height);
if (max <= MAX_EDGE) {
return source;
}
double scale = (double) MAX_EDGE / max;
int targetWidth = Math.max(1, (int) Math.round(width * scale));
int targetHeight = Math.max(1, (int) Math.round(height * scale));
int type = source.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : source.getType();
BufferedImage target = new BufferedImage(targetWidth, targetHeight, type);
Graphics2D graphics = target.createGraphics();
try {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.drawImage(source, 0, 0, targetWidth, targetHeight, null);
} finally {
graphics.dispose();
}
return target;
}
private static byte[] writePng(BufferedImage image) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
return outputStream.toByteArray();
}
private static byte[] writeJpeg(BufferedImage image) throws IOException {
BufferedImage rgbImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = rgbImage.createGraphics();
try {
graphics.drawImage(image, 0, 0, null);
} finally {
graphics.dispose();
}
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
if (!writers.hasNext()) {
throw new IOException("未找到 JPG 图片编码器");
}
ImageWriter writer = writers.next();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream)) {
writer.setOutput(imageOutputStream);
ImageWriteParam writeParam = writer.getDefaultWriteParam();
if (writeParam.canWriteCompressed()) {
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionQuality(JPEG_QUALITY);
}
writer.write(null, new IIOImage(rgbImage, null, null), writeParam);
} finally {
writer.dispose();
}
return outputStream.toByteArray();
}
private static boolean isPng(byte[] imageBytes) {
return imageBytes.length >= 8
&& (imageBytes[0] & 0xFF) == 0x89
&& imageBytes[1] == 0x50
&& imageBytes[2] == 0x4E
&& imageBytes[3] == 0x47
&& imageBytes[4] == 0x0D
&& imageBytes[5] == 0x0A
&& imageBytes[6] == 0x1A
&& imageBytes[7] == 0x0A;
}
private static boolean isJpeg(byte[] imageBytes) {
return imageBytes.length >= 3
&& (imageBytes[0] & 0xFF) == 0xFF
&& (imageBytes[1] & 0xFF) == 0xD8
&& (imageBytes[2] & 0xFF) == 0xFF;
}
private static String normalize(String value) {
return value == null ? "" : value.toLowerCase(Locale.ROOT);
}
@Data
@AllArgsConstructor
public static class ImageEchoPayload {
private boolean hasImage;
private String imageBase64;
private String imageContentType;
}
}

View File

@@ -0,0 +1,55 @@
package com.njcn.gather.device.util;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class PqDevImageSupportTest {
@Test
public void buildEchoPayloadReturnsEmptyFieldsWhenImageMissing() {
PqDevImageSupport.ImageEchoPayload payload = PqDevImageSupport.buildEchoPayload(null);
assertFalse(payload.isHasImage());
assertNull(payload.getImageBase64());
assertNull(payload.getImageContentType());
}
@Test
public void buildEchoPayloadDetectsPngAndCreatesBase64() throws Exception {
byte[] imageBytes = createImageBytes("png");
PqDevImageSupport.ImageEchoPayload payload = PqDevImageSupport.buildEchoPayload(imageBytes);
assertTrue(payload.isHasImage());
assertEquals("image/png", payload.getImageContentType());
assertNotNull(payload.getImageBase64());
assertFalse(payload.getImageBase64().isEmpty());
}
@Test(expected = IllegalArgumentException.class)
public void detectContentTypeRejectsInvalidImageBytes() {
PqDevImageSupport.detectContentType(new byte[]{1, 2, 3, 4});
}
private byte[] createImageBytes(String format) throws Exception {
BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, Color.RED.getRGB());
image.setRGB(1, 0, Color.GREEN.getRGB());
image.setRGB(0, 1, Color.BLUE.getRGB());
image.setRGB(1, 1, Color.WHITE.getRGB());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, format, outputStream);
return outputStream.toByteArray();
}
}