diff --git a/backend/ruoyi-modules/ruoyi-xg/pom.xml b/backend/ruoyi-modules/ruoyi-xg/pom.xml
index 3b47f0fb..cc54a015 100644
--- a/backend/ruoyi-modules/ruoyi-xg/pom.xml
+++ b/backend/ruoyi-modules/ruoyi-xg/pom.xml
@@ -113,6 +113,12 @@
${revision}
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxyHelper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxyHelper.java
new file mode 100644
index 00000000..bc6ddc73
--- /dev/null
+++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxyHelper.java
@@ -0,0 +1,77 @@
+package org.dromara.xg.helper;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.ConfigService;
+import org.dromara.common.core.utils.StringUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * 一年级代理学院(人文学院)解析与宿舍分配权限判定。
+ *
+ * 配置键复用请假:{@link FreshmanCollegeProxySupport#FRESHMAN_PROXY_COLLEGE_CONFIG_KEY}。
+ * 不修改班级真实 college_id,仅运行时判定操作权。
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class FreshmanCollegeProxyHelper {
+
+ private final ConfigService configService;
+
+ public int currentCohortYear() {
+ return FreshmanCollegeProxySupport.currentCohortYear();
+ }
+
+ public boolean isFreshmanByEnrollmentYear(Long enrollmentYear) {
+ return FreshmanCollegeProxySupport.isFreshmanByEnrollmentYear(enrollmentYear);
+ }
+
+ /**
+ * 读取代理学院;未配置或非法时抛业务异常(请假等强制场景)。
+ */
+ public Long requireProxyCollegeId() {
+ Long proxyCollegeId = resolveProxyCollegeIdOrNull();
+ if (proxyCollegeId == null) {
+ throw new ServiceException("一年级请假代理学院未配置或无效,请在系统参数中配置 "
+ + FreshmanCollegeProxySupport.FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
+ }
+ return proxyCollegeId;
+ }
+
+ /**
+ * 读取代理学院;未配置时返回 null(宿舍树降级为原逻辑,避免拖垮其它功能)。
+ */
+ public Long resolveProxyCollegeIdOrNull() {
+ String configValue = configService.getConfigValue(
+ FreshmanCollegeProxySupport.FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
+ if (StringUtils.isBlank(configValue)) {
+ log.warn("系统参数 {} 未配置,一年级宿舍代理不生效",
+ FreshmanCollegeProxySupport.FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
+ return null;
+ }
+ try {
+ return Long.valueOf(configValue.trim());
+ } catch (NumberFormatException e) {
+ log.warn("系统参数 {} 配置无效: {}",
+ FreshmanCollegeProxySupport.FRESHMAN_PROXY_COLLEGE_CONFIG_KEY, configValue);
+ return null;
+ }
+ }
+
+ public boolean isProxyCollege(Long collegeId) {
+ Long proxyCollegeId = resolveProxyCollegeIdOrNull();
+ return proxyCollegeId != null && proxyCollegeId.equals(collegeId);
+ }
+
+ /**
+ * 当前学院用户是否可对指定班级做宿舍「分配到班级 / 回收班级分配」。
+ */
+ public boolean canOperateClassForDormAllocation(Long operatorCollegeId,
+ Long classCollegeId,
+ Long enrollmentYear) {
+ return FreshmanCollegeProxySupport.canOperateClassForDormAllocation(
+ operatorCollegeId, classCollegeId, enrollmentYear, resolveProxyCollegeIdOrNull());
+ }
+}
diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxySupport.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxySupport.java
new file mode 100644
index 00000000..c9b1ec75
--- /dev/null
+++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/helper/FreshmanCollegeProxySupport.java
@@ -0,0 +1,70 @@
+package org.dromara.xg.helper;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+
+/**
+ * 一年级代理学院纯计算逻辑(无 Spring 依赖,便于单测)。
+ *
+ * 学年切换日:每年 9 月 1 日(Asia/Shanghai)。与请假模块口径一致。
+ */
+public final class FreshmanCollegeProxySupport {
+
+ public static final ZoneId SHANGHAI_ZONE = ZoneId.of("Asia/Shanghai");
+
+ /** 与请假共用的系统参数键 */
+ public static final String FRESHMAN_PROXY_COLLEGE_CONFIG_KEY = "xg.studentLeave.freshmanProxyCollegeId";
+
+ private FreshmanCollegeProxySupport() {
+ }
+
+ /**
+ * 当前入学届别年份(9 月 1 日起算新一届)。
+ */
+ public static int currentCohortYear(LocalDate today) {
+ LocalDate date = today != null ? today : LocalDate.now(SHANGHAI_ZONE);
+ return date.getMonthValue() >= 9 ? date.getYear() : date.getYear() - 1;
+ }
+
+ /**
+ * 当前入学届别年份(按上海时区当天)。
+ */
+ public static int currentCohortYear() {
+ return currentCohortYear(LocalDate.now(SHANGHAI_ZONE));
+ }
+
+ /**
+ * 是否一年级(入学年等于当前届)。入学年为空视为非一年级,避免误代理。
+ */
+ public static boolean isFreshmanByEnrollmentYear(Long enrollmentYear, LocalDate today) {
+ if (enrollmentYear == null) {
+ return false;
+ }
+ return enrollmentYear.intValue() == currentCohortYear(today);
+ }
+
+ public static boolean isFreshmanByEnrollmentYear(Long enrollmentYear) {
+ return isFreshmanByEnrollmentYear(enrollmentYear, LocalDate.now(SHANGHAI_ZONE));
+ }
+
+ /**
+ * 宿舍「分配到班级」权限判定。
+ *
+ * @param operatorCollegeId 操作人所属二级学院
+ * @param classCollegeId 班级真实所属学院
+ * @param enrollmentYear 班级入学年
+ * @param proxyCollegeId 代理学院(未配置则为 null)
+ */
+ public static boolean canOperateClassForDormAllocation(Long operatorCollegeId,
+ Long classCollegeId,
+ Long enrollmentYear,
+ Long proxyCollegeId) {
+ if (operatorCollegeId == null) {
+ return false;
+ }
+ if (isFreshmanByEnrollmentYear(enrollmentYear)) {
+ return proxyCollegeId != null && proxyCollegeId.equals(operatorCollegeId);
+ }
+ return classCollegeId != null && operatorCollegeId.equals(classCollegeId);
+ }
+}
diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java
index 2ce3da84..1aa21ee3 100644
--- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java
+++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java
@@ -110,6 +110,14 @@ public interface XgStudentMsgMapper extends BaseMapperPlus> getCollegeStudentStatsByClass(@Param("secondaryCollegeId") Long secondaryCollegeId);
+ /**
+ * 按入学年查询全校一年级班级学生统计(宿舍分配到班级:代理学院可见)
+ *
+ * @param enrollmentYear 入学年(当前届)
+ * @return 学生统计信息列表(含 enrollment_year)
+ */
+ List