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
|
||||
* @Description TODO
|
||||
*/
|
||||
public class RsaUtils {
|
||||
public class RsaUtil {
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.budwk.app.sys.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.codec.Base64Decoder;
|
||||
import cn.hutool.core.codec.Base64Encoder;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
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.interceptor.sLog.SLogService;
|
||||
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_user;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
@@ -42,13 +41,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
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.UUID;
|
||||
|
||||
@@ -269,9 +262,9 @@ public class SysLoginController {
|
||||
public Object publicKey() {
|
||||
try {
|
||||
// 生成密钥对
|
||||
KeyPair keyPair = RsaUtils.generateKeyPair();
|
||||
String publicKeyStr = RsaUtils.getPublicKeyBase64(keyPair.getPublic());
|
||||
String privateKeyStr = RsaUtils.getPrivateKeyBase64(keyPair.getPrivate());
|
||||
KeyPair keyPair = RsaUtil.generateKeyPair();
|
||||
String publicKeyStr = RsaUtil.getPublicKeyBase64(keyPair.getPublic());
|
||||
String privateKeyStr = RsaUtil.getPrivateKeyBase64(keyPair.getPrivate());
|
||||
|
||||
// 生成 UUID 作为 keyId
|
||||
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.exception.BaseException;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.RsaUtils;
|
||||
import com.budwk.app.base.utils.RsaUtil;
|
||||
import com.wf.captcha.ArithmeticCaptcha;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.integration.jedis.RedisService;
|
||||
@@ -14,7 +13,6 @@ import org.nutz.lang.random.R;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
@@ -118,6 +116,6 @@ public class ValidateService {
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
||||
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.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));
|
||||
|
||||
+35
-5
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+113
-64
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user