fix: 优化活动人数限制2
This commit is contained in:
+24
@@ -73,6 +73,7 @@ public class TrainSignUpAdjustController {
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "activityId") String activityId) {
|
||||
Pagination pagination = trainSignUpActivityStatisticsService.pageData(pageForm, activityId);
|
||||
fillMaxPeopleNumber(pagination.getList());
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@@ -103,9 +104,32 @@ public class TrainSignUpAdjustController {
|
||||
c.put("registerNum", trainSignUpActivityStatisticsService.queryCourseCount(c.getString("id"), c.getString("courseType")));
|
||||
c.put("hasWaitingNum", trainSignUpActivityStatisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType")));
|
||||
});
|
||||
fillMaxPeopleNumber(courseList);
|
||||
return Result.success(courseList);
|
||||
}
|
||||
|
||||
private void fillMaxPeopleNumber(List<NutMap> rows) {
|
||||
if (rows == null || rows.isEmpty()) return;
|
||||
List<String> courseIds = rows.stream().map(v -> v.getString("id")).toList();
|
||||
List<TrainSignUpCourse> courses = dao.query(TrainSignUpCourse.class, Cnd.where("id", "in", courseIds));
|
||||
List<TrainSignUpActivityCourse> times = dao.query(TrainSignUpActivityCourse.class, Cnd.where("courseId", "in", courseIds));
|
||||
NutMap maximums = NutMap.NEW();
|
||||
for (TrainSignUpCourse course : courses) {
|
||||
Long maximum = course.getCoursePeopleNumber() > 0 ? (long) course.getCoursePeopleNumber() : null;
|
||||
if (Boolean.TRUE.equals(course.getCourseIsLimitApply())) {
|
||||
long timeTotal = times.stream().filter(v -> course.getId().equals(v.getCourseId()))
|
||||
.mapToLong(v -> v.getCourseLimitNum() == null ? 0 : v.getCourseLimitNum()).sum();
|
||||
maximum = maximum == null ? timeTotal : Math.min(maximum, timeTotal);
|
||||
}
|
||||
if (course.getUnionLimit() != null && !course.getUnionLimit().isEmpty()) {
|
||||
long unionTotal = course.getUnionLimit().stream().mapToLong(v -> v.getInt("limitCount", 0)).sum();
|
||||
maximum = maximum == null ? unionTotal : Math.min(maximum, unionTotal);
|
||||
}
|
||||
maximums.put(course.getId(), maximum);
|
||||
}
|
||||
rows.forEach(v -> v.put("maxPeopleNumber", maximums.get(v.getString("id"))));
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("报名用户列表")
|
||||
@SaCheckPermission("trainSignUp.adjust")
|
||||
|
||||
+3
@@ -194,6 +194,9 @@ public class TrainSignUpApplyController {
|
||||
}
|
||||
}
|
||||
}
|
||||
Date now = new Date();
|
||||
c.put("allTimesExpired", !courseTimes.isEmpty() && courseTimes.stream()
|
||||
.allMatch(v -> v.getCourseEndTime() != null && !v.getCourseEndTime().after(now)));
|
||||
});
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
+23
@@ -70,6 +70,28 @@ public class TrainSignUpActivityStatisticsController {
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
private void fillMaxPeopleNumber(List<NutMap> rows) {
|
||||
if (rows == null || rows.isEmpty()) return;
|
||||
List<String> courseIds = rows.stream().map(v -> v.getString("id")).toList();
|
||||
List<TrainSignUpCourse> courses = dao.query(TrainSignUpCourse.class, Cnd.where("id", "in", courseIds));
|
||||
List<TrainSignUpActivityCourse> times = dao.query(TrainSignUpActivityCourse.class, Cnd.where("courseId", "in", courseIds));
|
||||
NutMap maximums = NutMap.NEW();
|
||||
for (TrainSignUpCourse course : courses) {
|
||||
Long maximum = course.getCoursePeopleNumber() > 0 ? (long) course.getCoursePeopleNumber() : null;
|
||||
if (Boolean.TRUE.equals(course.getCourseIsLimitApply())) {
|
||||
long timeTotal = times.stream().filter(v -> course.getId().equals(v.getCourseId()))
|
||||
.mapToLong(v -> v.getCourseLimitNum() == null ? 0 : v.getCourseLimitNum()).sum();
|
||||
maximum = maximum == null ? timeTotal : Math.min(maximum, timeTotal);
|
||||
}
|
||||
if (course.getUnionLimit() != null && !course.getUnionLimit().isEmpty()) {
|
||||
long unionTotal = course.getUnionLimit().stream().mapToLong(v -> v.getInt("limitCount", 0)).sum();
|
||||
maximum = maximum == null ? unionTotal : Math.min(maximum, unionTotal);
|
||||
}
|
||||
maximums.put(course.getId(), maximum);
|
||||
}
|
||||
rows.forEach(v -> v.put("maxPeopleNumber", maximums.get(v.getString("id"))));
|
||||
}
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("trainSignUp.statistics")
|
||||
@Ok("beetl:/platform/zhgh/activity/trainSignUp/statistics/index.html")
|
||||
@@ -82,6 +104,7 @@ public class TrainSignUpActivityStatisticsController {
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "activityId") String activityId) {
|
||||
Pagination pagination = trainSignUpActivityStatisticsService.pageData(pageForm, activityId);
|
||||
fillMaxPeopleNumber(pagination.getList());
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ const courseList = {
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="{row}">
|
||||
<el-button v-if="!row.isSign" type="primary" size="mini" @click="onSign(row)">我要报名</el-button>
|
||||
<el-button v-if="!row.isSign" type="primary" size="mini" :style="(isAllTimesExpired(row) || isQuotaFull(row)) ? { color: '#c0c4cc', borderColor: '#e4e7ed', cursor: 'not-allowed' } : {}" @click="onSign(row)">我要报名</el-button>
|
||||
<el-button v-else type="danger" size="mini" @click="onCancel(row)">取消报名</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -152,6 +152,21 @@ const courseList = {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isQuotaFull(row) {
|
||||
if (!Number(row.coursePeopleNumber) && row.quotaScope !== "本工会") return false
|
||||
const remaining = Number(row.coursePeopleNumber) - (Number(row.hasRegisterNum) + Number(row.courseReservedNumber))
|
||||
const waitingRemaining = Number(row.waitingNum) - Number(row.hasWaitingNum)
|
||||
return remaining <= 0 && !(row.reserveMode === 2 && waitingRemaining > 0)
|
||||
},
|
||||
isAllTimesExpired(row) {
|
||||
if (row.allTimesExpired === true) return true
|
||||
const times = row.courseTimes || []
|
||||
const now = this.$moment()
|
||||
return times.length > 0 && times.every(item => {
|
||||
const endTime = this.$moment(item.courseEndTime)
|
||||
return endTime.isValid() && endTime.isSameOrBefore(now)
|
||||
})
|
||||
},
|
||||
async onPreview(introduce) {
|
||||
try {
|
||||
const parser = new DOMParser();
|
||||
@@ -187,6 +202,20 @@ const courseList = {
|
||||
this.queryCourseAssort()
|
||||
},
|
||||
onSign(row) {
|
||||
if (this.isAllTimesExpired(row)) {
|
||||
this.$alert("该活动所有时段均已结束,无法报名", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.isQuotaFull(row)) {
|
||||
this.$alert("当前没有可用报名名额,暂无法报名", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
return
|
||||
}
|
||||
const user = this.$store.state.user
|
||||
const missingFields = []
|
||||
if (!user?.unit?.name) missingFields.push("所属单位")
|
||||
|
||||
@@ -41,14 +41,9 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column label="类型" prop="courseType" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="trainType + '地点'" prop="courseLocation" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="负责人" prop="courseInstructor" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" sortable align="center" header-align="center" show-overflow-tooltip>
|
||||
<el-table-column label="最多报名人数" prop="maxPeopleNumber" sortable align="center" header-align="center" show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.reserveMode === 1">
|
||||
{{row.coursePeopleNumber}}
|
||||
</span>
|
||||
<span v-if="row.reserveMode === 2">
|
||||
{{(row.coursePeopleNumber + row.waitingNum) + '(候补占' + row.waitingNum + ')'}}
|
||||
</span>
|
||||
{{row.maxPeopleNumber == null ? '—' : row.maxPeopleNumber}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留人数" prop="courseReservedNumber" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -98,7 +93,7 @@ layout("/layouts/platform.html"){
|
||||
{ label: "类型", prop: "courseType", sortable: true },
|
||||
{ label: "地点", prop: "courseLocation" },
|
||||
{ label: "教师", prop: "courseInstructor", sortable: true },
|
||||
{ label: "最多报名人数", prop: "coursePeopleNumber", sortable: true },
|
||||
{ label: "最多报名人数", prop: "maxPeopleNumber", sortable: true },
|
||||
{ label: "已报名人数", prop: "registerNum", sortable: true }
|
||||
],
|
||||
trainType: "培训班",
|
||||
|
||||
@@ -41,14 +41,9 @@ layout("/layouts/platform.html"){
|
||||
sortable
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" sortable show-overflow-tooltip>
|
||||
<el-table-column label="最多报名人数" prop="maxPeopleNumber" sortable show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.reserveMode === 1">
|
||||
{{row.coursePeopleNumber}}
|
||||
</span>
|
||||
<span v-if="row.reserveMode === 2">
|
||||
{{(row.coursePeopleNumber + row.waitingNum) + '(候补占' + row.waitingNum + ')'}}
|
||||
</span>
|
||||
{{row.maxPeopleNumber == null ? '—' : row.maxPeopleNumber}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留人数" prop="courseReservedNumber" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -98,7 +93,7 @@ layout("/layouts/platform.html"){
|
||||
{ label: "类型", prop: "courseType", sortable: true },
|
||||
{ label: "地点", prop: "courseLocation" },
|
||||
{ label: "教师", prop: "courseInstructor", sortable: true },
|
||||
{ label: "最多报名人数", prop: "coursePeopleNumber", sortable: true },
|
||||
{ label: "最多报名人数", prop: "maxPeopleNumber", sortable: true },
|
||||
{ label: "已报名人数", prop: "registerNum", sortable: true }
|
||||
],
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ const userInfo = {
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" align="center" header-align="center">
|
||||
<template v-slot="{row}">{{row.coursePeopleNumber === 0 ? '不限制' : row.coursePeopleNumber}}</template>
|
||||
<el-table-column label="最多报名人数" prop="maxPeopleNumber" align="center" header-align="center">
|
||||
<template v-slot="{row}">{{row.maxPeopleNumber == null ? '—' : row.maxPeopleNumber}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留名额" prop="courseReservedNumber" align="center" header-align="center"></el-table-column>
|
||||
<el-table-column label="已报名人数" prop="registerNum" align="center" header-align="center"></el-table-column>
|
||||
|
||||
@@ -89,8 +89,25 @@ const applyForm = {
|
||||
})
|
||||
},
|
||||
onCourseConfirm(val){
|
||||
if (!val || val.disabled || val.endTime <= Date.now()) {
|
||||
this.$toast("该时段不可报名,请选择其他时段")
|
||||
const activeTimes = this.courseTimeSelectList.filter(item => item.endTime > Date.now())
|
||||
if (activeTimes.length === 0) {
|
||||
this.$toast("当前没有未结束的报名时段,无法报名")
|
||||
return
|
||||
}
|
||||
if (activeTimes.every(item => item.disabled)) {
|
||||
this.$toast("当前可选时段名额均已满,暂无法报名")
|
||||
return
|
||||
}
|
||||
if (!val) {
|
||||
this.$toast("请选择报名时段")
|
||||
return
|
||||
}
|
||||
if (val.endTime <= Date.now()) {
|
||||
this.$toast("所选时段已结束,请选择其他时段")
|
||||
return
|
||||
}
|
||||
if (val.disabled) {
|
||||
this.$toast("所选时段名额已满,请选择其他时段")
|
||||
return
|
||||
}
|
||||
this.formData.activityCourseId = val.value
|
||||
|
||||
@@ -66,7 +66,7 @@ layout("/layouts/platform_h5.html"){
|
||||
<span>微信群二维码</span>
|
||||
</div>
|
||||
<template v-if="$moment().isBefore($moment(activity.activitySignUpEndTime))">
|
||||
<div v-if="row.isSign === false" class="action-btn" @click="onApply(row)">
|
||||
<div v-if="row.isSign === false" class="action-btn" :style="(isAllTimesExpired(row) || isQuotaFull(row)) ? { color: '#c8c9cc', cursor: 'not-allowed' } : {}" @click="onApply(row)">
|
||||
<i class="fa fa-sign-in"></i>
|
||||
<span>我要报名</span>
|
||||
</div>
|
||||
@@ -131,6 +131,21 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isQuotaFull(row) {
|
||||
if (!Number(row.coursePeopleNumber) && row.quotaScope !== "本工会") return false
|
||||
const remaining = Number(row.coursePeopleNumber) - (Number(row.hasRegisterNum) + Number(row.courseReservedNumber))
|
||||
const waitingRemaining = Number(row.waitingNum) - Number(row.hasWaitingNum)
|
||||
return remaining <= 0 && !(row.reserveMode === 2 && waitingRemaining > 0)
|
||||
},
|
||||
isAllTimesExpired(row) {
|
||||
if (row.allTimesExpired === true) return true
|
||||
const times = row.courseTimes || []
|
||||
const now = this.$moment()
|
||||
return times.length > 0 && times.every(item => {
|
||||
const endTime = this.$moment(item.courseEndTime)
|
||||
return endTime.isValid() && endTime.isSameOrBefore(now)
|
||||
})
|
||||
},
|
||||
tabClick(name) {
|
||||
this.pageForm.assortTypes = []
|
||||
this.pageForm.assortTypes.push(name)
|
||||
@@ -160,6 +175,22 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$refs.timesRef.onOpen(row, timeQuotas)
|
||||
},
|
||||
onApply(row) {
|
||||
if (this.isAllTimesExpired(row)) {
|
||||
vant.Dialog.alert({
|
||||
title: '提示',
|
||||
message: '该活动所有时段均已结束,无法报名',
|
||||
confirmButtonColor: '#1867b0'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.isQuotaFull(row)) {
|
||||
vant.Dialog.alert({
|
||||
title: '提示',
|
||||
message: '当前没有可用报名名额,暂无法报名',
|
||||
confirmButtonColor: '#1867b0'
|
||||
})
|
||||
return
|
||||
}
|
||||
const user = this.$store.state.user
|
||||
const missingFields = []
|
||||
if (!user?.unit?.name) missingFields.push("所属单位")
|
||||
|
||||
Reference in New Issue
Block a user