This commit is contained in:
2026-05-28 19:52:20 +08:00
parent daac940f3f
commit 8915ace193
48 changed files with 5333 additions and 1644 deletions
@@ -0,0 +1,44 @@
package com.budwk.app.base.dao;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.param.PageForm;
import org.nutz.dao.Cnd;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
/**
* 条件构造辅助类。
* 当前健步走移植代码需要按页面查询条件动态追加字段查询和排序,空字段不应参与 SQL 条件。
*/
public class CndPlus extends Cnd {
private static final NutMap ORDER_MAP = NutMap.NEW().addv("ascending", "asc").addv("descending", "desc");
public static CndPlus create() {
return new CndPlus();
}
public CndPlus and(PageForm pageForm) {
if (pageForm != null && StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
this.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
}
if (pageForm != null && StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
this.orderBy(pageForm.getPageOrderName(), ORDER_MAP.getString(pageForm.getPageOrderBy()));
}
return this;
}
/**
* 仅在字段名和值都有效时追加条件,避免可选筛选项为空时生成无效 SQL。
*
* @param name 字段名或表达式
* @param op 比较操作符
* @param value 比较值
* @return 当前条件对象
*/
public CndPlus andEX(String name, String op, Object value) {
if (StrUtil.isNotBlank(name) && !Lang.isEmpty(value)) {
this.and(name, op, value);
}
return this;
}
}
@@ -0,0 +1,196 @@
package com.budwk.app.task.job.fitnesswalk;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sys.models.Sys_task;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.service.impl.FitnessWalkCommonServiceImpl;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.mvc.Mvcs;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Arrays;
/**
* @author zhf
* @date 2026/4/11 14:01
* @description 自动创建活动
*/
@IocBean
@Slf4j
public class FitnessWalkAddActivityJob implements Job {
@Override
@Aop(TransAop.READ_COMMITTED)
public void execute(JobExecutionContext context) throws JobExecutionException {
Ioc ioc = Mvcs.ctx().getDefaultIoc();
Dao dao = ioc.get(Dao.class);
WeAppCloudUtil weAppCloudUtil = ioc.get(WeAppCloudUtil.class);
// Quartz 任务上下文里按接口取 Bean 容易命中 Nutz 的接口实例化异常,这里统一按实现类获取后再走 service 公共方法。
FitnessWalkCommonService fitnessWalkCommonService = ioc.get(FitnessWalkCommonServiceImpl.class);
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String sourceActivityId = getJobString(jobDataMap, "sourceActivityId");
String deleteId = getJobString(jobDataMap, "deleteId");
long targetDate = getJobLong(jobDataMap, "targetDate");
try {
FitnessWalkActivity sourceActivity = loadSourceActivity(weAppCloudUtil, sourceActivityId);
if (sourceActivity == null) {
disableCurrentTask(dao, deleteId, sourceActivityId);
return;
}
FitnessWalkActivity newActivity = JSON.parseObject(JSON.toJSONString(sourceActivity), FitnessWalkActivity.class);
shiftActivityDate(sourceActivity, newActivity, targetDate);
resetBranchActivityNameByRelationProject(dao, newActivity, targetDate);
long currentTime = System.currentTimeMillis();
long normalizedTargetDate = DateUtil.beginOfDay(DateUtil.date(targetDate)).getTime();
newActivity.set_id(null);
newActivity.setCreatedAt(currentTime);
newActivity.setUpdatedAt(currentTime);
// 自动复制出的活动补充来源标记,便于后续编辑原活动时识别哪些日期已经真正生成过活动。
newActivity.setAutoCreateSourceActivityId(sourceActivityId);
newActivity.setAutoCreateTargetDate(normalizedTargetDate);
JSONObject insertResult = weAppCloudUtil.request(WeAppCloudUtil.CRUD.INSERT,
"db.collection('activity').add({data:" + Json.toJson(newActivity) + "})");
if (insertResult.containsKey("id_list") && insertResult.getJSONArray("id_list") != null && !insertResult.getJSONArray("id_list").isEmpty()) {
newActivity.set_id(insertResult.getJSONArray("id_list").getString(0));
}
// 自动复制出的活动也要同步刷新缓存,并补齐该活动自身的抽奖任务。
fitnessWalkCommonService.addLotteryTask(newActivity);
fitnessWalkCommonService.addOrEditDoSaveRedis(newActivity);
} catch (Exception e) {
log.error("自动连续创建活动失败, sourceActivityId={}", sourceActivityId, e);
throw new JobExecutionException(e);
} finally {
disableCurrentTask(dao, deleteId, sourceActivityId);
}
}
/**
* Quartz 的 JobDataMap 可能直接存的是 Long、Integer 等对象,不能一律用 getString 读取。
* 这里统一兜底转成字符串,避免任务参数类型变化时再次触发 ClassCastException。
*/
private String getJobString(JobDataMap jobDataMap, String key) {
Object value = jobDataMap.get(key);
return value == null ? null : String.valueOf(value);
}
/**
* 定时任务中的日期时间参数既可能是数字,也可能是字符串。
* 这里统一兼容处理,确保 targetDate 在测试和正式任务下都能稳定转成时间戳。
*/
private long getJobLong(JobDataMap jobDataMap, String key) {
Object value = jobDataMap.get(key);
if (value == null) {
throw new IllegalArgumentException("定时任务缺少参数:" + key);
}
if (value instanceof Number) {
return ((Number) value).longValue();
}
return Long.parseLong(String.valueOf(value));
}
/**
* 根据原活动ID查询原活动。
* 定时任务执行时统一从云库读取最新活动内容,确保复制时拿到的是当前活动的最新配置。
*/
private FitnessWalkActivity loadSourceActivity(WeAppCloudUtil weAppCloudUtil, String sourceActivityId) {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY,
"db.collection('activity').doc('" + sourceActivityId + "').get()");
return jsonObject.getJSONArray("data").stream()
.map(item -> JSON.parseObject((String) item, FitnessWalkActivity.class))
.findFirst()
.orElse(null);
}
/**
* 将活动的报名时间和活动时间整体平移到目标日期。
* 这里保留原活动的时分秒和时长,仅根据目标日期替换所属自然日。
*/
private void shiftActivityDate(FitnessWalkActivity sourceActivity, FitnessWalkActivity newActivity, long targetDate) {
DateTime sourceStartDate = DateUtil.beginOfDay(DateUtil.date(sourceActivity.getStartTime()));
DateTime targetStartDate = DateUtil.beginOfDay(DateUtil.date(targetDate));
long offsetMillis = targetStartDate.getTime() - sourceStartDate.getTime();
if (sourceActivity.getApplyTime() != null && sourceActivity.getApplyTime().length == 2) {
Long[] applyTime = Arrays.copyOf(sourceActivity.getApplyTime(), 2);
applyTime[0] = applyTime[0] + offsetMillis;
applyTime[1] = applyTime[1] + offsetMillis;
newActivity.setApplyTime(applyTime);
newActivity.setApplyStartTime(applyTime[0]);
newActivity.setApplyEndTime(applyTime[1]);
}
if (sourceActivity.getTime() != null && sourceActivity.getTime().length == 2) {
Long[] time = Arrays.copyOf(sourceActivity.getTime(), 2);
time[0] = time[0] + offsetMillis;
time[1] = time[1] + offsetMillis;
newActivity.setTime(time);
newActivity.setStartTime(time[0]);
newActivity.setEndTime(time[1]);
}
}
/**
* 自动连续创建活动时,分活动名称统一取“关联活动配置名称 + 日期前缀”。
* 优先读取关联活动配置表中的主活动名称;若当前活动没有配置关联活动,则回退到原分活动名称。
*/
private void resetBranchActivityNameByRelationProject(Dao dao, FitnessWalkActivity newActivity, long targetDate) {
if (newActivity == null) {
return;
}
String datePrefix = DateUtil.format(DateUtil.date(targetDate), "yyyy年MM月dd日");
String targetName = null;
if (StrUtil.isNotBlank(newActivity.getRelationActivityId())) {
FitnessWalkActivityRelationProject relationProject = dao.fetch(
FitnessWalkActivityRelationProject.class,
Cnd.where("id", "=", newActivity.getRelationActivityId())
);
if (relationProject != null && StrUtil.isNotBlank(relationProject.getMasterActivityName())) {
targetName = relationProject.getMasterActivityName().trim();
}
}
if (StrUtil.isBlank(targetName) && StrUtil.isNotBlank(newActivity.getBranchActivityName())) {
targetName = newActivity.getBranchActivityName().trim();
}
if (StrUtil.isBlank(targetName)) {
return;
}
if (targetName.startsWith(datePrefix)) {
newActivity.setBranchActivityName(targetName);
return;
}
newActivity.setBranchActivityName(datePrefix + " " + targetName);
}
/**
* 当前任务执行完成后禁用自身,避免同一日期重复创建活动。
*/
private void disableCurrentTask(Dao dao, String deleteId, String sourceActivityId) {
dao.update(Sys_task.class, Chain.make("disabled", 1),
Cnd.where("data", "like", "%" + deleteId + "%").and("data", "like", "%" + sourceActivityId + "%"));
}
}
@@ -0,0 +1,203 @@
package com.budwk.app.task.job.fitnesswalk;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.sys.models.Sys_task;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkAwardUser;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkRaffleUser;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.Mvcs;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.*;
import java.util.stream.Collectors;
@IocBean
@Slf4j
public class FitnessWalkLotteryJob implements Job {
@Override
@Aop(TransAop.READ_COMMITTED)
public void execute(JobExecutionContext context) throws JobExecutionException {
Ioc ioc = Mvcs.ctx().getDefaultIoc();
Dao dao = ioc.get(Dao.class);
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String deleteId = jobDataMap.getString("deleteId");
int lotteryQualificationStep = Integer.parseInt(jobDataMap.getString("lotteryQualificationStep"));
int lotteryUserNum = Integer.parseInt(jobDataMap.getString("lotteryUserNum"));
String mode = jobDataMap.getString("mode");
String activityId = jobDataMap.getString("id");
String lotteryQualificationDay = jobDataMap.getString("lotteryQualificationDay");
String awardName;
Date startDate = null;
Date endDate = null;
if ("custom".equals(mode)) {
awardName = jobDataMap.getString("awardName");
String startTimeStr = jobDataMap.getString("startDate");
String endTimeStr = jobDataMap.getString("endDate");
startDate = DateUtil.parse(startTimeStr, "yyyy-MM-dd");
endDate = DateUtil.parse(endTimeStr, "yyyy-MM-dd");
} else {
awardName = null;
}
List<NutMap> userList = new ArrayList<>();
if ("custom".equals(mode)) {
//查询出符合条件的用户
Sql sql = Sqls.create("""
SELECT
u.id,
COALESCE(SUM(sub.step), 0) AS total_steps,
u.loginname,
u.username,
u.unionid,
u.unionname,
u.unitid,
u.unitname,
over3k.standardsDays
FROM
`user` u
LEFT JOIN (
SELECT
userId,
applyDate,
step
FROM
`fitness_walk_step`
WHERE
activityId = @activityId
AND DATE(applyDate) >= @startDate
AND DATE(applyDate) <= @endDate
$lotteryQualificationDaySql
GROUP BY
userId,
applyDate
) AS sub ON u.id = sub.userId
LEFT JOIN (
SELECT
userId,
COUNT(DISTINCT DATE(applyDate)) AS standardsDays
FROM
`fitness_walk_step`
WHERE
activityId = @activityId
AND DATE(applyDate) >= @startDate
AND DATE(applyDate) <= @endDate
$lotteryQualificationDaySql
GROUP BY
userId
) AS over3k ON u.id = over3k.userId
$whereSql
GROUP BY
u.id,
u.username,
u.loginname,
u.unionname,
u.unitname
HAVING
$stepHavingSql
""");
if (Strings.isNotBlank(lotteryQualificationDay)) {
sql.setVar("lotteryQualificationDaySql", new Static(" AND step >= '%s' ".formatted(lotteryQualificationStep)));
sql.setVar("stepHavingSql", new Static(" over3k.standardsDays >= '%s' ".formatted(lotteryQualificationDay)));
} else {
sql.setVar("stepHavingSql", new Static(" COALESCE(SUM(sub.step), 0) >= '%s' ".formatted(lotteryQualificationStep)));
}
sql.setVar("whereSql", new Static(" where u.loginname not in (select loginName from fitness_walk_award_user where activityId = " + activityId + " ) "));
sql.setParam("activityId", activityId);
sql.setParam("step", lotteryQualificationStep);
sql.setParam("startDate", startDate);
sql.setParam("endDate", endDate);
userList = (List<NutMap>) Daos.query(dao, sql.toString(), Sqls.callback.maps());
} else if ("everyday".equals(mode)) {
Sql sql = Sqls.create("""
SELECT
jws.userId AS id,
u.username,
u.loginname,
u.unionid,
u.unionname,
u.unitid,
u.unitname
FROM
fitness_walk_step jws
LEFT JOIN `user` u ON u.id = jws.userId
WHERE
jws.activityId = @activityId
AND jws.step >= @step
AND jws.applyDate = @date
""");
sql.setParam("activityId", activityId);
sql.setParam("step", lotteryQualificationStep);
sql.setParam("date", DateUtil.today());
userList = (List<NutMap>) Daos.query(dao, sql.toString(), Sqls.callback.maps());
}
// 记录达标人员,表明这些人有资格抽奖
List<FitnessWalkRaffleUser> raffleUserList = userList.stream().map(v -> {
FitnessWalkRaffleUser raffleUser = new FitnessWalkRaffleUser();
raffleUser.setId(R.UU32());
raffleUser.setActivityId(activityId);
raffleUser.setUserId(v.getString("id"));
raffleUser.setLoginName(v.getString("loginname"));
raffleUser.setUsername(v.getString("username"));
if ("custom".equals(mode)) {
raffleUser.setStandardsDays(v.getInt("standardsDays"));
raffleUser.setAwardSteps(v.getString("total_steps"));
}
raffleUser.setIsRaffle(false);
return raffleUser;
}).collect(Collectors.toList());
dao.fastInsert(raffleUserList);
// 随机抽奖,中奖人数为传递过来的 lotteryUserNum
Collections.shuffle(userList);
List<NutMap> lotteryUserList = userList.stream().limit(lotteryUserNum).collect(Collectors.toList());
Date finalStartDate = startDate;
Date finalEndDate = endDate;
List<FitnessWalkAwardUser> awardLists = lotteryUserList.stream().map(v -> {
FitnessWalkAwardUser awardUser = new FitnessWalkAwardUser();
awardUser.setActivityId(activityId);
awardUser.setUserId(v.getString("id"));
awardUser.setUsername(v.getString("username"));
awardUser.setLoginName(v.getString("loginname"));
awardUser.setAwardName(awardName);
awardUser.setUnionId(v.getString("unionid"));
awardUser.setUnionName(v.getString("unionname"));
awardUser.setUnitId(v.getString("unitid"));
awardUser.setUnitName(v.getString("unitname"));
awardUser.setApplyDate(new Date());
awardUser.setStartDate(finalStartDate);
awardUser.setEndDate(finalEndDate);
awardUser.setAwardSteps(v.getString("total_steps"));
return awardUser;
}).collect(Collectors.toList());
dao.insert(awardLists);
// 执行完此定时任务后,禁用此定时任务确保不会下次执行
dao.update(Sys_task.class, Chain.make("disabled", 1), Cnd.where("data", "like", "%" + deleteId + "%").and("data", "like", "%" + activityId + "%"));
}
}
@@ -4,13 +4,11 @@ import lombok.Data;
import java.util.List;
/**
* 获取活动的树形结构
*/
@Data
public class Cascader {
private String value;
private String label;
private List<Cascader> children;
}
@@ -16,3 +16,5 @@ public enum FitnessWalkMode {
private final String desc;
}
@@ -1,19 +1,18 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import org.nutz.aop.interceptor.ioc.TransAop;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.base.page.Pagination;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import io.swagger.annotations.ApiOperation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
@@ -23,11 +22,11 @@ import org.nutz.mvc.annotation.Param;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@IocBean
@Ok("json")
@ApiOperation("健步走-同步绑定记录")
@At("/platform/fitnessWalk/bindingRecord")
public class FitnessWalkActivityBindingRecordController {
@@ -40,29 +39,15 @@ public class FitnessWalkActivityBindingRecordController {
public void index() {
}
/**
* 获取用户绑定记录
* @param keyWord
* @param unionId
* @param searchName
* @param searchKeyword
* @param pageNumber
* @param pageSize
* @param pageOrderName
* @param pageOrderBy
* @return
* @throws IOException
*/
@At
@ApiOperation("获取用户绑定记录")
@SaCheckPermission("fitnessWalk.bindingRecord")
public Result pageData(@Param("keyWord") String keyWord,
@Param("unionId") String unionId,
@Param("searchName") String searchName,
@Param("searchKeyword") String searchKeyword,
@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize,
@Param("pageNumber") int pageNumber,@Param("pageSize") int pageSize,
@Param("pageOrderName") String pageOrderName,
@Param("pageOrderBy") String pageOrderBy) {
@Param("pageOrderBy") String pageOrderBy) throws IOException {
int skip = (pageNumber == 1 ? 0 : (pageNumber - 1)) * pageSize;
StringBuilder sql = new StringBuilder("db.collection('login_record')");
@@ -74,7 +59,7 @@ public class FitnessWalkActivityBindingRecordController {
sql.append("])");
sql.append(")");
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (!AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
sql.append(".where({'data.unionid':'").append(SecurityUtil.getUnionId()).append("'})");
} else {
if (Strings.isNotBlank(unionId)) {
@@ -88,46 +73,47 @@ public class FitnessWalkActivityBindingRecordController {
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
List<NutMap> data = jsonObject.getJSONArray("data").stream()
.map(v -> JSONUtil.toBean((String) v, NutMap.class))
.collect(Collectors.toList());
List<NutMap> data = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, NutMap.class)).collect(Collectors.toList());
JSONObject pager = jsonObject.getJSONObject("pager");
Pagination pagination = new Pagination(pageNumber, pageSize, pager.getInt("Total"), data);
return Result.success().addData(pagination);
} catch (Exception e) {
return Result.success(new Pagination(pageNumber, pageSize, pager.getIntValue("Total"), data));
} catch (Exception e){
return Result.error(e.getMessage());
}
}
/**
* 删除绑定记录
* @param ids
* @return
*/
@At
@ApiOperation("删除绑定记录")
@SLog(tag = "健步走-同步绑定记录", msg = "删除绑定记录")
@SaCheckPermission("fitnessWalk.bindingRecord")
@Aop(TransAop.READ_COMMITTED)
public Result delete(String[] ids) {
String sql = "db.collection('login_record').where({_id:_.in(" + Json.toJson(ids) + ")}).remove()";
weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, sql);
return Result.success();
try {
String sql = "db.collection('login_record').where({_id:_.in(" + Json.toJson(ids) + ")}).remove()";
weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE,sql);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
/**
* 删除所有绑定记录
* @return
*/
@At
@ApiOperation("删除所有绑定记录")
@SLog(tag = "健步走-同步绑定记录", msg = "删除所有绑定记录")
@SaCheckPermission("fitnessWalk.bindingRecord")
@Aop(TransAop.READ_COMMITTED)
public Result deleteAll() {
String sql = "db.collection('login_record').where({_id: _.neq('0')}).remove()";
weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, sql);
return Result.success();
try {
String sql = "db.collection('login_record').where({_id: _.neq('0')}).remove()";
weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE,sql);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -1,60 +1,75 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import org.nutz.aop.interceptor.ioc.TransAop;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.page.Pagination;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.models.Sys_task;
import com.budwk.app.sys.services.SysTaskService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.task.services.TaskPlatformService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkActivityService;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import io.swagger.annotations.ApiOperation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.tmpl.Tmpl;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import org.nutz.plugins.wkcache.annotation.CacheRemove;
import org.nutz.plugins.wkcache.annotation.CacheRemoveAll;
import org.nutz.trans.Trans;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@IocBean
@Ok("json")
@ApiOperation("健步走-活动管理")
@At("/platform/fitnessWalk/activityManage")
@Ok("json")
@IocBean
public class FitnessWalkActivityManageController {
private static final Log log = Logs.get();
@Inject
private WeAppCloudUtil weAppCloudUtil;
@Inject
private TaskPlatformService taskPlatformService;
@Inject
private SysTaskService sysTaskService;
@Inject
private SysUserService sysUserService;
@Inject
private TaskPlatformService taskPlatformService;
@Inject
private FitnessWalkCommonService fitnessWalkCommonService;
@Inject
private FitnessWalkActivityService fitnessWalkActivityService;
@At("")
@Ok("beetl:/platform/zhgh/activity/fitnesswalk/activityManage.html")
@SaCheckPermission("fitnessWalk.activityManage")
@@ -62,12 +77,8 @@ public class FitnessWalkActivityManageController {
}
@At
@ApiOperation("获取活动数据")
@SaCheckPermission("fitnessWalk.activityManage")
public Result pageData(@Param("year") Integer year, @Param("unionId") String unionId, @Param("searchName") String searchName,
@Param("searchKeyword") String searchKeyword, @Param("pageNumber") int pageNumber,
@Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName,
@Param("pageOrderBy") String pageOrderBy) {
public Result pageData(@Param("year") Integer year, @Param("unionId") String unionId, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
int skip = (pageNumber == 1 ? 0 : (pageNumber - 1)) * pageSize;
@@ -80,7 +91,7 @@ public class FitnessWalkActivityManageController {
sql.append("])");
sql.append(")");
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (!AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
sql.append(".where({unionId:'").append(SecurityUtil.getUnionId()).append("'})");
} else if (StrUtil.isNotBlank(unionId)) {
sql.append(".where({unionId:'").append(unionId).append("'})");
@@ -90,29 +101,49 @@ public class FitnessWalkActivityManageController {
sql.append(".get()");
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
List<FitnessWalkActivity> data = jsonObject.getJSONArray("data").stream()
.map(v -> JSONUtil.toBean((String) v, FitnessWalkActivity.class))
.collect(Collectors.toList());
List<Object> data = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, FitnessWalkActivity.class)).collect(Collectors.toList());
JSONObject pager = jsonObject.getJSONObject("pager");
Pagination pagination = new Pagination(pageNumber, pageSize, pager.getInt("Total"), data);
return Result.success().addData(pagination);
return Result.success(new Pagination(pageNumber, pageSize, pager.getIntValue("Total"), data));
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 获取当前年份关联活动下拉数据。
* 下拉数据统一由 service 生成,避免页面自己拼名称或数量导致规则不一致。
*/
@At
@SaCheckPermission("fitnessWalk.activityManage")
public Result relationActivityOptions() {
return Result.success(fitnessWalkActivityService.getCurrentYearRelationActivityOptions());
}
/**
* 获取福利项目下拉数据。
* 活动页面统一通过当前年份加载福利项目,避免前端直接跨模块取数。
*/
@At
@SaCheckPermission("fitnessWalk.activityManage")
public Result welfareProjectOptions(@Param("year") Integer year) {
return Result.success(fitnessWalkActivityService.getWelfareProjectOptions(year));
}
@At
@ApiOperation("添加活动")
@SLog(tag = "健步走-活动管理", msg = "添加活动")
@SaCheckPermission("fitnessWalk.activityManage")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result doAdd(@Param("fitnessWalkActivity") FitnessWalkActivity fitnessWalkActivity,
@SaCheckPermission("fitnessWalk.activityManage")
@Aop(TransAop.READ_COMMITTED)
public Result doAdd(String data, @Param("fitnessWalkActivity") FitnessWalkActivity fitnessWalkActivity,
@Param("file") TempFile tempFile,
@Param("stepFiles") TempFile[] stepFiles,
@Param("certificateFile") TempFile certificateTempFile) {
try {
long currentTime = System.currentTimeMillis();
fitnessWalkActivity.setCreatedAt(currentTime);
fitnessWalkActivity.setUpdatedAt(currentTime);
//设置时间
if ("punch".equals(fitnessWalkActivity.getActivityModel())) {
fitnessWalkActivity.setApplyStartTime(fitnessWalkActivity.getApplyTime()[0]);
@@ -140,8 +171,7 @@ public class FitnessWalkActivityManageController {
fitnessWalkActivity.setCompletionCertificateCover(fileId);
}
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_OPERATOR.name(), RoleConstant.BRANCH_UNION_ADMIN.name())
&& !AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_OPERATOR", "BRANCH_UNION_ADMIN") && !AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
fitnessWalkActivity.setUnionId(SecurityUtil.getUnionId());
} else {
fitnessWalkActivity.setUnionId("");
@@ -153,7 +183,12 @@ public class FitnessWalkActivityManageController {
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.INSERT, sql.toString());
// 新增成功后回填云库生成的活动ID,后续创建定时任务和刷新缓存都依赖这个ID。
if (jsonObject.containsKey("id_list") && jsonObject.getJSONArray("id_list") != null && !jsonObject.getJSONArray("id_list").isEmpty()) {
fitnessWalkActivity.set_id(jsonObject.getJSONArray("id_list").getString(0));
}
fitnessWalkCommonService.addLotteryTask(fitnessWalkActivity);
fitnessWalkCommonService.addCreateActivityTask(fitnessWalkActivity);
fitnessWalkCommonService.addOrEditDoSaveRedis(fitnessWalkActivity);
return Result.success();
} catch (Exception e) {
@@ -168,7 +203,6 @@ public class FitnessWalkActivityManageController {
@At
@Ok("json:full")
@ApiOperation("根据Id获取健步走活动")
@SaCheckPermission("fitnessWalk.activityManage")
public Result findOne(String id) {
return Result.success(fitnessWalkCommonService.getActivity(id));
@@ -176,7 +210,6 @@ public class FitnessWalkActivityManageController {
@At
@Ok("json")
@ApiOperation("获取附件")
@SaCheckPermission("fitnessWalk.activityManage")
public Result getFile(String pic) {
try {
@@ -188,7 +221,7 @@ public class FitnessWalkActivityManageController {
imgmap.put("id", imgurl);
imgmap.put("url", imgurl);
res.setv("img", imgmap);
return Result.success().addData(res);
return Result.success(res);
} catch (Exception e) {
return Result.error();
}
@@ -196,13 +229,15 @@ public class FitnessWalkActivityManageController {
@At
@ApiOperation("修改健步走活动")
@SaCheckPermission("fitnessWalk.activityManage")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@SaCheckPermission("fitnessWalk.activityManage")
@Aop(TransAop.READ_COMMITTED)
public Result doEdit(@Param("fitnessWalkActivity") FitnessWalkActivity fitnessWalkActivity,
@Param("file") TempFile tempFile,
@Param("stepFiles") TempFile[] stepFiles,
@Param("certificateFile") TempFile certificateTempFile) {
fitnessWalkActivity.setUpdatedAt(System.currentTimeMillis());
//设置时间
if ("punch".equals(fitnessWalkActivity.getActivityModel())) {
fitnessWalkActivity.setApplyStartTime(fitnessWalkActivity.getApplyTime()[0]);
@@ -231,8 +266,7 @@ public class FitnessWalkActivityManageController {
}
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_OPERATOR.name(), RoleConstant.BRANCH_UNION_ADMIN.name())
&& !AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_OPERATOR", "BRANCH_UNION_ADMIN") && !AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
fitnessWalkActivity.setUnionId(SecurityUtil.getUnionId());
} else {
fitnessWalkActivity.setUnionId("");
@@ -248,6 +282,7 @@ public class FitnessWalkActivityManageController {
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.UPDATE, sql.toString());
fitnessWalkCommonService.addLotteryTask(fitnessWalkActivity);
fitnessWalkCommonService.addCreateActivityTask(fitnessWalkActivity);
fitnessWalkCommonService.addOrEditDoSaveRedis(fitnessWalkActivity);
return Result.success();
} catch (Exception e) {
@@ -257,9 +292,8 @@ public class FitnessWalkActivityManageController {
@At
@ApiOperation("删除健步走活动")
@SLog(tag = "健步走-活动管理", msg = "删除活动")
@SaCheckPermission("fitnessWalk.activityManage")
@Aop(TransAop.READ_COMMITTED)
public Result delete(String id) {
try {
weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, "db.collection('activity').doc('" + id + "').remove()");
@@ -319,7 +353,7 @@ public class FitnessWalkActivityManageController {
Sys_task sys_task = new Sys_task();
sys_task.setName(name);
sys_task.setNote(id);
sys_task.setJobClass("io.v.nutz.task.job.walking.WalkingNotifyJob");
sys_task.setJobClass("com.budwk.app.task.job.walking.WalkingNotifyJob");
sys_task.setData(Json.toJson(Map.of("groupId", groupId)));
sys_task.setDisabled(false);
@@ -335,3 +369,10 @@ public class FitnessWalkActivityManageController {
}
}
}
@@ -0,0 +1,96 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import org.nutz.aop.interceptor.ioc.TransAop;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkActivityRelationProjectService;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkRelationActivityCompletionService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* 健步走活动关联菜单。
* 这里新增“关联项目”管理能力,主活动名称与达标活动数量统一落在 MySQL 中。
*/
@IocBean
@Ok("json")
@At("/platform/fitnessWalk/activityRelation")
public class FitnessWalkActivityRelationController {
@Inject
private FitnessWalkActivityRelationProjectService relationProjectService;
@Inject
private FitnessWalkRelationActivityCompletionService relationActivityCompletionService;
@At("")
@Ok("beetl:/platform/zhgh/activity/fitnesswalk/activityRelation.html")
@SaCheckPermission("fitnessWalk.activityRelation")
public void index() {
}
/**
* 查询关联项目分页列表。
*/
@At
@SaCheckPermission("fitnessWalk.activityRelation")
public Result pageData(PageForm pageForm) {
return Result.success(relationProjectService.pageData(pageForm));
}
/**
* 保存关联项目。
* 支持新增和编辑,保存字段仅包含主活动名称和达标活动数量。
*/
@At
@SaCheckPermission("fitnessWalk.activityRelation")
@Aop(TransAop.READ_COMMITTED)
public Result doSave(FitnessWalkActivityRelationProject relationProject) {
return relationProjectService.saveRelationProject(relationProject);
}
/**
* 删除关联项目。
*/
@At
@SaCheckPermission("fitnessWalk.activityRelation")
@Aop(TransAop.READ_COMMITTED)
public Result doRemove(String id) {
return relationProjectService.deleteRelationProject(id);
}
/**
* 查看关联项目下已关联的活动。
* 活动列表按活动数据中保存的关联ID查询,避免列表展示与实际活动数据不一致。
*/
@At
@SaCheckPermission("fitnessWalk.activityRelation")
public Result relationActivityList(String id) {
return Result.success(relationProjectService.getRelationActivityList(id));
}
/**
* 判断当前登录人是否满足某个关联项目的达标要求。
* controller 仅负责接参与返回结果,具体的关联活动和打卡完成判断统一放在独立 service 中处理。
*/
@At
@SaCheckPermission("fitnessWalk.activityRelation")
public Result isCurrentUserRelationActivityQualified(String relationActivityId,String userId) {
return Result.success(relationActivityCompletionService.isCurrentUserRelationActivityQualified(relationActivityId,userId));
}
}
@@ -5,48 +5,13 @@ import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* 健走公共答题
* 健走公共接口。
* 当前项目未启用来源项目中的答题模块,相关小程序白名单接口保留路由类,避免引入不存在的题库依赖。
*/
@IocBean
@At("/platform/fitnessWalk/common")
@Ok("json:full")
public class FitnessWalkCommonController {
// @Inject
// private QuestionService questionService;
//
// @Inject
// private QuestionIssueService questionIssueService;
//
// @Inject
// private QuestionWorService questionWorService;
//
// @Inject
// private QuestionReplyService questionReplyService;
//
// @At
// public Object getQuestion() {
// return questionService.query(Cnd.where("qflag", "=", 2));
// }
//
// @At
// public Object getIssueById(String id) {
// List<Question_issue> questionIssues = questionIssueService.query(Cnd.where("iqid", "=", id).asc("ipxbh"));
// questionIssues.forEach(issue -> {
// issue.setWors(questionWorService.query(Cnd.where("wiid", "=", issue.getIid()).asc("wpxbh")));
// });
// return questionIssues;
// }
//
// @At
// public Object saveAnswer(@Param("reply") Question_reply[] replys) {
// for (Question_reply reply : replys) {
// reply.setSave(false);
// reply.setRidentity(R.UU32());
// reply.setRtime(DateUtil.getDate());
// questionReplyService.insert(reply);
// }
// return null;
// }
}
@@ -26,7 +26,7 @@ public class FitnessWalkLoginController {
private SysUserService sysUserService;
@At("/")
public Object index(String username, String loginname) {
public Result index(String username, String loginname) {
try {
Sql sql = Sqls.create("""
SELECT
@@ -40,7 +40,7 @@ public class FitnessWalkLoginController {
u.unitid,
u.member,
unit.unionid,
un.unionname,
un.name unionname,
group_concat(sr.`code`) roles
FROM
sys_user u
@@ -73,3 +73,7 @@ public class FitnessWalkLoginController {
}
}
}
@@ -1,22 +1,28 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import org.nutz.aop.interceptor.ioc.TransAop;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.result.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkPunchLottery;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import io.swagger.annotations.ApiOperation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.lang.Lang;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -29,7 +35,6 @@ import java.util.stream.Collectors;
*/
@IocBean
@Ok("json")
@ApiOperation("健步走打卡抽奖")
@At("/platform/fitnessWalk/punchLottery")
public class FitnessWalkPunchLotteryController {
@@ -58,7 +63,6 @@ public class FitnessWalkPunchLotteryController {
* @return
*/
@At
@ApiOperation("打卡模式的抽奖")
public Result judgeWinningToPunch(String activityId, String userId) {
try {
if (StrUtil.isBlank(activityId) && StrUtil.isBlank(userId)) {
@@ -68,23 +72,21 @@ public class FitnessWalkPunchLotteryController {
lock.lock();
int winingCount = fitnessWalkCommonService.dao().count(FitnessWalkPunchLottery.class, Cnd.where("activityId", "=", activityId).and("userId", "=", userId));
if (winingCount > 0) {
return null;
return Result.success();
}
// 把中奖的用户直接存到redis里面去
String redisKey = this.getClass().getName() + "#judgeWinningToPunch#activityid:" + activityId + "#PRIZELIST:";
String getPrizeIndexesKey = this.getClass().getName() + "#judgeWinningToPunch#activityid:" + activityId + "#GETPRIZEINDEXES:";
// redisService.del(getPrizeIndexesKey);
// 获取奖品列表
List<FitnessWalkActivity.PunchLotteryPrize> punchLotteryPrizes = new ArrayList<>();
String punchLotteryPrizesJson = redisService.get(redisKey);
if (StrUtil.isNotBlank(punchLotteryPrizesJson)) {
punchLotteryPrizes = JSONUtil.toList(punchLotteryPrizesJson, FitnessWalkActivity.PunchLotteryPrize.class);
punchLotteryPrizes = JSON.parseArray(punchLotteryPrizesJson, FitnessWalkActivity.PunchLotteryPrize.class);
} else {
JSONObject prizeJsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, "db.collection('activity').doc('%s').field({punchLotteryPrizes: true}).get()".formatted(activityId));
List<FitnessWalkActivity.PunchLotteryPrize> prizeList = JSONUtil.parseObj((String) prizeJsonObject.getJSONArray("data").get(0)).getJSONArray("punchLotteryPrizes").toList(FitnessWalkActivity.PunchLotteryPrize.class);
redisService.set(redisKey, JSONUtil.toJsonStr(prizeList));
List<FitnessWalkActivity.PunchLotteryPrize> prizeList = JSON.parseObject((String) prizeJsonObject.getJSONArray("data").get(0)).getJSONArray("punchLotteryPrizes").toJavaList(FitnessWalkActivity.PunchLotteryPrize.class);
redisService.set(redisKey, JSON.toJSONString(prizeList));
punchLotteryPrizes = prizeList;
}
@@ -95,14 +97,14 @@ public class FitnessWalkPunchLotteryController {
if (!redisService.exists(getPrizeIndexesKey)) {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, "db.collection('register').where({activity_id:'%s'}).count()".formatted(activityId));
JSONObject pager = jsonObject.getJSONObject("pager");
String total = pager.getStr("Total");
String total = pager.getString("Total");
//报名人数的一半,从这里的人中取数(最多抽取人数)
Integer lotteryNum = (int) Math.ceil(Double.parseDouble(total) / 2);
winningUserIndexList = generateRandomNumber(1, lotteryNum, sum);
redisService.set(getPrizeIndexesKey, JSONUtil.toJsonStr(winningUserIndexList));
redisService.set(getPrizeIndexesKey, JSON.toJSONString(winningUserIndexList));
} else {
String data = redisService.get(getPrizeIndexesKey);
winningUserIndexList = JSONUtil.toList(data, Integer.class);
winningUserIndexList = JSONObject.parseArray(data, Integer.class);
}
List<FitnessWalkPunchLottery> punchLotteryList = fitnessWalkCommonService.dao().query(FitnessWalkPunchLottery.class, Cnd.where("activityId", "=", activityId));
@@ -123,7 +125,7 @@ public class FitnessWalkPunchLotteryController {
if (winningUserIndexList.contains((punchLotteryList.size()))) {
//奖项map
Map<String, String> prizeMap = punchLotteryPrizes.stream().collect(Collectors.toMap(FitnessWalkActivity.PunchLotteryPrize::getValue, FitnessWalkActivity.PunchLotteryPrize::getName));
Map<String, String> prizeMap = punchLotteryPrizes.stream().collect(Collectors.toMap(v -> v.getValue(), v -> v.getName()));
//奖项池
List<String> prizeIdList = new ArrayList<>();
@@ -135,11 +137,14 @@ public class FitnessWalkPunchLotteryController {
});
//已经中奖的奖项ID集合
List<String> winPrizeIdList = punchLotteryList.stream().filter(FitnessWalkPunchLottery::getIsWin).map(FitnessWalkPunchLottery::getPrizeId).toList();
winPrizeIdList.forEach(prizeIdList::remove);
List<String> winPrizeIdList = punchLotteryList.stream().filter(v -> v.getIsWin()).map(v -> v.getPrizeId()).collect(Collectors.toList());
winPrizeIdList.forEach(prizeId -> {
int i = prizeIdList.indexOf(prizeId);
prizeIdList.remove(i);
});
Random random = new Random();
if (Lang.isNotEmpty(prizeIdList.size())) {
if (prizeIdList.size() != 0) {
int index = random.nextInt(prizeIdList.size());
// 获取随机元素
@@ -161,7 +166,7 @@ public class FitnessWalkPunchLotteryController {
}
} catch (Exception e) {
e.printStackTrace();
return null;
return Result.error(e.getMessage());
} finally {
if (lock.isLocked()) {
lock.unlock();
@@ -170,7 +175,6 @@ public class FitnessWalkPunchLotteryController {
}
@At
@ApiOperation("获取中奖记录")
public Result getLotteryRecord(String activityId, String userId) {
List<FitnessWalkPunchLottery> list = fitnessWalkCommonService.dao().query(FitnessWalkPunchLottery.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", userId));
@@ -185,7 +189,7 @@ public class FitnessWalkPunchLotteryController {
* @return
*/
@At
@ApiOperation("兑奖")
@Aop(TransAop.READ_COMMITTED)
public Result doExchange(String id) {
int count = fitnessWalkCommonService.dao().count(FitnessWalkPunchLottery.class, Cnd.where("id", "=", id).and("isExchange", "=", 1));
@@ -209,7 +213,7 @@ public class FitnessWalkPunchLotteryController {
* @return
*/
@At
@ApiOperation("改为已读")
@Aop(TransAop.READ_COMMITTED)
public Result doReadLottery(String activityId, String userId) {
fitnessWalkCommonService.dao().update(FitnessWalkPunchLottery.class, Chain.make("isRead", 1),
Cnd.where("userId", "=", userId).and("activityId", "=", activityId));
@@ -223,7 +227,6 @@ public class FitnessWalkPunchLotteryController {
* @return
*/
@At
@ApiOperation("查看获奖人员")
public Result getPunchWining(String activityId) {
List<FitnessWalkPunchLottery> punchLotteryList = fitnessWalkCommonService.dao().query(FitnessWalkPunchLottery.class,
Cnd.where("isWin", "=", 1).and("activityId", "=", activityId));
@@ -232,7 +235,7 @@ public class FitnessWalkPunchLotteryController {
/**
* 抽奖方法的工具类,生成随机数,该随机数为中奖人
* 生成随机数,该随机数为中奖人
*
* @param minNum 最小值
* @param maxNum 最多抽取多少人
@@ -256,3 +259,10 @@ public class FitnessWalkPunchLotteryController {
return new ArrayList<>(randomNumbers);
}
}
@@ -2,22 +2,34 @@ package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.json.JSONObject;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.budwk.app.base.result.Result;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.Cascader;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkPunchStatisticsService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -25,16 +37,18 @@ import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 打卡统计
*/
@IocBean
@Ok("json")
@ApiOperation("健步走打卡统计")
@At("/platform/fitnessWalk/punchStatistics")
public class FitnessWalkPunchStatisticsController {
@@ -68,99 +82,110 @@ public class FitnessWalkPunchStatisticsController {
*/
@At
@Ok("json:full")
@ApiOperation("打卡记录统计")
@SaCheckPermission("fitnessWalk.punchStatistics")
public Result pageData(String activityId, String unionId) {
List<NutMap> list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(activityId, unionId);
public Result pageData(String mainActivityId, String subActivityId, String activityId, String unionId) {
List<NutMap> list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(mainActivityId, subActivityId, activityId, unionId);
return Result.success(list);
}
@At
@ApiOperation("获取活动列表")
@SaCheckPermission("fitnessWalk.punchStatistics")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success().addData(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.PUNCH));
return Result.success(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.PUNCH));
}
@At
@Ok("json:full")
@ApiOperation("根据工会查询获取报名人员")
@SaCheckPermission("fitnessWalk.punchStatistics")
public Result unionRegistrationData(String activityId, String unionId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId);
public Result unionRegistrationData(String mainActivityId, String subActivityId, String activityId, String unionId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(mainActivityId, subActivityId, activityId, unionId);
return Result.success(list);
}
@At
@Ok("json:full")
@ApiOperation("根据工会查询获取打卡人员")
@SaCheckPermission("fitnessWalk.punchStatistics")
public Result unionCheckInData(String activityId, String unionId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionCheckInData(activityId, unionId);
public Result unionCheckInData(String mainActivityId, String subActivityId, String activityId, String unionId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionCheckInData(mainActivityId, subActivityId, activityId, unionId);
return Result.success(list);
}
/**
* 导出各分工会报名人数、打卡人数
*
* @param activityId
*/
@At
@Ok("void")
@ApiOperation("导出各分工会报名人数、打卡人数")
@SaCheckPermission("fitnessWalk.punchStatistics")
public void exportUnionRegCheckInNum(HttpServletResponse response, String activityId) {
List<NutMap> list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(activityId, null);
public void exportUnionRegCheckInNum(HttpServletResponse response, String mainActivityId, String subActivityId, String activityId) {
List<NutMap> list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(mainActivityId, subActivityId, activityId, null);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("分工会", "unionname", 20));
entities.add(new ExcelExportEntity("报名人数", "regCount", 20));
entities.add(new ExcelExportEntity("打卡人数", "checkInCount", 20));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download("各分工会统计人数.xlsx", workbook, response);
} catch (IOException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 导出某个分工会的报名人员
*
* @param response
* @param activityId
* @param unionId
*/
@At
@Ok("void")
@ApiOperation("导出某个分工会的报名人员")
@SaCheckPermission("fitnessWalk.punchStatistics")
public void exportRegUsers(HttpServletResponse response, String activityId, String unionId) {
public void exportRegUsers(HttpServletResponse response, String mainActivityId, String subActivityId, String activityId, String unionId) {
Sys_union union = dao.fetch(Sys_union.class, unionId);
String unionName = Optional.ofNullable(union).map(Sys_union::getName).orElse(null);
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId);
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(mainActivityId, subActivityId, activityId, unionId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("活动名称", "activityName", 30));
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
// entities.add(new ExcelExportEntity("手机号", "mobile", 20));
entities.add(new ExcelExportEntity("报名时间", "register_time_str", 20));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download("分工会报名人员.xlsx", workbook, response);
} catch (IOException e) {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download(unionName + "分工会报名人员.xlsx", workbook, response);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 导出某个分工会的打卡人员
*
* @param response
* @param activityId
* @param unionId
*/
@At
@Ok("void")
@ApiOperation("导出某个分工会的打卡人员")
@SaCheckPermission("fitnessWalk.punchStatistics")
public void exportCheckInUsers(HttpServletResponse response, String activityId, String unionId) {
public void exportCheckInUsers(HttpServletResponse response, String mainActivityId, String subActivityId, String activityId, String unionId) {
Sys_union union = dao.fetch(Sys_union.class, unionId);
String unionName = Optional.ofNullable(union).map(Sys_union::getName).orElse(null);
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionCheckInData(activityId, unionId);
List<JSONObject> list = fitnessWalkPunchStatisticsService.unionCheckInData(mainActivityId, subActivityId, activityId, unionId);
for (JSONObject jsonObject : list) {
Boolean used = jsonObject.getBool("used");
Boolean used = jsonObject.getBoolean("used");
if (used == null) {
jsonObject.put("used", "未取得");
} else if (used) {
@@ -171,19 +196,21 @@ public class FitnessWalkPunchStatisticsController {
}
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("活动名称", "activityName", 30));
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
// entities.add(new ExcelExportEntity("手机号", "mobile", 20));
entities.add(new ExcelExportEntity("点位总数", "pts_size", 20));
entities.add(new ExcelExportEntity("已打卡点位数", "sign_size", 20));
entities.add(new ExcelExportEntity("礼品券", "used", 20));
// entities.add(new ExcelExportEntity("礼品券", "used", 20));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download(unionName + "分工会报名人员.xlsx", workbook, response);
} catch (IOException e) {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download(unionName + "分工会打卡人员.xlsx", workbook, response);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@@ -204,44 +231,61 @@ public class FitnessWalkPunchStatisticsController {
// }
/**
* 未领取得奖品券用户
*
* @param response
* @param activityId
*/
@At
@Ok("void")
@ApiOperation("导出未领取得奖品券用户")
@SaCheckPermission("fitnessWalk.punchStatistics")
public void exportNotGetGiftVoucherUsers(HttpServletResponse response, String activityId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotGetGiftVoucherUsers(activityId);
public void exportNotGetGiftVoucherUsers(HttpServletResponse response, String mainActivityId, String subActivityId, String activityId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotGetGiftVoucherUsers(mainActivityId, subActivityId, activityId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
// entities.add(new ExcelExportEntity("手机号", "mobile", 20));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download("未领取得奖品券人员.xlsx", workbook, response);
} catch (IOException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 未使用奖品券用户
*
* @param response
* @param activityId
*/
@At
@Ok("void")
@ApiOperation("导出未使用奖品券用户")
@SaCheckPermission("fitnessWalk.punchStatistics")
public void exportNotUseGiftVoucherUsers(HttpServletResponse response, String activityId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotUseGiftVoucherUsers(activityId);
public void exportNotUseGiftVoucherUsers(HttpServletResponse response, String mainActivityId, String subActivityId, String activityId) {
List<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotUseGiftVoucherUsers(mainActivityId, subActivityId, activityId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
// entities.add(new ExcelExportEntity("手机号", "mobile", 20));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download("导出未使用礼品券用户.xlsx", workbook, response);
} catch (IOException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -1,19 +1,25 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateBetween;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkAwardUser;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkStep;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.vo.FitnessWalkDateStepVO;
import com.budwk.app.zhgh.dayofficework.integral.model.IntegralDetail;
import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
@@ -24,6 +30,7 @@ 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.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -38,7 +45,6 @@ import java.util.stream.Collectors;
@IocBean
@Ok("json")
@ApiOperation("健步走步数管理")
@At("/platform/fitnessWalk/stepManage")
public class FitnessWalkStepManageController {
@@ -65,8 +71,6 @@ public class FitnessWalkStepManageController {
@At
@Ok("json:full")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "健步走步数管理", msg = "微信步数上传")
@ApiOperation("上传微信步数,再根据是否开启了积分,自动将步数转化成积分")
public Result updateStepMonth(String activityId, String userId, String monthSteps) {
try {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(monthSteps) || StrUtil.isBlank(activityId)) {
@@ -197,11 +201,9 @@ public class FitnessWalkStepManageController {
*/
@At
@Ok("json:full")
@ApiOperation("小程序获取开始时间至今的步数")
public Result getActivityDateStep(String activityId, String userId) {
try {
Cnd cnd = Cnd.NEW();
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
DateTime startTime = DateUtil.date(activity.getStartTime());
DateTime endTime = DateUtil.date(activity.getEndTime());
@@ -214,11 +216,13 @@ public class FitnessWalkStepManageController {
cnd.groupBy("applyDate");
List<FitnessWalkStep> stepList = baseService.dao().query(FitnessWalkStep.class, cnd);
List<Map<String, ? extends Number>> collect = stepList.stream().map(v -> {
return Map.of("step", v.getStep(), "timestamp", v.getApplyDate().getTime());
List<FitnessWalkDateStepVO> list = stepList.stream().map(v -> {
// 返回给小程序的折线图数据,timestamp 允许为空以兼容历史异常日期数据。
Long timestamp = v.getApplyDate() == null ? null : v.getApplyDate().getTime();
return new FitnessWalkDateStepVO(v.getStep(), timestamp);
}).collect(Collectors.toList());
return Result.success(list);
return Result.success().addData(collect);
} catch (Exception e) {
return Result.error(e.getMessage());
@@ -227,7 +231,6 @@ public class FitnessWalkStepManageController {
@At
@Ok("json:full")
@ApiOperation("获取活动达标的进度条")
public Result getActivityQualifyProgressBar(String activityId, String userId) {
NutMap resultMap = NutMap.NEW();
@@ -246,17 +249,14 @@ public class FitnessWalkStepManageController {
.and("DATE( applyDate )", "=", DateUtil.today()).and("activityId", "=", activityId)
.and("step", ">", lotteryQualificationStep));
// 今天的步数
Integer thisDayStep = userWalkStep.getStep();
// 去计算达标的百分比
BigDecimal lotteryQualificationStepBig = new BigDecimal(lotteryQualificationStep);
BigDecimal thisDayStepBig = new BigDecimal(thisDayStep);
//达标的小数,保留四位
BigDecimal divide = thisDayStepBig.divide(lotteryQualificationStepBig, 4, RoundingMode.HALF_UP);
BigDecimal percentValue = divide.multiply(new BigDecimal("100"));
// 格式化为两位小数
DecimalFormat decimalFormat = new DecimalFormat("#.##");
DecimalFormat decimalFormat = new DecimalFormat("#.##"); // 格式化为两位小数
//百分数
String formattedPercent = decimalFormat.format(percentValue);
@@ -290,7 +290,7 @@ public class FitnessWalkStepManageController {
List<FitnessWalkStep> partSteps = userWalkSteps.stream()
.filter(s -> (DateUtil.compare(s.getApplyDate(), rule.getStartDate()) >= 0 && DateUtil.compare(s.getApplyDate(), rule.getEndDate()) <= 0))
.toList();
.collect(Collectors.toList());
Integer lotteryQualificationDay = rule.getLotteryQualificationDay();
Integer lotteryQualificationStep = rule.getLotteryQualificationStep();
@@ -312,7 +312,7 @@ public class FitnessWalkStepManageController {
//总步数
nutMap.put("mode", "customLotterySumStepMode");
//用户总达标步数
nutMap.put("userSumStep", partSteps.stream().mapToInt(FitnessWalkStep::getStep).sum());
nutMap.put("userSumStep", partSteps.stream().mapToInt(s -> s.getStep()).sum());
//总达标步数
nutMap.put("complianceSumStep", lotteryQualificationStep);
@@ -323,7 +323,7 @@ public class FitnessWalkStepManageController {
}
resultMap.addv("customLotteryMode", result);
}
return Result.success().addData(resultMap);
return Result.success(resultMap);
}
/**
@@ -335,7 +335,6 @@ public class FitnessWalkStepManageController {
*/
@At
@Ok("json:full")
@ApiOperation("获取用户未读的奖")
public Result winningRecord(String activityId, String userId) {
Sql sql = Sqls.create("""
select awardName,startDate,endDate from fitness_walk_award_user where activityId=@activityId and userId=@userId and isRead=@isRead
@@ -347,6 +346,11 @@ public class FitnessWalkStepManageController {
return Result.success(baseService.listMap(sql));
}
@At
@Ok("json:full")
public Result hasReadAward(String activityId) {
return Result.success();
}
/**
@@ -401,3 +405,9 @@ public class FitnessWalkStepManageController {
return maxPoints != null && maxPoints > 0;
}
}
@@ -4,13 +4,10 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
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.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
@@ -20,11 +17,12 @@ import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkRaffleUser;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkStepRaffleService;
import com.budwk.app.zhgh.dayofficework.integral.model.IntegralDetail;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import com.budwk.app.base.dao.CndPlus;
import org.nutz.dao.Dao;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
@@ -32,6 +30,7 @@ import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -48,9 +47,8 @@ import java.util.List;
* @Date 2024/12/27 14:43
* @注释 健步走抽奖控制器
*/
@IocBean
@Ok("json")
@ApiOperation("健步走手动抽奖")
@IocBean
@At("/platform/fitnessWalk/stepRaffle")
public class FitnessWalkStepRaffleController {
@@ -64,52 +62,51 @@ public class FitnessWalkStepRaffleController {
private FitnessWalkStepRaffleService fitnessWalkStepRaffleService;
@At("")
@Ok("beetl:/platform/zhgh/activity/fitnesswalk/stepRaffle.html")
@SaCheckPermission("fitnessWalk.stepRaffle")
public void index() {
}
@At
@ApiOperation("获取抽奖列表")
@SaCheckPermission("fitnessWalk.stepRaffle")
public Result pageData(PageForm pageForm,
@Param("activityId") String activityId,
@Param("unionId") String unionId,
@Param("unitId") String unitId){
Sql sql = fitnessWalkStepRaffleService.getRaffleSql(pageForm, activityId, unionId, unitId);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At
@ApiOperation("获取活动级联数据")
@SaCheckPermission("fitnessWalk.stepRaffle")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success().addData(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
return Result.success(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
}
/**
* 手动抽奖规则
* @param fitnessWalkRaffleRules
* @return
*/
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("设置抽奖规则,并抽奖")
@SLog(tag = "健步走手动抽奖", msg = "设置抽奖规则并抽奖")
@SaCheckPermission("fitnessWalk.stepRaffle")
public Result saveRaffle(FitnessWalkRaffleRules fitnessWalkRaffleRules){
baseService.dao().insertOrUpdate(fitnessWalkRaffleRules);
fitnessWalkStepRaffleService.manualLottery(fitnessWalkRaffleRules.getActivityId());
return null;
return Result.success();
}
@At
@ApiOperation("获取抽奖规则")
@SaCheckPermission("fitnessWalk.stepRaffle")
public Result getRaffle(String activityId){
FitnessWalkRaffleRules raffleRules = baseService.dao().fetch(FitnessWalkRaffleRules.class, Cnd.where("activityId", "=", activityId));
return Result.success().addData(raffleRules);
return Result.success(baseService.dao().fetch(FitnessWalkRaffleRules.class, Cnd.where("activityId", "=", activityId)));
}
@@ -119,10 +116,8 @@ public class FitnessWalkStepRaffleController {
* @return
*/
@At
@ApiOperation("小程序获取奖项信息")
public Result getAwardList(String activityId){
List<NutMap> activityAwardList = fitnessWalkStepRaffleService.getActivityAwardList(activityId);
return Result.success().addData(activityAwardList);
return Result.success(fitnessWalkStepRaffleService.getActivityAwardList(activityId));
}
@@ -131,7 +126,6 @@ public class FitnessWalkStepRaffleController {
* @return
*/
@At
@ApiOperation("小程序获取自己的中奖信息")
public Result getAwardInfo(String activityId, String userId){
Dao dao = fitnessWalkStepRaffleService.dao();
FitnessWalkAwardUser awardUser = dao.fetch(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId).and("userId", "=", userId));
@@ -148,7 +142,7 @@ public class FitnessWalkStepRaffleController {
} else {
map.put("raffleNum", 0);
}
return Result.success().addData(map);
return Result.success(map);
}
@@ -157,7 +151,6 @@ public class FitnessWalkStepRaffleController {
* @return
*/
@At
@ApiOperation("小程序获取查询是否可以抽奖")
public Result checkRaffle(String activityId, String userId){
Dao dao = fitnessWalkStepRaffleService.dao();
FitnessWalkRaffleUser raffleUser = dao.fetch(FitnessWalkRaffleUser.class,
@@ -179,8 +172,6 @@ public class FitnessWalkStepRaffleController {
*/
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("抽奖成功后,修改数据库状态")
@SLog(tag = "健步走手动抽奖", msg = "抽奖成功后,修改数据库状态")
public Result updateUserAward(String activityId, String userId) {
fitnessWalkStepRaffleService.dao().update(FitnessWalkAwardUser.class,
Chain.make("isRead", true).add("applyDate", DateUtil.date()),
@@ -192,7 +183,6 @@ public class FitnessWalkStepRaffleController {
// 增加积分
FitnessWalkAwardUser awardUser = dao.fetch(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId).and("userId", "=", userId));
IntegralDetail detail = new IntegralDetail();
detail.setId(awardUser.getId());
detail.setYear(String.valueOf(DateUtil.thisYear()));
detail.setUserId(awardUser.getUserId());
detail.setIntegral(String.valueOf(awardUser.getPoints()));
@@ -200,17 +190,16 @@ public class FitnessWalkStepRaffleController {
detail.setBizId(awardUser.getId());
detail.setIntegralTime(DateUtil.date());
dao.insert(detail);
return null;
return Result.success();
}
@At
@Ok("void")
@ApiOperation("导出中奖名单")
@SaCheckPermission("fitnessWalk.stepRaffle")
public void exportAwardExcel(String searchKeyword, String activityId,
String lotteryTime, HttpServletResponse response) {
Cnd cnd = Cnd.NEW();
CndPlus cnd = CndPlus.create();
cnd.andEX("activityId", "=", activityId);
cnd.andEX("awardName", "=", lotteryTime);
if (StrUtil.isNotBlank(searchKeyword)) {
@@ -241,7 +230,6 @@ public class FitnessWalkStepRaffleController {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download("健步走中奖人员名单.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
@@ -249,9 +237,10 @@ public class FitnessWalkStepRaffleController {
}
@At
@Ok("void")
@ApiOperation("导出健步走达标人员名单")
@SaCheckPermission("fitnessWalk.stepRaffle")
public void exportExcel(String searchKeyword, String activityId, String unionId,
String unitId, HttpServletResponse response) {
@@ -259,6 +248,28 @@ public class FitnessWalkStepRaffleController {
pageForm.setSearchKeyword(searchKeyword);
Sql sql = fitnessWalkStepRaffleService.getRaffleSql(pageForm, activityId, unionId, unitId);
// Sql sql = Sqls.create("""
// SELECT
// ru.*,
// u.sex,
// u.unionname AS unionName,
// u.unitname AS unitName
// FROM
// fitness_walk_raffle_user ru left join `user` u on ru.userId = u.id
// $condition
// """);
// CndPlus cnd = CndPlus.create();
// cnd.andEX("ru.activityId", "=", activityId);
// cnd.andEX("u.unionid", "=", unionId);
// cnd.andEX("u.unitid", "=", unitId);
// if (StrUtil.isNotBlank(searchKeyword)) {
// SqlExpressionGroup seg = new SqlExpressionGroup();
// seg.orLike("ru.username", searchKeyword);
// seg.orLike("ru.loginName", searchKeyword);
// cnd.and(seg);
// }
// sql.setCondition(cnd);
List<NutMap> list = fitnessWalkStepRaffleService.listMap(sql);
List<ExcelExportEntity> entityList = new ArrayList<>();
@@ -276,10 +287,17 @@ public class FitnessWalkStepRaffleController {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download("健步走达标人员名单.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -4,25 +4,29 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.dao.CndPlus;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -32,14 +36,15 @@ import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 步数排行榜
*/
@Slf4j
@IocBean
@Slf4j
@Ok("json")
@ApiOperation("健步走步数排行榜")
@At("/platform/fitnessWalk/stepRanking")
public class FitnessWalkStepRankingController {
@@ -55,16 +60,15 @@ public class FitnessWalkStepRankingController {
public void index() {
}
@At
@ApiOperation("获取步数排行榜")
@SaCheckPermission("fitnessWalk.stepRanking")
public Result pageData(PageForm pageForm,
@Param("activityId") String activityId,
@Param("unionId") String unionId,
@Param("unitId") String unitId,
@Param("mode") String mode) {
Pagination pagination = fitnessWalkCommonService.getStepRankingPagination(pageForm, activityId, unionId, unitId, mode);
return Result.success().addData(pagination);
return Result.success(fitnessWalkCommonService.getStepRankingPagination(pageForm, activityId, unionId, unitId, mode));
}
@@ -77,8 +81,7 @@ public class FitnessWalkStepRankingController {
*/
@At
@Ok("json:full")
@ApiOperation("获取今日步数及活动范围内步数")
@SLog(type = "校工会特色活动", tag = "健身走-计步步数排行榜", msg = "小程序接口(获取今日步数及活动范围内步数)")
@SLog(type = "校工会特色活动", tag = "健身走-计步步数排行榜", msg = "小程序接口(获取今日步数及活动范围内步数", param = true, result = true)
public Result getUserStepRanking(String activityId, String mode, Integer pageNumber, Integer pageSize) {
if ("day".equals(mode)) {
Sql sql = Sqls.create("""
@@ -97,10 +100,8 @@ public class FitnessWalkStepRankingController {
""");
sql.setParam("activityId", activityId);
sql.setParam("today", DateUtil.today());
Pagination pagination = baseService.listPageMap(pageNumber, 50, sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageNumber, 50, sql));
} else if ("week".equals(mode)) {
// 周榜
Date startOfWeek = DateUtil.beginOfWeek(new Date());
Date endOfWeek = DateUtil.endOfWeek(new Date());
@@ -124,10 +125,8 @@ public class FitnessWalkStepRankingController {
sql.setParam("activityId", activityId);
sql.setParam("startTime", startOfWeek);
sql.setParam("endTime", endOfWeek);
Pagination pagination = baseService.listPageMap(pageNumber, 50, sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageNumber, 50, sql));
} else if ("month".equals(mode)) {
// 月榜
Date firstDayOfMonth = DateUtil.beginOfMonth(new Date());
Date lastDayOfMonth = DateUtil.endOfMonth(new Date());
Sql sql = Sqls.create("""
@@ -150,10 +149,8 @@ public class FitnessWalkStepRankingController {
sql.setParam("activityId", activityId);
sql.setParam("startTime", firstDayOfMonth);
sql.setParam("endTime", lastDayOfMonth);
Pagination pagination = baseService.listPageMap(pageNumber, 50, sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageNumber, 50, sql));
} else if ("all".equals(mode)) {
// 总达标榜
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
DateTime startTime = DateUtil.date(activity.getStartTime());
DateTime endTime = DateUtil.date(activity.getEndTime());
@@ -186,10 +183,8 @@ public class FitnessWalkStepRankingController {
sql.setParam("activityId", activityId);
sql.setParam("startTime", startTime);
sql.setParam("endTime", endTime);
Pagination pagination = baseService.listPageMap(pageNumber, 50, sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageNumber, 50, sql));
} else if ("points".equals(mode)) {
// 积分榜
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
DateTime startTime = DateUtil.date(activity.getStartTime());
DateTime endTime = DateUtil.date(activity.getEndTime());
@@ -222,19 +217,73 @@ public class FitnessWalkStepRankingController {
sql.setParam("activityId", activityId);
sql.setParam("startTime", startTime);
sql.setParam("endTime", endTime);
Pagination pagination = baseService.listPageMap(pageNumber, 50, sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageNumber, 50, sql));
} else {
return null;
return Result.error("不支持的排行榜模式");
}
}
@At
@Ok("void")
@SLog(type = "校工会特色活动", tag = "健身走-计步步数排行榜", msg = "步数排行榜导出", param = true, result = true)
@SaCheckPermission("fitnessWalk.stepRanking")
public void exportExcel2(@Param("searchName") String searchName,
@Param("searchKeyword") String searchKeyword,
@Param("activityId") String activityId,
@Param("unionId") String unionId,
@Param("unitId") String unitId,
HttpServletResponse response) {
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
CndPlus cnd = CndPlus.create();
Sql sql = Sqls.create("""
SELECT
u.id,
COALESCE(SUM(fws.step), 0) AS total_steps,
u.username,
u.loginname,
u.unionname,
u.unitname
FROM
fitness_walk_step fws
LEFT JOIN `user` u ON u.id = fws.userId
$condition
""");
cnd.and("fws.activityId", "=", activityId);
cnd.andEX("DATE(fws.applyDate)", ">=", DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd"));
cnd.andEX("DATE(fws.applyDate)", "<=", DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd"));
cnd.andEX("u.unionId", "=", unionId);
cnd.andEX("u.unitId", "=", unitId);
cnd.groupBy("fws.userId");
cnd.desc("total_steps");
sql.setCondition(cnd);
List<NutMap> stepRankingList = baseService.listMap(sql);
List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
no.setFormat("isAddIndex");
entityList.add(no);
entityList.add(new ExcelExportEntity("姓名", "username", 20));
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
entityList.add(new ExcelExportEntity("分工会", "unionname", 20));
entityList.add(new ExcelExportEntity("单位", "unitname", 20));
entityList.add(new ExcelExportEntity("活动期间总步数", "total_steps", 20));
try {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, stepRankingList);
CommonDownloadUtil.download("活动期间总步数榜.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
@At
@Ok("void")
@ApiOperation("步数排行榜导出")
@SaCheckPermission("fitnessWalk.stepRanking")
@SLog(type = "校工会特色活动", tag = "健身走-计步步数排行榜", msg = "步数排行榜导出", param = true, result = true)
@SaCheckPermission("fitnessWalk.stepRanking")
public void exportExcel(@Param("searchName") String searchName,
@Param("searchKeyword") String searchKeyword,
@Param("activityId") String activityId,
@@ -254,21 +303,25 @@ public class FitnessWalkStepRankingController {
entityList.add(new ExcelExportEntity("单位", "unitname", 20));
entityList.add(new ExcelExportEntity("today".equals(mode) ? "今日步数" : "活动期间总步数", "total_steps", 20));
try {
String title = ("today".equals(mode) ? DateUtil.format(new Date(), "yyyy年MM月dd日") : "活动期间总") + "步数榜.xlsx";
String fileName = ("today".equals(mode) ? DateUtil.format(new Date(), "yyyy年MM月dd日") : "活动期间总") + "步数榜.xlsx";
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, stepRankingList);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download(title, workbook, response);
CommonDownloadUtil.download(fileName, workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
@At
@ApiOperation("获取联级活动")
@SaCheckPermission("fitnessWalk.stepRanking")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success().addData(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
return Result.success(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
}
}
@@ -5,19 +5,24 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkStep;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import com.budwk.app.base.dao.CndPlus;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
@@ -25,27 +30,30 @@ import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
@IocBean
@Ok("json")
@ApiOperation("计步步数统计")
@At("/platform/fitnessWalk/stepStatistics")
public class FitnessWalkStepStatisticsController {
@Inject
private BaseService baseService;
@Inject
private RedisService redisService;
@Inject
private WeAppCloudUtil weAppCloudUtil;
@Inject
private RedisService redisService;
@Inject
private FitnessWalkCommonService fitnessWalkCommonService;
@@ -55,30 +63,26 @@ public class FitnessWalkStepStatisticsController {
public void index() {
}
/**
* 公共sql
* @return
*/
private String getSql() {
return """
SELECT
u.loginname,
u.username,
u.unionName AS unionname,
u.unitName AS unitname,
u.unionname,
u.unitname,
al.applyDate,
al.step,
date_format(al.applyDate,'%Y-%m-%d') as prizeData
FROM
`fitness_walk_step` al
LEFT JOIN `vw_user` u ON u.id = al.userId
LEFT JOIN `user` u ON u.id = al.userId
$condition
""";
}
@At
@Ok("json:full")
@ApiOperation("计步步数统计")
@SaCheckPermission("fitnessWalk.stepStatistics")
public Result pageData(PageForm pageForm,
@Param("year") Integer year,
@@ -86,7 +90,7 @@ public class FitnessWalkStepStatisticsController {
@Param("activityDate") String[] activityDate,
@Param("unionId") String unionId,
@Param("unitId") String unitId) {
Cnd cnd = Cnd.NEW();
CndPlus cnd = CndPlus.create();
Sql sql = Sqls.create(getSql());
if (Lang.isNotEmpty(activityDate)) {
cnd.and("date_format(al.applyDate,'%Y-%m-%d')", ">=", activityDate[0]);
@@ -107,28 +111,23 @@ public class FitnessWalkStepStatisticsController {
cnd.groupBy("al.applyDate", "al.userId");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success().addData(pagination);
return Result.success(baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At
@ApiOperation("获取联级活动")
@SaCheckPermission("fitnessWalk.stepStatistics")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success().addData(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
return Result.success(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
}
@Ok("void")
@At("/exportExcel")
@ApiOperation("计步步数统计表导出")
@Ok("void")
@SaCheckPermission("fitnessWalk.stepStatistics")
public void exportExcel(@Param("activityId") String activityId,
@Param("activityDate") String[] activityDate,
@Param("unionId") String unionId,
@Param("unitId") String unitId, HttpServletResponse response) {
Cnd cnd = Cnd.NEW();
CndPlus cnd = CndPlus.create();
Sql sql = Sqls.create(getSql());
if (activityDate.length > 0) {
cnd.and("date_format(al.applyDate,'%Y-%m-%d')", ">=", activityDate[0]);
@@ -156,10 +155,15 @@ public class FitnessWalkStepStatisticsController {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, exportList);
workbook.write(response.getOutputStream());
CommonDownloadUtil.download("计步步数统计表.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -2,22 +2,29 @@ package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkAwardUser;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import com.budwk.app.base.dao.CndPlus;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -27,16 +34,17 @@ import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 用户中奖榜
*/
@IocBean
@Ok("json")
@ApiOperation("小程序计步步数中奖榜")
@IocBean
@At("/platform/fitnessWalk/stepWining")
public class FitnessWalkStepWiningController {
@@ -62,25 +70,22 @@ public class FitnessWalkStepWiningController {
*/
@At
@Ok("json:full")
@ApiOperation("小程序获取中奖榜")
@SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "获取中奖榜")
@SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "获取中奖榜",param = true,result = true)
public Result getUserStepWining(String activityId) {
return Result.success().addData(fitnessWalkCommonService.getWiningRankingUserList(activityId));
return Result.success(fitnessWalkCommonService.getWiningRankingUserList(activityId));
}
@At
@ApiOperation("获取联级活动")
@SaCheckPermission("fitnessWalk.stepWining")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success().addData(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
return Result.success(fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT));
}
@At
@Ok("void")
@ApiOperation("小程序中奖榜导出")
@SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "导出中奖榜",param = true,result = true)
@SaCheckPermission("fitnessWalk.stepWining")
@SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "导出中奖榜")
public void exportUserStepWining(String activityId, HttpServletResponse response){
List<NutMap> winingRankingUserList = fitnessWalkCommonService.getWiningRankingUserList(activityId);
List<ExcelExportEntity> entityList = new ArrayList<>();
@@ -103,7 +108,9 @@ public class FitnessWalkStepWiningController {
List<NutMap> awardList = map.getAsList("awardList", NutMap.class);
awardList.forEach(v->v.setv("applyDate",DateUtil.format(v.getTime("applyDate"),"yyyy-MM-dd")));
zipOutputStream.putNextEntry(new ZipEntry(map.getString("title") + ".xlsx"));
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, awardList);
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, awardList);
workbook.write(zipOutputStream);
zipOutputStream.closeEntry();
}
@@ -115,7 +122,6 @@ public class FitnessWalkStepWiningController {
}
/**
* 中奖奖项列表
*
@@ -123,7 +129,6 @@ public class FitnessWalkStepWiningController {
* @return
*/
@At
@ApiOperation("小程序获取中奖奖项列表")
public Result prizeOption(String activityId) {
List<NutMap> list = fitnessWalkCommonService.prizeOption(activityId);
return Result.success(list);
@@ -136,9 +141,9 @@ public class FitnessWalkStepWiningController {
* @return
*/
@At
@ApiOperation("小程序获取中奖用户")
public Result prizeUsers(String lotteryTime, String activityId, String searchKeyword) {
Cnd cnd = Cnd.NEW();
CndPlus cnd = CndPlus.create();
cnd.andEX("activityId", "=", activityId);
cnd.andEX("awardName", "=", lotteryTime);
if (StrUtil.isNotBlank(searchKeyword)) {
@@ -149,7 +154,15 @@ public class FitnessWalkStepWiningController {
}
cnd.and("isRead", "=", true);
List<FitnessWalkAwardUser> awardUserList = fitnessWalkCommonService.dao().query(FitnessWalkAwardUser.class, cnd);
// String lotteryDate = lotteryTime.substring(0, 10);
// List<FitnessWalkAwardUser> awardUserList = fitnessWalkCommonService.dao().query(FitnessWalkAwardUser.class,
// Cnd.where("activityId", "=", activityId).and("date(applyDate)", "=", lotteryDate));
return Result.success(awardUserList);
}
}
@@ -0,0 +1,105 @@
package com.budwk.app.zhgh.activity.fitnesswalk.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkPunchStatisticsService;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* 人员打卡情况。
* 该页面按人员维度展示所选活动范围内的打卡完成情况,支持主活动聚合查询和分活动单独查询。
*/
@IocBean
@Ok("json")
@At("/platform/fitnessWalk/userPunchStatistics")
public class FitnessWalkUserPunchStatisticsController {
@Inject
private FitnessWalkPunchStatisticsService fitnessWalkPunchStatisticsService;
@At("")
@Ok("beetl:/platform/zhgh/activity/fitnesswalk/userPunchStatistics.html")
@SaCheckPermission("fitnessWalk.userPunchStatistics")
public void index() {
}
/**
* 查询活动级联选项。
* 这里只返回打卡模式活动,供前端年份切换后联动刷新主活动和分活动下拉。
*/
@At
@SaCheckPermission("fitnessWalk.userPunchStatistics")
public Result getCascadersActivity(@Param("year") int year) {
return Result.success(fitnessWalkPunchStatisticsService.userPunchCascaderActivity(year));
}
/**
* 查询人员打卡情况列表。
* 当前接口按人员维度返回点位总数、已打卡点位数以及是否全部完成全部点位。
* 当页面只选择主活动且该主活动存在 relationActivityId 时,还支持按达标/未达标筛选人员。
*/
@At
@Ok("json:full")
@SaCheckPermission("fitnessWalk.userPunchStatistics")
public Result pageData(String mainActivityId, String subActivityId, String activityId, String unionId, String searchKeyword,
String qualifiedStatus, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize) {
Pagination pagination = fitnessWalkPunchStatisticsService.userPunchPageData(
mainActivityId, subActivityId, activityId, unionId, searchKeyword, qualifiedStatus, pageNumber, pageSize
);
return Result.success(pagination);
}
/**
* 导出人员打卡情况。
* 导出条件与页面当前可见筛选项保持一致,确保“所见即所得”。
*/
@At
@Ok("void")
@SaCheckPermission("fitnessWalk.userPunchStatistics")
public void exportExcel(String mainActivityId, String subActivityId, String activityId, String unionId, String searchKeyword, String qualifiedStatus,
HttpServletResponse response) {
List<NutMap> list = fitnessWalkPunchStatisticsService.userPunchExportData(mainActivityId, subActivityId, activityId, unionId, searchKeyword, qualifiedStatus);
List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
no.setFormat("isAddIndex");
entityList.add(no);
entityList.add(new ExcelExportEntity("姓名", "username", 20));
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
entityList.add(new ExcelExportEntity("分工会", "unionname", 20));
entityList.add(new ExcelExportEntity("单位", "unitname", 40));
entityList.add(new ExcelExportEntity("达标几个活动", "qualifiedActivityNum", 20));
entityList.add(new ExcelExportEntity("点位总数", "pts_size", 20));
entityList.add(new ExcelExportEntity("已打卡点位数", "sign_size", 20));
entityList.add(new ExcelExportEntity("是否全部打卡完全部点位", "isAllSigned", 24));
try {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);
CommonDownloadUtil.download("健步走人员打卡情况.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,6 +1,5 @@
package com.budwk.app.zhgh.activity.fitnesswalk.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -10,159 +9,149 @@ import java.util.List;
@Data
public class FitnessWalkActivity {
@ApiModelProperty(value = "小程序活动Id")
private String _id;
// 主活动名称
@ApiModelProperty(value = "主活动名称")
private String masterActivityName;
// 分支活动名称
@ApiModelProperty(value = "分支活动名称")
private String branchActivityName;
// 活动地址
@ApiModelProperty(value = "活动地址")
// 关联活动ID,创建/编辑时通过下拉选择后回填
private String relationActivityId;
// 关联活动名称,保存时由服务层根据关联活动ID统一回填
private String relationActivityName;
// 关联福利项目ID,创建/编辑时通过福利下拉选择后回填
private String welfareId;
// 关联活动对应的达标活动数量,保存时由服务层统一回填
private Integer relationStandardActivityNum;
private String address;
@ApiModelProperty(value = "活动礼品")
private String giftName;
@ApiModelProperty(value = "活动分组Id")
private String groupId;
@ApiModelProperty(value = "创建分工会Id")
// 是否自动连续创建活动
private Boolean autoContinuousCreate;
// 连续创建活动日期区间,页面开启自动连续创建后由用户选择开始和结束日期
private Long[] continuousCreateDate;
// 自动创建来源活动ID,仅自动复制出的活动会写入,用于编辑原活动时识别已落地的历史活动
private String autoCreateSourceActivityId;
// 自动创建对应的目标活动日期(当天00:00:00时间戳),用于避免同一天活动被重复生成
private Long autoCreateTargetDate;
private String unionId;
@ApiModelProperty(value = "活动模式")
private String activityModel;
@ApiModelProperty(value = "活动报名时间范围,时间戳模式")
private Long[] applyTime;
@ApiModelProperty(value = "活动报名开始时间")
private Long applyStartTime;
@ApiModelProperty(value = "活动报名结束时间")
private Long applyEndTime;
@ApiModelProperty(value = "活动时间范围,时间戳模式")
private Long[] time;
@ApiModelProperty(value = "活动开始时间")
private Long startTime;
@ApiModelProperty(value = "活动结束时间")
private Long endTime;
@ApiModelProperty(value = "活动描述")
private String note;
@ApiModelProperty(value = "活动封面")
private String cover;
@ApiModelProperty(value = "活动临时封面")
private String tempCover;
@ApiModelProperty(value = "是否需要答题")
private Boolean isQuestion;
@ApiModelProperty(value = "答题活动Id")
private String questionId;
@ApiModelProperty(value = "步数模式")
private String speedControlMode;
//打卡完成之后 gift_voucher:礼品券 cert:完赛证书 null啥也不干
@ApiModelProperty(value = "打卡完成之后操作")
private String punchFinishAfter;
//完赛证书
@ApiModelProperty(value = "完赛证书")
private String completionCertificateCover;
//完赛证书临时url
@ApiModelProperty(value = "完赛证书临时url")
private String tempCompletionCertificateCover;
//是否抽奖
@ApiModelProperty(value = "是否抽奖")
private Boolean isLottery;
//打卡模式奖品列表
@ApiModelProperty(value = "打卡完成之后抽奖信息")
private List<PunchLotteryPrize> punchLotteryPrizes;
@ApiModelProperty(value = "是否显示礼品券")
private Boolean showGiftTicket;
@ApiModelProperty(value = "知识卡的图片")
private List<Pts> pts;
@ApiModelProperty(value = "打开点位,线路")
private List<Point> linePoints;
@ApiModelProperty(value = "打开点位,线路2")
private List<Point> linePoints2;
//是否按顺序签到
@ApiModelProperty(value = "是否按顺序签到")
private Boolean isOrderSignIn;
//是否多条线路
@ApiModelProperty(value = "是否多条线路")
private Boolean isMultipleLines;
//抽奖模式 none无 everyday每天 monthly每月 custom自定义
@ApiModelProperty(value = "抽奖模式")
private String lotteryMode;
//每月抽奖模式抽奖时间
@ApiModelProperty(value = "每月抽奖模式抽奖时间")
private List<Date> everyMonthLotteryTime;
@ApiModelProperty(value = "自定义模式抽奖抽奖时间规则")
//自定义模式抽奖抽奖时间规则
private List<CustomLotteryRule> customLotteryRules;
@ApiModelProperty(value = "每日模式抽奖抽奖时间规则")
//每日模式抽奖抽奖时间规则
private DayLotteryRule dayLotteryRule;
@ApiModelProperty(value = "随机图片数组")
//随机图片数组
private List<String> randomPics;
@ApiModelProperty(value = "模板随机图片数组")
private List<String> templateRandomPics;
@ApiModelProperty(value = "外链地址")
//外链地址
private String externalLinkAddress;
@ApiModelProperty(value = "是否开启距离限制")
//是否开启距离限制
private Boolean enableDistance;
@ApiModelProperty(value = "签到几个点位算完成")
//签到几个点位算完成
private Integer finishPointNum;
@ApiModelProperty(value = "是否自动抽奖")
// 是否自动抽奖
private Boolean isAutoLottery;
@ApiModelProperty(value = "手动抽奖,抽奖资格天数")
// 手动抽奖,抽奖资格天数
private Integer lotteryQualificationDays;
@ApiModelProperty(value = "手动抽奖,抽奖资格步数")
// 手动抽奖,抽奖资格步数
private Integer lotteryQualificationSteps;
@ApiModelProperty(value = "是否启用积分")
// 是否启用积分
private Boolean isPoints;
@ApiModelProperty(value = "达标获得积分")
// 达标获得积分
private Integer lotteryQualificationPoints;
@ApiModelProperty(value = "额外积分的达标步数")
// 额外积分的达标步数
private Integer otherSteps;
@ApiModelProperty(value = "根据额外步数来计算的额外积分")
// 根据额外步数来计算的额外积分
private Integer otherPoints;
@ApiModelProperty(value = "封顶积分")
// 封顶积分
private Integer maxPoints;
// 创建时间,用于筛选当年已创建的活动
private Long createdAt;
// 修改时间,保存编辑时同步更新
private Long updatedAt;
@Data
public static class Point implements Serializable {
private String type;
@@ -233,3 +222,5 @@ public class FitnessWalkActivity {
}
}
@@ -0,0 +1,43 @@
package com.budwk.app.zhgh.activity.fitnesswalk.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.ColType;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* 健步走活动关联项目。
* 该表用于保存用户手工创建的“主活动名称 + 达标活动数量”配置,数据统一落在 MySQL 中。
*/
@Data
@Table("fitness_walk_activity_relation_project")
@EqualsAndHashCode(callSuper = true)
public class FitnessWalkActivityRelationProject extends BaseModel {
private static final long serialVersionUID = 1L;
@Name
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
@Comment("主键ID")
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("主活动名称")
private String masterActivityName;
@Column
@ColDefine(type = ColType.INT)
@Comment("达标活动数量")
private Integer standardActivityNum;
}
@@ -99,3 +99,5 @@ public class FitnessWalkAwardUser extends BaseModel {
@Comment("积分")
private Integer points;
}
@@ -76,3 +76,5 @@ public class FitnessWalkPunchLottery extends BaseModel {
@Comment("是否兑换")
private Boolean isExchange;
}
@@ -53,3 +53,5 @@ public class FitnessWalkRaffleRules extends BaseModel {
private Boolean isSimultaneously;
}
}
@@ -59,3 +59,5 @@ public class FitnessWalkRaffleUser extends BaseModel {
@Comment("是否已抽奖")
private Boolean isRaffle;
}
@@ -48,3 +48,5 @@ public class FitnessWalkStep extends BaseModel implements Serializable {
@Comment("时间")
private Date applyDate;
}
@@ -0,0 +1,52 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* 健步走活动关联项目 service。
* 负责关联项目在 MySQL 中的分页查询、保存和删除。
*/
public interface FitnessWalkActivityRelationProjectService extends BaseService<FitnessWalkActivityRelationProject> {
/**
* 查询关联项目列表。
*
* @param pageForm 分页参数
* @return 分页结果
*/
Pagination pageData(PageForm pageForm);
/**
* 保存关联项目。
*
* @param relationProject 关联项目
* @return 保存结果
*/
Result saveRelationProject(FitnessWalkActivityRelationProject relationProject);
/**
* 删除关联项目。
*
* @param id 主键ID
* @return 删除结果
*/
Result deleteRelationProject(String id);
/**
* 查询某个关联项目下的活动列表。
* 这里按活动数据中保存的关联ID查询,保证查看结果与活动实际保存的数据一致。
*
* @param id 关联项目ID
* @return 关联活动列表
*/
List<NutMap> getRelationActivityList(String id);
}
@@ -0,0 +1,36 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* 健步走活动管理 service。
* 统一负责活动在 MySQL 中的查询、保存、更新、删除以及云库历史数据同步。
*/
public interface FitnessWalkActivityService extends BaseService<FitnessWalkActivityRelationProject> {
/**
* 获取当前年份可关联的活动下拉数据。
* 下拉内容统一返回活动ID、活动名称和达标活动数量,供创建/编辑页面直接使用。
*
* @return 关联活动下拉数据
*/
List<FitnessWalkActivityRelationProject> getCurrentYearRelationActivityOptions();
/**
* 获取福利项目下拉数据。
* 创建/编辑活动时统一从 service 层查询福利项目,避免页面直接跨模块拼查询。
*
* @param year 年份,为空时默认当前年份
* @return 福利项目下拉数据,仅返回页面下拉所需字段
*/
List<NutMap> getWelfareProjectOptions(Integer year);
}
@@ -53,6 +53,13 @@ public interface FitnessWalkCommonService extends BaseService<FitnessWalkAwardUs
*/
void addLotteryTask(FitnessWalkActivity fitnessWalkActivity);
/**
* 自动连续创建活动时添加定时创建任务。
* 任务会按活动配置的连续创建日期区间逐天执行,并基于原活动复制生成新活动。
*
* @param fitnessWalkActivity 原始活动
*/
void addCreateActivityTask(FitnessWalkActivity fitnessWalkActivity);
/**
* 获取步数排行榜
@@ -84,3 +91,5 @@ public interface FitnessWalkCommonService extends BaseService<FitnessWalkAwardUs
List<NutMap> prizeOption(String activityId);
}
@@ -1,7 +1,9 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.page.Pagination;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.Cascader;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkAwardUser;
import org.nutz.lang.util.NutMap;
@@ -9,12 +11,101 @@ import java.util.List;
public interface FitnessWalkPunchStatisticsService extends BaseService<FitnessWalkAwardUser> {
List<NutMap> unionRegCheckInNum(String activityId, String unionId);
/**
* 查询人员打卡统计页专用活动级联。
* 父级使用稳定的关联项目ID,不复用公共活动级联,避免父级 value 随最新活动变化。
*
* @param year 查询年份
* @return 人员打卡统计页活动级联
*/
List<Cascader> userPunchCascaderActivity(int year);
List<JSONObject> unionRegistrationData(String activityId, String unionId);
/**
* 查询分工会报名人数、打卡人数。
* 选择分活动时只查当前分活动;只选择主活动时按主活动关联项目下的全部活动汇总查询。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容原页面保留的最终活动ID
* @param unionId 分工会ID
* @return 分工会统计结果
*/
List<NutMap> unionRegCheckInNum(String mainActivityId, String subActivityId, String activityId, String unionId);
List<JSONObject> unionCheckInData(String activityId, String unionId);
/**
* 查询某个分工会的报名明细。
* 选择分活动时只查当前分活动;只选择主活动时按主活动关联项目下的全部活动汇总查询。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容原页面保留的最终活动ID
* @param unionId 分工会ID
* @return 报名明细
*/
List<JSONObject> unionRegistrationData(String mainActivityId, String subActivityId, String activityId, String unionId);
List<JSONObject> exportNotGetGiftVoucherUsers(String activityId);
List<JSONObject> exportNotUseGiftVoucherUsers(String activityId);
/**
* 查询某个分工会的打卡明细。
* 选择分活动时只查当前分活动;只选择主活动时按主活动关联项目下的全部活动汇总查询。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容原页面保留的最终活动ID
* @param unionId 分工会ID
* @return 打卡明细
*/
List<JSONObject> unionCheckInData(String mainActivityId, String subActivityId, String activityId, String unionId);
/**
* 导出未取得礼品券用户。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容原页面保留的最终活动ID
* @return 未取得礼品券用户
*/
List<JSONObject> exportNotGetGiftVoucherUsers(String mainActivityId, String subActivityId, String activityId);
/**
* 导出未使用礼品券用户。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容原页面保留的最终活动ID
* @return 未使用礼品券用户
*/
List<JSONObject> exportNotUseGiftVoucherUsers(String mainActivityId, String subActivityId, String activityId);
/**
* 查询人员打卡情况列表。
* 选择分活动时只查当前分活动;只选择主活动时按主活动关联项目下的全部活动汇总到人员维度。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容页面保留的最终活动ID
* @param unionId 分工会ID
* @param searchKeyword 姓名或工号关键字,空表示不过滤
* @param qualifiedStatus 达标筛选:qualified=已达标,unqualified=未达标,all/空=全部
* @param pageNumber 页码,从 1 开始
* @param pageSize 每页条数
* @return 人员打卡情况分页结果
*/
Pagination userPunchPageData(String mainActivityId, String subActivityId, String activityId, String unionId,
String searchKeyword, String qualifiedStatus, int pageNumber, int pageSize);
/**
* 导出人员打卡情况列表。
* 导出会按当前筛选条件返回全部人员,不能只返回页面当前页。
*
* @param mainActivityId 主活动ID
* @param subActivityId 分活动ID
* @param activityId 兼容页面保留的最终活动ID
* @param unionId 分工会ID
* @param searchKeyword 姓名或工号关键字,空表示不过滤
* @param qualifiedStatus 达标筛选:qualified=已达标,unqualified=未达标,all/空=全部
* @return 人员打卡情况全量列表
*/
List<NutMap> userPunchExportData(String mainActivityId, String subActivityId, String activityId, String unionId, String searchKeyword, String qualifiedStatus);
}
@@ -0,0 +1,22 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
/**
* 健步走关联活动完成情况 service。
* 该 service 专门处理“按关联项目查询当前登录人的关联活动完成进度”场景,避免把业务判断堆到通用 service 中。
*/
public interface FitnessWalkRelationActivityCompletionService extends BaseService<FitnessWalkActivityRelationProject> {
/**
* 根据活动关联项目ID,判断当前登录人是否满足关联活动达标要求。
* 只有当当前用户完成的达标活动数等于关联配置的 standardActivityNum 时,才返回 true。
*
* @param relationActivityId 活动关联项目ID
* @return true 代表全部合格,false 代表未达标
*/
boolean isCurrentUserRelationActivityQualified(String relationActivityId,String userId);
}
@@ -32,3 +32,5 @@ public interface FitnessWalkStepRaffleService extends BaseService<FitnessWalkRaf
*/
void manualLottery(String activityId);
}
@@ -0,0 +1,199 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkActivityRelationProjectService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 健步走活动关联项目 MySQL 实现。
*/
@IocBean(args = {"refer:dao"})
public class FitnessWalkActivityRelationProjectServiceImpl extends BaseServiceImpl<FitnessWalkActivityRelationProject>
implements FitnessWalkActivityRelationProjectService {
@Inject
private WeAppCloudUtil weAppCloudUtil;
public FitnessWalkActivityRelationProjectServiceImpl(Dao dao) {
super(dao);
}
@Override
public Pagination pageData(PageForm pageForm) {
PageForm currentPageForm = pageForm == null ? new PageForm() : pageForm;
Cnd cnd = buildPageCnd(currentPageForm);
Integer pageNumber = currentPageForm.getPageNumber() == null ? 1 : currentPageForm.getPageNumber();
Integer pageSize = currentPageForm.getPageSize() == null ? 10 : currentPageForm.getPageSize();
return listPageMap(pageNumber, pageSize, cnd);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public Result saveRelationProject(FitnessWalkActivityRelationProject relationProject) {
try {
validateAndNormalize(relationProject);
if (StrUtil.isBlank(relationProject.getId())) {
insert(relationProject);
} else {
updateIgnoreNull(relationProject);
}
return Result.success("保存成功");
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
@Override
@Aop(TransAop.READ_COMMITTED)
public Result deleteRelationProject(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("未获取到需要删除的关联项目");
}
delete(id);
return Result.success("删除成功");
}
@Override
public List<NutMap> getRelationActivityList(String id) {
if (StrUtil.isBlank(id)) {
return new ArrayList<>();
}
StringBuilder sql = new StringBuilder("db.collection('activity').where({relationActivityId:'")
.append(id)
.append("'");
// 非全局管理员查看时,仅返回当前工会下的关联活动,避免越权看到其他工会数据。
if (AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_OPERATOR", "BRANCH_UNION_ADMIN") && !AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
sql.append(",unionId:'").append(SecurityUtil.getUnionId()).append("'");
}
sql.append("}).field({")
.append("masterActivityName:true,")
.append("branchActivityName:true,")
.append("activityModel:true,")
.append("createdAt:true,")
.append("relationActivityId:true")
.append("}).orderBy('createdAt','desc').limit(1000).get()");
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
return jsonObject.getJSONArray("data").stream()
.map(item -> JSON.parseObject((String) item, FitnessWalkActivity.class))
.map(this::buildRelationActivityItem)
.collect(Collectors.toList());
} catch (Exception e) {
throw new RuntimeException("查询关联活动失败:" + e.getMessage());
}
}
/**
* 组装分页查询条件。
* 当前列表仅支持按主活动名称模糊查询,并默认按创建时间倒序展示。
*/
private Cnd buildPageCnd(PageForm pageForm) {
Cnd cnd = Cnd.NEW();
if (pageForm != null && StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and("masterActivityName", "like", "%" + pageForm.getSearchKeyword().trim() + "%");
}
cnd.desc("createdAt");
return cnd;
}
/**
* 保存前统一校验和标准化字段。
* 这里同时限制主活动名称唯一,避免重复创建同名关联项目影响后续配置。
*/
private void validateAndNormalize(FitnessWalkActivityRelationProject relationProject) {
if (relationProject == null) {
throw new RuntimeException("关联项目信息不能为空");
}
String masterActivityName = Strings.sNull(relationProject.getMasterActivityName()).trim();
if (Strings.isBlank(masterActivityName)) {
throw new RuntimeException("请填写主活动名称");
}
relationProject.setMasterActivityName(masterActivityName);
if (relationProject.getStandardActivityNum() == null || relationProject.getStandardActivityNum() <= 0) {
throw new RuntimeException("达标活动数量必须大于0");
}
Cnd cnd = Cnd.where("masterActivityName", "=", masterActivityName);
if (Strings.isNotBlank(relationProject.getId())) {
cnd.and("id", "<>", relationProject.getId());
}
if (count(cnd) > 0) {
throw new RuntimeException("主活动名称已存在,请勿重复创建");
}
}
/**
* 将活动对象转换为查看页需要的展示数据。
* 这里统一补充活动名称和活动模式文本,前端只负责展示,不再重复拼接字段。
*/
private NutMap buildRelationActivityItem(FitnessWalkActivity activity) {
NutMap item = NutMap.NEW();
item.put("activityId", activity.get_id());
item.put("activityName", buildRelationActivityName(activity));
item.put("activityModel", activity.getActivityModel());
item.put("activityModelName", getActivityModelName(activity.getActivityModel()));
item.put("createdAt", activity.getCreatedAt());
return item;
}
/**
* 统一生成活动展示名称。
* 没有分活动名称时仅显示主活动名称;有分活动名称时按“主活动(分活动)”展示。
*/
private String buildRelationActivityName(FitnessWalkActivity activity) {
String masterActivityName = Strings.sNull(activity.getMasterActivityName()).trim();
String branchActivityName = Strings.sNull(activity.getBranchActivityName()).trim();
if (Strings.isBlank(branchActivityName)) {
return masterActivityName;
}
return masterActivityName + "(" + branchActivityName + ")";
}
/**
* 返回活动模式中文名称,便于查看页面直接展示。
*/
private String getActivityModelName(String activityModel) {
if ("punch".equals(activityModel)) {
return "打卡模式";
}
if ("stepCount".equals(activityModel)) {
return "计步模式";
}
if ("GPS".equals(activityModel)) {
return "GPS模式";
}
return "";
}
}
@@ -0,0 +1,53 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service.impl;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkActivityService;
import com.budwk.app.base.dao.CndPlus;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* 健步走活动管理实现。
* 这里额外负责“关联活动”下拉构建,以及保存时的关联字段统一回填。
*/
@IocBean(args = {"refer:dao"})
public class FitnessWalkActivityServiceImpl extends BaseServiceImpl<FitnessWalkActivityRelationProject> implements FitnessWalkActivityService {
public FitnessWalkActivityServiceImpl(Dao dao) {
super(dao);
}
@Override
public List<FitnessWalkActivityRelationProject> getCurrentYearRelationActivityOptions() {
List<FitnessWalkActivityRelationProject> projectList = dao().query(FitnessWalkActivityRelationProject.class, CndPlus.create().andEX("YEAR(FROM_UNIXTIME(createdAt/ 1000))", "=", DateUtil.thisYear()));
return projectList;
}
@Override
public List<NutMap> getWelfareProjectOptions(Integer year) {
int targetYear = year == null ? DateUtil.thisYear() : year;
Sql sql = Sqls.create("""
SELECT
id,
`name`
FROM
welfare_project
$condition
""");
CndPlus cnd = CndPlus.create();
cnd.and("isDisabled", "=", false);
cnd.andEX("year", "=", targetYear);
sql.setCondition(cnd);
return listMap(sql);
}
}
@@ -1,20 +1,21 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.page.Pagination;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.dao.CndPlus;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.models.Sys_task;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysTaskService;
import com.budwk.app.task.services.TaskPlatformService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.Cascader;
import com.budwk.app.zhgh.activity.fitnesswalk.contants.FitnessWalkMode;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
@@ -23,12 +24,14 @@ import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkCommonService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.aop.Aop;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
@@ -38,6 +41,7 @@ import org.nutz.lang.util.NutMap;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@IocBean(args = {"refer:dao"})
@@ -69,16 +73,13 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
*/
@Override
public FitnessWalkActivity getActivity(String activityId) {
if (StrUtil.isBlank(activityId)) {
throw new BaseException("请传递活动");
}
String redisKey = "FitnessWalk:" + activityId;
Boolean exists = redisService.exists("FitnessWalk:" + activityId);
FitnessWalkActivity activity = null;
exists = false;
if (exists) {
String string = redisService.get(redisKey);
activity = JSONUtil.toBean(string, FitnessWalkActivity.class);
activity = JSONObject.parseObject(string, FitnessWalkActivity.class);
if (Lang.isNotEmpty(activity.getRandomPics())) {
List<String> urlStr = new ArrayList<>();
for (String url : activity.getRandomPics()) {
@@ -86,7 +87,7 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
urlStr.add(tempUrl);
}
activity.setTemplateRandomPics(urlStr);
redisService.set(redisKey, JSONUtil.toJsonStr(activity));
redisService.set(redisKey, JSONObject.toJSONString(activity));
}
if (Strings.isNotBlank(activity.getCover())) {
@@ -104,9 +105,7 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
sql.append("db.collection('activity').doc('").append(activityId).append("').get()");
try {
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
activity = jsonObject.getJSONArray("data").stream()
.map(v -> JSONUtil.toBean((String) v, FitnessWalkActivity.class))
.findFirst().orElse(null);
activity = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, FitnessWalkActivity.class)).findFirst().orElse(null);
if (Lang.isNotEmpty(activity.getRandomPics())) {
List<String> urlStr = new ArrayList<>();
for (String url : activity.getRandomPics()) {
@@ -125,15 +124,14 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
activity.setTempCompletionCertificateCover(tempUrl);
}
redisService.setex(redisKey, CACHE_TIME, JSONUtil.toJsonStr(activity));
redisService.setex(redisKey, CACHE_TIME, JSONObject.toJSONString(activity));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("获取数据异常!");
}
}
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_OPERATOR.name(), RoleConstant.BRANCH_UNION_ADMIN.name())
&& !AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_OPERATOR", "BRANCH_UNION_ADMIN") && !AuthUtil.hasRoleOr("SYSADMIN")) {
return SecurityUtil.getUnionId().equals(activity.getUnionId()) ? activity : null;
}
return activity;
@@ -145,29 +143,27 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
List<FitnessWalkActivity> fitnessWalkActivities;
if (redisService.exists("FitnessWalk:ActivityList")) {
String dataString = redisService.get("FitnessWalk:ActivityList");
fitnessWalkActivities = JSONUtil.toList(dataString, FitnessWalkActivity.class);
fitnessWalkActivities = JSONObject.parseArray(dataString, FitnessWalkActivity.class);
} else {
StringBuilder sql = new StringBuilder();
sql.append("db.collection('activity').field({")
.append("masterActivityName:true,")
.append("branchActivityName:true,")
.append("relationActivityId:true,")
.append("activityModel:true,")
.append("createdAt:true,")
.append("endTime:true,")
.append("startTime:true,")
.append("unionId:true")
.append("}).orderBy('startTime', 'desc').get()");
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
fitnessWalkActivities = jsonObject.getJSONArray("data").stream()
.map(v -> JSONUtil.toBean((String) v, FitnessWalkActivity.class)).collect(Collectors.toList());
fitnessWalkActivities = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, FitnessWalkActivity.class)).collect(Collectors.toList());
}
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_OPERATOR.name(), RoleConstant.BRANCH_UNION_ADMIN.name())
&& !AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
fitnessWalkActivities = fitnessWalkActivities.stream()
.filter(v -> SecurityUtil.getUnionId().equals(v.getUnionId()))
.collect(Collectors.toList());
if (AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_OPERATOR", "BRANCH_UNION_ADMIN") && !AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
fitnessWalkActivities = fitnessWalkActivities.stream().filter(v -> SecurityUtil.getUnionId().equals(v.getUnionId())).collect(Collectors.toList());
}
redisService.set("FitnessWalk:ActivityList", JSONUtil.toJsonStr(fitnessWalkActivities));
redisService.set("FitnessWalk:ActivityList", JSONObject.toJSONString(fitnessWalkActivities));
return fitnessWalkActivities;
}
@@ -206,13 +202,15 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void addOrEditDoSaveRedis(FitnessWalkActivity activity) {
redisService.del("FitnessWalk:" + activity.get_id());
redisService.del("FitnessWalk:ActivityList");
redisService.set("FitnessWalk:" + activity.get_id(), JSONUtil.toJsonStr(activity));
redisService.set("FitnessWalk:" + activity.get_id(), JSONObject.toJSONString(activity));
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void addLotteryTask(FitnessWalkActivity fitnessWalkActivity) {
//删除和该活动关联的定时任务
List<Sys_task> oldTasks = sysTaskService.dao().query(Sys_task.class, Cnd.where("data", "like", "%" + fitnessWalkActivity.get_id() + "%"));
@@ -240,7 +238,7 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
if (CollectionUtil.isNotEmpty(cronExeTimes)) {
//调用类
String jobClass = "io.v.nutz.task.job.fitnessWalk.FitnessWalkLotteryJob";
String jobClass = "com.budwk.app.task.job.fitnesswalk.FitnessWalkLotteryJob";
HashMap<String, Object> map = new HashMap<>(5);
map.put("id", fitnessWalkActivity.get_id());
// 唯一标识的删除id,用于执行定时任务完成后,将此定时任务禁用
@@ -278,7 +276,7 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
String cron = dateFormatCron.format(lotteryTime);
try {
//调用类
String jobClass = "io.v.nutz.task.job.fitnessWalk.FitnessWalkLotteryJob";
String jobClass = "com.budwk.app.task.job.fitnesswalk.FitnessWalkLotteryJob";
HashMap<String, Object> map = new HashMap<>(8);
map.put("id", fitnessWalkActivity.get_id());
// 唯一标识的删除id,用于执行定时任务完成后,将此定时任务禁用
@@ -315,6 +313,133 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
}
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void addCreateActivityTask(FitnessWalkActivity fitnessWalkActivity) {
if (fitnessWalkActivity == null || Strings.isBlank(fitnessWalkActivity.get_id())) {
return;
}
String jobClass = "com.budwk.app.task.job.fitnesswalk.FitnessWalkAddActivityJob";
List<Sys_task> oldTasks = sysTaskService.query(Cnd.where("note", "=", fitnessWalkActivity.get_id()).and("jobClass", "=", jobClass));
DateTime todayStart = DateUtil.beginOfDay(DateUtil.date());
Set<Long> lockedTargetDateSet = new HashSet<>();
// 编辑活动时,已经执行过或已经生成过活动的历史日期不再重建,避免把旧数据重新覆盖。
for (Sys_task task : oldTasks) {
Long targetDate = getCreateTaskTargetDate(task);
if (targetDate != null && shouldKeepHistoricalCreateTask(task, targetDate, todayStart.getTime(), fitnessWalkActivity.get_id())) {
lockedTargetDateSet.add(targetDate);
continue;
}
taskPlatformService.delete(task.getId(), task.getId());
sysTaskService.delete(task.getId());
}
if (!Boolean.TRUE.equals(fitnessWalkActivity.getAutoContinuousCreate())
|| fitnessWalkActivity.getContinuousCreateDate() == null
|| fitnessWalkActivity.getContinuousCreateDate().length < 2
|| fitnessWalkActivity.getContinuousCreateDate()[0] == null
|| fitnessWalkActivity.getContinuousCreateDate()[1] == null) {
return;
}
DateTime startDate = DateUtil.beginOfDay(DateUtil.date(fitnessWalkActivity.getContinuousCreateDate()[0]));
DateTime endDate = DateUtil.beginOfDay(DateUtil.date(fitnessWalkActivity.getContinuousCreateDate()[1]));
if (startDate.isAfter(endDate)) {
return;
}
DateTime now = DateUtil.date();
for (DateTime currentDate = startDate; !currentDate.isAfter(endDate); currentDate = DateUtil.offsetDay(currentDate, 1)) {
long targetDate = currentDate.getTime();
// 今天及以前的活动日期视为历史数据;已经落地的日期和已锁定的旧任务都不再改动。
if (targetDate <= todayStart.getTime()
|| lockedTargetDateSet.contains(targetDate)
|| hasCreatedActivityForTargetDate(fitnessWalkActivity.get_id(), targetDate)) {
continue;
}
// 每个目标活动日期都在前一天 23:59 触发创建任务。
DateTime executeTime = DateUtil.endOfDay(DateUtil.offsetDay(currentDate, -1));
executeTime.setField(DateField.MINUTE, 59);
executeTime.setField(DateField.SECOND, 0);
executeTime.setField(DateField.MILLISECOND, 0);
if (!executeTime.isAfter(now)) {
continue;
}
// 每天生成一个定时任务,执行时按原活动内容复制出当天的新活动。
Map<String, Object> taskData = new HashMap<>(4);
taskData.put("sourceActivityId", fitnessWalkActivity.get_id());
taskData.put("targetDate", targetDate);
taskData.put("deleteId", R.UU32());
taskData.put("activityName", fitnessWalkActivity.getMasterActivityName());
Sys_task task = new Sys_task();
task.setName(fitnessWalkActivity.getMasterActivityName() + "自动创建活动任务");
task.setJobClass(jobClass);
// 任务说明直接保存原活动ID,便于编辑和删除活动时统一清理相关任务。
task.setNote(fitnessWalkActivity.get_id());
task.setCron(new SimpleDateFormat("ss mm HH dd MM ? yyyy").format(executeTime));
task.setData(Json.toJson(taskData));
task.setDisabled(false);
sysTaskService.insert(task);
taskPlatformService.add(task.getId(), task.getId(), task.getJobClass(), task.getCron(), task.getNote(), task.getData());
}
}
/**
* 定时任务数据里会保存目标活动日期,编辑活动时要靠这个日期判断哪些任务已经属于历史数据。
* 这里统一从任务 data 中解析 targetDate,并归一化到当天 00:00:00,避免比较时出现毫秒偏差。
*/
private Long getCreateTaskTargetDate(Sys_task task) {
if (task == null || Strings.isBlank(task.getData())) {
return null;
}
try {
JSONObject data = JSONObject.parseObject(task.getData());
Object targetDateObj = data.get("targetDate");
if (targetDateObj == null) {
return null;
}
long targetDate = targetDateObj instanceof Number
? ((Number) targetDateObj).longValue()
: Long.parseLong(String.valueOf(targetDateObj));
return DateUtil.beginOfDay(DateUtil.date(targetDate)).getTime();
} catch (Exception e) {
return null;
}
}
/**
* 编辑原活动时,已经执行过的自动创建任务和已经生成过活动的日期都要保留。
* 这样可以确保用户修改未来配置时,不会把过去已经存在的活动和任务重新删除或覆盖。
*/
private boolean shouldKeepHistoricalCreateTask(Sys_task task, long targetDate, long todayStart, String sourceActivityId) {
return task.isDisabled()
|| targetDate <= todayStart
|| hasCreatedActivityForTargetDate(sourceActivityId, targetDate);
}
/**
* 自动创建出的活动会带上来源活动ID和目标活动日期。
* 编辑原活动时通过这两个字段判断某一天的活动是否已经落地,避免重复建任务或重复建活动。
*/
private boolean hasCreatedActivityForTargetDate(String sourceActivityId, long targetDate) {
if (Strings.isBlank(sourceActivityId)) {
return false;
}
StringBuilder sql = new StringBuilder("db.collection('activity').where({autoCreateSourceActivityId:'");
sql.append(sourceActivityId)
.append("',autoCreateTargetDate:")
.append(targetDate)
.append("}).count()");
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
JSONObject pager = jsonObject.getJSONObject("pager");
return pager != null && pager.getIntValue("Total") > 0;
}
@Override
public Pagination getStepRankingPagination(PageForm pageForm, String activityId, String unionId, String unitId, String mode) {
@@ -417,7 +542,7 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
private Sql rankingListSql(String searchName, String searchKeyword, String activityId, String unionId, String unitId, String mode) {
FitnessWalkActivity activity = getActivity(activityId);
Cnd cnd = Cnd.NEW();
CndPlus cnd = CndPlus.create();
Sql sql = Sqls.create("""
SELECT
@@ -425,11 +550,11 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
COALESCE(SUM(sub.step), 0) AS total_steps,
u.username,
u.loginname,
u.unionName,
u.unitName,
u.unionname,
u.unitname,
over3k.standardsDays
FROM
`vw_user` u
`user` u
LEFT JOIN (
SELECT
userId,
@@ -483,10 +608,14 @@ public class FitnessWalkCommonServiceImpl extends BaseServiceImpl<FitnessWalkAwa
cnd.and(searchName, "LIKE", "%" + searchKeyword + "%");
}
// cnd.and("u.id","in",Sqls.create("select userId from activity_user_scope where groupId = @groupId").setParam("groupId",activity.getGroupId()));
cnd.groupBy("u.id","u.username","u.loginname","u.unionName","u.unitName","over3k.standardsDays");
cnd.groupBy("u.id","u.username","u.loginname","u.unionname","u.unitname","over3k.standardsDays");
cnd.desc("total_steps");
cnd.having(Cnd.NEW().and("COALESCE(SUM(sub.step), 0)",">",0));
sql.setCondition(cnd);
return sql;
}
}
@@ -0,0 +1,167 @@
package com.budwk.app.zhgh.activity.fitnesswalk.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivity;
import com.budwk.app.zhgh.activity.fitnesswalk.model.FitnessWalkActivityRelationProject;
import com.budwk.app.zhgh.activity.fitnesswalk.service.FitnessWalkRelationActivityCompletionService;
import com.budwk.app.zhgh.activity.fitnesswalk.utils.WeAppCloudUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 健步走关联活动完成情况实现。
* 这里统一处理“查关联活动配置 + 查当前登录人的打卡情况 + 计算是否满足达标数量”的完整流程。
*/
@IocBean(args = {"refer:dao"})
public class FitnessWalkRelationActivityCompletionServiceImpl extends BaseServiceImpl<FitnessWalkActivityRelationProject>
implements FitnessWalkRelationActivityCompletionService {
@Inject
private WeAppCloudUtil weAppCloudUtil;
public FitnessWalkRelationActivityCompletionServiceImpl(Dao dao) {
super(dao);
}
/**
* 根据关联项目ID查询当前登录人的关联活动完成情况。
* 只有当前用户在某个活动中完成了全部点位打卡,该活动才计入“已达标活动数”。
* 最终必须达到关联项目配置的 standardActivityNum,才算整体合格。
*/
@Override
public boolean isCurrentUserRelationActivityQualified(String relationActivityId,String userId) {
if (Strings.isBlank(relationActivityId)) {
throw new RuntimeException("活动关联ID不能为空");
}
if (Strings.isBlank(userId)) {
throw new RuntimeException("未获取到当前登录人");
}
FitnessWalkActivityRelationProject relationProject = dao().fetch(FitnessWalkActivityRelationProject.class,
Cnd.where("id", "=", relationActivityId));
if (relationProject == null) {
throw new RuntimeException("未找到对应的活动关联配置");
}
List<FitnessWalkActivity> relationActivityList = queryRelationActivityList(relationActivityId);
Map<String, Integer> signedPtsNumMap = queryUserSignedPtsNumMap(userId, relationActivityList);
int qualifiedActivityNum = (int) relationActivityList.stream()
.filter(activity -> isActivityCompleted(activity, signedPtsNumMap))
.count();
int standardActivityNum = relationProject.getStandardActivityNum() == null ? 0 : relationProject.getStandardActivityNum();
return qualifiedActivityNum == standardActivityNum;
}
/**
* 查询某个关联项目下的所有活动。
* 这里只取完成情况计算需要的字段,避免无关字段增加云函数返回体积。
*/
private List<FitnessWalkActivity> queryRelationActivityList(String relationActivityId) {
StringBuilder sql = new StringBuilder("db.collection('activity').where({relationActivityId:'")
.append(relationActivityId)
.append("'}).field({")
.append("_id:true,")
.append("masterActivityName:true,")
.append("branchActivityName:true,")
.append("pts:true,")
.append("relationActivityId:true")
.append("}).orderBy('createdAt','desc').limit(1000).get()");
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString());
if (jsonObject.getJSONArray("data") == null || jsonObject.getJSONArray("data").isEmpty()) {
return new ArrayList<>();
}
return jsonObject.getJSONArray("data").stream()
.map(item -> JSON.parseObject((String) item, FitnessWalkActivity.class))
.collect(Collectors.toList());
}
/**
* 按活动维度统计当前登录人在 sign 表中已打卡的点位数量。
* 这里按 pts_code 去重后再计数,避免同一点位重复打卡时把活动误判成已完成。
*/
private Map<String, Integer> queryUserSignedPtsNumMap(String userId, List<FitnessWalkActivity> relationActivityList) {
if (relationActivityList == null || relationActivityList.isEmpty()) {
return Collections.emptyMap();
}
List<String> activityIds = relationActivityList.stream()
.map(FitnessWalkActivity::get_id)
.filter(Strings::isNotBlank)
.collect(Collectors.toList());
if (activityIds.isEmpty()) {
return Collections.emptyMap();
}
StringBuilder sql = new StringBuilder("db.collection('sign').aggregate()");
sql.append(".match({userid:'").append(userId).append("',activity_id:_.in(")
.append(JSON.toJSONString(activityIds))
.append(")})");
sql.append(".group({_id:'$activity_id',signedPtsCodeSet:$.addToSet('$pts_code')})");
sql.append(".project({_id:0,activityId:'$_id',signedPtsNum:$.size('$signedPtsCodeSet')})");
sql.append(".end()");
JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, sql.toString());
if (jsonObject.getJSONArray("data") == null || jsonObject.getJSONArray("data").isEmpty()) {
return Collections.emptyMap();
}
return jsonObject.getJSONArray("data").stream().map(item -> {
JSONObject rowData = JSONObject.parseObject((String) item);
String activityId = rowData.getString("activityId");
int signedPtsNum = parseCloudNumber(rowData.get("signedPtsNum"));
return NutMap.NEW().addv("activityId", activityId).addv("signedPtsNum", signedPtsNum);
}).collect(Collectors.toMap(v -> v.getString("activityId"), v -> v.getInt("signedPtsNum")));
}
/**
* 单个活动只有在存在点位,且当前用户已完成该活动全部点位打卡时,才算这个活动达标。
*/
private boolean isActivityCompleted(FitnessWalkActivity activity, Map<String, Integer> signedPtsNumMap) {
int totalPtsNum = activity.getPts() == null ? 0 : activity.getPts().size();
int signedPtsNum = signedPtsNumMap.getOrDefault(activity.get_id(), 0);
if (signedPtsNum > totalPtsNum && totalPtsNum > 0) {
signedPtsNum = totalPtsNum;
}
return totalPtsNum > 0 && signedPtsNum >= totalPtsNum;
}
/**
* 云函数聚合返回的数字字段可能是包装对象,这里统一兼容 Integer、Long 和 {$numberInt:xx} 结构。
*/
private int parseCloudNumber(Object value) {
if (value == null) {
return 0;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) value;
if (jsonObject.containsKey("$numberInt")) {
return jsonObject.getIntValue("$numberInt");
}
if (jsonObject.containsKey("$numberLong")) {
return jsonObject.getIntValue("$numberLong");
}
}
return Integer.parseInt(String.valueOf(value));
}
}
@@ -43,14 +43,6 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
@Inject
private FitnessWalkCommonService fitnessWalkCommonService;
/**
* 获取可抽奖用户,那就是达标用户
* @param pageForm
* @param activityId
* @param unionId
* @param unitId
* @return
*/
@Override
public Sql getRaffleSql(PageForm pageForm, String activityId, String unionId, String unitId) {
FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId);
@@ -67,13 +59,13 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
COALESCE(SUM(sub.step), 0) AS total_steps,
u.loginname,
u.username,
u.unionId,
u.unionName,
u.unitId,
u.unitName,
u.unionid,
u.unionname,
u.unitid,
u.unitname,
over3k.standardsDays
FROM
`vw_user` u
`user` u
LEFT JOIN (
SELECT
userId,
@@ -134,7 +126,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
cnd.and(seg);
}
// cnd.and("u.id","in",Sqls.create("select userId from activity_user_scope where groupId = @groupId").setParam("groupId",activity.getGroupId()));
cnd.groupBy("u.id", "u.username", "u.loginname", "u.unionName", "u.unitName");
cnd.groupBy("u.id", "u.username", "u.loginname", "u.unionname", "u.unitname");
cnd.desc("total_steps");
sql.setCondition(cnd);
return sql;
@@ -142,7 +134,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
/**
* 获取活动的奖项,然后再将奖项去遍历出来
* 获取活动的奖项
* @param activityId
* @return { index: 0, name: '奖项名称', type: 0 }
*/
@@ -290,9 +282,9 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
awardUser.setStartDate(startDate);
awardUser.setEndDate(endDate);
awardUser.setUnionId(v.getString("unionid"));
awardUser.setUnionName(v.getString("unionName"));
awardUser.setUnitId(v.getString("unitId"));
awardUser.setUnitName(v.getString("unitName"));
awardUser.setUnionName(v.getString("unionname"));
awardUser.setUnitId(v.getString("unitid"));
awardUser.setUnitName(v.getString("unitname"));
awardUser.setStandardsDays(v.getInt("standardsDays"));
awardUser.setAwardSteps(v.getString("total_steps"));
awardUser.setPoints(rank.getPoints());
@@ -311,23 +303,19 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
for (FitnessWalkRaffleRules.ManualLotteryRules reach : reachList) {
List<NutMap> nutMaps;
if (reach.getIsSimultaneously() != null && reach.getIsSimultaneously()) {
// 可以兼得, 达标了的抽奖就是全部达标的人
// 可以兼得
nutMaps = list;
} else {
// 不可兼得 这里要排除其他奖项的中奖人员
// 不可兼得
nutMaps = list.stream().filter(v -> !winningRankLoginNames.contains(v.getString("loginname"))).collect(Collectors.toList());
}
// 抽奖人数
Integer lotteryUserNum = reach.getLotteryUserNum();
// 奖项名称
String awardName = reach.getAwardName();
// 这里是随机打乱了再去抽奖
List<NutMap> reachNutMaps = nutMaps.stream().collect(Collectors.collectingAndThen(Collectors.toList(), collected -> {
int size = Math.min(lotteryUserNum, collected.size());
Collections.shuffle(collected);
return collected.subList(0, size);
return collected.subList(0, lotteryUserNum - 1);
}));
List<FitnessWalkAwardUser> collect = reachNutMaps.stream().map(v -> {
@@ -341,16 +329,16 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
awardUser.setStartDate(startDate);
awardUser.setEndDate(endDate);
awardUser.setUnionId(v.getString("unionid"));
awardUser.setUnionName(v.getString("unionName"));
awardUser.setUnitId(v.getString("unitId"));
awardUser.setUnitName(v.getString("unitName"));
awardUser.setUnionName(v.getString("unionname"));
awardUser.setUnitId(v.getString("unitid"));
awardUser.setUnitName(v.getString("unitname"));
awardUser.setStandardsDays(v.getInt("standardsDays"));
awardUser.setAwardSteps(v.getString("total_steps"));
awardUser.setPoints(reach.getPoints());
return awardUser;
}).toList();
winningRankLoginNames.addAll(collect.stream().map(FitnessWalkAwardUser::getLoginName).toList());
winningRankLoginNames.addAll(collect.stream().map(FitnessWalkAwardUser::getLoginName).collect(Collectors.toList()));
winningUsers.addAll(collect);
}
@@ -358,3 +346,7 @@ public class FitnessWalkStepRaffleServiceImpl extends BaseServiceImpl<FitnessWal
dao().fastInsert(winningUsers);
}
}
@@ -2,48 +2,49 @@ package com.budwk.app.zhgh.activity.fitnesswalk.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.constant.RedisConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.nutz.http.Http;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import javax.management.RuntimeMBeanException;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
/**
* 微信小程序云开发工具类
*/
@IocBean
public class WeAppCloudUtil {
public static String ENV = "zufe-6guuuwl17ba1b011";
public static String ENV = "cloud1-d8gmetslg087dd762";
private static final String APPID = "wx093225a38487550f";
private static final String APPID = "wx34ee585f13eebc04";
private static final String APP_SECRET = "23e506ca150f342e9afdcd772cced34a";
private static final String APP_SECRET = "2e467f13e8d25a8b3f45a8d08bf286b5";
@Inject
public RedisService redisService;
public JSONObject request(CRUD crud, String sql) {
String url = crud.url.replace("ACCESS_TOKEN", getAccessToken());
String responseJson = HttpUtil.createPost(url).header("Content-Type", "application/json")
.body(JSONUtil.toJsonStr(Map.of("env", ENV, "query", sql))).execute().body();
JSONObject response = JSONUtil.parseObj(responseJson);
if (response.getInt("errcode") == 42001) {
String responseJson = HttpUtil.createPost(url).header("Content-Type", "application/json").body(JSON.toJSONString(Map.of("env", ENV, "query", sql))).execute().body();
JSONObject response = JSON.parseObject(responseJson);
if (response.getIntValue("errcode") == 42001) {
redisService.del(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN);
// request(crud, sql);
} else if (response.getInt("errcode") == 40001) {
} else if (response.getIntValue("errcode") == 40001) {
redisService.del(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN);
} else if (response.getInt("errcode") != 0) {
throw new RuntimeException("小程序云函数接口调用失败,errcode:" + response.getStr("errcode") + ",errmsg:" + response.getStr("errmsg"));
} else if (response.getIntValue("errcode") != 0) {
throw new RuntimeException("小程序云函数接口调用失败,errcode:" + response.getString("errcode") + ",errmsg:" + response.getString("errmsg"));
}
return response;
}
@@ -60,9 +61,7 @@ public class WeAppCloudUtil {
}
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", APPID).replace("APPSECRET", APP_SECRET);
String responseJson = HttpUtil.createGet(url).execute().body();
TokenResponse tokenResponse = JSONUtil.toBean(responseJson, TokenResponse.class);
// 微信的Access_token,两个小时过期,也就是7200秒
TokenResponse tokenResponse = JSON.parseObject(responseJson, TokenResponse.class);
redisService.setex(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN, 7000, tokenResponse.getAccess_token());
return tokenResponse.getAccess_token();
@@ -112,23 +111,22 @@ public class WeAppCloudUtil {
public String uploadFile(String rootPath, File file) {
String path = rootPath + file.getName();
String url = "https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN".replace("ACCESS_TOKEN", getAccessToken());
String responseJson = HttpUtil.createPost(url).header("Content-Type", "application/json")
.body(JSONUtil.toJsonStr(Map.of("env", ENV, "path", path))).execute().body();
JSONObject jsonObject = JSONUtil.parseObj(responseJson);
if (jsonObject.getInt("errcode") != 0) {
throw new RuntimeException(jsonObject.getStr("errmsg"));
String responseJson = HttpUtil.createPost(url).header("Content-Type", "application/json").body(JSON.toJSONString(Map.of("env", ENV, "path", path))).execute().body();
JSONObject jsonObject = JSON.parseObject(responseJson);
if (jsonObject.getIntValue("errcode") != 0) {
throw new RuntimeException(jsonObject.getString("errmsg"));
}
try{
HttpUtil.createPost(jsonObject.getStr("url"))
HttpUtil.createPost(jsonObject.getString("url"))
.form("key", path)
.form("Signature", jsonObject.getStr("authorization"))
.form("x-cos-security-token", jsonObject.getStr("token"))
.form("x-cos-meta-fileid", jsonObject.getStr("cos_file_id"))
.form("Signature", jsonObject.getString("authorization"))
.form("x-cos-security-token", jsonObject.getString("token"))
.form("x-cos-meta-fileid", jsonObject.getString("cos_file_id"))
.form("file", file)
.execute().body();
return jsonObject.getStr("file_id");
return jsonObject.getString("file_id");
}catch (Exception e){
return jsonObject.getStr("file_id");
return jsonObject.getString("file_id");
}
}
@@ -156,15 +154,17 @@ public class WeAppCloudUtil {
String responseJson = HttpUtil.createPost(url)
.header("Content-Type", "application/json")
.body(JSONUtil.toJsonStr(body))
.body(JSON.toJSONString(body))
.execute().body();
System.out.println(JSONUtil.toJsonStr(body));
JSONObject jsonObject = JSONUtil.parseObj(responseJson);
if (jsonObject.getInt("errcode") != 0) {
throw new RuntimeException(jsonObject.getStr("errmsg"));
System.out.println(JSON.toJSONString(body));
JSONObject jsonObject = JSON.parseObject(responseJson);
if (jsonObject.getIntValue("errcode") != 0) {
throw new RuntimeException(jsonObject.getString("errmsg"));
}
return jsonObject.getJSONArray("file_list").toList(JSONObject.class).get(0).getStr("download_url");
return jsonObject.getJSONArray("file_list").toJavaList(JSONObject.class).get(0).getString("download_url");
}
}
@@ -0,0 +1,22 @@
package com.budwk.app.zhgh.activity.fitnesswalk.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 小程序活动步数日期数据:step 表示当天步数,timestamp 表示 applyDate 对应的毫秒时间戳。
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FitnessWalkDateStepVO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer step;
private Long timestamp;
}