diff --git a/backend/src/main/java/com/xly/erp/module/mod/entity/ModuleEntity.java b/backend/src/main/java/com/xly/erp/module/mod/entity/ModuleEntity.java
new file mode 100644
index 0000000..4bb6c61
--- /dev/null
+++ b/backend/src/main/java/com/xly/erp/module/mod/entity/ModuleEntity.java
@@ -0,0 +1,71 @@
+package com.xly.erp.module.mod.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 业务模块定义。表 {@code tModule}(详见 docs/03-数据库设计文档.md § tModule)。
+ *
+ *
字段名沿用 docs/03 的匈牙利前缀命名(i/s/t/b),保持 schema 与 Java 字段一一对应,
+ * 避免双向映射歧义。@TableField 显式声明列名以兼容 MyBatis-Plus 默认的下划线转换关闭场景。
+ */
+@Data
+@TableName("tModule")
+public class ModuleEntity {
+
+ @TableId(value = "iIncrement", type = IdType.AUTO)
+ private Integer iIncrement;
+
+ @TableField("sId")
+ private String sId;
+
+ @TableField("sBrandsId")
+ private String sBrandsId;
+
+ @TableField("sSubsidiaryId")
+ private String sSubsidiaryId;
+
+ @TableField("tCreateDate")
+ private LocalDateTime tCreateDate;
+
+ @TableField("sDisplayType")
+ private String sDisplayType;
+
+ @TableField("sProcedureName")
+ private String sProcedureName;
+
+ @TableField("sModuleType")
+ private String sModuleType;
+
+ @TableField("sManageDeptEn")
+ private String sManageDeptEn;
+
+ @TableField("bShowPermission")
+ private Boolean bShowPermission;
+
+ @TableField("sModuleNameZh")
+ private String sModuleNameZh;
+
+ @TableField("iParentId")
+ private Integer iParentId;
+
+ @TableField("iSortOrder")
+ private Integer iSortOrder;
+
+ @TableField("sCreatedBy")
+ private String sCreatedBy;
+
+ @TableField("bDeleted")
+ private Boolean bDeleted;
+
+ @TableField("tDeletedDate")
+ private LocalDateTime tDeletedDate;
+
+ @TableField("sDeletedBy")
+ private String sDeletedBy;
+}
diff --git a/backend/src/main/java/com/xly/erp/module/mod/mapper/ModuleMapper.java b/backend/src/main/java/com/xly/erp/module/mod/mapper/ModuleMapper.java
new file mode 100644
index 0000000..7abc096
--- /dev/null
+++ b/backend/src/main/java/com/xly/erp/module/mod/mapper/ModuleMapper.java
@@ -0,0 +1,7 @@
+package com.xly.erp.module.mod.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xly.erp.module.mod.entity.ModuleEntity;
+
+public interface ModuleMapper extends BaseMapper {
+}
diff --git a/backend/src/main/resources/mapper/mod/ModuleMapper.xml b/backend/src/main/resources/mapper/mod/ModuleMapper.xml
new file mode 100644
index 0000000..9e7b093
--- /dev/null
+++ b/backend/src/main/resources/mapper/mod/ModuleMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/backend/src/test/java/com/xly/erp/module/mod/mapper/ModuleMapperIT.java b/backend/src/test/java/com/xly/erp/module/mod/mapper/ModuleMapperIT.java
new file mode 100644
index 0000000..bd61361
--- /dev/null
+++ b/backend/src/test/java/com/xly/erp/module/mod/mapper/ModuleMapperIT.java
@@ -0,0 +1,77 @@
+package com.xly.erp.module.mod.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.xly.erp.module.mod.entity.ModuleEntity;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+@ActiveProfiles("test")
+@Transactional
+@Rollback
+class ModuleMapperIT {
+
+ @Autowired ModuleMapper moduleMapper;
+
+ @Test
+ void insertAndSelectById_persistsAllFields() {
+ ModuleEntity e = new ModuleEntity();
+ e.setSDisplayType("前端业务");
+ e.setSProcedureName("sp_audit_test_" + System.nanoTime());
+ e.setSModuleType("USR");
+ e.setSManageDeptEn("IT");
+ e.setBShowPermission(false);
+ e.setSModuleNameZh("测试模块");
+ e.setIParentId(null);
+ e.setISortOrder(0);
+ e.setBDeleted(false);
+ e.setTCreateDate(LocalDateTime.now());
+
+ int rows = moduleMapper.insert(e);
+ assertThat(rows).isEqualTo(1);
+ assertThat(e.getIIncrement()).isNotNull().isPositive();
+
+ ModuleEntity loaded = moduleMapper.selectById(e.getIIncrement());
+ assertThat(loaded).isNotNull();
+ assertThat(loaded.getSDisplayType()).isEqualTo("前端业务");
+ assertThat(loaded.getSProcedureName()).isEqualTo(e.getSProcedureName());
+ assertThat(loaded.getSModuleType()).isEqualTo("USR");
+ assertThat(loaded.getSManageDeptEn()).isEqualTo("IT");
+ assertThat(loaded.getBShowPermission()).isFalse();
+ assertThat(loaded.getSModuleNameZh()).isEqualTo("测试模块");
+ assertThat(loaded.getIParentId()).isNull();
+ assertThat(loaded.getISortOrder()).isZero();
+ assertThat(loaded.getBDeleted()).isFalse();
+ }
+
+ @Test
+ void selectCountByProcedureName_returnsExisting() {
+ String name = "sp_audit_uniq_" + System.nanoTime();
+ ModuleEntity e = new ModuleEntity();
+ e.setSDisplayType("接口");
+ e.setSProcedureName(name);
+ e.setSModuleType("MOD");
+ e.setSManageDeptEn("IT");
+ e.setBShowPermission(false);
+ e.setSModuleNameZh("唯一性检测");
+ e.setISortOrder(0);
+ e.setBDeleted(false);
+ e.setTCreateDate(LocalDateTime.now());
+ moduleMapper.insert(e);
+
+ Long count = moduleMapper.selectCount(
+ new LambdaQueryWrapper()
+ .eq(ModuleEntity::getSProcedureName, name)
+ .eq(ModuleEntity::getBDeleted, false)
+ );
+ assertThat(count).isEqualTo(1L);
+ }
+}