This commit is contained in:
@jyuhsin
2025-10-31 17:49:37 +08:00
parent fc5d6c21b7
commit ca7771e732
7 changed files with 338 additions and 79 deletions
@@ -10,6 +10,7 @@ import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.zhgh.activity.trainSignUp.models.*;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
import com.budwk.app.zhgh.club.model.SysClub;
@@ -206,14 +207,14 @@ public class TrainSignUpManageController {
@Ok("json:full")
@ApiOperation("查询分工会和协会")
@SaCheckPermission("trainSignUp.manage")
public Result selectUnionAndClub() {
public Result selectUnitAndClub() {
List<NutMap> result = new ArrayList<>();
List<Sys_union> unionList = dao.query(Sys_union.class, Cnd.NEW().asc(Sys_union::getUnionCode));
for (Sys_union union : unionList) {
List<Sys_unit> unitList = dao.query(Sys_unit.class, Cnd.NEW().asc(Sys_unit::getUnitcode));
for (Sys_unit unit : unitList) {
NutMap map = new NutMap();
map.put("id", union.getId());
map.put("name", union.getName());
map.put("type", "union");
map.put("id", unit.getId());
map.put("name", unit.getName());
map.put("type", "unit");
result.add(map);
}
List<SysClub> clubList = dao.query(SysClub.class, Cnd.NEW().asc(SysClub::getClubCode));
@@ -65,12 +65,18 @@ public class TrainsignUpMineController {
public void h5Index() {
}
@At("/scan")
@SaCheckPermission("h5.trainSignUp.mine")
@Ok("beetl:/platform/zhghh5/activity/trainSignUp/scan/index.html")
public void scan() {
}
@At
@ApiOperation("主动扫码签到")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
@SLog(tag = "品牌活动-活动签到", msg = "主动扫码签到")
public Result drivingScan(String courseId) {
public Result drivingScan(String courseId, Double lat, Double lng) {
// 主动扫码签到是用户自己打开扫一扫,扫二维码签到
int count = dao.count(TrainSignUpUserCourse.class, Cnd.where("courseId", "=", courseId).and("userId", "=", SecurityUtil.getUserId()));
@@ -79,7 +85,9 @@ public class TrainsignUpMineController {
}
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
List<Double> coordinates = course.getCourseLocationCoordinates();
int minute = course.getSignUnit() != null ? course.getSignUnit() : 0;
int radius = course.getRadius() != null ? course.getRadius() : 100;
boolean flag = true;
// 获取现在的日期,并根据设置的数据
@@ -96,9 +104,16 @@ public class TrainsignUpMineController {
if(flag) {
return Result.error(99, "未到签到时间");
}
double distance = DistanceUtils.getDistance(coordinates.get(0), coordinates.get(1), lat, lng);
if(distance > radius) {
int result = BigDecimal.valueOf(distance).setScale(0, RoundingMode.HALF_UP).intValue();
return Result.error(99, "签到失败,您距离签到点还有%s米".formatted(result));
}
dao.update(timeList);
return Result.success();
return Result.success("签到成功");
}
@At
@@ -138,15 +153,23 @@ public class TrainsignUpMineController {
public Result positionSign(String courseId, String timeId, Double lat, Double lng) {
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
List<Double> coordinates = course.getCourseLocationCoordinates();
double distance = DistanceUtils.getDistance(coordinates.get(0), coordinates.get(1), lat, lng);
int minute = course.getSignUnit() != null ? course.getSignUnit() : 0;
int radius = course.getRadius() != null ? course.getRadius() : 100;
TrainSignUpUserCourse userCourse = dao.fetch(TrainSignUpUserCourse.class, timeId);
DateTime startTime = DateUtil.offsetMinute(userCourse.getCourseStartTime(), -minute);
DateTime endTime = DateUtil.offsetMinute(userCourse.getCourseEndTime(), minute);
if(!DateUtil.isIn(DateUtil.date(), startTime, endTime)) {
return Result.error(99, "未到签到时间");
}
double distance = DistanceUtils.getDistance(coordinates.get(0), coordinates.get(1), lat, lng);
if(distance > radius) {
int result = BigDecimal.valueOf(distance).setScale(0, RoundingMode.HALF_UP).intValue();
return Result.error(99, "签到失败,您距离签到点还有%s米".formatted(result));
}
TrainSignUpUserCourse userCourse = dao.fetch(TrainSignUpUserCourse.class, timeId);
userCourse.setAttend(true);
userCourse.setAttendTime(DateUtil.date());
dao.update(userCourse);
@@ -193,4 +216,11 @@ public class TrainsignUpMineController {
List<NutMap> listMap = activityService.listMap(sql);
return Result.success(listMap);
}
@At
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
public Result fetchCourse(String courseId) {
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
return Result.success(course);
}
}
@@ -14,6 +14,7 @@ import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsServic
import com.budwk.app.zhgh.activity.trainSignUp.models.*;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityStatisticsService;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.aop.interceptor.ioc.TransAop;
@@ -29,10 +30,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@@ -80,72 +78,28 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
@Override
@Aop(TransAop.READ_COMMITTED)
public void edit(TrainSignUpActivity activity) {
//修改活动
// 1. 更新主活动
update(activity);
//修改类型限制
// 2. 处理类型限制
List<TrainSignUpTypeLimit> typeLimits = activity.getTypeLimits();
typeLimits.forEach(v -> v.setActivityId(activity.getId()));
if(Lang.isNotEmpty(typeLimits)) {
if (Lang.isNotEmpty(typeLimits)) {
typeLimits.forEach(limit -> limit.setActivityId(activity.getId()));
insertOrUpdate(typeLimits);
}
// 3. 处理课程列表
List<TrainSignUpCourse> courseList = activity.getCourseList();
courseList.forEach(v -> {
v.setActivityId(activity.getId());
dao().insertOrUpdate(v);
if (Lang.isNotEmpty(v.getCourseTimeList())) {
this.setCourseTimeAndInsert(v);
if (Lang.isEmpty(courseList)) {
return;
}
for (TrainSignUpCourse course : courseList) {
course.setActivityId(activity.getId());
dao().insertOrUpdate(course);
if (Lang.isNotEmpty(course.getCourseTimeList())) {
handleCourseTimes(activity, course);
}
});
//查询原来的活动
List<TrainSignUpCourse> oldCourseList = dao().query(TrainSignUpCourse.class, Cnd.where("activityId", "=", activity.getId()));
//原来的培训班id
List<String> oldCourseIdList = oldCourseList.stream().map(TrainSignUpCourse::getId).toList();
//原来的上课时间
List<TrainSignUpActivityCourse> oldActCourseTimeList = dao().query(TrainSignUpActivityCourse.class, Cnd.where("activityId", "=", activity.getId()));
//现在的上课时间
List<String> nowCourseTimeListId = new ArrayList<>();
activity.getCourseList().forEach(v -> {
if (v.getCourseTimeList() != null) {
nowCourseTimeListId.addAll(v.getCourseTimeList().stream().map(TrainSignUpActivityCourse::getId).toList());
}
});
List<String> deleteCourseTimeListId = oldActCourseTimeList.stream().map(TrainSignUpActivityCourse::getId).filter(id -> !nowCourseTimeListId.contains(id)).collect(Collectors.toList());
List<String> courseIdList = courseList.stream().map(TrainSignUpCourse::getId).collect(Collectors.toList());
//删除关联的培训班
List<String> deleteIdList = oldCourseIdList.stream().filter(v -> !courseIdList.contains(v)).collect(Collectors.toList());
dao().clear(TrainSignUpCourse.class, Cnd.where("id", "in", deleteIdList));
dao().clear(TrainSignUpActivityCourse.class, Cnd.where("id", "in", deleteCourseTimeListId));
dao().clear(TrainSignUpUser.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
dao().clear(TrainSignUpUserCourse.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
//查询修改过培训时间的记录
Sql tsuucSql = Sqls.create("""
SELECT
tsuuc.id,
tsuac.courseStartTime,
tsuac.courseEndTime
FROM
`train_sign_up_user_course` tsuuc
LEFT JOIN train_sign_up_activity_course tsuac ON tsuac.id = tsuuc.activityCourseId
where tsuuc.courseStartTime != tsuac.courseStartTime or tsuuc.courseEndTime != tsuac.courseEndTime
""");
List<NutMap> tsuucList = listMap(tsuucSql);
tsuucList.forEach(v -> {
Chain chain = Chain.make("courseStartTime", v.getTime("courseStartTime"));
chain.add("courseEndTime", v.getTime("courseEndTime"));
Cnd cnd = Cnd.where("id", "=", v.getString("id"));
dao().update("train_sign_up_user_course", chain, cnd);
});
}
// 4. 同步首页活动
if (!activity.isDisabled()) {
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
dao().insertOrUpdate(sysHomeActivity);
@@ -154,6 +108,101 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
}
}
private void handleCourseTimes(TrainSignUpActivity activity, TrainSignUpCourse course) {
String courseId = course.getId();
String activityId = activity.getId();
// 1. 获取新旧时间 ID 集合
Set<String> newTimeIds = course.getCourseTimeList().stream()
.map(TrainSignUpActivityCourse::getId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
List<TrainSignUpActivityCourse> oldAcList = dao().query(TrainSignUpActivityCourse.class,
Cnd.where("courseId", "=", courseId));
Set<String> oldTimeIds = oldAcList.stream()
.map(TrainSignUpActivityCourse::getId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
// 2. 删除已移除的时间段及其关联用户课程
Set<String> deletedTimeIds = Sets.difference(oldTimeIds, newTimeIds).immutableCopy();
if (!deletedTimeIds.isEmpty()) {
dao().clear(TrainSignUpActivityCourse.class, Cnd.where("id", "in", deletedTimeIds));
dao().clear(TrainSignUpUserCourse.class, Cnd.where("activityCourseId", "in", deletedTimeIds));
}
// 3. 插入/更新课程时间段(假设 setCourseTimeAndInsert 是插入新时间段)
setCourseTimeAndInsert(course);
// 4. 批量处理用户课程关联
// 查询当前课程下的所有用户
List<TrainSignUpUser> users = dao().query(TrainSignUpUser.class, Cnd.where("courseId", "=", courseId));
if (users.isEmpty()) {
return;
}
// 查询已存在的用户课程记录(按 activityCourseId 分组)
List<TrainSignUpUserCourse> existingUserCourses = dao().query(TrainSignUpUserCourse.class,
Cnd.where("courseId", "=", courseId));
Set<String> existingActivityCourseIds = existingUserCourses.stream()
.map(TrainSignUpUserCourse::getActivityCourseId)
.collect(Collectors.toSet());
List<TrainSignUpUserCourse> toUpdate = new ArrayList<>();
List<TrainSignUpUserCourse> toInsert = new ArrayList<>();
for (TrainSignUpActivityCourse timeSlot : course.getCourseTimeList()) {
String timeId = timeSlot.getId();
if (StrUtil.isBlank(timeId)) continue;
if (existingActivityCourseIds.contains(timeId)) {
// 更新时间
toUpdate.add(buildUserCourseForUpdate(timeId, timeSlot.getCourseStartTime(), timeSlot.getCourseEndTime()));
} else {
// 为每个用户新增记录
for (TrainSignUpUser user : users) {
toInsert.add(buildNewUserCourse(activityId, courseId, user.getUserId(), timeId, timeSlot));
}
}
}
// 批量更新(可根据 DAO 能力合并为 batchUpdate
for (TrainSignUpUserCourse item : toUpdate) {
dao().update(TrainSignUpUserCourse.class,
Chain.make("courseStartTime", item.getCourseStartTime())
.add("courseEndTime", item.getCourseEndTime()),
Cnd.where("activityCourseId", "=", item.getActivityCourseId()));
}
// 批量插入
if (!toInsert.isEmpty()) {
dao().insert(toInsert);
}
}
private TrainSignUpUserCourse buildUserCourseForUpdate(String activityCourseId, Date startTime, Date endTime) {
TrainSignUpUserCourse u = new TrainSignUpUserCourse();
u.setActivityCourseId(activityCourseId);
u.setCourseStartTime(startTime);
u.setCourseEndTime(endTime);
return u;
}
private TrainSignUpUserCourse buildNewUserCourse(String activityId, String courseId, String userId,
String activityCourseId, TrainSignUpActivityCourse timeSlot) {
TrainSignUpUserCourse u = new TrainSignUpUserCourse();
u.setActivityId(activityId);
u.setCourseId(courseId);
u.setUserId(userId);
u.setActivityCourseId(activityCourseId);
u.setCourseStartTime(timeSlot.getCourseStartTime());
u.setCourseEndTime(timeSlot.getCourseEndTime());
u.setAttend(false);
u.setAttendTime(null);
return u;
}
private void setCourseTimeAndInsert(TrainSignUpCourse course) {
course.getCourseTimeList().forEach(courseTime -> {
Calendar calendar = Calendar.getInstance();