This commit is contained in:
@jyuhsin
2025-10-30 17:38:59 +08:00
parent a5bdf21346
commit ef9b9bc03d
35 changed files with 707 additions and 103 deletions
@@ -0,0 +1,41 @@
package com.budwk.app.base.utils;
/**
* @ClassName DistanceUtils
* @Author JyuHsin
* @Date 2025/10/30 16:22
* @Version 1.0
* @Description TODO
*/
public class DistanceUtils {
private static final double EARTH_RADIUS = 6371000; // 地球半径,单位:米
/**
* 计算两个经纬度之间的距离(单位:米)
* @param lat1 纬度1(单位:度)
* @param lng1 经度1(单位:度)
* @param lat2 纬度2(单位:度)
* @param lng2 经度2(单位:度)
* @return 距离(米)
*/
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
// 将角度转为弧度
double lat1Rad = Math.toRadians(lat1);
double lng1Rad = Math.toRadians(lng1);
double lat2Rad = Math.toRadians(lat2);
double lng2Rad = Math.toRadians(lng2);
// 纬度和经度的差值(弧度)
double deltaLat = lat2Rad - lat1Rad;
double deltaLng = lng2Rad - lng1Rad;
// Haversine 公式
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
+ Math.cos(lat1Rad) * Math.cos(lat2Rad)
* Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS * c; // 返回米
}
}
@@ -139,6 +139,7 @@ public class ActivityBasicScopeController {
FROM
`vw_user` u
LEFT JOIN sys_user_role sur ON sur.userid = u.id
LEFT JOIN club_user clubuser ON clubuser.userid=u.id
$condition
""");
Cnd cnd = getCnd(activityUserScopePageParam);
@@ -86,7 +86,7 @@ public class ActivityBasicUnitController {
for (int i = 0; i < list.size(); i++) {
nodeList.add(new TreeNode<>(list.get(i).getId(), list.get(i).getParentId(), list.get(i).getName(), i));
}
List<Tree<String>> treeList = TreeUtil.build(nodeList, "1");
List<Tree<String>> treeList = TreeUtil.build(nodeList, "0000");
return Result.success(treeList);
}
@@ -6,9 +6,13 @@ import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
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.zhgh.activity.trainSignUp.models.*;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
import com.budwk.app.zhgh.club.model.SysClub;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -197,4 +201,38 @@ public class TrainSignUpManageController {
List<TrainSignUpActivity> query = dao.query(TrainSignUpActivity.class, Cnd.NEW().desc("activityStartTime"));
return Result.success().addData(query);
}
@At
@Ok("json:full")
@ApiOperation("查询分工会和协会")
@SaCheckPermission("trainSignUp.manage")
public Result selectUnionAndClub() {
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) {
NutMap map = new NutMap();
map.put("id", union.getId());
map.put("name", union.getName());
map.put("type", "union");
result.add(map);
}
List<SysClub> clubList = dao.query(SysClub.class, Cnd.NEW().asc(SysClub::getClubCode));
List<ProcessInstance> instanceList = dao.query(
ProcessInstance.class,
Cnd.where(ProcessInstance::getBusinessNo, "in", clubList.stream().map(SysClub::getId).toList())
.and(ProcessInstance::getState, "=", ProcessInstanceStateEnum.FINISHED.getCode())
);
List<String> passList = instanceList.stream().map(ProcessInstance::getBusinessNo).toList();
List<SysClub> passClubList = clubList.stream().filter(o -> passList.contains(o.getId())).toList();
for (SysClub sysClub : passClubList) {
NutMap map = new NutMap();
map.put("id", sysClub.getId());
map.put("name", sysClub.getClubName());
map.put("type", "club");
result.add(map);
}
return Result.success(result);
}
}
@@ -2,12 +2,15 @@ package com.budwk.app.zhgh.activity.trainSignUp.controller.manage;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.DistanceUtils;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpCourse;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpUserCourse;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
import io.swagger.annotations.Api;
@@ -26,6 +29,8 @@ import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
@@ -73,22 +78,25 @@ public class TrainsignUpMineController {
return Result.error(99, "未查询到您的报名记录");
}
// 获取现在的日期,并往后推1个小时
String oneHourLater = DateUtil.offsetHour(new Date(), 1).toString("yyyy-MM-dd HH:mm:ss");
TrainSignUpUserCourse userCourse = dao.fetch(
TrainSignUpUserCourse.class,
Cnd.where("courseId", "=", courseId)
.and("userId", "=", SecurityUtil.getUserId())
.and("courseStartTime", "<=", oneHourLater)
.and("courseEndTime", ">=", oneHourLater)
);
if (userCourse == null) {
TrainSignUpCourse course = dao.fetch(TrainSignUpCourse.class, courseId);
int minute = course.getSignUnit() != null ? course.getSignUnit() : 0;
boolean flag = true;
// 获取现在的日期,并根据设置的数据
List<TrainSignUpUserCourse> timeList = dao.query(TrainSignUpUserCourse.class, Cnd.where("courseId", "=", courseId));
for (TrainSignUpUserCourse userCourse : timeList) {
DateTime startTime = DateUtil.offsetMinute(userCourse.getCourseStartTime(), -minute);
DateTime endTime = DateUtil.offsetMinute(userCourse.getCourseEndTime(), minute);
if(DateUtil.isIn(DateUtil.date(), startTime, endTime)) {
userCourse.setAttend(true);
userCourse.setAttendTime(DateUtil.date());
flag = false;
}
}
if(flag) {
return Result.error(99, "未到签到时间");
}
userCourse.setAttend(true);
userCourse.setAttendTime(DateUtil.date());
dao.update(userCourse);
dao.update(timeList);
return Result.success();
}
@@ -122,6 +130,29 @@ public class TrainsignUpMineController {
return Result.success();
}
@At
@ApiOperation("定位签到")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
@SLog(tag = "品牌活动-定位签到", msg = "定位签到")
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 radius = course.getRadius() != null ? course.getRadius() : 100;
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);
return Result.success();
}
@At
@ApiOperation("分活动查询")
@SaCheckPermission(value = {"trainSignUp.mine", "h5.trainSignUp.mine"}, mode = SaMode.OR)
@@ -7,12 +7,15 @@ import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainMobileSignColumn;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpActivity;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpCourse;
@@ -96,7 +99,28 @@ public class TrainSignUpActivityStatisticsController {
@SaCheckPermission("trainSignUp.statistics")
public Result activityList(@Param(value = "year") Integer year) {
List<TrainSignUpActivity> list = dao.query(TrainSignUpActivity.class, Cnd.NEW().andEX("year", "=", year).desc("activityStartTime"));
return Result.success(list);
if(!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_CHAIRMAN.name())) {
// 获取当前登录用户的工会
String unionId = SecurityUtil.getUnionId();
// 获取当前登录用户的协会
List<String> clubIds = SecurityUtil.getClubIds();
List<TrainSignUpActivity> result = new ArrayList<>();
for (TrainSignUpActivity activity : list) {
if(AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
if(activity.getHostUnits().contains(unionId) || activity.getHelpUnits().contains(unionId)) {
result.add(activity);
}
}
if(AuthUtil.hasRoleOr(RoleConstant.CLUB_PRESIDENT.name(), RoleConstant.CLUB_OPERATOR.name())) {
if(clubIds.stream().anyMatch(activity.getHostUnits()::contains) || clubIds.stream().anyMatch(activity.getHelpUnits()::contains)) {
result.add(activity);
}
}
}
return Result.success(result);
}
return Result.success(list);
}
/**
@@ -114,6 +114,16 @@ public class TrainSignUpActivity extends BaseModel implements Serializable, SysH
@ColDefine(type = ColType.VARCHAR, width = 20)
private String trainType;
@Column
@Comment("主办单位")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> hostUnits;
@Column
@Comment("协办单位")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> helpUnits;
@Override
public Sys_home_activity covertToSysHomeActivity() {
Sys_home_activity sysHomeActivity = new Sys_home_activity();
@@ -114,6 +114,16 @@ public class TrainSignUpCourse extends BaseModel implements Serializable {
@Comment("签到方式 1.扫描二维码签到 2.被扫 3.gps签到")
private Integer signType;
@Column
@ColDefine(type = ColType.INT)
@Comment("签到时间误差")
private Integer signUnit;
@Column
@ColDefine(type = ColType.INT)
@Comment("签到半径")
private Integer radius;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("移动端是否签收礼品")
@@ -18,10 +18,13 @@ import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpActivity;
import com.budwk.app.zhgh.club.model.ClubUser;
import com.budwk.app.zhgh.club.model.SysClub;
import com.budwk.app.zhgh.club.param.ClubUserPageForm;
import com.budwk.app.zhgh.club.service.SysClubInfoManageService;
import com.budwk.app.zhgh.club.service.SysClubUserService;
import com.budwk.app.zhgh.club.vo.ClubCommonPageVo;
import com.budwk.app.zhgh.club.vo.ClubUserImportVo;
import io.swagger.annotations.ApiOperation;
@@ -67,6 +70,8 @@ public class ClubInfoManageController {
private SysRoleService sysRoleService;
@Inject
private SysUserService sysUserService;
@Inject
private SysClubUserService clubUserService;
@At("")
@Ok("beetl:/platform/zhgh/club/infoManage/manage/index.html")
@@ -159,6 +164,22 @@ public class ClubInfoManageController {
.and("clubId", "=", clubUser.getClubId()));
}
}
/* 根据品牌活动,操作user_scope表 start */
List<TrainSignUpActivity> list = dao.query(TrainSignUpActivity.class, Cnd.NEW());
List<TrainSignUpActivity> activityList = new ArrayList<>();
for (TrainSignUpActivity activity : list) {
boolean host = Lang.isNotEmpty(activity.getHostUnits()) && activity.getHostUnits().contains(clubUser.getClubId());
if(host) {
activityList.add(activity);
}
}
if(Lang.isNotEmpty(activityList)) {
List<Integer> groupList = activityList.stream().map(TrainSignUpActivity::getActivityGroupId).distinct().toList();
dao.clear(ActivityUserScope.class, Cnd.where("userId", "=", clubUser.getUserId()).and("groupId", "in", groupList));
}
/* 根据品牌活动,操作user_scope表 end */
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
@@ -282,7 +303,9 @@ public class ClubInfoManageController {
}
dao.insertOrUpdate(clubUser);
}
return Result.success();
clubUserService.clubUser2Scope(clubId, Arrays.asList(users));
return Result.success();
}
@At
@@ -353,6 +376,10 @@ public class ClubInfoManageController {
});
dao.insert(sysUserRoleList);
if(Lang.isNotEmpty(clubUserList)) {
clubUserService.clubUser2Scope(businessId, clubUserList.stream().map(ClubUser::getUserId).toList());
}
//如果有错误数据就返回给前端
if (Lang.isNotEmpty(errorInfos)) {
NutMap nutMap = NutMap.NEW();
@@ -7,9 +7,14 @@ import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.zhgh.club.model.ClubUser;
import com.budwk.app.zhgh.club.model.ClubUserApply;
import com.budwk.app.zhgh.club.service.SysClubUserService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.json.Json;
import java.util.List;
/**
* @ClassName ClubUserJoinInterceptor
* @Author JyuHsin
@@ -20,14 +25,18 @@ import org.nutz.json.Json;
public class ClubUserJoinInterceptor implements FlowInterceptor {
@Override
@Aop(TransAop.READ_COMMITTED)
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
ClubUserApply clubUserApply = Json.fromJson(ClubUserApply.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
SysClubUserService userService = ServiceContext.find(SysClubUserService.class);
ClubUser clubUser = BeanUtil.copyProperties(clubUserApply, ClubUser.class);
dao.insert(clubUser);
userService.clubUser2Scope(clubUser.getClubId(), List.of(clubUser.getUserId()));
}
}
@@ -22,4 +22,6 @@ public interface SysClubUserService extends BaseService<ClubUser> {
Pagination pageDataByApplyJoinClubAudit(@Valid ClubUserPageForm pageForm);
String getClubLeader(@Valid String clubId);
void clubUser2Scope(String clubId, List<String> users);
}
@@ -129,16 +129,7 @@ public class SysClubInfoManageServiceImpl extends BaseServiceImpl<ClubCommonPage
LEFT JOIN sys_club club ON scu.clubId = club.id
RIGHT JOIN `vw_user` u ON scu.userId = u.id
$condition
ORDER BY
CASE
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_PRESIDENT"') THEN 1
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_VICE_PRESIDENT"') THEN 2
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_SECRETARY"') THEN 3
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_VICE_SECRETARY"') THEN 4
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_OPERATOR"') THEN 5
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_MEMBER"') THEN 6
ELSE 99
END
$order
""");
Cnd cnd = Cnd.NEW();
@@ -155,7 +146,20 @@ public class SysClubInfoManageServiceImpl extends BaseServiceImpl<ClubCommonPage
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), "descending".equals(pageForm.getPageOrderBy()) ? "desc" : "asc");
}
} else {
sql.setVar("order", """
ORDER BY
CASE
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_PRESIDENT"') THEN 1
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_VICE_PRESIDENT"') THEN 2
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_SECRETARY"') THEN 3
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_VICE_SECRETARY"') THEN 4
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_OPERATOR"') THEN 5
WHEN JSON_CONTAINS(scu.roleCode, '"CLUB_MEMBER"') THEN 6
ELSE 99
END
""");
}
//查询理事机构
if (pageForm.getRadioType() != null && 1 == pageForm.getRadioType()) {
@@ -8,6 +8,8 @@ import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpActivity;
import com.budwk.app.zhgh.club.model.ClubUser;
import com.budwk.app.zhgh.club.param.ClubUserPageForm;
import com.budwk.app.zhgh.club.service.SysClubService;
@@ -23,6 +25,7 @@ import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import javax.validation.Valid;
@@ -142,4 +145,39 @@ public class SysClubUserServiceImpl extends BaseServiceImpl<ClubUser> implements
.filter(Objects::nonNull)
.collect(Collectors.joining(""));
}
@Override
public void clubUser2Scope(String clubId, List<String> users) {
// 添加协会成员,需要增加到品牌活动的组别去,wcnm
List<TrainSignUpActivity> list = dao().query(TrainSignUpActivity.class, Cnd.NEW());
List<TrainSignUpActivity> activityList = new ArrayList<>();
for (TrainSignUpActivity activity : list) {
boolean host = Lang.isNotEmpty(activity.getHostUnits()) && activity.getHostUnits().contains(clubId);
if(host) {
activityList.add(activity);
}
}
if(Lang.isNotEmpty(activityList)) {
// 查询所有的组别
List<ActivityUserScope> groupAllList = dao().query(ActivityUserScope.class, Cnd.NEW().groupBy("groupId"));
Map<Integer, String> groupMap = groupAllList.stream().collect(Collectors.toMap(ActivityUserScope::getGroupId, ActivityUserScope::getGroupName));
List<Integer> groupList = activityList.stream().map(TrainSignUpActivity::getActivityGroupId).distinct().toList();
List<ActivityUserScope> addScopes = new ArrayList<>();
for (Integer groupId : groupList) {
for (String user : users) {
int count = dao().count(ActivityUserScope.class, Cnd.where(ActivityUserScope::getGroupId, "=", groupId).and(ActivityUserScope::getUserId, "=", user));
if(count > 0) {
continue;
}
ActivityUserScope scope = new ActivityUserScope();
scope.setGroupId(groupId);
scope.setGroupName(groupMap.get(groupId));
scope.setUserId(user);
addScopes.add(scope);
}
}
dao().insert(addScopes);
}
}
}
@@ -0,0 +1,52 @@
package com.budwk.app.zhgh.map;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_config;
import com.budwk.app.sys.services.SysConfigService;
import com.budwk.app.zhgh.club.param.ClubUserPageForm;
import com.budwk.app.zhgh.club.vo.ClubCommonPageVo;
import io.swagger.annotations.ApiOperation;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.validation.Valid;
/**
* @ClassName TMapController
* @Author JyuHsin
* @Date 2025/10/30 11:22
* @Version 1.0
* @Description TODO
*/
@IocBean
@Ok("json")
@At("/platform/TMap")
public class TMapController {
private static String KEY = "MLLBZ-GQECI-ASXG7-5GNOZ-XW2OF-H5BVH";
@Inject
private SysConfigService configService;
@At
@SaCheckLogin
@ApiOperation("关键词输入提示")
public Result suggestion(String keyword) {
if(StrUtil.isBlank(keyword)) {
return Result.error("关键词不能为空");
}
Sys_config city = configService.getValueByKey("CityName");
String cityName = city != null ? city.getConfigValue() : "";
String url = "https://apis.map.qq.com/ws/place/v1/suggestion?key=%s&keyword=%s&region=%s"
.formatted(KEY, keyword, cityName);
String response = HttpUtil.get(url);
return Result.success(JSONUtil.parse(response));
}
}