hyy 1 месяц назад
Родитель
Сommit
d3154adefd

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

@@ -106,250 +106,6 @@ public class SpecimenInfoController {
                         BeanUtils.toBean(list, SpecimenInfoExportRespVO.class));
     }
 
-//    @GetMapping("/get-specimen-import-template")
-//    @Operation(summary = "获得导入标本信息模板")
-//    public void getSpecimenImportTemplate(HttpServletResponse response) throws IOException {
-//
-//        // 设置响应类型
-//        response.setContentType("application/vnd.ms-excel");
-//        response.setCharacterEncoding("UTF-8");
-//        // URL 编码文件名
-//        String fileName = URLEncoder.encode("标本导入模板.xls", "UTF-8");
-//        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
-//
-//        // 手动创建导出 demo
-//        List<SpecimenImportExcelVO> list = Arrays.asList(
-//                SpecimenImportExcelVO.builder()
-//                        .specimenNumber("01522")  // 标本编号
-//                        .assetNumber("20129103")  // 资产号
-//                        .chineseName("贵州龙")  // 中文名称
-//                        .englishName("keichousaurus")  // 外文名称
-//                        .specimenType(SpecimenTypeEnum.FOSSIL.getType()) // 使用枚举:标本类型(矿物/矿石/岩石/化石/陨石)
-//                        .storageLocation("临展厅")  // 存放位置
-//                        .preservationType(PreservationTypeEnum.SPECIMEN.getPreservationType()) // 使用枚举:保存类型(标本/原石/光片/薄片/切片/模型及其他)
-//                        .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态(完整/受损/严重受损/无实物)
-//                        .specimenAmount(1)  // 数量(件/套)
-//                        .size("1000cm")  // 规格(cm)
-//                        .weight("1.5g")  // 重量(g)
-//                        .composition("硅酸盐")  // 成分/化学式
-//                        .origin("兴义县顶效镇绿荫村")  // 产地/发现地(市级县级产地)
-//                        .economize("贵州省")  // 省
-//                        .country("中国(China)")  // 国家
-//                        .era("晚三叠世(距今2.1亿年)")  // 形成时代
-//                        .preservedLayer("上三叠统竹竿坡组")  // 地质产状或层位(产出状态,化石指产出层位)
-//                        .meteoriteType("脊索动物门鳍龙目肿肋龙亚目贵州龙科")  // 分类(矿物的类型/岩石的类型/化石的类型/陨石的类型)
-//                        .internationalName("Mineral A")  // 国际命名
-//                        .discoveryTime("2024/01/01")  // 发现时间
-//                        .fallTime("2024/01/02")  // 降落时间
-//                        .source(SourceEnum.PURCHASE.getSource()) // 使用枚举:来源(采购/捐赠/采集)
-//                        .provider("天娇雅石居")  // 标本提供者
-//                        .specimenPrice(new BigDecimal("5900.01"))  // 单价
-//                        .acquisitionTime("2012/12/20")  // 入藏时间
-//                        .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途(工业原料/药用/建材/科学研究/观赏/其它)
-//                        .purpose("科学普及;对比研究")  // 具体用途
-//                        .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态(在馆/展陈/借出)
-//                        .imageName("image1.jpg、image2.jpg、image3.jpg")  // 图片资料(图件名称)
-//                        .description("这是一个矿石标本")  // 文献资料
-//                        .notes("备注信息")  // 备注
-//                        .build()
-//        );
-//        ExcelUtils.write(response, "标本导入模板.xls", "标本信息", SpecimenImportExcelVO.class, list);
-//    }
-//
-//    @GetMapping("/get-specimen-import-template")
-//    @Operation(summary = "获得导入标本信息模板")
-//    public void getSpecimenImportTemplate(@RequestParam("specimenType") Integer specimenType, HttpServletResponse response) throws IOException {
-//
-//        // 设置响应类型
-//        response.setContentType("application/vnd.ms-excel");
-//        response.setCharacterEncoding("UTF-8");
-//        // URL 编码文件名
-//        String fileName = URLEncoder.encode("标本导入模板.xls", "UTF-8");
-//        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
-//
-//        // 根据 specimen_type 参数选择模板
-//        List<SpecimenImportExcelVO> list;
-//
-//        // 根据标本类型生成不同的模板
-//        switch (specimenType) {
-//            case 0: // 矿物
-//                list = Arrays.asList(
-//                        SpecimenImportExcelVO.builder()
-//                                .specimenNumber("00716")  // 标本编号
-//                                .assetNumber("20121324")  // 资产号
-//                                .chineseName("文石晶簇")  // 中文名称
-//                                .englishName("Aragonite")  // 外文名称
-//                                .specimenType(SpecimenTypeEnum.MINERAL.getType())  // 标本类型:矿物
-//                                .storageLocation("奇妙的矿物世界")  // 存放位置
-//                                .preservationType(PreservationTypeEnum.SPECIMEN.getPreservationType())  // 保存类型:标本
-//                                .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态:完整
-//                                .specimenAmount(1)  // 数量:1件
-//                                .size("11000")  // 规格:无
-//                                .weight("11220.22")  // 重量:无
-//                                .composition("CaCO3")  // 成分/化学式:碳酸钙
-//                                .origin("湖北")  // 产地
-//                                .economize("湖北")  // 省
-//                                .country("中国(China)")  // 国家
-//                                .era("N/A")  // 形成时代:无
-//                                .meteoriteType("碳酸盐")  // 分类:矿物类型
-//                                .source(SourceEnum.PURCHASE.getSource())  // 来源:采购
-//                                .provider("无")  // 标本提供者:无
-//                                .specimenPrice(new BigDecimal("56000"))  // 单价:56000元
-//                                .acquisitionTime("2012/5/5")  // 入藏时间:2012年5月5日
-//                                .mainPurpose(MainPurposeEnum.APPRECIATE.getMainPurpose())  // 主要用途:观赏
-//                                .purpose("观赏,品质较佳者,经加工打磨后呈现美丽的同心圆花纹")  // 具体用途
-//                                .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
-//                                .imageName("P1110890.JPG")  // 图片资料:图件名称
-//                                .description("这是一个矿石标本")  // 文献资料
-//                                .notes("无")  // 备注
-//                                .build()
-//                );
-//                break;
-//            case 1: // 岩石-矿石
-//                list = Arrays.asList(
-//                        SpecimenImportExcelVO.builder()
-//                                .specimenNumber("00881")  // 标本编号
-//                                .assetNumber("")  // 资产号(没有提供)
-//                                .chineseName("辉石橄榄岩")  // 中文名称
-//                                .englishName("Pyroxene peridotite")  // 外文名称
-//                                .specimenType(SpecimenTypeEnum.ROCK.getType())  // 标本类型:岩石
-//                                .storageLocation("岩石王国")  // 存放位置
-//                                .preservationType(PreservationTypeEnum.SPECIMEN.getPreservationType())  // 保存类型:标本
-//                                .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态:完整
-//                                .specimenAmount(1)  // 数量:1件
-//                                .size("1000")  // 规格:未提供
-//                                .weight("1000.01")  // 重量:未提供
-//                                .composition("")  // 成分/化学式:未提供
-//                                .origin("张家口万全县")  // 产地/发现地:张家口万全县
-//                                .economize("河北")  // 省:河北
-//                                .country("中国(China)")  // 国家:中国
-//                                .preservedLayer("N/A")  // 地质产状或层位:未提供
-//                                .meteoriteType("N/A")  // 分类:未提供
-//                                .source(SourceEnum.DONATION.getSource())  // 来源:捐赠
-//                                .provider("化探63级校友")  // 标本提供者:化探63级校友
-//                                .specimenPrice(new BigDecimal("0.00"))  // 单价:未提供
-//                                .acquisitionTime("2016/11/2")  // 入藏时间:2016年11月2日
-//                                .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途:科学研究
-//                                .purpose("可作耐火材料原料")  // 具体用途:可作耐火材料原料
-//                                .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
-//                                .imageName("DSC00183.JPG")  // 图片资料:图件名称
-//                                .description("N/A")  // 文献资料:未提供
-//                                .notes("N/A")  // 备注:未提供
-//                                .build()
-//                );
-//                break;
-//            case 2: // 总表
-//                list = Arrays.asList(
-//                        SpecimenImportExcelVO.builder()
-//                                .specimenNumber("01522")  // 标本编号
-//                                .assetNumber("20129103")  // 资产号
-//                                .chineseName("贵州龙")  // 中文名称
-//                                .englishName("keichousaurus")  // 外文名称
-//                                .specimenType(SpecimenTypeEnum.FOSSIL.getType()) // 使用枚举:标本类型(矿物/矿石/岩石/化石/陨石)
-//                                .storageLocation("临展厅")  // 存放位置
-//                                .preservationType(PreservationTypeEnum.SPECIMEN.getPreservationType()) // 使用枚举:保存类型(标本/原石/光片/薄片/切片/模型及其他)
-//                                .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态(完整/受损/严重受损/无实物)
-//                                .specimenAmount(1)  // 数量(件/套)
-//                                .size("1000cm")  // 规格(cm)
-//                                .weight("1.5g")  // 重量(g)
-//                                .composition("硅酸盐")  // 成分/化学式
-//                                .origin("兴义县顶效镇绿荫村")  // 产地/发现地(市级县级产地)
-//                                .economize("贵州省")  // 省
-//                                .country("中国(China)")  // 国家
-//                                .era("晚三叠世(距今2.1亿年)")  // 形成时代
-//                                .preservedLayer("上三叠统竹竿坡组")  // 地质产状或层位(产出状态,化石指产出层位)
-//                                .meteoriteType("脊索动物门鳍龙目肿肋龙亚目贵州龙科")  // 分类(矿物的类型/岩石的类型/化石的类型/陨石的类型)
-//                                .internationalName("Mineral A")  // 国际命名
-//                                .discoveryTime("2024/01/01")  // 发现时间
-//                                .fallTime("2024/01/02")  // 降落时间
-//                                .source(SourceEnum.PURCHASE.getSource()) // 使用枚举:来源(采购/捐赠/采集)
-//                                .provider("天娇雅石居")  // 标本提供者
-//                                .specimenPrice(new BigDecimal("5900.01"))  // 单价
-//                                .acquisitionTime("2012/12/20")  // 入藏时间
-//                                .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途(工业原料/药用/建材/科学研究/观赏/其它)
-//                                .purpose("科学普及;对比研究")  // 具体用途
-//                                .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态(在馆/展陈/借出)
-//                                .imageName("image1.jpg、image2.jpg、image3.jpg")  // 图片资料(图件名称)
-//                                .description("这是一个矿石标本")  // 文献资料
-//                                .notes("备注信息")  // 备注
-//                                .build()
-//                );
-//                break;
-//            case 3: // 化石
-//                list = Arrays.asList(
-//                        SpecimenImportExcelVO.builder()
-//                                .specimenNumber("01522")  // 标本编号
-//                                .assetNumber("20129103")  // 资产号
-//                                .chineseName("贵州龙")  // 中文名称
-//                                .englishName("keichousaurus")  // 外文名称
-//                                .specimenType(SpecimenTypeEnum.FOSSIL.getType())  // 标本类型:化石
-//                                .storageLocation("临展厅")  // 存放位置
-//                                .preservationType(PreservationTypeEnum.SPECIMEN.getPreservationType())  // 保存类型:标本
-//                                .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态:完整
-//                                .specimenAmount(1)  // 数量(件/套)
-//                                .size("")  // 规格(cm) - 未提供,留空
-//                                .origin("兴义县顶效镇绿荫村")  // 产地/发现地(市级县级产地)
-//                                .economize("贵州省")  // 省
-//                                .country("中国(China)")  // 国家
-//                                .era("晚三叠世(距今2.1亿年)")  // 形成时代
-//                                .preservedLayer("上三叠统竹竿坡组")  // 地质产状或层位
-//                                .meteoriteType("脊索动物门鳍龙目肿肋龙亚目贵州龙科")  // 分类(化石的类型)
-//                                .source(SourceEnum.PURCHASE.getSource())  // 来源:采购
-//                                .provider("天娇雅石居")  // 标本提供者
-//                                .specimenPrice(new BigDecimal("5900"))  // 单价(元)
-//                                .acquisitionTime("2012/12/20")  // 入藏时间
-//                                .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途:科学研究
-//                                .purpose("科学普及;对比研究")  // 具体用途
-//                                .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
-//                                .imageName("1730775369277.JPG")  // 图片资料(图件名称)
-//                                .description("贵州龙化石")  // 文献资料
-//                                .notes("")  // 备注 - 未提供,留空
-//                                .build()
-//                );
-//                break;
-//            case 4: // 陨石
-//                list = Arrays.asList(
-//                        SpecimenImportExcelVO.builder()
-//                                .specimenNumber("00691")  // 标本编号
-//                                .assetNumber("")  // 资产号
-//                                .chineseName("南丹铁陨石")  // 中文名称
-//                                .englishName("Iron meteorite")  // 外文名称
-//                                .specimenType(SpecimenTypeEnum.METEORITE.getType())  // 标本类型:陨石
-//                                .storageLocation("序厅")  // 存放位置
-//                                .preservationType(PreservationTypeEnum.ROUGH_STONE.getPreservationType())  // 保存类型:原石
-//                                .saveStatus(SaveStatusEnum.COMPLETE.getSaveStatus())  // 保存状态:完整
-//                                .specimenAmount(1)  // 数量(件/套)
-//                                .size("150*120*90")  // 规格(cm)
-//                                .weight("3500000")  // 重量(g)
-//                                .composition("铁镍金属")  // 成分/化学式
-//                                .origin("南丹")  // 产地/发现地(市级县级产地)
-//                                .economize("广西")  // 省
-//                                .country("中国(China)")  // 国家
-//                                .meteoriteType("Iron, IAB-MG")  // 陨石的类型
-//                                .internationalName("Nantan")  // 国际命名
-//                                .discoveryTime("1958")  // 发现时间
-//                                .fallTime("")  // 降落时间
-//                                .source(SourceEnum.DONATION.getSource())  // 来源:捐赠
-//                                .provider("化探63级校友")  // 标本提供者
-//                                .specimenPrice(new BigDecimal("0"))  // 单价(元)
-//                                .acquisitionTime("2016/11/2")  // 入藏时间
-//                                .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途:科学研究
-//                                .purpose("科学研究")  // 具体用途
-//                                .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
-//                                .imageName("DSC03583.JPG, DSC01271.JPG")  // 图片资料(图件名称)
-//                                .description("南丹铁陨石样本")  // 文献资料
-//                                .notes("")  // 备注
-//                                .build()
-//                );
-//                break;
-//            default:
-//                throw exception(INVALID_SPECIMEN_TYPE);
-//        }
-//
-//        // 使用 ExcelUtils 写入 Excel 文件
-//        ExcelUtils.write(response, "标本导入模板.xls", "标本信息", SpecimenImportExcelVO.class, list);
-//    }
-
     @GetMapping("/get-specimen-import-template")
     @Operation(summary = "获得导入标本信息模板")
     public void getSpecimenImportTemplate(@RequestParam("specimenType") Integer specimenType, HttpServletResponse response) throws IOException {
@@ -392,21 +148,21 @@ public class SpecimenInfoController {
         if (list != null && !list.isEmpty()) {
             if (voClass == MineralSpecimenImportExcelVO.class) {
                 List<MineralSpecimenImportExcelVO> mineralList = (List<MineralSpecimenImportExcelVO>) list;
-                ExcelUtils.write(response, "矿物导入模板.xls", "标本信息", MineralSpecimenImportExcelVO.class, mineralList);
+                ExcelUtils.write(response, "矿物导入模板.xls", "矿物信息", MineralSpecimenImportExcelVO.class, mineralList);
             } else if (voClass == RockSpecimenImportExcelVO.class) {
                 List<RockSpecimenImportExcelVO> rockList = (List<RockSpecimenImportExcelVO>) list;
-                ExcelUtils.write(response, "岩石-矿石导入模板.xls", "标本信息", RockSpecimenImportExcelVO.class, rockList);
+                ExcelUtils.write(response, "岩石-矿石导入模板.xls", "岩石-矿石信息", RockSpecimenImportExcelVO.class, rockList);
 
             } else if (voClass == SpecimenImportExcelVO.class) {
                 List<SpecimenImportExcelVO> allList = (List<SpecimenImportExcelVO>) list;
-                ExcelUtils.write(response, "标本导入模板.xls", "标本信息", SpecimenImportExcelVO.class, allList);
+                ExcelUtils.write(response, "标本总表导入模板.xls", "标本信息", SpecimenImportExcelVO.class, allList);
 
             } else if (voClass == FossilSpecimenImportExcelVO.class) {
                 List<FossilSpecimenImportExcelVO> fossilList = (List<FossilSpecimenImportExcelVO>) list;
-                ExcelUtils.write(response, "化石导入模板.xls", "标本信息", FossilSpecimenImportExcelVO.class, fossilList);
+                ExcelUtils.write(response, "化石导入模板.xls", "化石信息", FossilSpecimenImportExcelVO.class, fossilList);
             } else if (voClass == MeteoriteSpecimenImportExcelVO.class) {
                 List<MeteoriteSpecimenImportExcelVO> meteoriteList = (List<MeteoriteSpecimenImportExcelVO>) list;
-                ExcelUtils.write(response, "陨石导入模板.xls", "标本信息", MeteoriteSpecimenImportExcelVO.class, meteoriteList);
+                ExcelUtils.write(response, "陨石导入模板.xls", "陨石信息", MeteoriteSpecimenImportExcelVO.class, meteoriteList);
             }
         }
     }
@@ -429,7 +185,7 @@ public class SpecimenInfoController {
                         .origin("湖北")  // 产地
                         .economize("湖北")  // 省
                         .country("中国(China)")  // 国家
-                        .era("N/A")  // 形成时代:无
+                        .preservedLayer("")  // 形成时代:无
                         .meteoriteType("碳酸盐")  // 分类:矿物类型
                         .source(SourceEnum.PURCHASE.getSource())  // 来源:采购
                         .provider("无")  // 标本提供者:无
@@ -463,8 +219,8 @@ public class SpecimenInfoController {
                         .origin("张家口万全县")  // 产地/发现地:张家口万全县
                         .economize("河北")  // 省:河北
                         .country("中国(China)")  // 国家:中国
-                        .preservedLayer("N/A")  // 地质产状或层位:未提供
-                        .meteoriteType("N/A")  // 分类:未提供
+                        .preservedLayer("")  // 地质产状或层位:未提供
+                        .meteoriteType("")  // 分类:未提供
                         .source(SourceEnum.DONATION.getSource())  // 来源:捐赠
                         .provider("化探63级校友")  // 标本提供者:化探63级校友
                         .specimenPrice(new BigDecimal("0.00"))  // 单价:未提供
@@ -473,8 +229,8 @@ public class SpecimenInfoController {
                         .purpose("可作耐火材料原料")  // 具体用途:可作耐火材料原料
                         .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
                         .imageName("DSC00183.JPG")  // 图片资料:图件名称
-                        .description("N/A")  // 文献资料:未提供
-                        .notes("N/A")  // 备注:未提供
+                        .description("")  // 文献资料:未提供
+                        .notes("")  // 备注:未提供
                         .build()
         );
     }
@@ -497,8 +253,8 @@ public class SpecimenInfoController {
                         .origin("张家口万全县")  // 产地/发现地
                         .economize("河北")  // 省:河北
                         .country("中国(China)")  // 国家:中国
-                        .preservedLayer("N/A")  // 地质产状或层位:未提供
-                        .meteoriteType("N/A")  // 分类:未提供
+                        .preservedLayer("")  // 地质产状或层位:未提供
+                        .meteoriteType("")  // 分类:未提供
                         .source(SourceEnum.DONATION.getSource())  // 来源:捐赠
                         .provider("化探63级校友")  // 标本提供者
                         .specimenPrice(new BigDecimal("0.00"))  // 单价:未提供
@@ -507,8 +263,8 @@ public class SpecimenInfoController {
                         .purpose("可作耐火材料原料")  // 具体用途:可作耐火材料原料
                         .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
                         .imageName("DSC00183.JPG")  // 图片资料:图件名称
-                        .description("N/A")  // 文献资料
-                        .notes("N/A")  // 备注
+                        .description("")  // 文献资料
+                        .notes("")  // 备注
                         .build()
         );
     }
@@ -566,8 +322,8 @@ public class SpecimenInfoController {
                                 .country("中国(China)")  // 国家
                                 .meteoriteType("Iron, IAB-MG")  // 陨石的类型
                                 .internationalName("Nantan")  // 国际命名
-                                .discoveryTime("1958")  // 发现时间
-                                .fallTime("")  // 降落时间
+                                .discoveryTime("1958/11/11")  // 发现时间
+                                .fallTime("1943/11/12")  // 降落时间
                                 .source(SourceEnum.DONATION.getSource())  // 来源:捐赠
                                 .provider("化探63级校友")  // 标本提供者
                                 .specimenPrice(new BigDecimal("0"))  // 单价(元)
@@ -575,7 +331,7 @@ public class SpecimenInfoController {
                                 .mainPurpose(MainPurposeEnum.RESERECH.getMainPurpose())  // 主要用途:科学研究
                                 .purpose("科学研究")  // 具体用途
                                 .collectionStatus(CollectionStatusEnum.EXHIBITION.getStatus())  // 馆藏状态:展陈
-                                .imageName("DSC03583.JPG, DSC01271.JPG")  // 图片资料(图件名称)
+                                .imageName("DSC03583.JPG DSC01271.JPG")  // 图片资料(图件名称)
                                 .description("南丹铁陨石样本")  // 文献资料
                                 .notes("")  // 备注
                                 .build()

+ 2 - 2
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/MineralSpecimenImportExcelVO.java

@@ -66,8 +66,8 @@ public class MineralSpecimenImportExcelVO {
     @ExcelProperty("国家")
     private String country;
 
-    @ExcelProperty("形成时代")
-    private String era;
+    @ExcelProperty("地质产状或层位(产出状态,化石指产出层位)")
+    private String preservedLayer;
 
     @ExcelProperty("分类(矿物的类型/岩石的类型/化石的类型/陨石的类型)")
     private String meteoriteType;

+ 0 - 3
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/photogroup/PhotoGroupMapper.java

@@ -1,14 +1,11 @@
 package cn.iocoder.yudao.module.museums.dal.mysql.photogroup;
 
-import java.util.*;
-
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.museums.dal.dataobject.photogroup.PhotoGroupDO;
 import org.apache.ibatis.annotations.Mapper;
 import cn.iocoder.yudao.module.museums.controller.admin.photogroup.vo.*;
-import org.apache.ibatis.annotations.Param;
 
 /**
  * 博物馆照片组 Mapper

+ 4 - 1
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/photos/PhotosMapper.java

@@ -5,6 +5,7 @@ import java.util.*;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.museums.dal.dataobject.photogroup.PhotoGroupDO;
 import cn.iocoder.yudao.module.museums.dal.dataobject.photos.PhotosDO;
 import org.apache.ibatis.annotations.Insert;
 import org.apache.ibatis.annotations.Mapper;
@@ -26,7 +27,9 @@ public interface PhotosMapper extends BaseMapperX<PhotosDO> {
                 .eqIfPresent(PhotosDO::getGroupId, reqVO.getGroupId())
                 .eqIfPresent(PhotosDO::getPhotoUrl, reqVO.getPhotoUrl())
                 .betweenIfPresent(PhotosDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(PhotosDO::getId));
+//                .likeIfPresent(PhotosDO::getId, String.valueOf(reqVO.getId()))
+                .orderByDesc(PhotosDO::getId)
+        );
     }
 
     @Select("SELECT * FROM museums_photos WHERE group_id = #{groupId} AND deleted = 0")

+ 0 - 1
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimenoutbound/SpecimenOutboundMapper.java

@@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimenoutbound.SpecimenOutboundDO;
 import org.apache.ibatis.annotations.Mapper;
 import cn.iocoder.yudao.module.museums.controller.admin.specimenoutbound.vo.*;
-import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
 /**

+ 51 - 12
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/photogroup/PhotoGroupServiceImpl.java

@@ -1,17 +1,17 @@
 package cn.iocoder.yudao.module.museums.service.photogroup;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.module.museums.dal.dataobject.photos.PhotosDO;
 import cn.iocoder.yudao.module.museums.dal.mysql.photos.PhotosMapper;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
+import java.io.*;
 import java.nio.file.Files;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
@@ -148,16 +148,55 @@ public class PhotoGroupServiceImpl implements PhotoGroupService {
         photoGroupMapper.insert(photoGroup);
 
         Integer groupId = photoGroup.getId();
-        File tempDir = Files.createTempDirectory("photo_group_images").toFile();
-
-        try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
-            List<Integer> photoIds = processZipFile(zipInputStream, groupId);
-        } catch (Exception e) {
-            throw exception(PHOTO_GROUP_PACKAGE_FAILED_DECOMPRESS);
-        } finally {
-            FileUtils.deleteDirectory(tempDir);
+        List<Integer> photoIds = new ArrayList<>();
+        File tempDir;
+        try {
+            tempDir = Files.createTempDirectory("photo_group_images").toFile();
+        } catch (IOException e) {
+            throw new RuntimeException("创建临时目录失败", e);
+        }
+
+        if (file != null && !file.isEmpty()) {
+            if (!file.getOriginalFilename().endsWith(".zip")) {
+                throw exception(PHOTO_GROUP_MUST_BE_COMPRESSED_PACKAGE);
+            }
+            try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream())) {
+                ZipArchiveEntry entry;
+                while ((entry = zipInputStream.getNextEntry()) != null) {
+                    if (!entry.isDirectory()) {
+                        File newFile = new File(tempDir, entry.getName());
+                        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
+                            byte[] buffer = new byte[1024];
+                            int len;
+                            while ((len = zipInputStream.read(buffer)) > 0) {
+                                bos.write(buffer, 0, len);
+                            }
+                        }
+
+                        String imagePath = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+                        // 创建照片信息记录
+                        PhotosDO photoRecord = new PhotosDO();
+                        photoRecord.setGroupId(groupId);
+                        photoRecord.setPhotoUrl(imagePath);
+                        photosMapper.insert(photoRecord);
+
+                        // 获取并存储新插入的照片 ID
+                        photoIds.add(photoRecord.getId());
+                    }
+                }
+            } catch (IOException e) {
+                throw exception(PHOTO_GROUP_PACKAGE_FAILED_DECOMPRESS);
+            }
         }
 
         return groupId;
     }
+    private boolean isSupportedImage(String fileName) {
+        // 转换文件名为小写
+        fileName = fileName.toLowerCase();
+        return fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".gif") ||
+                fileName.endsWith(".bmp") || fileName.endsWith(".tiff") || fileName.endsWith(".jpeg") ||
+                fileName.endsWith(".psd") || fileName.endsWith(".raw") || fileName.endsWith(".svg");
+
+    }
 }

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

@@ -308,6 +308,9 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
 
 
     @Override
+    @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
+    @LogRecord(type = MUSEUMS_SPECIMEN_TYPE, subType = SPECIMEN_IMPORT_SUB_TYPE, bizNo = "1",
+            success = SPECIMEN_IMPORT_SUCCESS, extra = "{{#extra}}")
     public SpecimenImportRespVO importSpecimenListAndImages(List<SpecimenImportExcelVO> importSpecimens,
                                                             MultipartFile file, Integer updateType, boolean isUpdateSupport) {
 
@@ -318,7 +321,7 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
             throw new RuntimeException("创建临时目录失败", e);
         }
 
-        if(file != null && !file.isEmpty()) {
+        if (file != null && !file.isEmpty()) {
             if (!file.getOriginalFilename().endsWith(".zip")) {
                 throw exception(PHOTO_GROUP_MUST_BE_COMPRESSED_PACKAGE);
             }
@@ -370,37 +373,53 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
             if (!isValidImageName(importSpecimen.getImageName())) {
                 return;
             }
-                    List<String> imagePathSet = new ArrayList<>();
-                    if(importSpecimen.getImageName() != null){
-                        String[] names = importSpecimen.getImageName().split("、");
-                        for (String importName : names) {
-                            File imageFile = findImageInTempDir(tempDir, importName);
-                            if (imageFile != null) {
-                                try {
-                                    byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
-                                    String imagePath = fileApi.createFile(imageBytes);
-                                    imagePathSet.add(imagePath);
-                                    respVO.getCreateSpecimenImages().add(importName);
-                                    // 处理上传后的路径,如存储到数据库或更新状态等
-                                } catch (IOException e) {
-                                    respVO.getFailureSpecimenImages().put(importName, "图片上传失败");
-                                }
-                            } else {
-                                respVO.getFailureSpecimenImages().put(importSpecimen.getSpecimenNumber(), "图片不存在压缩包中");
-                            }
-                            if (existSpecimen != null &&  imagePathSet.isEmpty()) {
-                                imagePathSet = BeanUtils.toBean(existSpecimen, SpecimenInfoRespVO.class).getImagePath();
-                            }
+            List<String> imagePathSet = new ArrayList<>();
+            if (importSpecimen.getImageName() != null) {
+                String[] names = importSpecimen.getImageName().split("、");
+                for (String importName : names) {
+                    File imageFile = findImageInTempDir(tempDir, importName);
+                    if (imageFile != null) {
+                        try {
+                            byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
+                            String imagePath = fileApi.createFile(imageBytes);
+                            imagePathSet.add(imagePath);
+                            respVO.getCreateSpecimenImages().add(importName);
+                            // 处理上传后的路径,如存储到数据库或更新状态等
+                        } catch (IOException e) {
+                            respVO.getFailureSpecimenImages().put(importName, "图片上传失败");
                         }
-                    } respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "图片名称格式不正确");
-
-
-
+                    } else {
+                        respVO.getFailureSpecimenImages().put(importSpecimen.getSpecimenNumber(), "图片不存在压缩包中");
+                    }
+                    if (existSpecimen != null && imagePathSet.isEmpty()) {
+                        imagePathSet = BeanUtils.toBean(existSpecimen, SpecimenInfoRespVO.class).getImagePath();
+                    }
+                }
+            }
             // 处理文献资料字段,如果为空就赋值 <br>
             if (importSpecimen.getDescription() == null || importSpecimen.getDescription().trim().isEmpty()) {
                 importSpecimen.setDescription("<p><br></p>");
             }
 
+            LocalDateTime qidian = LocalDateTime.of(1, Month.JANUARY, 1, 0, 0);
+            if (importSpecimen.getAcquisitionTime() != null
+                    && parseToLocalDateTime(importSpecimen.getAcquisitionTime()).equals(qidian)) {
+                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的入藏时间!");
+                return;
+            }
+
+            if (importSpecimen.getFallTime() != null
+                    && parseToLocalDateTime(importSpecimen.getFallTime()).equals(qidian)) {
+                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的降落时间!");
+                return;
+            }
+
+            if (importSpecimen.getDiscoveryTime() != null
+                    && parseToLocalDateTime(importSpecimen.getDiscoveryTime()).equals(qidian)) {
+                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的发现时间!");
+                return;
+            }
+
             if (existSpecimen == null) {
                 // 2.2.1 不存在则插入
                 SpecimenInfoDO newSpecimen = BeanUtils.toBean(importSpecimen, SpecimenInfoDO.class);
@@ -420,30 +439,13 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                 respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "标本编号已存在,且不支持更新");
                 return;
             }
-            LocalDateTime qidian = LocalDateTime.of(1, Month.JANUARY, 1, 0, 0);
-            if (importSpecimen.getAcquisitionTime() != null
-                    && parseToLocalDateTime(importSpecimen.getAcquisitionTime()).equals(qidian)) {
-                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的入藏时间!");
-                return;
-            }
 
-            if (importSpecimen.getFallTime() != null
-                    && parseToLocalDateTime(importSpecimen.getFallTime()).equals(qidian)) {
-                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的降落时间!");
-                return;
-            }
-
-            if (importSpecimen.getDiscoveryTime() != null
-                    && parseToLocalDateTime(importSpecimen.getDiscoveryTime()).equals(qidian)) {
-                respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "无效的发现时间!");
-                return;
-            }
             // 更新逻辑
             SpecimenInfoDO updateSpecimen = BeanUtils.toBean(importSpecimen, SpecimenInfoDO.class);
 
-            if(imagePathSet != null){
+            if (imagePathSet != null) {
                 updateSpecimen.setImagePath(imagePathSet.toString());
-            }else {
+            } else {
                 updateSpecimen.setImagePath(null);
             }
             if (updateType != -1) {
@@ -465,9 +467,12 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
 
     }
      private boolean isSupportedImage(String fileName) {
+         // 转换文件名为小写
+         fileName = fileName.toLowerCase();
         return fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".gif") ||
                fileName.endsWith(".bmp") || fileName.endsWith(".tiff") || fileName.endsWith(".jpeg") ||
                fileName.endsWith(".psd") || fileName.endsWith(".raw") || fileName.endsWith(".svg");
+
     }
 
     private File findImageInTempDir(File tempDir, String imageName) {
@@ -509,43 +514,6 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         return LocalDateTime.of(1, Month.JANUARY, 1, 0, 0);
     }
 
-    //公共方法
-//    public List<Integer> processZipFile(ZipInputStream zipInputStream, Integer groupId) throws Exception {
-//        List<Integer> photoIds = new ArrayList<>();
-//        ZipEntry entry;
-//        while ((entry = zipInputStream.getNextEntry()) != null) {
-//            if (!entry.isDirectory()) {
-//                String fileName = entry.getName().toLowerCase();  // 转为小写
-//                // 检查文件类型,只处理图片(转换为小写后进行检查)
-//                if (fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".gif")
-//                        || fileName.endsWith(".bmp") || fileName.endsWith(".tiff")|| fileName.endsWith(".jpeg")
-//                        || fileName.endsWith(".psd") || fileName.endsWith(".raw") || fileName.endsWith(".svg")) {
-//
-//                    // 使用 ByteArrayOutputStream 读取文件内容
-//                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
-//                    byte[] buffer = new byte[1024];
-//                    int length;
-//                    while ((length = zipInputStream.read(buffer)) != -1) {
-//                        bos.write(buffer, 0, length);
-//                    }
-//                    byte[] imageBytes = bos.toByteArray();
-//
-//                    // 上传图片并获取 URL
-//                    String imagePath = fileApi.createFile(imageBytes);
-//
-//                    // 创建照片信息记录
-//                    PhotosDO photoRecord = new PhotosDO();
-//                    photoRecord.setGroupId(groupId);
-//                    photoRecord.setPhotoUrl(imagePath);
-//                    photosMapper.insert(photoRecord);
-//
-//                    // 获取并存储新插入的照片 ID
-//                    photoIds.add(photoRecord.getId());
-//                }
-//            }
-//        }
-//        return photoIds;
-//    }
     //工作台
     //根据入库的登记情况统计本年标本入库信息
     @Override