commit
This commit is contained in:
@@ -64,7 +64,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
|||||||
* @param user
|
* @param user
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@CacheResult(cacheKey = "${args[0].id}_getRoleCodeList")
|
// @CacheResult(cacheKey = "${args[0].id}_getRoleCodeList")
|
||||||
public List<String> getRoleCodeList(Sys_user user) {
|
public List<String> getRoleCodeList(Sys_user user) {
|
||||||
dao().fetchLinks(user, "roles");
|
dao().fetchLinks(user, "roles");
|
||||||
List<String> roleNameList = new ArrayList<String>();
|
List<String> roleNameList = new ArrayList<String>();
|
||||||
|
|||||||
+2
@@ -248,6 +248,8 @@ public class TheRapyRecuperationEnrollController {
|
|||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object doSignUpForBaseManagement(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
|
public Object doSignUpForBaseManagement(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
|
||||||
|
// 行锁会持续到当前事务结束,保证同一目的地的人数校验与保存不会并发执行。
|
||||||
|
enrollService.lockBaseManagementForSignUp(enrollInfo.getTakePartInBaseManagementId());
|
||||||
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "recuperationVersion"));
|
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "recuperationVersion"));
|
||||||
Map<Boolean, String> resultMap = new HashMap<>();
|
Map<Boolean, String> resultMap = new HashMap<>();
|
||||||
if("zjxu".equals(config.getConfigValue())) {
|
if("zjxu".equals(config.getConfigValue())) {
|
||||||
|
|||||||
+5
@@ -117,6 +117,11 @@ public class TheRapyRecuperationBaseManagement {
|
|||||||
@Excel(name = "预计费用")
|
@Excel(name = "预计费用")
|
||||||
private String estimatedCost;
|
private String estimatedCost;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
@Comment("最大报名人数")
|
||||||
|
private Integer maxApplyNum;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@ColDefine(type = ColType.MYSQL_JSON)
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
@Comment("缩略图")
|
@Comment("缩略图")
|
||||||
|
|||||||
+7
@@ -64,6 +64,13 @@ public interface TheRapyRecuperationEnrollService extends ViService<TheRapyRecup
|
|||||||
*/
|
*/
|
||||||
void doSignUpForHotel(TheRapyRecuperationEnroll enrollInfo);
|
void doSignUpForHotel(TheRapyRecuperationEnroll enrollInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前报名事务中锁定目的地记录,确保同一目的地的人数校验和保存串行执行。
|
||||||
|
*
|
||||||
|
* @param baseManagementId 目的地ID
|
||||||
|
*/
|
||||||
|
void lockBaseManagementForSignUp(String baseManagementId);
|
||||||
|
|
||||||
void updateSignUpHotel(TheRapyRecuperationEnroll enrollInfo);
|
void updateSignUpHotel(TheRapyRecuperationEnroll enrollInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+50
@@ -434,6 +434,19 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
insertWith(enrollInfo, "companionList");
|
insertWith(enrollInfo, "companionList");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前报名事务中锁定目的地记录。
|
||||||
|
*
|
||||||
|
* @param baseManagementId 目的地ID,用于锁定本次报名对应的目的地
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void lockBaseManagementForSignUp(String baseManagementId) {
|
||||||
|
Sql sql = Sqls.create("SELECT id FROM the_rapy_recuperation_base_management WHERE id = @baseManagementId FOR UPDATE")
|
||||||
|
.setParam("baseManagementId", baseManagementId);
|
||||||
|
sql.setCallback(Sqls.callback.str());
|
||||||
|
dao().execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 变更报名
|
* 变更报名
|
||||||
*
|
*
|
||||||
@@ -467,6 +480,35 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
updateIgnoreNull(enrollInfo);
|
updateIgnoreNull(enrollInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验定点疗休养目的地是否还有报名名额。
|
||||||
|
*
|
||||||
|
* @param enrollInfo 当前提交的报名信息,包含目的地ID、报名记录ID和改报记录ID
|
||||||
|
* @param baseManagement 目的地配置,用于读取最大报名人数
|
||||||
|
* @return 达到人数上限时返回失败信息;未配置人数上限或仍有名额时返回null
|
||||||
|
*/
|
||||||
|
private Map<Boolean, String> validBaseMaxApplyNum(TheRapyRecuperationEnroll enrollInfo,
|
||||||
|
TheRapyRecuperationBaseManagement baseManagement) {
|
||||||
|
Integer maxApplyNum = baseManagement.getMaxApplyNum();
|
||||||
|
// 兼容尚未维护最大报名人数的历史目的地,避免旧数据无法继续报名。
|
||||||
|
if (maxApplyNum == null || maxApplyNum <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cnd cnd = Cnd.where("takePartInBaseManagementId", "=", baseManagement.getId())
|
||||||
|
.and("isNormal", "=", true)
|
||||||
|
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL,
|
||||||
|
TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL));
|
||||||
|
// 编辑或改报时排除原报名记录,防止当前报名人被重复计入名额。
|
||||||
|
cnd.andEX("id", "!=", enrollInfo.getId());
|
||||||
|
cnd.andEX("id", "!=", enrollInfo.getEditOther());
|
||||||
|
int appliedNum = dao().count(TheRapyRecuperationEnroll.class, cnd);
|
||||||
|
if (appliedNum >= maxApplyNum) {
|
||||||
|
return Map.of(false, "该目的地报名人数已满,最大报名人数为" + maxApplyNum + "人");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证报名登记信息
|
* 验证报名登记信息
|
||||||
*
|
*
|
||||||
@@ -583,6 +625,10 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
if (DateUtil.compare(new Date(), signUpEndTime) > 0) {
|
if (DateUtil.compare(new Date(), signUpEndTime) > 0) {
|
||||||
return Map.of(false, "报名时间已过,抱歉不能报名");
|
return Map.of(false, "报名时间已过,抱歉不能报名");
|
||||||
}
|
}
|
||||||
|
Map<Boolean, String> maxApplyNumResult = validBaseMaxApplyNum(enrollInfo, baseManagement);
|
||||||
|
if (maxApplyNumResult != null) {
|
||||||
|
return maxApplyNumResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrUtil.isBlank(enrollInfo.getId())) {
|
if (StrUtil.isBlank(enrollInfo.getId())) {
|
||||||
@@ -1221,6 +1267,10 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
if (DateUtil.compare(new Date(), signUpEndTime) > 0) {
|
if (DateUtil.compare(new Date(), signUpEndTime) > 0) {
|
||||||
return Map.of(false, "报名时间已过,抱歉不能报名");
|
return Map.of(false, "报名时间已过,抱歉不能报名");
|
||||||
}
|
}
|
||||||
|
Map<Boolean, String> maxApplyNumResult = validBaseMaxApplyNum(enrollInfo, baseManagement);
|
||||||
|
if (maxApplyNumResult != null) {
|
||||||
|
return maxApplyNumResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+15
-2
@@ -276,7 +276,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :md="12" :sm="24" :xs="24">
|
<el-col span="6">
|
||||||
<el-form-item label="活动开始时间" prop="activityStartTime">
|
<el-form-item label="活动开始时间" prop="activityStartTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
placeholder="活动开始时间"
|
placeholder="活动开始时间"
|
||||||
@@ -287,7 +287,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="12" :sm="24" :xs="24">
|
<el-col span="6">
|
||||||
<el-form-item label="活动结束时间" prop="activityEndTime">
|
<el-form-item label="活动结束时间" prop="activityEndTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
placeholder="活动结束时间"
|
placeholder="活动结束时间"
|
||||||
@@ -298,6 +298,16 @@ layout("/layouts/platform.html"){
|
|||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col span="12">
|
||||||
|
<el-form-item label="最大报名人数" prop="maxApplyNum">
|
||||||
|
<el-input-number :min="1"
|
||||||
|
:precision="0"
|
||||||
|
:step="1"
|
||||||
|
placeholder="请输入最大报名人数"
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="formData.maxApplyNum"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -320,6 +330,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-switch>
|
</el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@@ -479,6 +490,7 @@ layout("/layouts/platform.html"){
|
|||||||
files: [],
|
files: [],
|
||||||
createMode: '',
|
createMode: '',
|
||||||
estimatedCost: '',
|
estimatedCost: '',
|
||||||
|
maxApplyNum: null,
|
||||||
activityStartTime: '',
|
activityStartTime: '',
|
||||||
activityEndTime: '',
|
activityEndTime: '',
|
||||||
baseContactPerson: '',
|
baseContactPerson: '',
|
||||||
@@ -515,6 +527,7 @@ layout("/layouts/platform.html"){
|
|||||||
activityStartTime: [{ required: true, validator: validateActivityStartTime, trigger: ['change', 'blur'] }],
|
activityStartTime: [{ required: true, validator: validateActivityStartTime, trigger: ['change', 'blur'] }],
|
||||||
activityEndTime: [{ required: true, validator: validateActivityEndTime, trigger: ['change', 'blur'] }],
|
activityEndTime: [{ required: true, validator: validateActivityEndTime, trigger: ['change', 'blur'] }],
|
||||||
estimatedCost: [{required: true, message: '请输入预计费用', trigger: ['change', 'blur']}],
|
estimatedCost: [{required: true, message: '请输入预计费用', trigger: ['change', 'blur']}],
|
||||||
|
maxApplyNum: [{required: true, message: '请输入最大报名人数', trigger: ['change', 'blur']}],
|
||||||
},
|
},
|
||||||
//目的地导入
|
//目的地导入
|
||||||
importVisible: false,
|
importVisible: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user