hyy 4 сар өмнө
parent
commit
bffb669231
13 өөрчлөгдсөн 162 нэмэгдсэн , 259 устгасан
  1. 2 1
      yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
  2. 1 0
      yudao-module-museums/yudao-module-museums-api/src/main/java/cn/iocoder/yudao/module/museums/enums/ErrorCodeConstants.java
  3. 25 14
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/SpecimenInfoController.java
  4. 26 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenOutboundFormRespVO.java
  5. 1 9
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/SpecimenOutboundController.java
  6. 10 10
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundConfirmReqVO.java
  7. 0 6
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundReturnReqVO.java
  8. 31 31
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundSaveReqVO.java
  9. 3 65
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundWithInfoRespVO.java
  10. 1 1
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimeninfo/SpecimenInfoMapper.java
  11. 1 1
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImpl.java
  12. 0 9
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimenoutbound/SpecimenOutboundService.java
  13. 61 112
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimenoutbound/SpecimenOutboundServiceImpl.java

+ 2 - 1
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java

@@ -47,7 +47,8 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
 @RestControllerAdvice
 @AllArgsConstructor
 @Slf4j
-public class GlobalExceptionHandler {
+public class
+GlobalExceptionHandler {
 
     /**
      * 忽略的 ServiceException 错误提示,避免打印过多 logger

+ 1 - 0
yudao-module-museums/yudao-module-museums-api/src/main/java/cn/iocoder/yudao/module/museums/enums/ErrorCodeConstants.java

@@ -16,6 +16,7 @@ public class ErrorCodeConstants {
     // ========== 标本出库回库信息 1-016-001-000 ==========
     public static final ErrorCode SPECIMEN_OUTBOUND_NOT_EXISTS = new ErrorCode(1-016-001-000, "标本出库回库信息不存在");
     public static final ErrorCode NO_PERMISSION_VIEW_NON_RETURNED_SPECIMENS = new ErrorCode(1-016-001-000, "没有权限查看非已回库的标本出库信息");
+    public static final ErrorCode SPECIMEN_IS_LENDING_OUT = new ErrorCode(1-016-001-000, "标本当前状态为借出中,无法进行出库操作");
     // ========== 博物馆照片组 1-016-002-000 ==========
     public static final ErrorCode PHOTO_GROUP_NOT_EXISTS = new ErrorCode(1-016-002-000, "博物馆照片组不存在");
     public static final ErrorCode PHOTO_GROUP_UPLOAD_FAILED = new ErrorCode(1-016-000-003, "照片组上传失败");

+ 25 - 14
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/SpecimenInfoController.java

@@ -145,7 +145,8 @@ public class SpecimenInfoController {
                         .imageName("image1.jpg,image3.jpg,image3.jpg")
                         .specimenPrice(new BigDecimal("100.01"))
                         .specimenAmount(20)
-                        .collectionStatus(0)
+//                        .collectionStatus("在馆")
+                        .collectionStatus(0)//在馆
                         .build()
         );
         ExcelUtils.write(response, "标本导入模板.xls", "标本信息", SpecimenImportExcelVO.class, list);
@@ -184,32 +185,42 @@ public class SpecimenInfoController {
     @PostMapping("/import-specimen-with-images")
     @Operation(summary = "导入标本及其图片")
     @Parameters({
-            @Parameter(name = "file", description = "Excel 文件", required = true),
-            @Parameter(name = "imageFile", description = "压缩包文件", required = true),
+            @Parameter(name = "file", description = "Excel 文件", required = false), // 将 required 设置为 false
+            @Parameter(name = "imageFile", description = "压缩包文件", required = false), // 将 required 设置为 false
             @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
     })
     @PreAuthorize("@ss.hasPermission('museums:specimen-info:import')")
     public CommonResult<SpecimenImportRespVO> importSpecimenWithImages(
-            @RequestParam("file") MultipartFile file,
-            @RequestParam("imageFile") MultipartFile imageFile,
+            @RequestParam(value = "file", required = false) MultipartFile file, // 将 required 设置为 false
+            @RequestParam(value = "imageFile", required = false) MultipartFile imageFile, // 将 required 设置为 false
             @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
 
-        // 读取 Excel 文件中的标本数据
-        List<SpecimenImportExcelVO> specimenList = ExcelUtils.read(file, SpecimenImportExcelVO.class);
+        SpecimenImportRespVO importResult = null;
 
-        // 处理标本的导入
-        SpecimenImportRespVO importResult = specimenInfoService.importSpecimenList(specimenList, updateSupport);
+        // 处理 Excel 文件中的标本数据(如果存在)
+        if (file != null && !file.isEmpty()) {
+            List<SpecimenImportExcelVO> specimenList = ExcelUtils.read(file, SpecimenImportExcelVO.class);
+            importResult = specimenInfoService.importSpecimenList(specimenList, updateSupport);
+        }
 
-        // 处理标本图片的导入
-        String imageResult = specimenInfoService.importSpecimenImages(imageFile);
-        // 确保返回的数据不为 null
-        if (imageResult == null) {
-            throw exception(INVALID_IMAGE_FORMAT);
+        // 处理标本图片的导入(如果存在)
+        if (imageFile != null && !imageFile.isEmpty()) {
+            String imageResult = specimenInfoService.importSpecimenImages(imageFile);
+            // 确保返回的数据不为 null
+            if (imageResult == null) {
+                throw exception(INVALID_IMAGE_FORMAT);
+            }
+        }
+
+        // 如果没有上传任何文件,返回相应的提示信息
+        if (importResult == null && imageFile == null) {
+            throw new Exception("请至少上传一个标本文件或一个图片文件。");
         }
 
         return success(importResult);
     }
 
+
     //工作台
     //根据入库的登记情况统计本年标本入库信息。
     @GetMapping("/statistics/entry/{year}")

+ 26 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenOutboundFormRespVO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+@Schema(description = "管理后台 - 标本出库单 Request VO")
+@Data
+public class SpecimenOutboundFormRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer id;
+
+    @Schema(description = "标本类型(矿物、岩石矿石、化石、陨石)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "标本类型(矿物、岩石矿石、化石、陨石)不能为空")
+    private Integer specimenType;
+
+    @Schema(description = "存放位置")
+    private String storageLocation;
+
+    @Schema(description = "图片名称", example = "芋艿")
+    private String imageName;
+
+    @Schema(description = "图片路径")
+    private String imagePath;
+}

+ 1 - 9
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/SpecimenOutboundController.java

@@ -8,13 +8,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
 
-import javax.validation.constraints.*;
 import javax.validation.*;
 import javax.servlet.http.*;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.io.IOException;
-import java.util.stream.Collectors;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -22,7 +20,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -31,7 +28,6 @@ import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.NO_PERMISSION_VIEW_NON_RETURNED_SPECIMENS;
-import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.SPECIMEN_OUTBOUND_NOT_EXISTS;
 
 import cn.iocoder.yudao.module.museums.controller.admin.specimenoutbound.vo.*;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimenoutbound.SpecimenOutboundDO;
@@ -92,8 +88,6 @@ public class SpecimenOutboundController {
 //        specimenOutboundService.confirmOutbound(id, getLoginUserId());
 //        return success(true);
 //    }
-
-
     @PostMapping("/confirmOutbound")
     @Operation(summary = "确认标本出库")
     @PreAuthorize("@ss.hasPermission('museums:specimen-outbound:confirm')")
@@ -140,7 +134,6 @@ public class SpecimenOutboundController {
         }
     }
 
-
     @GetMapping("/page")
     @Operation(summary = "获得标本出库回库信息分页")
     @PreAuthorize("@ss.hasPermission('museums:specimen-outbound:query')")
@@ -204,7 +197,6 @@ public class SpecimenOutboundController {
 //        List<SpecimenOutboundReturnReqVO> result = specimenOutboundService.getReturnStatistics(year);
 //        return success(result);
 //    }
-
     @GetMapping("/statistics/return/{year}")
     @Operation(summary = "根据回库登记情况统计本年标本回库信息")
     @Parameter(name = "year", description = "年份", required = true, example = "2024")
@@ -229,6 +221,7 @@ public class SpecimenOutboundController {
     }
 
 
+    //获取出库单,方便操作员查看标本编号、图片及标本存放位置等。
     @GetMapping("/specimenInfo")
     @Operation(summary = "获得标本出库回库信息")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
@@ -239,7 +232,6 @@ public class SpecimenOutboundController {
         if (specimenOutbound == null) {
             throw exception(NO_PERMISSION_VIEW_NON_RETURNED_SPECIMENS);
         }
-
         return success(specimenOutbound);
     }
 

+ 10 - 10
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundConfirmReqVO.java

@@ -11,16 +11,16 @@ public class SpecimenOutboundConfirmReqVO {
 
     @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
     private Long id;
-
-    @Schema(description = "审批状态", example = "2")
-    private Integer status;
-
-    @Schema(description = "出库员", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Long operator;
-
-    @Schema(description = "出库时间")
-    private LocalDateTime outgoingTime;
-
+//
+//    @Schema(description = "审批状态", example = "2")
+//    private Integer status;
+//
+//    @Schema(description = "出库员", requiredMode = Schema.RequiredMode.REQUIRED)
+//    private Long operator;
+//
+//    @Schema(description = "出库时间")
+//    private LocalDateTime outgoingTime;
+//
 //    @Schema(description = "标本状态(已出库、已回库、出库审批中)", example = "2")
 //    private Integer sampleStatus;
 

+ 0 - 6
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundReturnReqVO.java

@@ -24,12 +24,6 @@ public class SpecimenOutboundReturnReqVO {
     @Schema(description = "点收人")
     private String receiver;
 
-    @Schema(description = "退还日期")
-    private LocalDateTime returnDate;
-
     @Schema(description = "备注信息")
     private String remarks;
-
-    @Schema(description = "审批状态", example = "2")
-    private Integer status;
 }

+ 31 - 31
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundSaveReqVO.java

@@ -40,40 +40,40 @@ public class SpecimenOutboundSaveReqVO {
     @Schema(description = "附件上传")
     private String attachments;
 
-    @Schema(description = "审批状态", example = "2")
-    private Integer status;
+//    @Schema(description = "审批状态", example = "2")
+//    private Integer status;
 
     @Schema(description = "备注信息")
     private String remarks;
 
-    @Schema(description = "出库时间")
-    private LocalDateTime outgoingTime;
-
-    @Schema(description = "标本情况")
-    private String specimenCondition;
-
-    @Schema(description = "标本状态(已出库、已回库、出库审批中)", example = "2")
-    private Integer sampleStatus;
-
-    @Schema(description = "驳回原因", example = "反对")
-    private String processInstanceId;
-
-    @Schema(description = "出库员")
-    private Long operator;
-
-    @Schema(description = "退还人")
-    private String returner;
-
-    @Schema(description = "点收人")
-    private String receiver;
-
-    @Schema(description = "退还日期")
-    private LocalDateTime returnDate;
-
-    @Schema(description = "审批时间")
-    private LocalDateTime approvalTime;
-
-    @Schema(description = "审批员")
-    private Long approveUsers;
+//    @Schema(description = "出库时间")
+//    private LocalDateTime outgoingTime;
+//
+//    @Schema(description = "标本情况")
+//    private String specimenCondition;
+//
+//    @Schema(description = "标本状态(已出库、已回库、出库审批中)", example = "2")
+//    private Integer sampleStatus;
+//
+//    @Schema(description = "驳回原因", example = "反对")
+//    private String processInstanceId;
+//
+//    @Schema(description = "出库员")
+//    private Long operator;
+//
+//    @Schema(description = "退还人")
+//    private String returner;
+//
+//    @Schema(description = "点收人")
+//    private String receiver;
+//
+//    @Schema(description = "退还日期")
+//    private LocalDateTime returnDate;
+//
+//    @Schema(description = "审批时间")
+//    private LocalDateTime approvalTime;
+//
+//    @Schema(description = "审批员")
+//    private Long approveUsers;
 
 }

+ 3 - 65
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/vo/SpecimenOutboundWithInfoRespVO.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.museums.controller.admin.specimenoutbound.vo;
 
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.SpecimenOutboundFormRespVO;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
@@ -14,7 +15,7 @@ import java.util.List;
 @Schema(description = "管理后台 - 标本出库回库信息 Response VO")
 @Data
 @ExcelIgnoreUnannotated
-public class SpecimenOutboundWithInfoRespVO extends SpecimenOutboundRespVO{
+public class SpecimenOutboundWithInfoRespVO {
     @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
     @ExcelProperty("主键")
     private Long id;
@@ -43,79 +44,16 @@ public class SpecimenOutboundWithInfoRespVO extends SpecimenOutboundRespVO{
     @ExcelProperty("申请出库的用途")
     private String applicationUsage;
 
-    @Schema(description = "附件上传")
-    @ExcelProperty("附件上传")
-    private String attachments;
-
-    @Schema(description = "审批状态", example = "2")
-    @ExcelProperty(value = "审批状态", converter = DictConvert.class)
-    @DictFormat("museums_specimen_info") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
-    private Integer status;
-
     @Schema(description = "备注信息")
     @ExcelProperty("备注信息")
     private String remarks;
 
-    @Schema(description = "出库时间")
-    @ExcelProperty("出库时间")
-    private LocalDateTime outgoingTime;
-
     @Schema(description = "标本情况")
     @ExcelProperty("标本情况")
     private String specimenCondition;
 
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "标本状态(已出库、已回库、出库审批中)", example = "2")
-    @ExcelProperty(value = "标本状态(已出库、已回库、出库审批中)", converter = DictConvert.class)
-    @DictFormat("museums_specimen_info") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
-    private Integer sampleStatus;
-
-    @Schema(description = "驳回原因", example = "27504")
-    @ExcelProperty("驳回原因")
-    private String processInstanceId;
-
-    @Schema(description = "出库员")
-    @ExcelProperty("出库员")
-    private Long operator;
-
-    @Schema(description = "退还人")
-    @ExcelProperty("退还人")
-    private String returner;
-
-    @Schema(description = "点收人")
-    @ExcelProperty("点收人")
-    private String receiver;
-
-    @Schema(description = "退还日期")
-    @ExcelProperty("退还日期")
-    private LocalDateTime returnDate;
-
-    @Schema(description = "审批时间")
-    @ExcelProperty("审批时间")
-    private LocalDateTime approvalTime;
-
-    @Schema(description = "审批员")
-    @ExcelProperty("审批员")
-    private Long approveUsers;
-
-//    @Schema(description = "图片路径")
-//    @ExcelProperty("图片路径")
-//    private String imagePath;
-//
-//    @Schema(description = "存放位置")
-//    @ExcelProperty("存放位置")
-//    private String storageLocation;
-//
-//    @Schema(description = "标本编号", requiredMode = Schema.RequiredMode.REQUIRED)
-//    @ExcelProperty("标本编号")
-//    private String specimenNumber;
-
-
     @Schema(description = "关联标本信息列表")
     @ExcelProperty("关联标本信息")
-    private List<SpecimenInfoDO> specimenInfoList;
+    private List<SpecimenOutboundFormRespVO> specimenInfoList;
 
 }

+ 1 - 1
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimeninfo/SpecimenInfoMapper.java

@@ -149,7 +149,7 @@ public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
 
 
     // 根据多个 ID 查询标本信息
-    List<SpecimenInfoDO> selectByIds(List<Long> ids);
+    List<SpecimenOutboundFormRespVO> selectByIds(List<Long> ids);
 
     List<Map<String, Object>> selectMonthlyEntryStatisticsByYear(@Param("year") int year);
 

+ 1 - 1
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImpl.java

@@ -145,7 +145,6 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
 
         return respVO;
     }
-    //测试成功
     private boolean isValidImageName(String imageNames) {
         if (imageNames == null) return false;
         String[] names = imageNames.split(",");
@@ -156,6 +155,7 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         }
         return true;
     }
+    //图片导入
     @Override
     @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
     public String importSpecimenImages(MultipartFile file) throws Exception {

+ 0 - 9
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimenoutbound/SpecimenOutboundService.java

@@ -38,14 +38,6 @@ public interface SpecimenOutboundService {
      */
     void confirmOutbound(Long id, Long operator);
 
-    /**
-     * 更新标本信息中的馆藏状态
-     *
-     * @param id 标本ID
-     */
-    void updateSpecimenInfoLendStatus(Long id);
-    void updateSpecimenInfoExistStatus(Long id);
-
     /**
      * 删除标本出库回库信息
      *
@@ -77,7 +69,6 @@ public interface SpecimenOutboundService {
      */
     PageResult<SpecimenOutboundDO> getSpecimenOutboundPage(SpecimenOutboundPageReqVO pageReqVO);
 
-
     void updateStatus(SpecimenOutboundApprovalReqVO req);
 
     //工作台

+ 61 - 112
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimenoutbound/SpecimenOutboundServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.museums.service.specimenoutbound;
 
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.SpecimenOutboundFormRespVO;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
 import cn.iocoder.yudao.module.museums.dal.mysql.specimeninfo.SpecimenInfoMapper;
 import org.springframework.stereotype.Service;
@@ -42,16 +43,50 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
     private SpecimenInfoMapper specimenInfoMapper; // 引入标本信息的Mapper
 
     //创建出库申请
+//    @Override
+//    public Long createSpecimenOutbound(SpecimenOutboundSaveReqVO createReqVO) {
+//        // 插入
+//        SpecimenOutboundDO specimenOutbound = BeanUtils.toBean(createReqVO, SpecimenOutboundDO.class);
+//        //TODO 判断标本是否已经出库,如果已经出库,则要求先完成回库
+//        specimenOutboundMapper.insert(specimenOutbound);
+//        // 返回
+//        return specimenOutbound.getId();
+//    }
     @Override
     public Long createSpecimenOutbound(SpecimenOutboundSaveReqVO createReqVO) {
-        // 插入
+        // 将逗号分隔的字符串拆分为List<String>
+        List<String> infoIds = Arrays.asList(createReqVO.getInfoId().split(","));
+
+        // 校验标本状态,收集有效的ID
+        List<Long> validInfoIds = infoIds.stream()
+                .map(infoId -> {
+                    SpecimenInfoDO specimenInfo = specimenInfoMapper.selectById(infoId.trim()); // 去除可能的空格
+                    if (specimenInfo == null) {
+                        throw exception(SPECIMEN_OUTBOUND_NOT_EXISTS);
+                    }
+                    // 判断标本是否在馆或展陈
+                    if (specimenInfo.getCollectionStatus() == 0 || specimenInfo.getCollectionStatus() == 2) {
+                        return Long.valueOf(infoId); // 收集符合条件的ID
+                    } else {
+                        throw exception(SPECIMEN_IS_LENDING_OUT);
+                    }
+                })
+                .collect(Collectors.toList());
+
+        // 拼接info_id字符串
+        String infoIdString = String.join(",", validInfoIds.stream().map(String::valueOf).toArray(String[]::new));
+
+        // 创建出库记录
         SpecimenOutboundDO specimenOutbound = BeanUtils.toBean(createReqVO, SpecimenOutboundDO.class);
-        //TODO 判断标本是否已经出库,如果已经出库,则要求先完成回库
+        specimenOutbound.setInfoId(infoIdString); // 存储逗号分隔的标本ID
         specimenOutboundMapper.insert(specimenOutbound);
-        // 返回
+
+        // 返回出库记录ID
         return specimenOutbound.getId();
     }
 
+
+
     //用来填写回库表单,为方便添加数据,现在先用上面这段
 //    @Override
 //    public void updateSpecimenOutbound(SpecimenOutboundSaveReqVO updateReqVO) {
@@ -61,7 +96,7 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
 //        SpecimenOutboundDO updateObj = BeanUtils.toBean(updateReqVO, SpecimenOutboundDO.class);
 //        specimenOutboundMapper.updateById(updateObj);
 //    }
-    //填写回库表单测试成功
+    //填写回库表单
     @Override
     public void updateSpecimenOutbound(SpecimenOutboundReturnReqVO updateReqVO) {
         // 校验存在
@@ -75,40 +110,27 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
             throw new IllegalStateException("只能更新状态为已出库的标本回库单");
         }
 
-        //TODO 合并一下set写法,可以减少重复代码
-        //existingSpecimen.setStatus(4).setReturnDate(LocalDateTime.now())
-        // .setSpecimenCondition(updateReqVO.getSpecimenCondition())
-        // .setReturner(updateReqVO.getReturner())
-        // .setReceiver(updateReqVO.getReceiver())
-        // .setReceiver(updateReqVO.getRemarks())
-
-
-        // 更新标本状态为已回库(4)
-        existingSpecimen.setStatus(4); // 修改状态为已回库
-
-        // 设置回库时间为当前时间
-        existingSpecimen.setReturnDate(LocalDateTime.now());
-
-        // 填写回库表单信息
-        existingSpecimen.setSpecimenCondition(updateReqVO.getSpecimenCondition());
-        existingSpecimen.setReturner(updateReqVO.getReturner());
-        existingSpecimen.setReceiver(updateReqVO.getReceiver());
-        existingSpecimen.setReceiver(updateReqVO.getRemarks());
+        // 使用链式调用合并设置
+        existingSpecimen.setStatus(4) // 修改状态为已回库
+                .setReturnDate(LocalDateTime.now()) // 设置回库时间为当前时间
+                .setSpecimenCondition(updateReqVO.getSpecimenCondition()) // 设置标本状态
+                .setReturner(updateReqVO.getReturner()) // 设置归还人
+                .setReceiver(updateReqVO.getReceiver()) // 设置接收人
+                .setRemarks(updateReqVO.getRemarks()); // 设置备注
 
         // 更新数据库
         specimenOutboundMapper.updateById(existingSpecimen);
 
-        //TODO 下面只有一句,并且全局只使用了一次,没必要写另外的方法
+        // 更新 info_id 字符串为列表,假设 info_id 是一个用逗号分隔的字符串
+        String[] infoIds = existingSpecimen.getInfoId().split(",");
 
-        // 更新标本信息的馆藏状态为0(在馆)
-        updateSpecimenInfoExistStatus(Long.valueOf(existingSpecimen.getInfoId()));
-    }
-    @Override
-    public void updateSpecimenInfoExistStatus(Long id) {
-        // 更新馆藏状态为0(在馆)
-        specimenInfoMapper.updateCollectionStatus(id, 0);
+        // 更新所有标本信息的馆藏状态为0(在馆)
+        for (String infoId : infoIds) {
+            specimenInfoMapper.updateCollectionStatus(Long.valueOf(infoId.trim()), 0);
+        }
     }
 
+
     //出库审批
     @Override
     public void updateStatus(SpecimenOutboundApprovalReqVO req) {
@@ -131,51 +153,33 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
 
         // TODO 获取用户的id有现成的方法
         //  specimenOutbound.setApproveUsers(getLoginUserId()); // 设置操作员 ID
-
-//        // 获取当前用户 ID
-//        SecurityFrameworkUtils UserContext = null;
-//        Long userId = getLoginUserId(); // 通过方法获取当前用户 ID
-//        specimenOutbound.setApproveUsers(userId); // 设置操作员 ID
         specimenOutbound.setApproveUsers(getLoginUserId()); // 设置操作员 ID
 
         // 更新数据库
         specimenOutboundMapper.updateById(specimenOutbound);
     }
 
-    //确认出库
+    //确认出库,已经简化
     @Override
     public void confirmOutbound(Long id, Long operator) {
         // 校验存在
         validateSpecimenOutboundExists(id);
-
-        // TODO 下面方法的改动和上面同理, 合并set 并且减少一个额外方法的引入
         // 获取当前标本的状态
         SpecimenOutboundDO existingSpecimen = specimenOutboundMapper.selectById(id);
-
         // 判断状态是否为审批通过(1)
         if (existingSpecimen == null || existingSpecimen.getStatus() != 1) {
             throw new IllegalStateException("只有状态为审批通过的标本才能确认出库");
         }
-
-        // 更新标本状态为已出库(3)
-        existingSpecimen.setStatus(3);
-
-        // 设置出库员ID和出库时间
-        existingSpecimen.setOperator(operator);
-        existingSpecimen.setOutgoingTime(LocalDateTime.now());
-
+        // 使用链式调用合并设置
+        existingSpecimen.setStatus(3) // 更新状态为已出库(3)
+                .setOperator(operator) // 设置出库员ID
+                .setOutgoingTime(LocalDateTime.now()); // 设置出库时间
         // 更新数据库
         specimenOutboundMapper.updateById(existingSpecimen);
-
         // 更新标本信息的馆藏状态为1(借出)
-        updateSpecimenInfoLendStatus(Long.valueOf(existingSpecimen.getInfoId()));
+        specimenInfoMapper.updateCollectionStatus(Long.valueOf(existingSpecimen.getInfoId()), 1);
     }
 
-    @Override
-    public void updateSpecimenInfoLendStatus(Long id) {
-        // 更新馆藏状态为1(借出)
-        specimenInfoMapper.updateCollectionStatus(id, 1);
-    }
 
     @Override
     public void deleteSpecimenOutbound(Long id) {
@@ -225,52 +229,13 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
         return specimenOutboundMapper.selectMonthlyOutboundStatistics(year);
     }
 
-    //根据回库的登记情况统计本年标本回库信息
-//    @Override
-//    public List<SpecimenOutboundReturnReqVO> getReturnStatistics(int year) {
-//        return specimenOutboundMapper.selectReturnStatisticsByYear(year);
-//    }
     @Override
     public List<Map<String, Object>> getMonthlyReturnStatistics(int year) {
         return specimenOutboundMapper.getMonthlyReturnStatistics(year);
     }
 
-//    @Override
-//    public List<SpecimenOutboundDO> getSpecimenOutboundsByOutboundOrderId(Long outboundOrderId) {
-//        return specimenOutboundMapper.selectByOutboundOrderId(outboundOrderId);
-//    }
-
-
-//    @Override
-//    public SpecimenOutboundWithInfoRespVO getSpecimenOutboundWithInfo(Long id) {
-//        SpecimenOutboundDO specimenOutbound = specimenOutboundMapper.selectById(id);
-//
-//        if (specimenOutbound == null) {
-//            return null; // 或抛出自定义异常
-//        }
-//
-//
-//        String infoId = specimenOutbound.getInfoId();
-//        SpecimenInfoDO specimenInfo = specimenInfoMapper.selectById(infoId);
-//
-//        SpecimenOutboundWithInfoRespVO response = new SpecimenOutboundWithInfoRespVO();
-//
-//        try {
-//            BeanUtilsBean.getInstance().copyProperties(response, specimenOutbound);
-//        } catch (Exception e) {
-//            // 处理异常,例如记录日志
-//        }
-//
-//        if (specimenInfo != null) {
-//            response.setSpecimenNumber(specimenInfo.getSpecimenNumber());
-//            response.setImagePath(specimenInfo.getImagePath());
-//            response.setStorageLocation(specimenInfo.getStorageLocation());
-//        }
-//
-//        return response;
-//    }
-
 
+    //获取出库标单的方法
     @Override
     public SpecimenOutboundWithInfoRespVO getSpecimenOutboundWithInfo(Long id) {
         // 查询出库信息
@@ -280,19 +245,15 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
         if (specimenOutbound == null) {
             return null; // 或抛出自定义异常
         }
-
         // 查询关联的标本信息
         String infoIds = specimenOutbound.getInfoId(); // 获取 info_id,假设是字符串
         List<Long> idList = Arrays.stream(infoIds.split(","))
                 .map(Long::parseLong)
                 .collect(Collectors.toList());
-
         // 查询所有关联的标本信息
-        List<SpecimenInfoDO> specimenInfoList = specimenInfoMapper.selectByIds(idList); // 假设你有这个 Mapper
-
+        List<SpecimenOutboundFormRespVO> specimenInfoList = specimenInfoMapper.selectByIds(idList); // 假设你有这个 Mapper
         // 创建返回对象
         SpecimenOutboundWithInfoRespVO response = new SpecimenOutboundWithInfoRespVO();
-
         // 手动复制出库信息属性
         response.setId(specimenOutbound.getId());
         response.setInfoId(specimenOutbound.getInfoId());
@@ -300,21 +261,9 @@ public class SpecimenOutboundServiceImpl implements SpecimenOutboundService {
         response.setApplicantName(specimenOutbound.getApplicantName());
         response.setApplicationDate(specimenOutbound.getApplicationDate());
         response.setApplicationUsage(specimenOutbound.getApplicationUsage());
-        response.setImagePath(specimenOutbound.getImagePath());
-        response.setStorageLocation(specimenOutbound.getStorageLocation());
-        response.setSpecimenNumber(specimenOutbound.getSpecimenNumber());
-
         // 设置所有关联的标本信息
         response.setSpecimenInfoList(specimenInfoList);
-
         return response;
     }
 
-
-
-
-
-
-
-
 }