change普惠疗休养

This commit is contained in:
2026-07-14 17:41:39 +08:00
parent 33a9a3df05
commit cbc0dcf67d
8 changed files with 113 additions and 0 deletions
@@ -667,6 +667,14 @@ public class TourMySignupController {
}
}
if (isInProvinceLine(line.getLineType())) {
// 修改报名时排除当前台账,再按实际参加记录校验省内线路间隔。
String inProvinceMessage = tourLedgerService.checkInProvinceParticipation(
jobNo,
setting.getInProvinceYears(),
oldLedger == null ? null : oldLedger.getId());
if (StrUtil.isNotBlank(inProvinceMessage)) {
return Result.error(inProvinceMessage);
}
Cnd sameYearCnd = Cnd.where(TourLedger::getDelFlag, "=", false)
.and(TourLedger::getJobNo, "=", jobNo)
.and(TourLedger::getYear, "=", matter.getYear());
@@ -241,6 +241,9 @@ public class TourSettingController {
&& tourSetting.getMinGroupPeople() > tourSetting.getMaxGroupPeople()) {
return Result.error("最少成团人数不能大于最多成团人数");
}
if (tourSetting.getInProvinceYears() != null && tourSetting.getInProvinceYears() < 0) {
return Result.error("省内间隔年限必须为非负整数");
}
if (tourSetting.getCycleStartYear() != null && tourSetting.getCycleEndYear() != null
&& tourSetting.getCycleStartYear() > tourSetting.getCycleEndYear()) {
return Result.error("周期开始年度不能大于周期结束年度");
@@ -531,6 +531,21 @@ public class TourSignupController {
.addv("currentLineCost", cycleTotalCost.currentCost())
.addv("message", buildCycleTotalCostNotice(cycleTotalCost)));
}
if (isInProvinceLine(line.getLineType())) {
// 进入报名表单前先校验省内参加间隔,最终提交时还会再次执行相同规则。
String inProvinceMessage = tourLedgerService.checkInProvinceParticipation(
currentJobNo(),
setting.getInProvinceYears(),
oldLedger == null ? null : oldLedger.getId());
if (StrUtil.isNotBlank(inProvinceMessage)) {
return Result.success(NutMap.NEW()
.addv("canApply", false)
.addv("noticeRequired", true)
.addv("noticeType", "inProvinceYears")
.addv("message", inProvinceMessage));
}
return Result.success(NutMap.NEW().addv("canApply", true).addv("noticeRequired", false));
}
if (!isOutProvinceLine(line.getLineType())) {
return Result.success(NutMap.NEW().addv("canApply", true).addv("noticeRequired", false));
}
@@ -940,6 +955,14 @@ public class TourSignupController {
}
}
if (isInProvinceLine(line.getLineType())) {
// 最终提交以台账中的实际参加记录为准,避免绕过资格提示接口直接报名。
String inProvinceMessage = tourLedgerService.checkInProvinceParticipation(
jobNo,
setting.getInProvinceYears(),
oldLedger == null ? null : oldLedger.getId());
if (StrUtil.isNotBlank(inProvinceMessage)) {
return Result.error(inProvinceMessage);
}
Cnd sameYearCnd = Cnd.where(TourLedger::getDelFlag, "=", false)
.and(TourLedger::getJobNo, "=", jobNo)
.and(TourLedger::getYear, "=", matter.getYear());
@@ -69,6 +69,11 @@ public class TourSetting extends BaseModel implements Serializable {
@ColDefine(type = ColType.INT)
private Integer maxGroupPeople;
@Column
@Comment("省内几年去一次")
@ColDefine(type = ColType.INT)
private Integer inProvinceYears;
@Column
@Comment("省外几年去一次")
@ColDefine(type = ColType.INT)
@@ -8,6 +8,18 @@ import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
*/
public interface TourLedgerService extends BaseService<TourLedger> {
/**
* 校验当前人员在省内间隔周期内是否已经实际参加过省内线路
*
* @param jobNo 当前登录人工号
* @param inProvinceYears 包含当前年份在内的省内限制年数小于等于0表示不限制
* @param excludeLedgerId 修改报名时需要排除的当前台账ID新增时允许为空
* @return 校验通过返回空字符串否则返回不能报名的业务提示
*/
String checkInProvinceParticipation(String jobNo,
Integer inProvinceYears,
String excludeLedgerId);
/**
* 在同一事务中锁定分工会名额校验并发容量并写入报名台账
*
@@ -14,6 +14,8 @@ import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.time.LocalDate;
/**
* 疗休养报名台账服务实现
*/
@@ -24,6 +26,46 @@ public class TourLedgerServiceImpl extends BaseServiceImpl<TourLedger> implement
super(dao);
}
@Override
public String checkInProvinceParticipation(String jobNo,
Integer inProvinceYears,
String excludeLedgerId) {
if (inProvinceYears == null || inProvinceYears <= 0) {
return "";
}
if (StrUtil.isBlank(jobNo)) {
return "未查询到当前登录人工号,不能校验省内线路报名资格";
}
int currentYear = LocalDate.now().getYear();
// N年按包含当前年份在内的N个自然年度计算例如2026年的3年周期为2024至2026年
long calculatedStartYear = (long) currentYear - inProvinceYears + 1L;
int startYear = calculatedStartYear < 0 ? 0 : (int) calculatedStartYear;
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND id <> @excludeLedgerId";
Sql sql = Sqls.create("""
SELECT COUNT(1)
FROM tour_ledger
WHERE delFlag = 0
AND joined = 1
AND jobNo = @jobNo
AND `year` >= @startYear
AND `year` <= @currentYear
AND lineType IN ('省内线路', '省内')
""" + excludeSql);
sql.setParam("jobNo", jobNo);
sql.setParam("startYear", startYear);
sql.setParam("currentYear", currentYear);
if (StrUtil.isNotBlank(excludeLedgerId)) {
sql.setParam("excludeLedgerId", excludeLedgerId);
}
sql.setCallback(Sqls.callback.integer());
dao().execute(sql);
if (sql.getInt() <= 0) {
return "";
}
return "您在 " + startYear + "" + currentYear
+ " 年内已参加过省内线路,省内线路每 " + inProvinceYears + " 年可参加一次,当前不能报名";
}
@Override
@Aop(TransAop.READ_COMMITTED)
public String saveWithUnionSignupQuota(TourLedger ledger,