Browse Source

代码生成

hyy 10 months ago
commit
7321e05264
14 changed files with 1174 additions and 0 deletions
  1. 38 0
      yudao-module-museums/pom.xml
  2. 26 0
      yudao-module-museums/yudao-module-museums-api/pom.xml
  3. 14 0
      yudao-module-museums/yudao-module-museums-api/src/main/java/cn/iocoder/yudao/module/museums/enums/ErrorCodeConstants.java
  4. 56 0
      yudao-module-museums/yudao-module-museums-biz/pom.xml
  5. 95 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/SpecimenInfoController.java
  6. 116 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenInfoPageReqVO.java
  7. 142 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenInfoRespVO.java
  8. 109 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenInfoSaveReqVO.java
  9. 149 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/dataobject/specimeninfo/SpecimenInfoDO.java
  10. 55 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimeninfo/SpecimenInfoMapper.java
  11. 55 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoService.java
  12. 73 0
      yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImpl.java
  13. 12 0
      yudao-module-museums/yudao-module-museums-biz/src/main/resources/mapper/specimeninfo/SpecimenInfoMapper.xml
  14. 234 0
      yudao-module-museums/yudao-module-museums-biz/src/test/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImplTest.java

+ 38 - 0
yudao-module-museums/pom.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--    <modelVersion>4.0.0</modelVersion>-->
+<!--    <parent>-->
+<!--        <groupId>cn.iocoder.boot</groupId>-->
+<!--        <artifactId>yudao</artifactId>-->
+<!--        <version>2.2.0-jdk8-snapshot</version>-->
+<!--    </parent>-->
+
+<!--    <artifactId>yudao_module_museums</artifactId>-->
+
+<!--    <properties>-->
+<!--        <maven.compiler.source>22</maven.compiler.source>-->
+<!--        <maven.compiler.target>22</maven.compiler.target>-->
+<!--        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
+<!--    </properties>-->
+    <parent>
+        <artifactId>yudao</artifactId>
+        <groupId>cn.iocoder.boot</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modules>
+        <module>yudao-module-museums-api</module>
+        <module>yudao-module-museums-biz</module>
+
+    </modules>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>yudao-module-museums</artifactId>
+    <packaging>pom</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>
+        museums模块,主要实现工作台、标本库管理、博物馆照片和文件管理等功能。
+    </description>
+</project>

+ 26 - 0
yudao-module-museums/yudao-module-museums-api/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>yudao-module-museums</artifactId>
+        <groupId>cn.iocoder.boot</groupId>
+        <version>${revision}</version> <!-- 1. 修改 version 为 ${revision} -->
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>yudao-module-museums-api</artifactId>
+    <packaging>jar</packaging> <!-- 2. 新增 packaging 为 jar -->
+
+    <name>${project.artifactId}</name> <!-- 3. 新增 name 为 ${project.artifactId} -->
+    <description> <!-- 4. 新增 description 为该模块的描述 -->
+        demo 模块 API,暴露给其它模块调用
+    </description>
+
+    <dependencies>  <!-- 5. 新增 yudao-common 依赖 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-common</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

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

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.museums.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+
+/**
+ * Museums 错误码枚举类
+ *
+ * museums 系统,使用 1-018-000-000 段
+ */
+public class ErrorCodeConstants {
+    // ========== 标本管理 1-016-000-000 ==========
+   public static final ErrorCode SPECIMEN_INFO_NOT_EXISTS = new ErrorCode(1-016-000-000, "标本管理不存在");
+
+}

+ 56 - 0
yudao-module-museums/yudao-module-museums-biz/pom.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>yudao-module-museums</artifactId>
+        <groupId>cn.iocoder.boot</groupId>
+        <version>${revision}</version> <!-- 1. 修改 version 为 ${revision} -->
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging> <!-- 2. 新增 packaging 为 jar -->
+
+    <artifactId>yudao-module-museums-biz</artifactId>
+
+    <name>${project.artifactId}</name> <!-- 3. 新增 name 为 ${project.artifactId} -->
+    <description> <!-- 4. 新增 description 为该模块的描述 -->
+        demo 模块,主要实现 XXX、YYY、ZZZ 等功能。
+    </description>
+
+    <dependencies>  <!-- 5. 新增依赖,这里引入的都是比较常用的业务组件、技术组件 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-museums-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+        <!-- Web 相关 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- DB 相关 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
+        </dependency>
+
+        <!-- Test 测试相关 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-excel</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

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

@@ -0,0 +1,95 @@
+package cn.iocoder.yudao.module.museums.controller.admin.specimeninfo;
+
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+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.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
+import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
+import cn.iocoder.yudao.module.museums.service.specimeninfo.SpecimenInfoService;
+
+@Tag(name = "管理后台 - 标本管理")
+@RestController
+@RequestMapping("/museums/specimen-info")
+@Validated
+public class SpecimenInfoController {
+
+    @Resource
+    private SpecimenInfoService specimenInfoService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建标本管理")
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:create')")
+    public CommonResult<Integer> createSpecimenInfo(@Valid @RequestBody SpecimenInfoSaveReqVO createReqVO) {
+        return success(specimenInfoService.createSpecimenInfo(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新标本管理")
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:update')")
+    public CommonResult<Boolean> updateSpecimenInfo(@Valid @RequestBody SpecimenInfoSaveReqVO updateReqVO) {
+        specimenInfoService.updateSpecimenInfo(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除标本管理")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:delete')")
+    public CommonResult<Boolean> deleteSpecimenInfo(@RequestParam("id") Integer id) {
+        specimenInfoService.deleteSpecimenInfo(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得标本管理")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:query')")
+    public CommonResult<SpecimenInfoRespVO> getSpecimenInfo(@RequestParam("id") Integer id) {
+        SpecimenInfoDO specimenInfo = specimenInfoService.getSpecimenInfo(id);
+        return success(BeanUtils.toBean(specimenInfo, SpecimenInfoRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得标本管理分页")
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:query')")
+    public CommonResult<PageResult<SpecimenInfoRespVO>> getSpecimenInfoPage(@Valid SpecimenInfoPageReqVO pageReqVO) {
+        PageResult<SpecimenInfoDO> pageResult = specimenInfoService.getSpecimenInfoPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, SpecimenInfoRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出标本管理 Excel")
+    @PreAuthorize("@ss.hasPermission('museums:specimen-info:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportSpecimenInfoExcel(@Valid SpecimenInfoPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<SpecimenInfoDO> list = specimenInfoService.getSpecimenInfoPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "标本管理.xls", "数据", SpecimenInfoRespVO.class,
+                        BeanUtils.toBean(list, SpecimenInfoRespVO.class));
+    }
+
+}

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

@@ -0,0 +1,116 @@
+package cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo;
+
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import java.math.BigDecimal;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 标本管理分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SpecimenInfoPageReqVO extends PageParam {
+
+    @Schema(description = "标本类型(矿物、岩石矿石、化石、陨石)", example = "1")
+    private Integer specimenType;
+
+    @Schema(description = "标本编号")
+    private String specimenNumber;
+
+    @Schema(description = "资产号")
+    private String assetNumber;
+
+    @Schema(description = "存放位置")
+    private String storageLocation;
+
+    @Schema(description = "中文名称", example = "赵六")
+    private String chineseName;
+
+    @Schema(description = "英文名称", example = "Maven")
+    private String englishName;
+
+    @Schema(description = "成分")
+    private String composition;
+
+    @Schema(description = "产地")
+    private String origin;
+
+    @Schema(description = "时代")
+    private String era;
+
+    @Schema(description = "保存地层")
+    private String preservedLayer;
+
+    @Schema(description = "陨石类型", example = "2")
+    private String meteoriteType;
+
+    @Schema(description = "国际命名", example = "王五")
+    private String internationalName;
+
+    @Schema(description = "发现时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDate[] discoveryTime;
+
+    @Schema(description = "降落时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDate[] fallTime;
+
+    @Schema(description = "保存类型(标本、光片、薄片模型及其他)", example = "1")
+    private Integer preservationType;
+
+    @Schema(description = "尺寸")
+    private String size;
+
+    @Schema(description = "重量")
+    private BigDecimal weight;
+
+    @Schema(description = "来源(采购、捐赠、采集)")
+    private Integer source;
+
+    @Schema(description = "标本提供者(供应商、捐赠人、采集人)")
+    private String provider;
+
+    @Schema(description = "入藏时间(购买、捐赠、采集时间)")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDate[] acquisitionTime;
+
+    @Schema(description = "用途")
+    private String purpose;
+
+    @Schema(description = "描述", example = "黑红色陨石")
+    private String description;
+
+    @Schema(description = "馆藏状态(在馆、借出)", example = "2")
+    private Integer collectionStatus;
+
+    @Schema(description = "备注")
+    private String notes;
+
+    @Schema(description = "图片名称", example = "芋艿")
+    private String imageName;
+
+    @Schema(description = "图片路径")
+    private String imagePath;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDate[] createTime;
+
+    @Schema(description = "注销原因", example = "不香")
+    private String deletedReason;
+
+    @Schema(description = "入库操作员")
+    private String operator;
+
+    @Schema(description = "入库时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] entryDate;
+
+}

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

@@ -0,0 +1,142 @@
+package cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.math.BigDecimal;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 标本管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class SpecimenInfoRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("主键")
+    private Integer id;
+
+    @Schema(description = "标本类型(矿物、岩石矿石、化石、陨石)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("标本类型(矿物、岩石矿石、化石、陨石)")
+    private Integer specimenType;
+
+    @Schema(description = "标本编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("标本编号")
+    private String specimenNumber;
+
+    @Schema(description = "资产号")
+    @ExcelProperty("资产号")
+    private String assetNumber;
+
+    @Schema(description = "存放位置")
+    @ExcelProperty("存放位置")
+    private String storageLocation;
+
+    @Schema(description = "中文名称", example = "赵六")
+    @ExcelProperty("中文名称")
+    private String chineseName;
+
+    @Schema(description = "英文名称", example = "Maven")
+    @ExcelProperty("英文名称")
+    private String englishName;
+
+    @Schema(description = "成分")
+    @ExcelProperty("成分")
+    private String composition;
+
+    @Schema(description = "产地")
+    @ExcelProperty("产地")
+    private String origin;
+
+    @Schema(description = "时代")
+    @ExcelProperty("时代")
+    private String era;
+
+    @Schema(description = "保存地层")
+    @ExcelProperty("保存地层")
+    private String preservedLayer;
+
+    @Schema(description = "陨石类型", example = "2")
+    @ExcelProperty("陨石类型")
+    private String meteoriteType;
+
+    @Schema(description = "国际命名", example = "王五")
+    @ExcelProperty("国际命名")
+    private String internationalName;
+
+    @Schema(description = "发现时间")
+    @ExcelProperty("发现时间")
+    private LocalDate discoveryTime;
+
+    @Schema(description = "降落时间")
+    @ExcelProperty("降落时间")
+    private LocalDate fallTime;
+
+    @Schema(description = "保存类型(标本、光片、薄片模型及其他)", example = "1")
+    @ExcelProperty("保存类型(标本、光片、薄片模型及其他)")
+    private Integer preservationType;
+
+    @Schema(description = "尺寸")
+    @ExcelProperty("尺寸")
+    private String size;
+
+    @Schema(description = "重量")
+    @ExcelProperty("重量")
+    private BigDecimal weight;
+
+    @Schema(description = "来源(采购、捐赠、采集)")
+    @ExcelProperty("来源(采购、捐赠、采集)")
+    private Integer source;
+
+    @Schema(description = "标本提供者(供应商、捐赠人、采集人)")
+    @ExcelProperty("标本提供者(供应商、捐赠人、采集人)")
+    private String provider;
+
+    @Schema(description = "入藏时间(购买、捐赠、采集时间)")
+    @ExcelProperty("入藏时间(购买、捐赠、采集时间)")
+    private LocalDate acquisitionTime;
+
+    @Schema(description = "用途")
+    @ExcelProperty("用途")
+    private String purpose;
+
+    @Schema(description = "描述", example = "黑红色陨石")
+    @ExcelProperty("描述")
+    private String description;
+
+    @Schema(description = "馆藏状态(在馆、借出)", example = "2")
+    @ExcelProperty("馆藏状态(在馆、借出)")
+    private Integer collectionStatus;
+
+    @Schema(description = "备注")
+    @ExcelProperty("备注")
+    private String notes;
+
+    @Schema(description = "图片名称", example = "芋艿")
+    @ExcelProperty("图片名称")
+    private String imageName;
+
+    @Schema(description = "图片路径")
+    @ExcelProperty("图片路径")
+    private String imagePath;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDate createTime;
+
+    @Schema(description = "注销原因", example = "不香")
+    @ExcelProperty("注销原因")
+    private String deletedReason;
+
+    @Schema(description = "入库操作员")
+    @ExcelProperty("入库操作员")
+    private String operator;
+
+    @Schema(description = "入库时间")
+    @ExcelProperty("入库时间")
+    private LocalDateTime entryDate;
+
+}

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

@@ -0,0 +1,109 @@
+package cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import javax.validation.constraints.*;
+import java.math.BigDecimal;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 标本管理新增/修改 Request VO")
+@Data
+public class SpecimenInfoSaveReqVO {
+
+    @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 = "标本编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "标本编号不能为空")
+    private String specimenNumber;
+
+    @Schema(description = "资产号")
+    private String assetNumber;
+
+    @Schema(description = "存放位置")
+    private String storageLocation;
+
+    @Schema(description = "中文名称", example = "赵六")
+    private String chineseName;
+
+    @Schema(description = "英文名称", example = "Maven")
+    private String englishName;
+
+    @Schema(description = "成分")
+    private String composition;
+
+    @Schema(description = "产地")
+    private String origin;
+
+    @Schema(description = "时代")
+    private String era;
+
+    @Schema(description = "保存地层")
+    private String preservedLayer;
+
+    @Schema(description = "陨石类型", example = "2")
+    private String meteoriteType;
+
+    @Schema(description = "国际命名", example = "王五")
+    private String internationalName;
+
+    @Schema(description = "发现时间")
+    private LocalDate discoveryTime;
+
+    @Schema(description = "降落时间")
+    private LocalDate fallTime;
+
+    @Schema(description = "保存类型(标本、光片、薄片模型及其他)", example = "1")
+    private Integer preservationType;
+
+    @Schema(description = "尺寸")
+    private String size;
+
+    @Schema(description = "重量")
+    private BigDecimal weight;
+
+    @Schema(description = "来源(采购、捐赠、采集)")
+    private Integer source;
+
+    @Schema(description = "标本提供者(供应商、捐赠人、采集人)")
+    private String provider;
+
+    @Schema(description = "入藏时间(购买、捐赠、采集时间)")
+    private LocalDate acquisitionTime;
+
+    @Schema(description = "用途")
+    private String purpose;
+
+    @Schema(description = "描述", example = "黑红色陨石")
+    private String description;
+
+    @Schema(description = "馆藏状态(在馆、借出)", example = "2")
+    private Integer collectionStatus;
+
+    @Schema(description = "备注")
+    private String notes;
+
+    @Schema(description = "图片名称", example = "芋艿")
+    private String imageName;
+
+    @Schema(description = "图片路径")
+    private String imagePath;
+
+    @Schema(description = "注销原因", example = "不香")
+    private String deletedReason;
+
+    @Schema(description = "入库操作员")
+    private String operator;
+
+    @Schema(description = "入库时间")
+    private LocalDateTime entryDate;
+
+}

+ 149 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/dataobject/specimeninfo/SpecimenInfoDO.java

@@ -0,0 +1,149 @@
+package cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo;
+
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 标本管理 DO
+ *
+ * @author 普伟
+ */
+@TableName("museums_specimen_info")
+@KeySequence("museums_specimen_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SpecimenInfoDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer id;
+    /**
+     * 标本类型(矿物、岩石矿石、化石、陨石)
+     */
+    private Integer specimenType;
+    /**
+     * 标本编号
+     */
+    private String specimenNumber;
+    /**
+     * 资产号
+     */
+    private String assetNumber;
+    /**
+     * 存放位置
+     */
+    private String storageLocation;
+    /**
+     * 中文名称
+     */
+    private String chineseName;
+    /**
+     * 英文名称
+     */
+    private String englishName;
+    /**
+     * 成分
+     */
+    private String composition;
+    /**
+     * 产地
+     */
+    private String origin;
+    /**
+     * 时代
+     */
+    private String era;
+    /**
+     * 保存地层
+     */
+    private String preservedLayer;
+    /**
+     * 陨石类型
+     */
+    private String meteoriteType;
+    /**
+     * 国际命名
+     */
+    private String internationalName;
+    /**
+     * 发现时间
+     */
+    private LocalDate discoveryTime;
+    /**
+     * 降落时间
+     */
+    private LocalDate fallTime;
+    /**
+     * 保存类型(标本、光片、薄片模型及其他)
+     */
+    private Integer preservationType;
+    /**
+     * 尺寸
+     */
+    private String size;
+    /**
+     * 重量
+     */
+    private BigDecimal weight;
+    /**
+     * 来源(采购、捐赠、采集)
+     */
+    private Integer source;
+    /**
+     * 标本提供者(供应商、捐赠人、采集人)
+     */
+    private String provider;
+    /**
+     * 入藏时间(购买、捐赠、采集时间)
+     */
+    private LocalDate acquisitionTime;
+    /**
+     * 用途
+     */
+    private String purpose;
+    /**
+     * 描述
+     */
+    private String description;
+    /**
+     * 馆藏状态(在馆、借出)
+     */
+    private Integer collectionStatus;
+    /**
+     * 备注
+     */
+    private String notes;
+    /**
+     * 图片名称
+     */
+    private String imageName;
+    /**
+     * 图片路径
+     */
+    private String imagePath;
+    /**
+     * 注销原因
+     */
+    private String deletedReason;
+    /**
+     * 入库操作员
+     */
+    private String operator;
+    /**
+     * 入库时间
+     */
+    private LocalDateTime entryDate;
+
+}

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

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.museums.dal.mysql.specimeninfo;
+
+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.specimeninfo.SpecimenInfoDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
+
+/**
+ * 标本管理 Mapper
+ *
+ * @author 普伟
+ */
+@Mapper
+public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
+
+    default PageResult<SpecimenInfoDO> selectPage(SpecimenInfoPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<SpecimenInfoDO>()
+                .eqIfPresent(SpecimenInfoDO::getSpecimenType, reqVO.getSpecimenType())
+                .eqIfPresent(SpecimenInfoDO::getSpecimenNumber, reqVO.getSpecimenNumber())
+                .eqIfPresent(SpecimenInfoDO::getAssetNumber, reqVO.getAssetNumber())
+                .eqIfPresent(SpecimenInfoDO::getStorageLocation, reqVO.getStorageLocation())
+                .likeIfPresent(SpecimenInfoDO::getChineseName, reqVO.getChineseName())
+                .likeIfPresent(SpecimenInfoDO::getEnglishName, reqVO.getEnglishName())
+                .eqIfPresent(SpecimenInfoDO::getComposition, reqVO.getComposition())
+                .eqIfPresent(SpecimenInfoDO::getOrigin, reqVO.getOrigin())
+                .eqIfPresent(SpecimenInfoDO::getEra, reqVO.getEra())
+                .eqIfPresent(SpecimenInfoDO::getPreservedLayer, reqVO.getPreservedLayer())
+                .eqIfPresent(SpecimenInfoDO::getMeteoriteType, reqVO.getMeteoriteType())
+                .likeIfPresent(SpecimenInfoDO::getInternationalName, reqVO.getInternationalName())
+                .betweenIfPresent(SpecimenInfoDO::getDiscoveryTime, reqVO.getDiscoveryTime())
+                .betweenIfPresent(SpecimenInfoDO::getFallTime, reqVO.getFallTime())
+                .eqIfPresent(SpecimenInfoDO::getPreservationType, reqVO.getPreservationType())
+                .eqIfPresent(SpecimenInfoDO::getSize, reqVO.getSize())
+                .eqIfPresent(SpecimenInfoDO::getWeight, reqVO.getWeight())
+                .eqIfPresent(SpecimenInfoDO::getSource, reqVO.getSource())
+                .eqIfPresent(SpecimenInfoDO::getProvider, reqVO.getProvider())
+                .betweenIfPresent(SpecimenInfoDO::getAcquisitionTime, reqVO.getAcquisitionTime())
+                .eqIfPresent(SpecimenInfoDO::getPurpose, reqVO.getPurpose())
+                .eqIfPresent(SpecimenInfoDO::getDescription, reqVO.getDescription())
+                .eqIfPresent(SpecimenInfoDO::getCollectionStatus, reqVO.getCollectionStatus())
+                .eqIfPresent(SpecimenInfoDO::getNotes, reqVO.getNotes())
+                .likeIfPresent(SpecimenInfoDO::getImageName, reqVO.getImageName())
+                .eqIfPresent(SpecimenInfoDO::getImagePath, reqVO.getImagePath())
+                .betweenIfPresent(SpecimenInfoDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(SpecimenInfoDO::getDeletedReason, reqVO.getDeletedReason())
+                .eqIfPresent(SpecimenInfoDO::getOperator, reqVO.getOperator())
+                .betweenIfPresent(SpecimenInfoDO::getEntryDate, reqVO.getEntryDate())
+                .orderByDesc(SpecimenInfoDO::getId));
+    }
+
+}

+ 55 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoService.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.museums.service.specimeninfo;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
+import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+
+/**
+ * 标本管理 Service 接口
+ *
+ * @author 普伟
+ */
+public interface SpecimenInfoService {
+
+    /**
+     * 创建标本管理
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Integer createSpecimenInfo(@Valid SpecimenInfoSaveReqVO createReqVO);
+
+    /**
+     * 更新标本管理
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateSpecimenInfo(@Valid SpecimenInfoSaveReqVO updateReqVO);
+
+    /**
+     * 删除标本管理
+     *
+     * @param id 编号
+     */
+    void deleteSpecimenInfo(Integer id);
+
+    /**
+     * 获得标本管理
+     *
+     * @param id 编号
+     * @return 标本管理
+     */
+    SpecimenInfoDO getSpecimenInfo(Integer id);
+
+    /**
+     * 获得标本管理分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 标本管理分页
+     */
+    PageResult<SpecimenInfoDO> getSpecimenInfoPage(SpecimenInfoPageReqVO pageReqVO);
+
+}

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

@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.module.museums.service.specimeninfo;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
+import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import cn.iocoder.yudao.module.museums.dal.mysql.specimeninfo.SpecimenInfoMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.*;
+/**
+ * 标本管理 Service 实现类
+ *
+ * @author 普伟
+ */
+@Service
+@Validated
+public class SpecimenInfoServiceImpl implements SpecimenInfoService {
+
+    @Resource
+    private SpecimenInfoMapper specimenInfoMapper;
+
+    @Override
+    public Integer createSpecimenInfo(SpecimenInfoSaveReqVO createReqVO) {
+        // 插入
+        SpecimenInfoDO specimenInfo = BeanUtils.toBean(createReqVO, SpecimenInfoDO.class);
+        specimenInfoMapper.insert(specimenInfo);
+        // 返回
+        return specimenInfo.getId();
+    }
+
+    @Override
+    public void updateSpecimenInfo(SpecimenInfoSaveReqVO updateReqVO) {
+        // 校验存在
+        validateSpecimenInfoExists(updateReqVO.getId());
+        // 更新
+        SpecimenInfoDO updateObj = BeanUtils.toBean(updateReqVO, SpecimenInfoDO.class);
+        specimenInfoMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteSpecimenInfo(Integer id) {
+        // 校验存在
+        validateSpecimenInfoExists(id);
+        // 删除
+        specimenInfoMapper.deleteById(id);
+    }
+
+    private void validateSpecimenInfoExists(Integer id) {
+        if (specimenInfoMapper.selectById(id) == null) {
+            throw exception(SPECIMEN_INFO_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public SpecimenInfoDO getSpecimenInfo(Integer id) {
+        return specimenInfoMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<SpecimenInfoDO> getSpecimenInfoPage(SpecimenInfoPageReqVO pageReqVO) {
+        return specimenInfoMapper.selectPage(pageReqVO);
+    }
+
+}

+ 12 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/resources/mapper/specimeninfo/SpecimenInfoMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.museums.dal.mysql.specimeninfo.SpecimenInfoMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
+     -->
+
+</mapper>

+ 234 - 0
yudao-module-museums/yudao-module-museums-biz/src/test/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImplTest.java

@@ -0,0 +1,234 @@
+//package cn.iocoder.yudao.module.museums.service.specimeninfo;
+//
+//import org.junit.jupiter.api.Disabled;
+//import org.junit.jupiter.api.Test;
+//
+//import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
+//import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
+//import cn.iocoder.yudao.module.museums.dal.mysql.specimeninfo.SpecimenInfoMapper;
+//import cn.iocoder.yudao.framework.common.pojo.PageResult;
+//
+//import javax.annotation.Resource;
+//import org.springframework.context.annotation.Import;
+//
+//import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
+//import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
+//import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
+//import static org.junit.jupiter.api.Assertions.*;
+//
+///**
+// * {@link SpecimenInfoServiceImpl} 的单元测试类
+// *
+// * @author 普伟
+// */
+//@Import(SpecimenInfoServiceImpl.class)
+//public class SpecimenInfoServiceImplTest extends BaseDbUnitTest {
+//
+//    @Resource
+//    private SpecimenInfoServiceImpl specimenInfoService;
+//
+//    @Resource
+//    private SpecimenInfoMapper specimenInfoMapper;
+//
+//    @Test
+//    public void testCreateSpecimenInfo_success() {
+//        // 准备参数
+//        SpecimenInfoSaveReqVO createReqVO = randomPojo(SpecimenInfoSaveReqVO.class).setId(null);
+//
+//        // 调用
+//        Integer specimenInfoId = specimenInfoService.createSpecimenInfo(createReqVO);
+//        // 断言
+//        assertNotNull(specimenInfoId);
+//        // 校验记录的属性是否正确
+//        SpecimenInfoDO specimenInfo = specimenInfoMapper.selectById(specimenInfoId);
+//        assertPojoEquals(createReqVO, specimenInfo, "id");
+//    }
+//
+//    @Test
+//    public void testUpdateSpecimenInfo_success() {
+//        // mock 数据
+//        SpecimenInfoDO dbSpecimenInfo = randomPojo(SpecimenInfoDO.class);
+//        specimenInfoMapper.insert(dbSpecimenInfo);// @Sql: 先插入出一条存在的数据
+//        // 准备参数
+//        SpecimenInfoSaveReqVO updateReqVO = randomPojo(SpecimenInfoSaveReqVO.class, o -> {
+//            o.setId(dbSpecimenInfo.getId()); // 设置更新的 ID
+//        });
+//
+//        // 调用
+//        specimenInfoService.updateSpecimenInfo(updateReqVO);
+//        // 校验是否更新正确
+//        SpecimenInfoDO specimenInfo = specimenInfoMapper.selectById(updateReqVO.getId()); // 获取最新的
+//        assertPojoEquals(updateReqVO, specimenInfo);
+//    }
+//
+//    @Test
+//    public void testUpdateSpecimenInfo_notExists() {
+//        // 准备参数
+//        SpecimenInfoSaveReqVO updateReqVO = randomPojo(SpecimenInfoSaveReqVO.class);
+//
+//        // 调用, 并断言异常
+//        assertServiceException(() -> specimenInfoService.updateSpecimenInfo(updateReqVO), SPECIMEN_INFO_NOT_EXISTS);
+//    }
+//
+//    @Test
+//    public void testDeleteSpecimenInfo_success() {
+//        // mock 数据
+//        SpecimenInfoDO dbSpecimenInfo = randomPojo(SpecimenInfoDO.class);
+//        specimenInfoMapper.insert(dbSpecimenInfo);// @Sql: 先插入出一条存在的数据
+//        // 准备参数
+//        Integer id = dbSpecimenInfo.getId();
+//
+//        // 调用
+//        specimenInfoService.deleteSpecimenInfo(id);
+//       // 校验数据不存在了
+//       assertNull(specimenInfoMapper.selectById(id));
+//    }
+//
+//    @Test
+//    public void testDeleteSpecimenInfo_notExists() {
+//        // 准备参数
+//        Integer id = randomIntegerId();
+//
+//        // 调用, 并断言异常
+//        assertServiceException(() -> specimenInfoService.deleteSpecimenInfo(id), SPECIMEN_INFO_NOT_EXISTS);
+//    }
+//
+//    @Test
+//    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+//    public void testGetSpecimenInfoPage() {
+//       // mock 数据
+//       SpecimenInfoDO dbSpecimenInfo = randomPojo(SpecimenInfoDO.class, o -> { // 等会查询到
+//           o.setSpecimenType(null);
+//           o.setSpecimenNumber(null);
+//           o.setAssetNumber(null);
+//           o.setStorageLocation(null);
+//           o.setChineseName(null);
+//           o.setEnglishName(null);
+//           o.setComposition(null);
+//           o.setOrigin(null);
+//           o.setEra(null);
+//           o.setPreservedLayer(null);
+//           o.setMeteoriteType(null);
+//           o.setInternationalName(null);
+//           o.setDiscoveryTime(null);
+//           o.setFallTime(null);
+//           o.setPreservationType(null);
+//           o.setSize(null);
+//           o.setWeight(null);
+//           o.setSource(null);
+//           o.setProvider(null);
+//           o.setAcquisitionTime(null);
+//           o.setPurpose(null);
+//           o.setDescription(null);
+//           o.setCollectionStatus(null);
+//           o.setNotes(null);
+//           o.setImageName(null);
+//           o.setImagePath(null);
+//           o.setCreateTime(null);
+//           o.setDeletedReason(null);
+//           o.setOperator(null);
+//           o.setEntryDate(null);
+//       });
+//       specimenInfoMapper.insert(dbSpecimenInfo);
+//       // 测试 specimenType 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setSpecimenType(null)));
+//       // 测试 specimenNumber 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setSpecimenNumber(null)));
+//       // 测试 assetNumber 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setAssetNumber(null)));
+//       // 测试 storageLocation 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setStorageLocation(null)));
+//       // 测试 chineseName 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setChineseName(null)));
+//       // 测试 englishName 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setEnglishName(null)));
+//       // 测试 composition 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setComposition(null)));
+//       // 测试 origin 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setOrigin(null)));
+//       // 测试 era 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setEra(null)));
+//       // 测试 preservedLayer 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setPreservedLayer(null)));
+//       // 测试 meteoriteType 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setMeteoriteType(null)));
+//       // 测试 internationalName 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setInternationalName(null)));
+//       // 测试 discoveryTime 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setDiscoveryTime(null)));
+//       // 测试 fallTime 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setFallTime(null)));
+//       // 测试 preservationType 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setPreservationType(null)));
+//       // 测试 size 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setSize(null)));
+//       // 测试 weight 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setWeight(null)));
+//       // 测试 source 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setSource(null)));
+//       // 测试 provider 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setProvider(null)));
+//       // 测试 acquisitionTime 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setAcquisitionTime(null)));
+//       // 测试 purpose 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setPurpose(null)));
+//       // 测试 description 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setDescription(null)));
+//       // 测试 collectionStatus 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setCollectionStatus(null)));
+//       // 测试 notes 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setNotes(null)));
+//       // 测试 imageName 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setImageName(null)));
+//       // 测试 imagePath 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setImagePath(null)));
+//       // 测试 createTime 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setCreateTime(null)));
+//       // 测试 deletedReason 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setDeletedReason(null)));
+//       // 测试 operator 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setOperator(null)));
+//       // 测试 entryDate 不匹配
+//       specimenInfoMapper.insert(cloneIgnoreId(dbSpecimenInfo, o -> o.setEntryDate(null)));
+//       // 准备参数
+//       SpecimenInfoPageReqVO reqVO = new SpecimenInfoPageReqVO();
+//       reqVO.setSpecimenType(null);
+//       reqVO.setSpecimenNumber(null);
+//       reqVO.setAssetNumber(null);
+//       reqVO.setStorageLocation(null);
+//       reqVO.setChineseName(null);
+//       reqVO.setEnglishName(null);
+//       reqVO.setComposition(null);
+//       reqVO.setOrigin(null);
+//       reqVO.setEra(null);
+//       reqVO.setPreservedLayer(null);
+//       reqVO.setMeteoriteType(null);
+//       reqVO.setInternationalName(null);
+//       reqVO.setDiscoveryTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//       reqVO.setFallTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//       reqVO.setPreservationType(null);
+//       reqVO.setSize(null);
+//       reqVO.setWeight(null);
+//       reqVO.setSource(null);
+//       reqVO.setProvider(null);
+//       reqVO.setAcquisitionTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//       reqVO.setPurpose(null);
+//       reqVO.setDescription(null);
+//       reqVO.setCollectionStatus(null);
+//       reqVO.setNotes(null);
+//       reqVO.setImageName(null);
+//       reqVO.setImagePath(null);
+//       reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//       reqVO.setDeletedReason(null);
+//       reqVO.setOperator(null);
+//       reqVO.setEntryDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//
+//       // 调用
+//       PageResult<SpecimenInfoDO> pageResult = specimenInfoService.getSpecimenInfoPage(reqVO);
+//       // 断言
+//       assertEquals(1, pageResult.getTotal());
+//       assertEquals(1, pageResult.getList().size());
+//       assertPojoEquals(dbSpecimenInfo, pageResult.getList().get(0));
+//    }
+//
+//}