Merge branch 'main' of https://dd3skj.picp.vip/zhaoxinyu/v4
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ import java.util.Base64;
|
|||||||
* @Version 1.0
|
* @Version 1.0
|
||||||
* @Description TODO
|
* @Description TODO
|
||||||
*/
|
*/
|
||||||
public class RsaUtils {
|
public class RsaUtil {
|
||||||
static {
|
static {
|
||||||
Security.addProvider(new BouncyCastleProvider());
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.budwk.app.sys.controller;
|
package com.budwk.app.sys.controller;
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.codec.Base64Decoder;
|
|
||||||
import cn.hutool.core.codec.Base64Encoder;
|
import cn.hutool.core.codec.Base64Encoder;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
@@ -13,7 +12,7 @@ import com.budwk.app.base.enums.LoginType;
|
|||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
import com.budwk.app.base.interceptor.sLog.SLogService;
|
import com.budwk.app.base.interceptor.sLog.SLogService;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.utils.RsaUtils;
|
import com.budwk.app.base.utils.RsaUtil;
|
||||||
import com.budwk.app.sys.models.Sys_log;
|
import com.budwk.app.sys.models.Sys_log;
|
||||||
import com.budwk.app.sys.models.Sys_user;
|
import com.budwk.app.sys.models.Sys_user;
|
||||||
import com.budwk.app.sys.services.SysUserService;
|
import com.budwk.app.sys.services.SysUserService;
|
||||||
@@ -42,13 +41,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -269,9 +262,9 @@ public class SysLoginController {
|
|||||||
public Object publicKey() {
|
public Object publicKey() {
|
||||||
try {
|
try {
|
||||||
// 生成密钥对
|
// 生成密钥对
|
||||||
KeyPair keyPair = RsaUtils.generateKeyPair();
|
KeyPair keyPair = RsaUtil.generateKeyPair();
|
||||||
String publicKeyStr = RsaUtils.getPublicKeyBase64(keyPair.getPublic());
|
String publicKeyStr = RsaUtil.getPublicKeyBase64(keyPair.getPublic());
|
||||||
String privateKeyStr = RsaUtils.getPrivateKeyBase64(keyPair.getPrivate());
|
String privateKeyStr = RsaUtil.getPrivateKeyBase64(keyPair.getPrivate());
|
||||||
|
|
||||||
// 生成 UUID 作为 keyId
|
// 生成 UUID 作为 keyId
|
||||||
String keyId = UUID.randomUUID().toString().replace("-", "");
|
String keyId = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ package com.budwk.app.web.commons.auth.service;
|
|||||||
|
|
||||||
import com.budwk.app.base.constant.RedisConstant;
|
import com.budwk.app.base.constant.RedisConstant;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.utils.RsaUtil;
|
||||||
import com.budwk.app.base.utils.RsaUtils;
|
|
||||||
import com.wf.captcha.ArithmeticCaptcha;
|
import com.wf.captcha.ArithmeticCaptcha;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
import org.nutz.integration.jedis.RedisService;
|
||||||
@@ -14,7 +13,6 @@ import org.nutz.lang.random.R;
|
|||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
@@ -118,6 +116,6 @@ public class ValidateService {
|
|||||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
||||||
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
||||||
// 解密密码
|
// 解密密码
|
||||||
return RsaUtils.decrypt(password, privateKey);
|
return RsaUtil.decrypt(password, privateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -10,6 +10,7 @@ import com.budwk.app.flow.entity.ProcessInstance;
|
|||||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||||
import com.budwk.app.sys.models.Sys_home_activity;
|
import com.budwk.app.sys.models.Sys_home_activity;
|
||||||
import com.budwk.app.sys.models.Sys_union;
|
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.models.*;
|
||||||
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
|
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
|
||||||
import com.budwk.app.zhgh.club.model.SysClub;
|
import com.budwk.app.zhgh.club.model.SysClub;
|
||||||
@@ -206,14 +207,14 @@ public class TrainSignUpManageController {
|
|||||||
@Ok("json:full")
|
@Ok("json:full")
|
||||||
@ApiOperation("查询分工会和协会")
|
@ApiOperation("查询分工会和协会")
|
||||||
@SaCheckPermission("trainSignUp.manage")
|
@SaCheckPermission("trainSignUp.manage")
|
||||||
public Result selectUnionAndClub() {
|
public Result selectUnitAndClub() {
|
||||||
List<NutMap> result = new ArrayList<>();
|
List<NutMap> result = new ArrayList<>();
|
||||||
List<Sys_union> unionList = dao.query(Sys_union.class, Cnd.NEW().asc(Sys_union::getUnionCode));
|
List<Sys_unit> unitList = dao.query(Sys_unit.class, Cnd.NEW().asc(Sys_unit::getUnitcode));
|
||||||
for (Sys_union union : unionList) {
|
for (Sys_unit unit : unitList) {
|
||||||
NutMap map = new NutMap();
|
NutMap map = new NutMap();
|
||||||
map.put("id", union.getId());
|
map.put("id", unit.getId());
|
||||||
map.put("name", union.getName());
|
map.put("name", unit.getName());
|
||||||
map.put("type", "union");
|
map.put("type", "unit");
|
||||||
result.add(map);
|
result.add(map);
|
||||||
}
|
}
|
||||||
List<SysClub> clubList = dao.query(SysClub.class, Cnd.NEW().asc(SysClub::getClubCode));
|
List<SysClub> clubList = dao.query(SysClub.class, Cnd.NEW().asc(SysClub::getClubCode));
|
||||||
|
|||||||
+35
-5
@@ -65,12 +65,18 @@ public class TrainsignUpMineController {
|
|||||||
public void h5Index() {
|
public void h5Index() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At("/scan")
|
||||||
|
@SaCheckPermission("h5.trainSignUp.mine")
|
||||||
|
@Ok("beetl:/platform/zhghh5/activity/trainSignUp/scan/index.html")
|
||||||
|
public void scan() {
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ApiOperation("主动扫码签到")
|
@ApiOperation("主动扫码签到")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
|
||||||
@SLog(tag = "品牌活动-活动签到", msg = "主动扫码签到")
|
@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()));
|
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);
|
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
|
||||||
|
List<Double> coordinates = course.getCourseLocationCoordinates();
|
||||||
int minute = course.getSignUnit() != null ? course.getSignUnit() : 0;
|
int minute = course.getSignUnit() != null ? course.getSignUnit() : 0;
|
||||||
|
int radius = course.getRadius() != null ? course.getRadius() : 100;
|
||||||
|
|
||||||
boolean flag = true;
|
boolean flag = true;
|
||||||
// 获取现在的日期,并根据设置的数据
|
// 获取现在的日期,并根据设置的数据
|
||||||
@@ -96,9 +104,16 @@ public class TrainsignUpMineController {
|
|||||||
if(flag) {
|
if(flag) {
|
||||||
return Result.error(99, "未到签到时间");
|
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);
|
dao.update(timeList);
|
||||||
|
|
||||||
return Result.success();
|
return Result.success("签到成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -138,15 +153,23 @@ public class TrainsignUpMineController {
|
|||||||
public Result positionSign(String courseId, String timeId, Double lat, Double lng) {
|
public Result positionSign(String courseId, String timeId, Double lat, Double lng) {
|
||||||
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
|
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
|
||||||
List<Double> coordinates = course.getCourseLocationCoordinates();
|
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;
|
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) {
|
if(distance > radius) {
|
||||||
int result = BigDecimal.valueOf(distance).setScale(0, RoundingMode.HALF_UP).intValue();
|
int result = BigDecimal.valueOf(distance).setScale(0, RoundingMode.HALF_UP).intValue();
|
||||||
return Result.error(99, "签到失败,您距离签到点还有%s米".formatted(result));
|
return Result.error(99, "签到失败,您距离签到点还有%s米".formatted(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrainSignUpUserCourse userCourse = dao.fetch(TrainSignUpUserCourse.class, timeId);
|
|
||||||
userCourse.setAttend(true);
|
userCourse.setAttend(true);
|
||||||
userCourse.setAttendTime(DateUtil.date());
|
userCourse.setAttendTime(DateUtil.date());
|
||||||
dao.update(userCourse);
|
dao.update(userCourse);
|
||||||
@@ -193,4 +216,11 @@ public class TrainsignUpMineController {
|
|||||||
List<NutMap> listMap = activityService.listMap(sql);
|
List<NutMap> listMap = activityService.listMap(sql);
|
||||||
return Result.success(listMap);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+111
-62
@@ -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.models.*;
|
||||||
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
|
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
|
||||||
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityStatisticsService;
|
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityStatisticsService;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.aop.interceptor.async.Async;
|
import org.nutz.aop.interceptor.async.Async;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
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.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -80,72 +78,28 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void edit(TrainSignUpActivity activity) {
|
public void edit(TrainSignUpActivity activity) {
|
||||||
|
// 1. 更新主活动
|
||||||
//修改活动
|
|
||||||
update(activity);
|
update(activity);
|
||||||
|
// 2. 处理类型限制
|
||||||
//修改类型限制
|
|
||||||
List<TrainSignUpTypeLimit> typeLimits = activity.getTypeLimits();
|
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);
|
insertOrUpdate(typeLimits);
|
||||||
}
|
}
|
||||||
|
// 3. 处理课程列表
|
||||||
List<TrainSignUpCourse> courseList = activity.getCourseList();
|
List<TrainSignUpCourse> courseList = activity.getCourseList();
|
||||||
courseList.forEach(v -> {
|
if (Lang.isEmpty(courseList)) {
|
||||||
v.setActivityId(activity.getId());
|
return;
|
||||||
dao().insertOrUpdate(v);
|
|
||||||
if (Lang.isNotEmpty(v.getCourseTimeList())) {
|
|
||||||
this.setCourseTimeAndInsert(v);
|
|
||||||
}
|
}
|
||||||
});
|
for (TrainSignUpCourse course : courseList) {
|
||||||
|
course.setActivityId(activity.getId());
|
||||||
|
dao().insertOrUpdate(course);
|
||||||
|
|
||||||
//查询原来的活动
|
if (Lang.isNotEmpty(course.getCourseTimeList())) {
|
||||||
List<TrainSignUpCourse> oldCourseList = dao().query(TrainSignUpCourse.class, Cnd.where("activityId", "=", activity.getId()));
|
handleCourseTimes(activity, course);
|
||||||
//原来的培训班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());
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
// 4. 同步首页活动
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!activity.isDisabled()) {
|
if (!activity.isDisabled()) {
|
||||||
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
|
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
|
||||||
dao().insertOrUpdate(sysHomeActivity);
|
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) {
|
private void setCourseTimeAndInsert(TrainSignUpCourse course) {
|
||||||
course.getCourseTimeList().forEach(courseTime -> {
|
course.getCourseTimeList().forEach(courseTime -> {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
|||||||
@@ -591,11 +591,11 @@ const basicForm = {
|
|||||||
this.activityGroupList = await this.getActivityGroup()
|
this.activityGroupList = await this.getActivityGroup()
|
||||||
this.historicalActList = await this.getHistoricalActList()
|
this.historicalActList = await this.getHistoricalActList()
|
||||||
this.courseTypeList = await this.getAllType()
|
this.courseTypeList = await this.getAllType()
|
||||||
await this.selectUnionAndClub()
|
await this.selectUnitAndClub()
|
||||||
await this.init(row)
|
await this.init(row)
|
||||||
},
|
},
|
||||||
async selectUnionAndClub() {
|
async selectUnitAndClub() {
|
||||||
const resp = await this.$axios.post("/platform/trainSignUp/manage/selectUnionAndClub")
|
const resp = await this.$axios.post("/platform/trainSignUp/manage/selectUnitAndClub")
|
||||||
this.undertakeOptions = resp.data
|
this.undertakeOptions = resp.data
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ const makeQrcode = {
|
|||||||
this.courseDialog = true
|
this.courseDialog = true
|
||||||
},
|
},
|
||||||
makeCourseCode(row) {
|
makeCourseCode(row) {
|
||||||
const url = '${AppDomain!}/platform/trainSignUp/mine/drivingScan'
|
//const url = '${AppDomain!}/platform/trainSignUp/mine/drivingScan'
|
||||||
|
const url = '${AppDomain!}/platform/trainSignUp/mine/scan'
|
||||||
const data = url + '?courseId=' + row.id
|
const data = url + '?courseId=' + row.id
|
||||||
console.log(data)
|
console.log(data)
|
||||||
const content = jrQrcode.getQrBase64(data)
|
const content = jrQrcode.getQrBase64(data)
|
||||||
|
|||||||
@@ -122,12 +122,19 @@ const times = {
|
|||||||
callback(null);
|
callback(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const loading = vant.Toast.loading({
|
||||||
|
message: "获取定位中...",
|
||||||
|
forbidClick: false,
|
||||||
|
loadingType: "spinner",
|
||||||
|
duration: 0,
|
||||||
|
})
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
callback({
|
callback({
|
||||||
lat: position.coords.latitude,
|
lat: position.coords.latitude,
|
||||||
lng: position.coords.longitude
|
lng: position.coords.longitude
|
||||||
});
|
});
|
||||||
|
loading.close()
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
let msg = '定位失败,请稍后重试';
|
let msg = '定位失败,请稍后重试';
|
||||||
@@ -144,6 +151,7 @@ const times = {
|
|||||||
}
|
}
|
||||||
this.$toast(msg);
|
this.$toast(msg);
|
||||||
callback(null);
|
callback(null);
|
||||||
|
loading.close()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform_h5.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.weui-msg {
|
||||||
|
min-height: calc(100vh - 40vh - 46px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<van-nav-bar title="活动签到" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||||
|
|
||||||
|
<div id="mapContainer" style="width: 100%; height: 40vh"></div>
|
||||||
|
<div class="weui-msg">
|
||||||
|
<div class="weui-msg__icon-area">
|
||||||
|
<i v-if="res?.code !== 0" class="weui-icon-warn weui-icon_msg"></i>
|
||||||
|
<i v-if="res?.code === 0" class="weui-icon-success weui-icon_msg"></i>
|
||||||
|
</div>
|
||||||
|
<div class="weui-msg__text-area">
|
||||||
|
<div class="weui-msg__title">温馨提醒</div>
|
||||||
|
<div v-html="res?.msg"></div>
|
||||||
|
</div>
|
||||||
|
<div class="weui-msg__opr-area">
|
||||||
|
<p class="weui-btn-area">
|
||||||
|
<a v-if="res?.code !== 0" @click="res = {}; onSign()" class="weui-btn weui-btn_default">重新签到</a>
|
||||||
|
<a v-if="res?.code === 0" class="weui-btn weui-btn_primary">您已签到</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const vue = new Vue({
|
||||||
|
el: "#app",
|
||||||
|
store,
|
||||||
|
components: {
|
||||||
|
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
courseId: GetQueryString('courseId'),
|
||||||
|
markerLayer: null,
|
||||||
|
map: null,
|
||||||
|
res: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initMap() {
|
||||||
|
if(!this.row.courseLocationCoordinates) {
|
||||||
|
this.$toast('未设置签到点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const posi = this.row.courseLocationCoordinates
|
||||||
|
const center = new TMap.LatLng(posi[0], posi[1])
|
||||||
|
this.map = new TMap.Map('mapContainer', {
|
||||||
|
resizeEnable: true,
|
||||||
|
zoom: 16,
|
||||||
|
center: center
|
||||||
|
})
|
||||||
|
this.markerLayer = new TMap.MultiMarker({
|
||||||
|
map: this.map,
|
||||||
|
styles: {
|
||||||
|
"current": new TMap.MarkerStyle({
|
||||||
|
"src": "https://mapapi.qq.com/web/bundles/lbs-home/prod/assets/markerActive-NhH9NoBV.png",
|
||||||
|
"width": 40, // 点标记样式宽度(像素)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
geometries: []
|
||||||
|
})
|
||||||
|
this.createMarker(center)
|
||||||
|
this.createCircle(center)
|
||||||
|
},
|
||||||
|
createMarker(position, styleId = 'marker', id = 'marker_' + Date.now()) {
|
||||||
|
this.markerLayer.add([
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
position: position,
|
||||||
|
styleId: styleId
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
createCircle(position) {
|
||||||
|
this.circle = new TMap.MultiCircle({
|
||||||
|
map: this.map,
|
||||||
|
geometries: [{
|
||||||
|
center: position,
|
||||||
|
radius: this.row.radius || 100,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getLocation(callback) {
|
||||||
|
if (typeof callback !== 'function') {
|
||||||
|
callback = () => {};
|
||||||
|
}
|
||||||
|
if (!navigator.geolocation) {
|
||||||
|
this.$toast('当前浏览器不支持定位功能');
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const loading = vant.Toast.loading({
|
||||||
|
message: "获取定位中...",
|
||||||
|
forbidClick: false,
|
||||||
|
loadingType: "spinner",
|
||||||
|
duration: 0,
|
||||||
|
})
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
(position) => {
|
||||||
|
callback({
|
||||||
|
lat: position.coords.latitude,
|
||||||
|
lng: position.coords.longitude
|
||||||
|
});
|
||||||
|
loading.close()
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
let msg = '定位失败,请稍后重试';
|
||||||
|
switch (error.code) {
|
||||||
|
case error.PERMISSION_DENIED:
|
||||||
|
msg = '请允许浏览器获取位置信息';
|
||||||
|
break;
|
||||||
|
case error.POSITION_UNAVAILABLE:
|
||||||
|
msg = '无法获取当前位置';
|
||||||
|
break;
|
||||||
|
case error.TIMEOUT:
|
||||||
|
msg = '定位超时,请重试';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.$toast(msg);
|
||||||
|
callback(null);
|
||||||
|
loading.close()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 10000,
|
||||||
|
maximumAge: 60000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
async fetchCourse() {
|
||||||
|
const res = await this.$axios.post('/platform/trainSignUp/mine/fetchCourse', {courseId: this.courseId})
|
||||||
|
this.row = res.data
|
||||||
|
},
|
||||||
|
onSign() {
|
||||||
|
if(this.markerLayer) {
|
||||||
|
this.markerLayer.remove(["current"])
|
||||||
|
}
|
||||||
|
this.getLocation(async (coords) => {
|
||||||
|
if (coords) {
|
||||||
|
const center = new TMap.LatLng(coords.lat, coords.lng)
|
||||||
|
this.createMarker(center, 'current', 'current')
|
||||||
|
this.res = await this.$axios.post('/platform/trainSignUp/mine/drivingScan', {
|
||||||
|
courseId: this.row.id,
|
||||||
|
lat: coords.lat,
|
||||||
|
lng: coords.lng
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
await this.fetchCourse()
|
||||||
|
this.initMap()
|
||||||
|
this.onSign()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
Reference in New Issue
Block a user