南大三十年教职工疗休养

This commit is contained in:
2026-07-02 14:22:32 +08:00
parent 8b5de6b196
commit f637e02c08
4 changed files with 257 additions and 2 deletions
@@ -131,6 +131,15 @@ public class ThirtyTeachTourBranchUserAssignmentController {
return Result.success(tourUserAssignmentService.branchPeriodQuotaInfo(settingId, periodId));
}
/**
* 查询当前配置维护的乘车地点选项,供列表操作列修改乘车地点时选择。
*/
@At
@SaCheckPermission("thirtyTeachTour.branchUserAssignment.assign")
public Result boardingPlaceOptions(String settingId) {
return Result.success(tourUserAssignmentService.boardingPlaceOptions(settingId));
}
/**
* 保存分工会人员分配,保存时数据来源固定为 BRANCH_UNION。
*/
@@ -215,6 +224,22 @@ public class ThirtyTeachTourBranchUserAssignmentController {
}
}
/**
* 更新当前分工会人员分配记录的乘车地点,地点范围由疗休养配置中的乘车地点列表控制。
*/
@At
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("thirtyTeachTour.branchUserAssignment.assign")
@SLog(type = "tour", tag = "疗休养分工会人员分配", msg = "更新分工会人员分配乘车地点")
public Result updateBoardingPlace(String id, String boardingPlace) {
try {
tourUserAssignmentService.updateCurrentBranchAssignmentBoardingPlace(id, boardingPlace);
return Result.success();
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 恢复当前分工会已取消退出的人员分配记录,只恢复状态,不恢复已删除台账。
*/
@@ -212,6 +212,14 @@ public interface ThirtyTeachTourUserAssignmentService extends BaseService<Thirty
*/
NutMap branchPeriodQuotaInfo(String settingId, String periodId);
/**
* 查询指定配置维护的乘车地点选项,供分工会人员分配列表行内修改乘车地点使用。
*
* @param settingId 疗休养配置ID
* @return 乘车地点选项
*/
List<String> boardingPlaceOptions(String settingId);
/**
* 保存分工会人员分配。保存前会重新按配置可参加人员范围和当前登录人所在分工会过滤,并校验正式/替补名额。
* 正式人员必须选择出行时间段,并按“当前分工会 + 出行时间段”校验正式名额;替补人员沿用分工会替补名额。
@@ -365,6 +373,15 @@ public interface ThirtyTeachTourUserAssignmentService extends BaseService<Thirty
*/
void updateCurrentBranchAssignmentPhotoFiles(String id, String photoFiles, String currentPeriodPhotoFiles);
/**
* 更新当前分工会人员分配记录的乘车地点,并同步同事项、同工号下已生成的台账乘车地点。
* 乘车地点必须来自该疗休养配置维护的乘车地点列表,避免写入配置外数据。
*
* @param id 人员分配记录ID
* @param boardingPlace 乘车地点
*/
void updateCurrentBranchAssignmentBoardingPlace(String id, String boardingPlace);
/**
* 删除指定来源的人员分配记录,避免校工会页面误删分工会分配的数据。
*
@@ -21,9 +21,12 @@ import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -318,12 +321,15 @@ public class ThirtyTeachTourUserAssignmentServiceImpl extends BaseServiceImpl<Th
m.settingId,
m.signupStartTime,
m.signupEndTime,
m.defaultBoardingPlace,
s.boardingPlace AS boardingPlaceOptions,
m.lineId,
l.lineName,
l.lineType,
l.travelAgencyId,
ta.agencyName AS travelAgencyName
FROM thirty_teach_tour_matter m
LEFT JOIN thirty_teach_tour_setting s ON s.id = m.settingId
LEFT JOIN thirty_teach_tour_line l ON l.id = m.lineId
LEFT JOIN thirty_teach_tour_travel_agency ta ON ta.id = l.travelAgencyId
$condition
@@ -778,6 +784,16 @@ public class ThirtyTeachTourUserAssignmentServiceImpl extends BaseServiceImpl<Th
.addv("formalRemaining", Math.max(formalQuota - formalUsed, 0));
}
@Override
public List<String> boardingPlaceOptions(String settingId) {
if (StrUtil.isBlank(settingId)) {
return Collections.emptyList();
}
ThirtyTeachTourSetting setting = dao().fetch(ThirtyTeachTourSetting.class, Cnd.where(ThirtyTeachTourSetting::getId, "=", settingId)
.and(ThirtyTeachTourSetting::getDelFlag, "=", false));
return parseBoardingPlaceOptions(setting == null ? "" : setting.getBoardingPlace());
}
@Override
public NutMap switchCurrentBranchPersonType(String id, String personType) {
String unionId = SecurityUtil.getUnionId();
@@ -1084,6 +1100,28 @@ public class ThirtyTeachTourUserAssignmentServiceImpl extends BaseServiceImpl<Th
updateAssignmentPhotoFiles(assignment, photoFiles, currentPeriodPhotoFiles);
}
@Override
public void updateCurrentBranchAssignmentBoardingPlace(String id, String boardingPlace) {
ThirtyTeachTourUserAssignment assignment = fetchCurrentBranchAssignment(id);
if (assignment == null) {
throw new IllegalArgumentException("人员分配记录不存在或无权限操作");
}
String normalizedBoardingPlace = StrUtil.trimToEmpty(boardingPlace);
if (StrUtil.isBlank(normalizedBoardingPlace)) {
throw new IllegalArgumentException("请选择乘车地点");
}
ThirtyTeachTourSetting setting = dao().fetch(ThirtyTeachTourSetting.class, Cnd.where(ThirtyTeachTourSetting::getId, "=", assignment.getSettingId())
.and(ThirtyTeachTourSetting::getDelFlag, "=", false));
List<String> options = parseBoardingPlaceOptions(setting == null ? "" : setting.getBoardingPlace());
if (Lang.isEmpty(options)) {
throw new IllegalArgumentException("当前配置未维护乘车地点");
}
if (!options.contains(normalizedBoardingPlace)) {
throw new IllegalArgumentException("乘车地点不在当前疗休养配置范围内");
}
updateAssignmentBoardingPlace(assignment, normalizedBoardingPlace);
}
@Override
public void deleteBySource(String id, String assignSource) {
deleteBySource(id, assignSource, false);
@@ -1424,6 +1462,61 @@ public class ThirtyTeachTourUserAssignmentServiceImpl extends BaseServiceImpl<Th
.and(ThirtyTeachTourLedger::getDelFlag, "=", false));
}
/**
* 更新人员分配乘车地点,并同步同一事项和工号下已生成的报名台账,保证列表和台账乘车地点一致。
*/
private void updateAssignmentBoardingPlace(ThirtyTeachTourUserAssignment assignment, String boardingPlace) {
if (assignment == null || StrUtil.isBlank(assignment.getId())) {
throw new IllegalArgumentException("人员分配记录不存在或无权限操作");
}
update(Chain.make("boardingPlace", boardingPlace),
Cnd.where(ThirtyTeachTourUserAssignment::getId, "=", assignment.getId())
.and(ThirtyTeachTourUserAssignment::getDelFlag, "=", false));
if (StrUtil.isBlank(assignment.getMatterId()) || StrUtil.isBlank(assignment.getLoginName())) {
return;
}
dao().update(ThirtyTeachTourLedger.class,
Chain.make("boardingPlace", boardingPlace),
Cnd.where(ThirtyTeachTourLedger::getMatterId, "=", assignment.getMatterId())
.and(ThirtyTeachTourLedger::getJobNo, "=", assignment.getLoginName())
.and(ThirtyTeachTourLedger::getDelFlag, "=", false));
}
/**
* 解析疗休养配置中维护的乘车地点,兼容 JSON 数组和逗号分隔的历史值。
*/
private List<String> parseBoardingPlaceOptions(String value) {
if (StrUtil.isBlank(value)) {
return Collections.emptyList();
}
try {
List<?> rows = Json.fromJson(List.class, value);
if (Lang.isEmpty(rows)) {
return Collections.emptyList();
}
List<String> options = new ArrayList<>();
for (Object row : rows) {
if (row instanceof Map) {
Map<?, ?> map = (Map<?, ?>) row;
// 配置页面按 name 保存乘车地点;兼容历史 route/value 字段,避免旧数据无法显示。
Object place = map.get("name") == null ? (map.get("route") == null ? map.get("value") : map.get("route")) : map.get("name");
if (place != null && StrUtil.isNotBlank(String.valueOf(place))) {
options.add(String.valueOf(place).trim());
}
} else if (row != null && StrUtil.isNotBlank(String.valueOf(row))) {
options.add(String.valueOf(row).trim());
}
}
return options.stream().distinct().collect(Collectors.toList());
} catch (Exception ignored) {
return Arrays.stream(value.split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
}
}
private void deleteAssignmentLedgers(ThirtyTeachTourUserAssignment assignment) {
List<ThirtyTeachTourLedger> ledgers = dao().query(ThirtyTeachTourLedger.class, Cnd.where(ThirtyTeachTourLedger::getMatterId, "=", assignment.getMatterId())
.and(ThirtyTeachTourLedger::getJobNo, "=", assignment.getLoginName())