diff --git a/src/main/java/com/iflytop/colortitration/app/controller/PhotoController.java b/src/main/java/com/iflytop/colortitration/app/controller/PhotoController.java index 4b042cc..a995ab6 100644 --- a/src/main/java/com/iflytop/colortitration/app/controller/PhotoController.java +++ b/src/main/java/com/iflytop/colortitration/app/controller/PhotoController.java @@ -1,6 +1,7 @@ package com.iflytop.colortitration.app.controller; import com.iflytop.colortitration.app.model.dto.PhotoSaveDTO; +import com.iflytop.colortitration.app.model.dto.PhotoTakeDTO; import com.iflytop.colortitration.common.base.BasePageQuery; import com.iflytop.colortitration.common.model.vo.PhotoListVO; import com.iflytop.colortitration.common.model.vo.PhotoVO; @@ -40,11 +41,11 @@ public class PhotoController { @Operation(summary = "拍摄一张照片") @PostMapping("/take") - public Result take() throws Exception { - return Result.success(photosService.take()); + public Result take(@RequestBody PhotoTakeDTO photoTakeDTO) throws Exception { + photosService.take(photoTakeDTO.getModuleCode()); + return Result.success(); } - @Operation(summary = "保存照片") @PostMapping("/save") public Result save(@RequestBody PhotoSaveDTO photoSaveDTO) { diff --git a/src/main/java/com/iflytop/colortitration/app/core/state/TitrationModuleState.java b/src/main/java/com/iflytop/colortitration/app/core/state/TitrationModuleState.java index 1eb9a44..5d3f6b6 100644 --- a/src/main/java/com/iflytop/colortitration/app/core/state/TitrationModuleState.java +++ b/src/main/java/com/iflytop/colortitration/app/core/state/TitrationModuleState.java @@ -8,12 +8,14 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.io.File; + @Schema(description = "当前滴定模块状态") @Data @Component @Scope("prototype") @RequiredArgsConstructor -@JsonIgnoreProperties(value = {"advisors", "frozen", "preFiltered", "proxyTargetClass", "targetSource", "exposeProxy", "advisorCount", "proxiedInterfaces", "targetClass"}) +@JsonIgnoreProperties(value = {"advisors", "frozen", "preFiltered", "proxyTargetClass", "targetSource", "exposeProxy", "advisorCount", "proxiedInterfaces", "targetClass", "currentPhoto"}) public class TitrationModuleState { @Schema(description = "滴定模块code") private MultipleModuleCode moduleCode; @@ -21,6 +23,9 @@ public class TitrationModuleState { @Schema(description = "是否存在试管,true 存在 false不存在") private boolean tubeExist = false; + @Schema(description = "当前滴定位照片") + private File currentPhoto; + public TitrationModuleState(MultipleModuleCode moduleCode) { this.moduleCode = moduleCode; } diff --git a/src/main/java/com/iflytop/colortitration/app/model/dto/PhotoTakeDTO.java b/src/main/java/com/iflytop/colortitration/app/model/dto/PhotoTakeDTO.java new file mode 100644 index 0000000..30e1018 --- /dev/null +++ b/src/main/java/com/iflytop/colortitration/app/model/dto/PhotoTakeDTO.java @@ -0,0 +1,11 @@ +package com.iflytop.colortitration.app.model.dto; + +import com.iflytop.colortitration.app.common.enums.MultipleModuleCode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class PhotoTakeDTO { + @Schema(description = "滴定模块code") + private MultipleModuleCode moduleCode; +} diff --git a/src/main/java/com/iflytop/colortitration/app/service/module/TitrationModuleService.java b/src/main/java/com/iflytop/colortitration/app/service/module/TitrationModuleService.java index 2deb0af..ab1c963 100644 --- a/src/main/java/com/iflytop/colortitration/app/service/module/TitrationModuleService.java +++ b/src/main/java/com/iflytop/colortitration/app/service/module/TitrationModuleService.java @@ -362,4 +362,11 @@ public class TitrationModuleService { deviceCommandService.sendCommand(deviceCommand); } + /** + * 判断指定滴定模块是否有试管 + */ + public boolean hasTestTube(MultipleModuleCode moduleCode){ + return true; + } + } diff --git a/src/main/java/com/iflytop/colortitration/app/websocket/server/WebSocketMessageType.java b/src/main/java/com/iflytop/colortitration/app/websocket/server/WebSocketMessageType.java index 9f770bd..8ebf122 100644 --- a/src/main/java/com/iflytop/colortitration/app/websocket/server/WebSocketMessageType.java +++ b/src/main/java/com/iflytop/colortitration/app/websocket/server/WebSocketMessageType.java @@ -47,5 +47,9 @@ public class WebSocketMessageType { * 加热倒计时 */ public static final String HEAT_COUNTDOWN = "heat_countdown"; + /** + * 照片 + */ + public static final String PHOTO = "photo"; } diff --git a/src/main/java/com/iflytop/colortitration/common/service/PhotosService.java b/src/main/java/com/iflytop/colortitration/common/service/PhotosService.java index 3091606..6381e11 100644 --- a/src/main/java/com/iflytop/colortitration/common/service/PhotosService.java +++ b/src/main/java/com/iflytop/colortitration/common/service/PhotosService.java @@ -4,7 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.iflytop.colortitration.app.common.enums.MultipleModuleCode; +import com.iflytop.colortitration.app.core.state.DeviceState; import com.iflytop.colortitration.app.model.dto.PhotoSaveDTO; +import com.iflytop.colortitration.app.websocket.server.WebSocketMessageType; +import com.iflytop.colortitration.app.websocket.server.WebSocketSender; import com.iflytop.colortitration.common.base.BasePageQuery; import com.iflytop.colortitration.common.enums.PhotoModeType; import com.iflytop.colortitration.common.exception.AppException; @@ -16,17 +20,19 @@ import com.iflytop.colortitration.common.result.ResultCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; +import org.springframework.util.StreamUtils; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -36,6 +42,9 @@ import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class PhotosService extends ServiceImpl { + private final ResourceLoader resourceLoader; + private final DeviceState deviceState; + private final WebSocketSender webSocketSender; @Value("${photo.url}") private String url; @@ -79,32 +88,42 @@ public class PhotosService extends ServiceImpl { return null; } - public String take() throws Exception { -// Path directoryPath = Paths.get(path + "/temp"); -// try (Stream paths = Files.list(directoryPath)) { -// paths.forEach(file -> { -// try { -// Files.delete(file); -// } catch (IOException e) { -// log.error("删除文件时发生错误", e); -// } -// }); -// } catch (IOException e) { -// log.error("读取目录时发生错误", e); -// } -// -// try { -// String tempFilePath = "/temp/" + System.currentTimeMillis() + ".png"; -// String filePath = path + tempFilePath; -// driver.enable(); -// driver.saveColorImg(filePath); -// return url + tempFilePath; -// } catch (Exception e) { -// throw new AppException(ResultCode.SYSTEM_ERROR); -// } finally { -// driver.disable(); -// } - return null; + public void take(MultipleModuleCode moduleCode) throws IOException { + File file = getStaticFile("1.png"); + deviceState.getTitrationModuleStateMap().get(moduleCode).setCurrentPhoto(file); + + // 1. 读取图片并转 Base64 + byte[] bytes = Files.readAllBytes(file.toPath()); + String b64 = Base64.getEncoder().encodeToString(bytes); + String dataUrl = "data:image/png;base64," + b64; + + // 2. 构造要发送的对象 + Map payload = new HashMap<>(); + payload.put("moduleCode", moduleCode); + payload.put("image", dataUrl); + + webSocketSender.push(WebSocketMessageType.PHOTO, payload); + } + + public File getStaticFile(String fileName) throws IOException { + Resource res = resourceLoader.getResource("classpath:static/" + fileName); + if (!res.exists()) { + throw new FileNotFoundException("找不到资源"); + } + try { + // 运行在“解压”目录下,直接返回真实文件 + return res.getFile(); + } catch (IOException e) { + // 运行在 JAR 内部,复制到临时文件 + File tmp = File.createTempFile("static-" + fileName, ".png"); + try (InputStream is = res.getInputStream(); + OutputStream os = new FileOutputStream(tmp)) { + StreamUtils.copy(is, os); + } + //在 JVM 退出时删除 + tmp.deleteOnExit(); + return tmp; + } } public void save(PhotoSaveDTO photoSaveDTO) { diff --git a/src/main/resources/static/1.png b/src/main/resources/static/1.png new file mode 100644 index 0000000..08d0cd2 Binary files /dev/null and b/src/main/resources/static/1.png differ diff --git a/src/main/resources/static/2.png b/src/main/resources/static/2.png new file mode 100644 index 0000000..64eace8 Binary files /dev/null and b/src/main/resources/static/2.png differ diff --git a/src/main/resources/static/3.png b/src/main/resources/static/3.png new file mode 100644 index 0000000..03d4905 Binary files /dev/null and b/src/main/resources/static/3.png differ