diff --git a/data/src/main/java/com/sdm/data/dao/FileStorageMapper.java b/data/src/main/java/com/sdm/data/dao/FileStorageMapper.java
new file mode 100644
index 00000000..d58d3d4f
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/dao/FileStorageMapper.java
@@ -0,0 +1,33 @@
+package com.sdm.data.dao;
+
+import com.sdm.data.model.dto.NodeSizeDTO;
+import com.sdm.data.model.dto.UserTotalFileSizeDTO;
+import com.sdm.data.model.entity.FileStorage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 文件存储统计主表(支持项目/学科/用户维度的存储占用统计) Mapper 接口
+ *
+ *
+ * @author author
+ * @since 2025-11-04
+ */
+public interface FileStorageMapper extends BaseMapper {
+ List selectNodeSizeByNodeType(@Param("directoryIds") List directoryIds,@Param("intervalMonths") Integer intervalMonths);
+
+ /**
+ * 批量统计项目的存储占用:目标年月之前(历史累计) + 目标年月(当月增量)
+ * @param dirIds 待统计的项目ID列表(批量查询)
+ * @param targetYm 目标年月(格式:YYYY-MM,如 "2024-10",与表中 createYearMonth 一致)
+ * @return 统计结果列表:每个项目对应2条记录(历史累计 + 当月增量)
+ */
+ List statDirStorageByTargetYm(@Param("dirIds") List dirIds, @Param("targetYm") String targetYm);
+
+ List getTotalFileSizeByCreator(@Param("userIds") List userIds,@Param("intervalMonths") Integer intervalMonths);
+
+ List getTotalFileSizeByCreatorAndTargetYm(@Param("userIds") List userIds,@Param("targetYm") String targetYm);
+}
diff --git a/data/src/main/java/com/sdm/data/dao/FileStorageQuotaMapper.java b/data/src/main/java/com/sdm/data/dao/FileStorageQuotaMapper.java
new file mode 100644
index 00000000..3fbdd559
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/dao/FileStorageQuotaMapper.java
@@ -0,0 +1,16 @@
+package com.sdm.data.dao;
+
+import com.sdm.data.model.entity.FileStorageQuota;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 文件存储-用户存储配额表(支持TB/GB/MB/KB多单位) Mapper 接口
+ *
+ *
+ * @author author
+ * @since 2025-11-05
+ */
+public interface FileStorageQuotaMapper extends BaseMapper {
+
+}
diff --git a/data/src/main/java/com/sdm/data/model/entity/FileStorage.java b/data/src/main/java/com/sdm/data/model/entity/FileStorage.java
new file mode 100644
index 00000000..4a92aed5
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/model/entity/FileStorage.java
@@ -0,0 +1,81 @@
+package com.sdm.data.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * 文件存储统计主表(支持项目/学科/用户维度的存储占用统计)
+ *
+ *
+ * @author author
+ * @since 2025-11-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("file_storage")
+@ApiModel(value="FileStorage对象", description="文件存储统计主表(支持项目/学科/用户维度的存储占用统计)")
+public class FileStorage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "主键ID(自增)")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ @ApiModelProperty(value = "文件名(含后缀)")
+ @TableField("fileName")
+ private String fileName;
+
+ @ApiModelProperty(value = "文件唯一标识ID(关联文件元数据表)")
+ @TableField("fileId")
+ private Long fileId;
+
+ @ApiModelProperty(value = "用户组ID")
+ @TableField("userGroupId")
+ private Long userGroupId;
+
+ @ApiModelProperty(value = "文件所属用户ID")
+ @TableField("userId")
+ private Long userId;
+
+ @ApiModelProperty(value = "目录ID(项目/学科等目录的唯一标识)")
+ @TableField("dirId")
+ private Long dirId;
+
+ @ApiModelProperty(value = "文件类型(如txt、jpg、pdf)")
+ @TableField("fileType")
+ private String fileType;
+
+ @ApiModelProperty(value = "文件大小(字节数,存储占用计算依据)")
+ @TableField("fileSize")
+ private Long fileSize;
+
+ @ApiModelProperty(value = "文件创建时间(精确到秒,自动填充当前时间)")
+ @TableField("createTime")
+ private LocalDateTime createTime;
+
+ @ApiModelProperty(value = "记录更新时间(自动更新)")
+ @TableField("updateTime")
+ private LocalDateTime updateTime;
+
+ @ApiModelProperty(value = "文件完整路径(冗余字段,优化查询)")
+ @TableField("fullPath")
+ private String fullPath;
+
+ @ApiModelProperty(value = "创建时间年月(冗余列,格式YYYY-MM,用于分组统计)")
+ @TableField("createYearMonth")
+ private String createYearMonth;
+
+
+}
diff --git a/data/src/main/java/com/sdm/data/model/entity/FileStorageQuota.java b/data/src/main/java/com/sdm/data/model/entity/FileStorageQuota.java
new file mode 100644
index 00000000..3b36cc08
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/model/entity/FileStorageQuota.java
@@ -0,0 +1,56 @@
+package com.sdm.data.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * 文件存储-用户存储配额表(支持TB/GB/MB/KB多单位)
+ *
+ *
+ * @author author
+ * @since 2025-11-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("file_storage_quota")
+@ApiModel(value="FileStorageQuota对象", description="文件存储-用户存储配额表(支持TB/GB/MB/KB多单位)")
+public class FileStorageQuota implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "主键ID(自增)")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ @ApiModelProperty(value = "关联用户表sys_user的id(唯一标识用户)")
+ @TableField("userId")
+ private Long userId;
+
+ @ApiModelProperty(value = "存储阈值(单位:字节)")
+ @TableField("quotaValue")
+ private Long quotaValue;
+
+ @ApiModelProperty(value = "阈值显示单位(枚举:TB/GB/MB/KB)")
+ @TableField("quotaUnit")
+ private String quotaUnit;
+
+ @ApiModelProperty(value = "已使用存储(单位:字节)")
+ @TableField("usedValue")
+ private Long usedValue;
+
+ @ApiModelProperty(value = "配额状态(枚举:NORMAL-正常/WARNING-临界/EXCEED-超限)")
+ @TableField("status")
+ private String status;
+
+
+}
diff --git a/data/src/main/java/com/sdm/data/service/IFileStorageQuotaService.java b/data/src/main/java/com/sdm/data/service/IFileStorageQuotaService.java
new file mode 100644
index 00000000..7955e2ab
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/service/IFileStorageQuotaService.java
@@ -0,0 +1,16 @@
+package com.sdm.data.service;
+
+import com.sdm.data.model.entity.FileStorageQuota;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 文件存储-用户存储配额表(支持TB/GB/MB/KB多单位) 服务类
+ *
+ *
+ * @author author
+ * @since 2025-11-05
+ */
+public interface IFileStorageQuotaService extends IService {
+
+}
diff --git a/data/src/main/java/com/sdm/data/service/IFileStorageService.java b/data/src/main/java/com/sdm/data/service/IFileStorageService.java
new file mode 100644
index 00000000..011afa42
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/service/IFileStorageService.java
@@ -0,0 +1,28 @@
+package com.sdm.data.service;
+
+import com.sdm.data.model.dto.NodeSizeDTO;
+import com.sdm.data.model.dto.UserTotalFileSizeDTO;
+import com.sdm.data.model.entity.FileStorage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 文件存储统计主表(支持项目/学科/用户维度的存储占用统计) 服务类
+ *
+ *
+ * @author author
+ * @since 2025-11-04
+ */
+public interface IFileStorageService extends IService {
+ List selectNodeSizeByNodeType(List directoryIds,Integer intervalMonths);
+
+ List statDirStorageByTargetYm(List dirIds, String targetYm);
+
+ List getTotalFileSizeByCreator(List userIds,Integer intervalMonths);
+
+ List getTotalFileSizeByCreatorAndTargetYm(List userIds,String targetYm);
+
+}
diff --git a/data/src/main/java/com/sdm/data/service/impl/FileStorageQuotaServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/FileStorageQuotaServiceImpl.java
new file mode 100644
index 00000000..d21d10dd
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/service/impl/FileStorageQuotaServiceImpl.java
@@ -0,0 +1,20 @@
+package com.sdm.data.service.impl;
+
+import com.sdm.data.model.entity.FileStorageQuota;
+import com.sdm.data.dao.FileStorageQuotaMapper;
+import com.sdm.data.service.IFileStorageQuotaService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 文件存储-用户存储配额表(支持TB/GB/MB/KB多单位) 服务实现类
+ *
+ *
+ * @author author
+ * @since 2025-11-05
+ */
+@Service
+public class FileStorageQuotaServiceImpl extends ServiceImpl implements IFileStorageQuotaService {
+
+}
diff --git a/data/src/main/java/com/sdm/data/service/impl/FileStorageServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/FileStorageServiceImpl.java
new file mode 100644
index 00000000..9b78984d
--- /dev/null
+++ b/data/src/main/java/com/sdm/data/service/impl/FileStorageServiceImpl.java
@@ -0,0 +1,43 @@
+package com.sdm.data.service.impl;
+
+import com.sdm.data.model.dto.NodeSizeDTO;
+import com.sdm.data.model.dto.UserTotalFileSizeDTO;
+import com.sdm.data.model.entity.FileStorage;
+import com.sdm.data.dao.FileStorageMapper;
+import com.sdm.data.service.IFileStorageService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ *
+ * 文件存储统计主表(支持项目/学科/用户维度的存储占用统计) 服务实现类
+ *
+ *
+ * @author author
+ * @since 2025-11-04
+ */
+@Service
+public class FileStorageServiceImpl extends ServiceImpl implements IFileStorageService {
+ @Override
+ public List selectNodeSizeByNodeType(List directoryIds, Integer intervalMonths) {
+ return baseMapper.selectNodeSizeByNodeType(directoryIds, intervalMonths);
+ }
+
+ @Override
+ public List statDirStorageByTargetYm(List dirIds, String targetYm) {
+ return baseMapper.statDirStorageByTargetYm(dirIds, targetYm);
+ }
+
+ @Override
+ public List getTotalFileSizeByCreator(List userIds, Integer intervalMonths) {
+ return baseMapper.getTotalFileSizeByCreator(userIds, intervalMonths);
+ }
+
+ @Override
+ public List getTotalFileSizeByCreatorAndTargetYm(List userIds, String targetYm) {
+ return baseMapper.getTotalFileSizeByCreatorAndTargetYm(userIds, targetYm);
+ }
+}
diff --git a/data/src/main/resources/mapper/FileStorageMapper.xml b/data/src/main/resources/mapper/FileStorageMapper.xml
new file mode 100644
index 00000000..e54fb7ec
--- /dev/null
+++ b/data/src/main/resources/mapper/FileStorageMapper.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/src/main/resources/mapper/FileStorageQuotaMapper.xml b/data/src/main/resources/mapper/FileStorageQuotaMapper.xml
new file mode 100644
index 00000000..e4556a23
--- /dev/null
+++ b/data/src/main/resources/mapper/FileStorageQuotaMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+