重构项2: 优化编排规则

变更点1 - 使用项目maxParticipants:
- 优先使用项目配置的单位容纳人数进行分组
- 未配置时回退到全局配置(35人)
- 添加日志记录使用的容纳人数

变更点2 - 实现集体优先策略:
- 集体项目(projectType=2)优先于单人项目(projectType=1)
- 同类型项目按预计时长降序排列
- 添加排序结果日志便于调试

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
2026-01-08 15:50:21 +08:00
parent 496537ceef
commit 742272026b
9 changed files with 23 additions and 5 deletions

View File

@@ -458,10 +458,14 @@ public class MartialScheduleArrangeServiceImpl implements IMartialScheduleArrang
} }
// 自动拆分大组:如果人数过多,拆分成多个小组 // 自动拆分大组:如果人数过多,拆分成多个小组
// 改进策略:根据人数动态拆分,确保能充分利用所有时间槽 // 优先使用项目配置的单位容纳人数(maxParticipants)
// 目标:让分组数量接近可用时间槽数量,实现均匀分配
int maxPeoplePerGroup; int maxPeoplePerGroup;
if (members.size() <= scheduleConfig.getMaxPeoplePerGroup()) { Integer projectMax = project.getMaxParticipants();
if (projectMax != null && projectMax > 0) {
// 使用项目配置的单位容纳人数
maxPeoplePerGroup = projectMax;
log.debug("项目 '{}' 使用自定义容纳人数: {}", projectName, projectMax);
} else if (members.size() <= scheduleConfig.getMaxPeoplePerGroup()) {
// 35人以内不拆分 // 35人以内不拆分
maxPeoplePerGroup = members.size(); maxPeoplePerGroup = members.size();
} else { } else {
@@ -585,8 +589,22 @@ public class MartialScheduleArrangeServiceImpl implements IMartialScheduleArrang
log.info("总共初始化了 {} 个场地×时间段组合", slots.size()); log.info("总共初始化了 {} 个场地×时间段组合", slots.size());
// 按预计时长降序排序(先安排时间长的) // 排序策略: 集体项目(projectType=2)优先,同类型按预计时长降序
groups.sort((a, b) -> b.getEstimatedDuration() - a.getEstimatedDuration()); groups.sort((a, b) -> {
// 1. 集体项目优先于单人项目
int aType = a.getProjectType() != null ? a.getProjectType() : 1;
int bType = b.getProjectType() != null ? b.getProjectType() : 1;
if (aType != bType) {
return bType - aType; // 2(集体) > 1(单人)
}
// 2. 同类型按预计时长降序(先安排时间长的)
int aDuration = a.getEstimatedDuration() != null ? a.getEstimatedDuration() : 0;
int bDuration = b.getEstimatedDuration() != null ? b.getEstimatedDuration() : 0;
return bDuration - aDuration;
});
log.info("排序后分组顺序(集体优先): {}",
groups.stream().map(g -> g.getGroupName() + "(type=" + g.getProjectType() + ")").collect(java.util.stream.Collectors.joining(", ")));
// 使用轮询算法进行均匀分配 // 使用轮询算法进行均匀分配
int assignedCount = 0; int assignedCount = 0;