From 9affbf3f0420d7b4a4886b0a21fde1b0acac9e7b Mon Sep 17 00:00:00 2001 From: zhaoxinyu Date: Sun, 28 Apr 2024 16:50:47 +0800 Subject: [PATCH] condolence jug --- .../v/nutz/base/constant/RedisConstant.java | 2 + .../v/nutz/fitnessWalk/contants/Cascader.java | 12 + .../fitnessWalk/contants/FitnessWalkMode.java | 18 + ...ssWalkActivityBindingRecordController.java | 114 + .../FitnessWalkActivityManageController.java | 329 +++ ...alkActivityPersonnelStaticsController.java | 11 + .../FitnessWalkPunchStatisticsController.java | 277 +++ .../FitnessWalkStepManageController.java | 370 ++++ .../FitnessWalkStepRankingController.java | 224 ++ .../FitnessWalkStepStatisticsController.java | 156 ++ .../FitnessWalkStepWiningController.java | 116 ++ .../model/FitnessWalkActivity.java | 168 ++ .../model/FitnessWalkAwardUser.java | 76 + .../fitnessWalk/model/FitnessWalkStep.java | 45 + .../service/FitnessWalkCommonService.java | 78 + .../FitnessWalkPunchStatisticsService.java | 19 + .../impl/FitnessWalkCommonServiceImpl.java | 419 ++++ ...FitnessWalkPunchStatisticsServiceImpl.java | 241 +++ .../fitnessWalk/utils/WeAppCloudUtil.java | 164 ++ .../impl/ProposalExportServiceImpl.java | 3 +- .../fitnessWalk/FitnessWalkLotteryJob.java | 160 ++ .../task/services/TaskPlatformService.java | 10 + .../impl/TaskPlatformServiceImpl.java | 18 + .../web/commons/proc/NutShiroProcessor.java | 9 +- .../shiro/config/EasyCredentialsMatch.java | 2 +- .../static/fitness_walk_login_bg.png | Bin 0 -> 151638 bytes .../platform/fitnessWalk/activityManage.html | 1852 +++++++++++++++++ .../platform/fitnessWalk/bindingRecord.html | 287 +++ .../platform/fitnessWalk/punchStatistics.html | 262 +++ .../platform/fitnessWalk/stepRanking.html | 197 ++ .../platform/fitnessWalk/stepStatistics.html | 224 ++ .../platform/fitnessWalk/stepWining.html | 238 +++ 32 files changed, 6098 insertions(+), 3 deletions(-) create mode 100644 src/main/java/io/v/nutz/fitnessWalk/contants/Cascader.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/contants/FitnessWalkMode.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityBindingRecordController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityManageController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityPersonnelStaticsController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkPunchStatisticsController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepManageController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepRankingController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepStatisticsController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepWiningController.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkActivity.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkAwardUser.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkStep.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkCommonService.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkPunchStatisticsService.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkCommonServiceImpl.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkPunchStatisticsServiceImpl.java create mode 100644 src/main/java/io/v/nutz/fitnessWalk/utils/WeAppCloudUtil.java create mode 100644 src/main/java/io/v/nutz/task/job/fitnessWalk/FitnessWalkLotteryJob.java create mode 100644 src/main/resources/static/fitness_walk_login_bg.png create mode 100644 src/main/resources/views/platform/fitnessWalk/activityManage.html create mode 100644 src/main/resources/views/platform/fitnessWalk/bindingRecord.html create mode 100644 src/main/resources/views/platform/fitnessWalk/punchStatistics.html create mode 100644 src/main/resources/views/platform/fitnessWalk/stepRanking.html create mode 100644 src/main/resources/views/platform/fitnessWalk/stepStatistics.html create mode 100644 src/main/resources/views/platform/fitnessWalk/stepWining.html diff --git a/src/main/java/io/v/nutz/base/constant/RedisConstant.java b/src/main/java/io/v/nutz/base/constant/RedisConstant.java index b4a81f6..57788df 100644 --- a/src/main/java/io/v/nutz/base/constant/RedisConstant.java +++ b/src/main/java/io/v/nutz/base/constant/RedisConstant.java @@ -19,4 +19,6 @@ public class RedisConstant { //企业微信TOKEN public final static String REDIS_KEY_QIYE_WECHAT_ACCESS_TOKEN = "qiyewx:token:"; + //健步走小程序TOKEN + public final static String REDIS_KEY_WE_APP_ACCESS_TOKEN = "weapp:token:"; } diff --git a/src/main/java/io/v/nutz/fitnessWalk/contants/Cascader.java b/src/main/java/io/v/nutz/fitnessWalk/contants/Cascader.java new file mode 100644 index 0000000..e76df4b --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/contants/Cascader.java @@ -0,0 +1,12 @@ +package io.v.nutz.fitnessWalk.contants; + +import lombok.Data; + +import java.util.List; + +@Data +public class Cascader { + private String value; + private String label; + private List children; +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/contants/FitnessWalkMode.java b/src/main/java/io/v/nutz/fitnessWalk/contants/FitnessWalkMode.java new file mode 100644 index 0000000..66de9ee --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/contants/FitnessWalkMode.java @@ -0,0 +1,18 @@ +package io.v.nutz.fitnessWalk.contants; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum FitnessWalkMode { + + PUNCH("punch", "打卡"), + STEP_COUNT("stepCount", "计步"), + GPS("gps", "GPS"); + + + private final String value; + private final String desc; + +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityBindingRecordController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityBindingRecordController.java new file mode 100644 index 0000000..7bf9c5c --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityBindingRecordController.java @@ -0,0 +1,114 @@ +package io.v.nutz.fitnessWalk.controller; + +import cn.hutool.core.util.StrUtil; +import cn.wizzer.framework.base.Result; +import cn.wizzer.framework.page.Pagination; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.utils.Vi; +import io.v.nutz.base.utils.WxHttpUtil; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.web.commons.utils.ShiroUtil; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +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 java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@IocBean +@Ok("json") +@At("/platform/fitnessWalk/bindingRecord") +public class FitnessWalkActivityBindingRecordController { + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Inject + private WxHttpUtil wxHttpUtil; + + @At("") + @Ok("beetl:/platform/fitnessWalk/bindingRecord.html") + @RequiresPermissions("fitnessWalk.bindingRecord") + public void index() { + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.bindingRecord") + public Object pageData(@Param(value = "keyWord",required = false) String keyWord, + @Param(value = "unionId",required = false) String unionId, + @Param(value = "searchName",required = false) String searchName, + @Param(value = "searchKeyword",required = false) String searchKeyword, + @Param("pageNumber") int pageNumber,@Param("pageSize") int pageSize, + @Param(value = "pageOrderName",required = false) String pageOrderName, + @Param(value = "pageOrderBy",required = false) String pageOrderBy) throws IOException { + int skip = (pageNumber == 1 ? 0 : (pageNumber - 1)) * pageSize; + + StringBuilder sql = new StringBuilder("db.collection('login_record')"); + if (StrUtil.isNotBlank(keyWord)) { + sql.append(".where("); + sql.append("_.or(["); + sql.append("{loginname:{$regex:'").append(keyWord).append("',$options:'i'}},"); + sql.append("{username:{$regex:'").append(keyWord).append("',$options:'i'}}"); + sql.append("])"); + sql.append(")"); + } + if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) { + sql.append(".where({'data.unionid':'").append(Vi.getUnionId()).append("'})"); + } else { + if (Strings.isNotBlank(unionId)) sql.append(".where({'data.unionid':'").append(unionId).append("'})"); + } + sql.append(".field({ data: false })"); + sql.append(".skip(").append(skip).append(")"); + sql.append(".limit(").append(pageSize).append(")"); + sql.append(".get()"); + + try { + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString()); + List data = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, NutMap.class)).collect(Collectors.toList()); + JSONObject pager = jsonObject.getJSONObject("pager"); + return new Pagination(pageNumber, pageSize, pager.getIntValue("Total"), data); + } catch (Exception e){ + return Result.error(e.getMessage()); + } + } + + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.bindingRecord") + public Object delete(String[] ids) throws IOException { + 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(); + } + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.bindingRecord") + public Object deleteAll() { + 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(); + } + } + + +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityManageController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityManageController.java new file mode 100644 index 0000000..fe3fba2 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityManageController.java @@ -0,0 +1,329 @@ +package io.v.nutz.fitnessWalk.controller; + +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.wizzer.framework.base.Result; +import cn.wizzer.framework.page.Pagination; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.utils.Vi; +import io.v.nutz.base.utils.WxHttpUtil; +import io.v.nutz.fitnessWalk.model.FitnessWalkActivity; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.sys.models.Sys_task; +import io.v.nutz.sys.services.SysTaskService; +import io.v.nutz.sys.services.SysUserService; +import io.v.nutz.task.services.TaskPlatformService; +import io.v.nutz.web.commons.utils.ShiroUtil; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.dao.Cnd; +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.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 java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +@At("/platform/fitnessWalk/activityManage") +@Ok("json") +@IocBean +public class FitnessWalkActivityManageController { + private static final Log log = Logs.get(); + @Inject + private WxHttpUtil wxHttpUtil; + @Inject + private WeAppCloudUtil weAppCloudUtil; + @Inject + private TaskPlatformService taskPlatformService; + @Inject + private SysTaskService sysTaskService; + @Inject + private SysUserService sysUserService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + @At("") + @Ok("beetl:/platform/fitnessWalk/activityManage.html") + @RequiresPermissions("fitnessWalk.activityManage") + public void index() { + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.activityManage") + public Object pageData(@Param(value = "year", required = false) Integer year, @Param(value = "unionId", required = false) String unionId, @Param(value = "searchName", required = false) String searchName, @Param(value = "searchKeyword", required = false) String searchKeyword, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param(value = "pageOrderName", required = true) String pageOrderName, @Param(value = "pageOrderBy", required = false) String pageOrderBy) { + + int skip = (pageNumber == 1 ? 0 : (pageNumber - 1)) * pageSize; + + StringBuilder sql = new StringBuilder("db.collection('activity')"); + if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) { + sql.append("where("); + sql.append("_.or(["); + sql.append("{name:{$regex:'").append(searchKeyword).append("',$options:'i'}}"); + sql.append("{tag:{$regex:'").append(searchKeyword).append("',$options:'i'}}"); + sql.append("])"); + sql.append(")"); + } + if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) { + sql.append(".where({unionId:'").append(Vi.getUnionId()).append("'})"); + } else if (StrUtil.isNotBlank(unionId)) { + sql.append(".where({unionId:'").append(unionId).append("'})"); + } + sql.append(".skip(").append(skip).append(")"); + sql.append(".limit(").append(pageSize).append(")"); + sql.append(".get()"); + try { + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString()); + List data = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, FitnessWalkActivity.class)).collect(Collectors.toList()); + JSONObject pager = jsonObject.getJSONObject("pager"); + return new Pagination(pageNumber, pageSize, pager.getIntValue("Total"), data); + } catch (Exception e) { + return Result.error(e.getMessage()); + } + + } + + + @At + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + @RequiresPermissions("fitnessWalk.activityManage") + public Object doAdd(String data, @Param("fitnessWalkActivity") FitnessWalkActivity fitnessWalkActivity, + @Param("file") TempFile tempFile, + @Param("stepFiles") TempFile[] stepFiles, + @Param(value = "certificateFile", required = false) TempFile certificateTempFile) { + try { + //设置时间 + if ("punch".equals(fitnessWalkActivity.getActivityModel())) { + fitnessWalkActivity.setApplyStartTime(fitnessWalkActivity.getApplyTime()[0]); + fitnessWalkActivity.setApplyEndTime(fitnessWalkActivity.getApplyTime()[1]); + } + fitnessWalkActivity.setStartTime(fitnessWalkActivity.getTime()[0]); + fitnessWalkActivity.setEndTime(fitnessWalkActivity.getTime()[1]); + + if (tempFile != null) { + String fileId = weAppCloudUtil.uploadFile("activity/", tempFile.getFile()); + fitnessWalkActivity.setCover(fileId); + } + + if (Lang.isNotEmpty(stepFiles)) { + List stepFileIdList = new ArrayList<>(); + for (TempFile file : stepFiles) { + String fileId = weAppCloudUtil.uploadFile("activity/", file.getFile()); + stepFileIdList.add(fileId); + } + fitnessWalkActivity.setRandomPics(stepFileIdList); + } + + if (certificateTempFile != null) { + String fileId = weAppCloudUtil.uploadFile("activity/", certificateTempFile.getFile()); + fitnessWalkActivity.setCompletionCertificateCover(fileId); + } + + if (ShiroUtil.hasRole("H04") && !ShiroUtil.hasAnyRoles("sysadmin,SchoolUnionAdmin,SchoolUnionFitnessWalkAdmin,A06")) { + fitnessWalkActivity.setUnionId(Vi.getUnionId()); + } else { + fitnessWalkActivity.setUnionId(""); + } + + fitnessWalkActivity.setNote(fitnessWalkActivity.getNote().replace("\"", "'")); + StringBuilder sql = new StringBuilder(); + sql.append("db.collection('activity').add({data:").append(Json.toJson(fitnessWalkActivity)).append("})"); + + try { + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.INSERT, sql.toString()); + fitnessWalkCommonService.addLotteryTask(fitnessWalkActivity); + fitnessWalkCommonService.addOrEditDoSaveRedis(fitnessWalkActivity, true); + return Result.success(); + } catch (Exception e) { + return Result.error(e.getMessage()); + } + } catch (Exception e) { + e.printStackTrace(); + return Result.error(); + } + } + + + @At + @Ok("json:full") + @RequiresPermissions("fitnessWalk.activityManage") + public Result findOne(String id) { + return Result.success(fitnessWalkCommonService.getActivity(id)); + } + + @At + @Ok("json") + @RequiresPermissions("fitnessWalk.activityManage") + public Object getFile(String pic) { + try { + NutMap res = NutMap.NEW(); + String imgurl = weAppCloudUtil.httpFile(pic); + HashMap imgmap = new HashMap<>(); + imgmap.put("status", "success"); + imgmap.put("name", imgurl.substring(imgurl.lastIndexOf("/") + 1)); + imgmap.put("id", imgurl); + imgmap.put("url", imgurl); + res.setv("img", imgmap); + return Result.success().addData(res); + } catch (Exception e) { + return Result.error(); + } + } + + + @At + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + @RequiresPermissions("fitnessWalk.activityManage") + public Result doEdit(@Param("fitnessWalkActivity") FitnessWalkActivity fitnessWalkActivity, + @Param(value = "file", required = false) TempFile tempFile, + @Param("stepFiles") TempFile[] stepFiles, + @Param(value = "certificateFile", required = false) TempFile certificateTempFile) { + //设置时间 + if ("punch".equals(fitnessWalkActivity.getActivityModel())) { + fitnessWalkActivity.setApplyStartTime(fitnessWalkActivity.getApplyTime()[0]); + fitnessWalkActivity.setApplyEndTime(fitnessWalkActivity.getApplyTime()[1]); + } + fitnessWalkActivity.setStartTime(fitnessWalkActivity.getTime()[0]); + fitnessWalkActivity.setEndTime(fitnessWalkActivity.getTime()[1]); + + if (tempFile != null) { + String fileId = weAppCloudUtil.uploadFile("activity/", tempFile.getFile()); + fitnessWalkActivity.setCover(fileId); + } + + if (Lang.isNotEmpty(stepFiles)) { + List stepFileIdList = new ArrayList<>(); + for (TempFile file : stepFiles) { + String fileId = weAppCloudUtil.uploadFile("activity/", file.getFile()); + stepFileIdList.add(fileId); + } + fitnessWalkActivity.setRandomPics(stepFileIdList); + } + + if (certificateTempFile != null) { + String fileId = weAppCloudUtil.uploadFile("activity/", certificateTempFile.getFile()); + fitnessWalkActivity.setCompletionCertificateCover(fileId); + } + + + if (ShiroUtil.hasRole("H04") && !ShiroUtil.hasAnyRoles("sysadmin,SchoolUnionAdmin,SchoolUnionFitnessWalkAdmin,A06")) { + fitnessWalkActivity.setUnionId(Vi.getUnionId()); + } else { + fitnessWalkActivity.setUnionId(""); + } + + fitnessWalkActivity.setNote(fitnessWalkActivity.getNote().replace("\"", "'")); + + StringBuilder sql = new StringBuilder(); + sql.append("db.collection('activity').doc('") + .append(fitnessWalkActivity.get_id()) + .append("').update({data:").append(Json.toJson(fitnessWalkActivity)).append("})"); + + try { + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.UPDATE, sql.toString()); + fitnessWalkCommonService.addLotteryTask(fitnessWalkActivity); + fitnessWalkCommonService.addOrEditDoSaveRedis(fitnessWalkActivity, false); + return Result.success(); + } catch (Exception e) { + return Result.error(e.getMessage()); + } + } + + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.activityManage") + public Object delete(String id) { + try { + weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, "db.collection('activity').doc('" + id + "').remove()"); + weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, "db.collection('register').where({activity_id:'" + id + "'}).remove()"); + weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, "db.collection('sign').where({activity_id:'" + id + "'}).remove()"); + weAppCloudUtil.request(WeAppCloudUtil.CRUD.DELETE, "db.collection('gift_voucher').where({activity_id:'" + id + "'}).remove()"); + + List sys_tasks = sysTaskService.query(Cnd.where("note", "=", id)); + if (sys_tasks != null) { + sys_tasks.forEach(v -> { + taskPlatformService.delete(v.getId(), v.getId()); + sysTaskService.delete(v.getId()); + }); + + } + return Result.success(); + } catch (Exception e) { + return Result.error(); + } + } + + /** + * 健身走健步模式通知提醒 + * + * @param map + */ + private void addNotifyTask(NutMap map) { + if (map.getBoolean("sendNotify")) { + String id = map.getString("_id"); + String name = map.getString("name"); + String groupId = map.getString("groupId"); + + //提醒频率 + int notifyGap = 10; + + List sys_tasks = sysTaskService.query(Cnd.where("note", "=", id)); + if (Lang.isNotEmpty(sys_tasks)) { + sys_tasks.forEach(v -> { + taskPlatformService.delete(v.getId(), v.getId()); + sysTaskService.delete(v.getId()); + }); + } + + DateTime startTime = DateUtil.date(map.getLong("start_time")); + DateTime endTime = DateUtil.date(map.getLong("end_time")); + + Set result = new HashSet<>(); + DateTime offsetDay = DateUtil.offsetDay(startTime, notifyGap); + while (offsetDay.isBefore(endTime) && offsetDay.isAfter(new Date())) { + result.add(offsetDay); + offsetDay = DateUtil.offsetDay(offsetDay, notifyGap); + } + //活动结束前一天再添加一个日期提醒 + result.add(DateUtil.offsetDay(endTime, -1)); + + for (DateTime dateTime : result) { + 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.setData(Json.toJson(Map.of("groupId", groupId))); + sys_task.setDisabled(false); + + String dateFormat = "ss mm HH dd MM ? yyyy"; + SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); + String corn = sdf.format(dateTime); + sys_task.setCron(corn); + + sysTaskService.insert(sys_task); + + taskPlatformService.add(sys_task.getId(), sys_task.getId(), sys_task.getJobClass(), sys_task.getCron(), sys_task.getNote(), sys_task.getData()); + } + } + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityPersonnelStaticsController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityPersonnelStaticsController.java new file mode 100644 index 0000000..7608299 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkActivityPersonnelStaticsController.java @@ -0,0 +1,11 @@ +package io.v.nutz.fitnessWalk.controller; + +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +@IocBean +@Ok("json") +@At("/platform/fitnessWalk/personnelStatics") +public class FitnessWalkActivityPersonnelStaticsController { +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkPunchStatisticsController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkPunchStatisticsController.java new file mode 100644 index 0000000..cb81984 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkPunchStatisticsController.java @@ -0,0 +1,277 @@ +package io.v.nutz.fitnessWalk.controller; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +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 cn.wizzer.framework.base.Result; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.service.BaseService; +import io.v.nutz.base.utils.Vi; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.fitnessWalk.service.FitnessWalkPunchStatisticsService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.sys.models.Sys_union; +import io.v.nutz.util.ViTool; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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; +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") +@At("/platform/fitnessWalk/punchStatistics") +public class FitnessWalkPunchStatisticsController { + + @Inject + private Dao dao; + + @Inject + private BaseService baseService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Inject + private FitnessWalkPunchStatisticsService fitnessWalkPunchStatisticsService; + + @At("") + @Ok("beetl:/platform/fitnessWalk/punchStatistics.html") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void index() { + } + + /** + * 分工会统计 + * + * @param activityId + * @param unionId + * @return + */ + @At + @Ok("json:full") + @RequiresPermissions("fitnessWalk.punchStatistics") + public Result pageData(String activityId, String unionId) { + List list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(activityId, unionId); + return Result.success(list); + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.punchStatistics") + public Object getCascadersActivity(@Param(value = "year") int year) { + return fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.PUNCH); + } + + @At + @Ok("json:full") + @RequiresPermissions("fitnessWalk.punchStatistics") + public Result unionRegistrationData(String activityId, String unionId) { + List list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId); + return Result.success(list); + } + + @At + @Ok("json:full") + @RequiresPermissions("fitnessWalk.punchStatistics") + public Result unionCheckInData(String activityId, String unionId) { + List list = fitnessWalkPunchStatisticsService.unionCheckInData(activityId, unionId); + return Result.success(list); + } + + /** + * 导出各分工会报名人数、打卡人数 + * + * @param activityId + */ + @At + @Ok("void") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void exportUnionRegCheckInNum(HttpServletResponse response, String activityId) { + List list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(activityId, null); + List entities = new ArrayList<>(); + entities.add(new ExcelExportEntity("分工会", "unionname", 20)); + entities.add(new ExcelExportEntity("报名人数", "regCount", 20)); + entities.add(new ExcelExportEntity("打卡人数", "checkInCount", 20)); + + try { + ViTool.excelResponse(response, "各分工会统计人数.xlsx"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 导出某个分工会的报名人员 + * + * @param response + * @param activityId + * @param unionId + */ + @At + @Ok("void") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void exportRegUsers(HttpServletResponse response, String activityId, String unionId) { + Sys_union union = dao.fetch(Sys_union.class, unionId); + String unionName = Optional.ofNullable(union).map(Sys_union::getUnionname).orElse(null); + + List list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId); + List 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("报名时间", "register_time_str", 20)); + + try { + ViTool.excelResponse(response, unionName + "分工会报名人员.xlsx"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 导出某个分工会的打卡人员 + * + * @param response + * @param activityId + * @param unionId + */ + @At + @Ok("void") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void exportCheckInUsers(HttpServletResponse response, String activityId, String unionId) { + Sys_union union = dao.fetch(Sys_union.class, unionId); + String unionName = Optional.ofNullable(union).map(Sys_union::getUnionname).orElse(null); + + List list = fitnessWalkPunchStatisticsService.unionCheckInData(activityId, unionId); + + for (JSONObject jsonObject : list) { + Boolean used = jsonObject.getBoolean("used"); + if (used == null) { + jsonObject.put("used", "未取得"); + } else if (used) { + jsonObject.put("used", "已领取"); + } else { + jsonObject.put("used", "未领取"); + } + } + + List 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("点位总数", "pts_size", 20)); + entities.add(new ExcelExportEntity("已打卡点位数", "sign_size", 20)); + entities.add(new ExcelExportEntity("礼品券", "used", 20)); + + try { + ViTool.excelResponse(response, unionName + "分工会打卡人员.xlsx"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +// /** +// * 导出礼品领取情况 +// * @param response +// * @param activityId +// * @param unionId 工会id +// * @param used +// */ +// @At +// @Ok("void") +// public void exportGiftInfo(HttpServletResponse response, String activityId, String unionId, boolean used) { +// +// +// +// } + + + /** + * 未领取得奖品券用户 + * + * @param response + * @param activityId + */ + @At + @Ok("void") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void exportNotGetGiftVoucherUsers(HttpServletResponse response, String activityId) { + List list = fitnessWalkPunchStatisticsService.exportNotGetGiftVoucherUsers(activityId); + List 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)); + try { + ViTool.excelResponse(response, "未领取得奖品券人员.xlsx"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 未使用奖品券用户 + * + * @param response + * @param activityId + */ + @At + @Ok("void") + @RequiresPermissions("fitnessWalk.punchStatistics") + public void exportNotUseGiftVoucherUsers(HttpServletResponse response, String activityId) { + List list = fitnessWalkPunchStatisticsService.exportNotUseGiftVoucherUsers(activityId); + List 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)); + try { + ViTool.excelResponse(response, "导出未使用礼品券用户.xlsx"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepManageController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepManageController.java new file mode 100644 index 0000000..91e3ded --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepManageController.java @@ -0,0 +1,370 @@ +package io.v.nutz.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 cn.wizzer.framework.base.Result; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.page.Pagination; +import io.v.nutz.base.service.BaseService; +import io.v.nutz.fitnessWalk.model.FitnessWalkActivity; +import io.v.nutz.fitnessWalk.model.FitnessWalkAwardUser; +import io.v.nutz.fitnessWalk.model.FitnessWalkStep; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.integration.jedis.RedisService; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; + +@IocBean +@Ok("json") +@At("/platform/fitnessWalk/stepManage") +public class FitnessWalkStepManageController { + + @Inject + private BaseService baseService; + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Inject + private RedisService redisService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + + /** + * 用户上传一个近31天的步数 + * + * @param activityId 活动id + * @param userId 用户id + * @param monthSteps 步数(当天往前推30天) + * @param start_time 活动开始时间 + * @param end_time 结束时间 + * @return + */ + @At + @Ok("json:full") + @ViReturn + @Aop(TransAop.READ_COMMITTED) + public Object updateStepMonth(String activityId, String userId, String monthSteps, Long start_time, Long end_time) { + if (StrUtil.isBlank(userId)) { + return Result.error("上传步数失败,请重新登录后再次上传!"); + } + + DateTime activityStartDate = DateUtil.date(start_time); + DateTime activityEndDate = DateUtil.date(end_time); + + List steps = Json.fromJsonAsList(NutMap.class, monthSteps); + + /*//前一个月的时间 + DateTime dateTime = DateUtil.offsetMonth(new Date(), -1); + String format = DateUtil.format(dateTime, "yyyyMM"); + + //上一个月的步数 + List lastMonthSteps = steps.stream().filter(v -> { + long timestamp = v.getLong("timestamp") * 1000; + String userStep = DateUtil.format(DateUtil.date(timestamp), "yyyyMM"); + return userStep.equals(format); + }).collect(Collectors.toList()); + + List lastMonthInsertWxSteps = steps.stream().map(v -> { + FitnessWalkStep step = new FitnessWalkStep(); + step.setActivityId(activityId); + step.setUserId(userId); + step.setStep(v.getInt("step")); + DateTime date = DateUtil.date(v.getLong("timestamp") * 1000); + step.setApplyDate(date); + return step; + }).collect(Collectors.toList()); + List applyDates = lastMonthInsertWxSteps.stream().map(v -> v.getApplyDate()).collect(Collectors.toList()); + + applyDates.remove(applyDates.stream().min(Date::compareTo).orElse(null)); + + System.out.println(lastMonthInsertWxSteps.size()); + System.out.println(applyDates.size()); + System.out.println(Json.toJson(applyDates)); + + baseService.dao().clear("fitness_walk_step_" + format, Cnd.where("activityId", "=", activityId).and("userId", "=", userId).and("applyDate", "in", applyDates)); +// baseService.dao().insert("fitness_walk_step_" + format,lastMonthInsertWxSteps); + + + //本月步数 + List thisMonthSteps = (List) CollectionUtil.subtract(steps,lastMonthSteps);*/ + + //判断数据是否完整 微信运动会在晚上10点多进行步数的更新 会导致31天前的步数获取变为0 所以这里去除掉第一个元素 即为31天前的数据 每次只保存最近30天的数据 + if (Lang.isNotEmpty(steps) && steps.size() == 31) { + steps.remove(0); + } + + //如果在活动开始之前进来了 就只保存近7天的数据 不然前台展示为空 不好看 + List insertWxSteps = steps.stream().map(v -> { + FitnessWalkStep step = new FitnessWalkStep(); + step.setActivityId(activityId); + step.setUserId(userId); + step.setStep(v.getInt("step")); + DateTime date = DateUtil.date(v.getLong("timestamp") * 1000); + step.setApplyDate(date); + return step; + }).collect(Collectors.toList()); + //.filter(v -> v.getApplyDate().compareTo(DateUtil.offsetDay(activityStartDate, -7)) >= 0 && v.getApplyDate().compareTo(activityEndDate) <= 0).collect(Collectors.toList()); + //.filter(v -> (v.getApplyDate().compareTo(activityStartDate) >= 0) && (v.getApplyDate().compareTo(activityEndDate) <= 0)).collect(Collectors.toList()); + List applyDates = insertWxSteps.stream().map(v -> v.getApplyDate()).collect(Collectors.toList()); + + applyDates.remove(applyDates.stream().min(Date::compareTo).orElse(null)); + + System.out.println(insertWxSteps.size()); + System.out.println(applyDates.size()); + System.out.println(Json.toJson(applyDates)); + + baseService.dao().clear(FitnessWalkStep.class, Cnd.where("activityId", "=", activityId).and("userId", "=", userId).and("applyDate", "in", applyDates)); + baseService.dao().insert(insertWxSteps); + return null; + } + + + /** + * 小程序获取开始时间至今的步数 + * + * @param activityId + * @param userId + * @return + */ + @At + @Ok("json:full") + @ViReturn + public Object getActivityDateStep(String activityId, String userId) { + try { + //查询Redis中是否有该用户的步数数据 +// String userRedisKey = activityId + userId; +// +// StringBuilder sql = new StringBuilder(); +// sql.append("db.collection('activity').doc('").append(activityId).append("').get()"); +// +// JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.QUERY, sql.toString()); +// FitnessWalkActivity data = jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v, FitnessWalkActivity.class)).findFirst().orElse(null); +// +// Map map = new HashMap<>(); +// List userStepList = new ArrayList<>(); +// List dateList = new ArrayList<>(); +// + Cnd cnd = Cnd.NEW(); +// if (redisService.exists(userRedisKey)) { +// String redisValue = redisService.get(userRedisKey); +// JSONObject parsedObject = JSONObject.parseObject(redisValue); +// dateList = parsedObject.getObject("x", List.class); +// userStepList = parsedObject.getObject("y", List.class); +// +// Long redisMaxTime = dateList.get(dateList.size() - 1); +// DateTime startDate = DateUtil.date(redisMaxTime); +// +// cnd.and("DATE(applyDate)",">=",DateUtil.format(startDate, "yyyy-MM-dd")); +// cnd.and("DATE(applyDate)","<=",DateUtil.format(new Date(), "yyyy-MM-dd")); +// +// dateList.remove(dateList.size() - 1); +// userStepList.remove(userStepList.size() - 1); +// +// } else { +// assert data != null; +// DateTime startDate = DateUtil.date(data.getStartTime()); +// DateTime endDate = DateUtil.date(data.getEndTime()); +// +// cnd.and("DATE(applyDate)",">=",DateUtil.format(startDate, "yyyy-MM-dd")); +// cnd.and("DATE(applyDate)","<=",DateUtil.format(endDate, "yyyy-MM-dd")); +// } + FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId); + DateTime startTime = DateUtil.date(activity.getStartTime()); + DateTime endTime = DateUtil.date(activity.getEndTime()); + + cnd.and("activityId", "=", activityId); + cnd.and("userId", "=", userId); + cnd.and("applyDate", ">=", startTime); + cnd.and("applyDate", "<=", endTime); + cnd.asc("applyDate"); + cnd.groupBy("applyDate"); + List stepList = baseService.dao().query(FitnessWalkStep.class, cnd); + + return stepList.stream().map(v -> { + return Map.of("step", v.getStep(), "timestamp", v.getApplyDate().getTime()/1000); + }).collect(Collectors.toList()); + + // userStepList.addAll(stepList.stream().map(FitnessWalkStep::getStep).collect(Collectors.toList())); +// dateList.addAll(stepList.stream().map(v -> v.getApplyDate().getTime()).collect(Collectors.toList())); +// +// map.put("x", dateList); +// map.put("y", userStepList); +// redisService.set(userRedisKey,JSONObject.toJSONString(map)); + +// return map; + + + } catch (Exception e) { + return Result.error(e.getMessage()); + } + } + + @At + @Ok("json:full") + @ViReturn + public Object getActivityQualifyProgressBar(String activityId, String userId) { + NutMap resultMap = NutMap.NEW(); + + FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId); + //计步的抽奖模式 everyday custom + String lotteryMode = activity.getLotteryMode(); + if ("everyday".equals(lotteryMode)) { + FitnessWalkActivity.DayLotteryRule dayLotteryRule = activity.getDayLotteryRule(); + //每日抽奖资格步数 + Integer lotteryQualificationStep = dayLotteryRule.getLotteryQualificationStep(); + + FitnessWalkStep userWalkStep = baseService.dao().fetch(FitnessWalkStep.class, Cnd.where("userId", "=", userId) + .and("DATE( applyDate )", "=", DateUtil.today()).and("activityId", "=", activityId)); + + int complianceDay = baseService.dao().count(FitnessWalkStep.class, Cnd.where("userId", "=", userId) + .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("#.##"); // 格式化为两位小数 + //百分数 + String formattedPercent = decimalFormat.format(percentValue); + + long betweenDay = DateUtil.date(activity.getStartTime()).between(DateUtil.date(activity.getEndTime()), DateUnit.DAY); + NutMap map = new NutMap(); + map.setv("mode", "everyDayLottery"); + //当前达标步数 + map.setv("userStep", thisDayStep); + //达标总步数 + map.setv("complianceSumStep", lotteryQualificationStep); + //达标比例 + map.setv("complianceProportion", Integer.parseInt(formattedPercent)); + //活动天数 + map.setv("betweenDay", betweenDay); + //达标天数 + map.setv("complianceDay", complianceDay); + resultMap.addv("everyDayLotteryMode", map); + } else if ("custom".equals(lotteryMode)) { + List customLotteryRules = activity.getCustomLotteryRules(); + List userWalkSteps = baseService.dao(). + query(FitnessWalkStep.class, Cnd.where("userId", "=", userId) + .and("activityId", "=", activityId) + .and("DATE(applyDate)", ">=", DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd")) + .and("DATE(applyDate)", "<=", DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd")) + ); + + List result = new ArrayList<>(); + + for (FitnessWalkActivity.CustomLotteryRule rule : customLotteryRules) { + NutMap nutMap = NutMap.NEW(); + + List partSteps = userWalkSteps.stream() + .filter(s -> (DateUtil.compare(s.getApplyDate(), rule.getStartDate()) >= 0 && DateUtil.compare(s.getApplyDate(), rule.getEndDate()) <= 0)) + .collect(Collectors.toList()); + + Integer lotteryQualificationDay = rule.getLotteryQualificationDay(); + Integer lotteryQualificationStep = rule.getLotteryQualificationStep(); + + if (lotteryQualificationDay != null && lotteryQualificationStep != null) { + //每天步数 + nutMap.put("mode", "customLotteryEveryDayStepMode"); + //用户总达标步数 + nutMap.put("userSumStep", partSteps.stream().filter(s -> DateUtil.compare(s.getApplyDate(), new Date(), "yyyy-MM-dd") == 0).findFirst().map(s -> s.getStep()).orElse(0)); + //今天达标步数 + nutMap.put("complianceStep", lotteryQualificationStep); + //总达标步数 + nutMap.put("complianceSumStep", lotteryQualificationDay * lotteryQualificationStep); + //用户当前达标总天数 + nutMap.put("userComplianceSumDay", partSteps.stream().filter(s -> s.getStep() > lotteryQualificationStep).count()); + //总达标天数 + nutMap.put("complianceSumDay", lotteryQualificationDay); + } else if (lotteryQualificationDay == null && lotteryQualificationStep != null) { + //总步数 + nutMap.put("mode", "customLotterySumStepMode"); + //用户总达标步数 + nutMap.put("userSumStep", partSteps.stream().mapToInt(s -> s.getStep()).sum()); + //总达标步数 + nutMap.put("complianceSumStep", lotteryQualificationStep); + + nutMap.put("title", DateUtil.format(rule.getStartDate(), "MM月dd日") + "至" + DateUtil.format(rule.getEndDate(), "MM月dd日")); + + } + result.add(nutMap); + } + resultMap.addv("customLotteryMode", result); + } + return resultMap; + } + + /** + * 获取用户未读的奖 + * + * @param activityId + * @param userId + * @return + */ + @At + @Ok("json:full") + public Result winningRecord(String activityId, String userId) { + List awardUsers = baseService.dao().query(FitnessWalkAwardUser.class, + Cnd.where("activityId", "=", activityId) + .and("userId", "=", userId)); + baseService.dao().update(FitnessWalkAwardUser.class, Chain.make("isRead", 1), + Cnd.where("activityId", "=", activityId) + .and("userId", "=", userId)); + return Result.success(awardUsers); + } + + @At + @Ok("json:full") + public Result hasReadAward(String activityId) { + return Result.success(); + } + + @At + @Ok("json:full") + public Result qualifiedProgress(String activityId, String userId) { + FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId); + int count = baseService.dao(). + count(FitnessWalkStep.class, Cnd.where("userId", "=", userId) + .and("activityId", "=", activityId) + .and("DATE(applyDate)", ">=", DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd")) + .and("DATE(applyDate)", "<=", DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd")) + .and("step", ">=", 6000) + ); + + Long startTime = activity.getStartTime(); + Long endTime = activity.getEndTime(); + long sumCount = DateUtil.betweenDay(DateUtil.date(startTime), DateUtil.date(endTime), true); + return Result.success(Map.of("day", count, "sumDay", sumCount, "percentage", Math.round((float) count / sumCount * 100))); + } + +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepRankingController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepRankingController.java new file mode 100644 index 0000000..647d43c --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepRankingController.java @@ -0,0 +1,224 @@ +package io.v.nutz.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.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.service.BaseService; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.model.FitnessWalkActivity; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.modules.models.PageForm; +import io.v.nutz.sys.models.Sys_user; +import io.v.nutz.util.ViTool; +import io.v.nutz.web.commons.slog.annotation.SLog; +import io.v.nutz.web.commons.utils.ShiroUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 步数排行榜 + */ + +@IocBean +@Slf4j +@Ok("json") +@At("/platform/fitnessWalk/stepRanking") +public class FitnessWalkStepRankingController { + + @Inject + private BaseService baseService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + @At("") + @Ok("beetl:/platform/fitnessWalk/stepRanking.html") + @RequiresPermissions("fitnessWalk.stepRanking") + public void index() { + } + + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.stepRanking") + @SLog(type = "健身走", tag = "步数排行榜", msg = "获取排行榜", param = true, result = true) + public Object pageData(PageForm pageForm, + @Param(value = "activityId", required = false) String activityId, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId, + @Param(value = "mode", required = false) String mode) { + return fitnessWalkCommonService.getStepRankingPagination(pageForm, activityId, unionId, unitId, mode); + } + + + /** + * 获取所有教工 今天的步数及活动时间范围内的步数 + * + * @param activityId + * @param mode day:今天 all:所有 + * @return {@link Object} + */ + @At + @Ok("json:full") + @ViReturn +// @SLog(type = "校工会特色活动",tag = "健身走-计步步数排行榜",msg = "小程序接口(获取今日步数及活动范围内步数)",param = true,result = true) + public Object getUserStepRanking(String activityId, String mode, Integer pageNumber, Integer pageSize) { + if (mode.equals("day")) { + Sql sql = Sqls.create(""" + SELECT + t.step, + t.applyDate, + u.username + FROM + `fitness_walk_step` t + LEFT JOIN sys_user u ON u.id = t.userId\s + WHERE + t.activityId = @activityId + AND t.applyDate = @today + ORDER BY t.step DESC + """); + sql.setParam("activityId", activityId); + sql.setParam("today", DateUtil.today()); + return baseService.listPageMap(pageNumber, pageSize, sql); + }else if(mode.equals("week")){ + Date startOfWeek = DateUtil.beginOfWeek(new Date()); + Date endOfWeek = DateUtil.endOfWeek(new Date()); + + Sql sql = Sqls.create(""" + SELECT + t.userId, + sum( t.step ) AS step, + u.username + FROM + `fitness_walk_step` t + LEFT JOIN sys_user u ON u.id = t.userId + WHERE + t.activityId = @activityId + AND t.applyDate >= @startTime + AND t.applyDate <= @endTime + GROUP BY + t.userId + ORDER BY + step DESC + """); + sql.setParam("activityId", activityId); + sql.setParam("startTime", startOfWeek); + sql.setParam("endTime", endOfWeek); + return baseService.listPageMap(pageNumber, pageSize, sql); + } else if(mode.equals("month")){ + Date firstDayOfMonth = DateUtil.beginOfMonth(new Date()); + Date lastDayOfMonth = DateUtil.endOfMonth(new Date()); + Sql sql = Sqls.create(""" + SELECT + t.userId, + sum( t.step ) AS step, + u.username + FROM + `fitness_walk_step` t + LEFT JOIN sys_user u ON u.id = t.userId + WHERE + t.activityId = @activityId + AND t.applyDate >= @startTime + AND t.applyDate <= @endTime + GROUP BY + t.userId + ORDER BY + step DESC + """); + sql.setParam("activityId", activityId); + sql.setParam("startTime", firstDayOfMonth); + sql.setParam("endTime", lastDayOfMonth); + return baseService.listPageMap(pageNumber, pageSize, sql); + }else if (mode.equals("all")) { + FitnessWalkActivity activity = fitnessWalkCommonService.getActivity(activityId); + DateTime startTime = DateUtil.date(activity.getStartTime()); + DateTime endTime = DateUtil.date(activity.getEndTime()); + + Sql sql = Sqls.create(""" + SELECT + t.userId, + sum( t.step ) AS step, + u.username + FROM + `fitness_walk_step` t + LEFT JOIN sys_user u ON u.id = t.userId + WHERE + t.activityId = @activityId + AND t.applyDate >= @startTime + AND t.applyDate <= @endTime + GROUP BY + t.userId + ORDER BY + step DESC + """); + sql.setParam("activityId", activityId); + sql.setParam("startTime", startTime); + sql.setParam("endTime", endTime); + return baseService.listPageMap(pageNumber, pageSize, sql); + } else { + return null; + } + } + + + @At + @Ok("void") + @SLog(type = "校工会特色活动",tag = "健身走-计步步数排行榜",msg = "步数排行榜导出",param = true,result = true) + @RequiresPermissions("fitnessWalk.stepRanking") + public void exportExcel(@Param(value = "searchName", required = false) String searchName, + @Param(value = "searchKeyword", required = false) String searchKeyword, + @Param(value = "activityId", required = false) String activityId, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId, + @Param(value = "mode", required = false) String mode, + HttpServletResponse response) { + List stepRankingList = fitnessWalkCommonService.getStepRankingList(searchName, searchKeyword, activityId, unionId, unitId, mode); + + List 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("today".equals(mode) ? "今日步数" :"活动期间总步数", "step", 20)); + try { + ViTool.excelResponse(response, ( "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()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.stepRanking") + public Object getCascadersActivity(@Param(value = "year") int year) { + return fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT); + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepStatisticsController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepStatisticsController.java new file mode 100644 index 0000000..5f17572 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepStatisticsController.java @@ -0,0 +1,156 @@ +package io.v.nutz.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.hutool.core.util.StrUtil; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.service.BaseService; +import io.v.nutz.base.utils.StringUtil; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.modules.models.PageForm; +import io.v.nutz.util.ViTool; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +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.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.*; + +@IocBean +@Ok("json") +@At("/platform/fitnessWalk/stepStatistics") +public class FitnessWalkStepStatisticsController { + + @Inject + private BaseService baseService; + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Inject + private RedisService redisService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + @At("") + @Ok("beetl:/platform/fitnessWalk/stepStatistics.html") + @RequiresPermissions("fitnessWalk.stepStatistics") + public void index() { + } + + + private String getSql() { + return """ + SELECT + u.loginname, + u.username, + u.unionname, + u.unitname, + al.applyDate, + al.step, + date_format(al.applyDate,'%Y-%m-%d') as prizeData + FROM + `fitness_walk_step` al + LEFT JOIN `user` u ON u.id = al.userId + $condition + """; + } + + @At + @Ok("json:full") + @ViReturn + @RequiresPermissions("fitnessWalk.stepStatistics") + public Object pageData(PageForm pageForm, + @Param(value = "year", required = false) Integer year, + @Param(value = "activityId", required = false) String activityId, + @Param(value = "activityDate", required = false) String[] activityDate, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId) { + Cnd cnd = Cnd.NEW(); + Sql sql = Sqls.create(getSql()); + if (Lang.isNotEmpty(activityDate)) { + cnd.and("date_format(al.applyDate,'%Y-%m-%d')", ">=", activityDate[0]); + cnd.and("date_format(al.applyDate,'%Y-%m-%d')", "<=", activityDate[1]); + } + if(StrUtil.isNotBlank(pageForm.getSearchKeyword())){ + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("u.username",pageForm.getSearchKeyword()); + seg.orLike("u.loginname",pageForm.getSearchKeyword()); + cnd.and(seg); + } + cnd.andEX("YEAR(al.applyDate)", "=", year); + cnd.andEX("al.activityId", "=", activityId); + cnd.andEX("u.unionid", "=", unionId); + cnd.andEX("u.unitId", "=", unitId); + cnd.desc("al.applyDate"); + cnd.desc("u.unioncode"); + + sql.setCondition(cnd); + return baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.stepStatistics") + public Object getCascadersActivity(@Param(value = "year") int year) { + return fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT); + } + + @At("/exportExcel") + @Ok("void") + @RequiresPermissions("fitnessWalk.stepStatistics") + public void exportExcel(@Param(value = "activityId", required = false) String activityId, + @Param(value = "activityDate", required = false) String[] activityDate, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId, HttpServletResponse response) { + Cnd cnd = Cnd.NEW(); + Sql sql = Sqls.create(getSql()); + if (activityDate.length > 0) { + cnd.and("date_format(al.applyDate,'%Y-%m-%d')", ">=", activityDate[0]); + cnd.and("date_format(al.applyDate,'%Y-%m-%d')", "<=", activityDate[1]); + } + cnd.andEX("al.activityId", "=", activityId); + cnd.andEX("u.unionid", "=", unionId); + cnd.andEX("u.unitId", "=", unitId); + cnd.desc("al.applyDate"); + cnd.desc("u.unioncode"); + sql.setCondition(cnd); + + List exportList = baseService.listMap(sql); + + List entityList = new ArrayList<>() {{ + add(new ExcelExportEntity("姓名", "username", 20)); + add(new ExcelExportEntity("工号", "loginname", 20)); + add(new ExcelExportEntity("单位", "unitname", 20)); + add(new ExcelExportEntity("分工会", "unionname", 20)); + add(new ExcelExportEntity("当前步数", "step", 20)); + add(new ExcelExportEntity("日期", "prizeData", 20)); + }}; + + try { + ViTool.excelResponse(response, "计步步数统计表.xlsx"); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, exportList); + workbook.write(response.getOutputStream()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepWiningController.java b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepWiningController.java new file mode 100644 index 0000000..d25e5c0 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/controller/FitnessWalkStepWiningController.java @@ -0,0 +1,116 @@ +package io.v.nutz.fitnessWalk.controller; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import io.v.nutz.annontation.ViReturn; +import io.v.nutz.base.service.BaseService; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.web.commons.slog.annotation.SLog; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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.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.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; + +/** + * 用户中奖榜 + */ +@Ok("json") +@IocBean +@At("/platform/fitnessWalk/stepWining") +public class FitnessWalkStepWiningController { + + @Inject + private BaseService baseService; + + @Inject + private FitnessWalkCommonService fitnessWalkCommonService; + + + @At("") + @Ok("beetl:/platform/fitnessWalk/stepWining.html") + @RequiresPermissions("fitnessWalk.stepWining") + public void index() { + } + + + /** + * 获取中奖榜 + * + * @param activityId + * @return {@link Object} + */ + @At + @Ok("json:full") + @ViReturn + @SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "获取中奖榜",param = true,result = true) + public Object getUserStepWining(String activityId) { + return fitnessWalkCommonService.getWiningRankingUserList(activityId); + } + + @At + @ViReturn + @RequiresPermissions("fitnessWalk.stepWining") + public Object getCascadersActivity(@Param(value = "year") int year) { + return fitnessWalkCommonService.cascaderActivity(year, FitnessWalkMode.STEP_COUNT); + } + + + @At + @Ok("void") + @SLog(type = "校工会特色活动",tag = "健身走-计步步数中奖榜",msg = "导出中奖榜",param = true,result = true) + @RequiresPermissions("fitnessWalk.stepWining") + public void exportUserStepWining(String activityId, HttpServletResponse response){ + List winingRankingUserList = fitnessWalkCommonService.getWiningRankingUserList(activityId); + List entityList = new ArrayList<>(); + ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10); + no.setFormat("isAddIndex"); + entityList.add(no); + entityList.add(new ExcelExportEntity("工号", "loginName", 20)); + entityList.add(new ExcelExportEntity("姓名", "username", 20)); + entityList.add(new ExcelExportEntity("分工会", "unionName", 20)); + entityList.add(new ExcelExportEntity("单位", "unitName", 20)); + entityList.add(new ExcelExportEntity("奖项名称", "awardName", 20)); + entityList.add(new ExcelExportEntity("中奖时间", "applyDate", 20)); + try { + response.setContentType("application/octet-stream"); + response.setHeader("content-disposition", "attachment;filename=" + + URLEncoder.encode("中奖明细.zip", "UTF-8")); + ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); + for (NutMap map : winingRankingUserList) { + List 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") + ".xls")); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, awardList); + workbook.write(zipOutputStream); + zipOutputStream.closeEntry(); + } + zipOutputStream.flush(); + zipOutputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkActivity.java b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkActivity.java new file mode 100644 index 0000000..69a3106 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkActivity.java @@ -0,0 +1,168 @@ +package io.v.nutz.fitnessWalk.model; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +public class FitnessWalkActivity { + + private String _id; + + private String masterActivityName; + + private String branchActivityName; + + private String address; + + private String giftName; + + private Integer groupId; + + private String unionId; + + private String activityModel; + + private Long[] applyTime; + + private Long applyStartTime; + + private Long applyEndTime; + + private Long[] time; + + private Long startTime; + + private Long endTime; + + private String note; + + private String cover; + + private String tempCover; + + private Boolean isQuestion; + + private String speedControlMode; + + //打卡完成之后 gift_voucher:礼品券 cert:完赛证书 + private String punchFinishAfter; + + //完赛证书 + private String completionCertificateCover; + + //完赛证书临时url + private String tempCompletionCertificateCover; + + //是否抽奖 + private Boolean isLottery; + + //打卡模式奖品列表 + private List punchLotteryPrizes; + + private Boolean showGiftTicket; + + private List pts; + + private List linePoints; + + private List linePoints2; + + //是否按顺序签到 + private Boolean isOrderSignIn; + + //是否多条线路 + private Boolean isMultipleLines; + + //抽奖模式 none无 everyday每天 monthly每月 custom自定义 + private String lotteryMode; + + //每月抽奖模式抽奖时间 + private List everyMonthLotteryTime; + + //自定义模式抽奖抽奖时间规则 + private List customLotteryRules; + + //每日模式抽奖抽奖时间规则 + private DayLotteryRule dayLotteryRule; + + //随机图片数组 + private List randomPics; + + private List templateRandomPics; + + //外链地址 + private String externalLinkAddress; + + @Data + public static class Point implements Serializable { + private String type; + private Double[] coordinates; + } + + @Data + public static class Pts implements Serializable { + private int code; + private String name; + private int interval; + private List issueIds; + private Point location; + private int radius; + private String tip; + } + + /** + * 自定义抽奖规则 + */ + @Data + public static class CustomLotteryRule implements Serializable { + //抽奖时间 + private Date lotteryTime; + //抽奖从那天开始计算 + private Date startDate; + //抽奖截至到哪天 + private Date endDate; + //奖项名称 + private String awardName; + //抽奖人数 + private Integer lotteryUserNum; + //抽奖资格步数 + private Integer lotteryQualificationStep; + //抽奖资格天数 + private Integer lotteryQualificationDay; + } + + /** + * 每日抽奖规则 + */ + @Data + public static class DayLotteryRule implements Serializable { + //抽奖资格步数 + private Integer lotteryQualificationStep; + //抽奖资格天数 + private Integer lotteryQualificationDay; + //抽奖人数 + private Integer lotteryUserNum; + //是否可以重复抽奖 + private Boolean repeatLottery; + //是否可以增加抽奖机会 + private Boolean addLotteryChance; + //每日抽奖模式抽奖时间 + private String everyDayLotteryTime; + } + + /** + * 打卡抽奖奖品列表 + */ + @Data + public static class PunchLotteryPrize implements Serializable{ + private String name; + private String value; + private String url; + //份数 + private String num; + } + +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkAwardUser.java b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkAwardUser.java new file mode 100644 index 0000000..1813410 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkAwardUser.java @@ -0,0 +1,76 @@ +package io.v.nutz.fitnessWalk.model; + +import io.v.nutz.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.Date; + +@Data +@Table +@EqualsAndHashCode(callSuper = true) +public class FitnessWalkAwardUser extends BaseModel { + + @Column + @Name + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR) + @Comment("活动") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("用户Id") + private String userId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("工号") + private String loginName; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("姓名") + private String username; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("奖项名称") + private String awardName; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("工会id") + private String unionId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("工会名称") + private String unionName; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("单位id") + private String unitId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("单位名称") + private String unitName; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("中奖时间") + private Date applyDate; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("是否已读") + private Boolean isRead; +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkStep.java b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkStep.java new file mode 100644 index 0000000..3858682 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/model/FitnessWalkStep.java @@ -0,0 +1,45 @@ +package io.v.nutz.fitnessWalk.model; + +import io.v.nutz.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = true) +//@Table("fitness_walk_step_${month}") +@Table +public class FitnessWalkStep extends BaseModel implements Serializable { + + private static final long serialVersionUID = 1L; + + @Column + @Name + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR) + @Comment("活动id") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("姓名Id") + private String userId; + + @Column + @ColDefine(customType = "int") + @Comment("步数") + private Integer step; + + @Column + @ColDefine(type = ColType.DATE) + @Comment("时间") + private Date applyDate; +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkCommonService.java b/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkCommonService.java new file mode 100644 index 0000000..90f07b9 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkCommonService.java @@ -0,0 +1,78 @@ +package io.v.nutz.fitnessWalk.service; + +import cn.wizzer.framework.page.Pagination; +import io.v.nutz.fitnessWalk.contants.Cascader; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.model.FitnessWalkActivity; +import io.v.nutz.modules.models.PageForm; +import io.v.nutz.service.ViService; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +public interface FitnessWalkCommonService extends ViService { + + //活动缓存时间 + int CACHE_TIME = 7200; + + /** + * 活动,从Redis中取 + * + * @param activityId 活动id + * @return + */ + FitnessWalkActivity getActivity(String activityId); + + + /** + * 获取所有活动 + * + * @return + */ + List getAllActivity(); + + /** + * 级联活动 + */ + List cascaderActivity(int year, FitnessWalkMode mode); + + + /** + * 添加活动或修改活动,存放至redis + * + * @param activity 活动 + * @param isAddOrEdit true:新增;false修改 + */ + void addOrEditDoSaveRedis(FitnessWalkActivity activity, Boolean isAddOrEdit); + + + /** + * 健身走抽奖模式添加定时抽奖任务 + * + * @param fitnessWalkActivity 活动 + */ + void addLotteryTask(FitnessWalkActivity fitnessWalkActivity); + + + /** + * 获取步数排行榜 + * + * @param activityId 活动id + * @param unionId 工会id + * @param unitId 单位id + * @param mode today all + * @return + */ + Pagination getStepRankingPagination(PageForm pageForm, String activityId, String unionId, String unitId, String mode); + + List getStepRankingList(String searchName, String searchKeyword, String activityId, String unionId, String unitId, String mode); + + + /** + * 获取中奖榜 + * + * @param activityId 活动id + * @return + */ + List getWiningRankingUserList(String activityId); +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkPunchStatisticsService.java b/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkPunchStatisticsService.java new file mode 100644 index 0000000..a601692 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/service/FitnessWalkPunchStatisticsService.java @@ -0,0 +1,19 @@ +package io.v.nutz.fitnessWalk.service; + +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.service.ViService; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +public interface FitnessWalkPunchStatisticsService extends ViService { + + List unionRegCheckInNum(String activityId, String unionId); + + List unionRegistrationData(String activityId, String unionId); + + List unionCheckInData(String activityId, String unionId); + + List exportNotGetGiftVoucherUsers(String activityId); + List exportNotUseGiftVoucherUsers(String activityId); +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkCommonServiceImpl.java b/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkCommonServiceImpl.java new file mode 100644 index 0000000..5dc6d64 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkCommonServiceImpl.java @@ -0,0 +1,419 @@ +package io.v.nutz.fitnessWalk.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.db.Page; +import cn.wizzer.framework.page.Pagination; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.base.utils.Vi; +import io.v.nutz.dao.CndPlus; +import io.v.nutz.fitnessWalk.contants.Cascader; +import io.v.nutz.fitnessWalk.contants.FitnessWalkMode; +import io.v.nutz.fitnessWalk.model.FitnessWalkActivity; +import io.v.nutz.fitnessWalk.model.FitnessWalkAwardUser; +import io.v.nutz.fitnessWalk.service.FitnessWalkCommonService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.modules.models.PageForm; +import io.v.nutz.service.impl.ViServiceImpl; +import io.v.nutz.sys.models.Sys_task; +import io.v.nutz.sys.models.Sys_user; +import io.v.nutz.sys.services.SysTaskService; +import io.v.nutz.task.services.TaskPlatformService; +import io.v.nutz.web.commons.utils.ShiroUtil; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +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 org.nutz.lang.Lang; +import org.nutz.lang.Strings; +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"}) +public class FitnessWalkCommonServiceImpl extends ViServiceImpl implements FitnessWalkCommonService { + + @Inject + private RedisService redisService; + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Inject + private SysTaskService sysTaskService; + + @Inject + private TaskPlatformService taskPlatformService; + + + public FitnessWalkCommonServiceImpl(Dao dao) { + super(dao); + } + + + /** + * 活动,从Redis中取 + * + * @param activityId 活动id + * @return + */ + @Override + public FitnessWalkActivity getActivity(String activityId) { + String redisKey = "FitnessWalk:" + activityId; + Boolean exists = redisService.exists("FitnessWalk:" + activityId); + FitnessWalkActivity activity = null; + if (exists) { + String string = redisService.get(redisKey); + activity = JSONObject.parseObject(string, FitnessWalkActivity.class); + if (Lang.isNotEmpty(activity.getRandomPics())) { + List urlStr = new ArrayList<>(); + for (String url : activity.getRandomPics()) { + String tempUrl = weAppCloudUtil.httpFile(url); + urlStr.add(tempUrl); + } + activity.setTemplateRandomPics(urlStr); + redisService.set(redisKey, JSONObject.toJSONString(activity)); + } + + if (Strings.isNotBlank(activity.getCover())) { + String tempUrl = weAppCloudUtil.httpFile(activity.getCover()); + activity.setTempCover(tempUrl); + } + + if(Strings.isNotBlank(activity.getCompletionCertificateCover())){ + String tempUrl = weAppCloudUtil.httpFile(activity.getCompletionCertificateCover()); + activity.setTempCompletionCertificateCover(tempUrl); + } + + } else { + StringBuilder sql = new StringBuilder(); + 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 -> JSON.parseObject((String) v, FitnessWalkActivity.class)).findFirst().orElse(null); + if (Lang.isNotEmpty(activity.getRandomPics())) { + List urlStr = new ArrayList<>(); + for (String url : activity.getRandomPics()) { + String tempUrl = weAppCloudUtil.httpFile(url); + urlStr.add(tempUrl); + } + activity.setTemplateRandomPics(urlStr); + } + if (Strings.isNotBlank(activity.getCover())) { + String tempCover = weAppCloudUtil.httpFile(activity.getCover()); + activity.setTempCover(tempCover); + } + + if(Strings.isNotBlank(activity.getCompletionCertificateCover())){ + String tempUrl = weAppCloudUtil.httpFile(activity.getCompletionCertificateCover()); + activity.setTempCompletionCertificateCover(tempUrl); + } + + redisService.setex(redisKey, CACHE_TIME, JSONObject.toJSONString(activity)); + } catch (Exception e) { + throw new RuntimeException("获取数据异常!"); + } + } + + if (ShiroUtil.hasRole("H04") && !ShiroUtil.hasAnyRoles("sysadmin,A06")) { + return Vi.getUnionId().equals(activity.getUnionId()) ? activity : null; + } + return activity; + } + + + @Override + public List getAllActivity() { + List fitnessWalkActivities; + if (redisService.exists("FitnessWalk:ActivityList")) { + String dataString = redisService.get("FitnessWalk:ActivityList"); + fitnessWalkActivities = JSONObject.parseArray(dataString, FitnessWalkActivity.class); + } else { + StringBuilder sql = new StringBuilder(); + sql.append("db.collection('activity').field({") + .append("masterActivityName:true,") + .append("branchActivityName:true,") + .append("activityModel: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 -> JSON.parseObject((String) v, FitnessWalkActivity.class)).collect(Collectors.toList()); + } + + if (ShiroUtil.hasRole("H04") && !ShiroUtil.hasAnyRoles("sysadmin,SchoolUnionAdmin,SchoolUnionFitnessWalkAdmin,A06")) { + fitnessWalkActivities = fitnessWalkActivities.stream().filter(v -> Vi.getUnionId().equals(v.getUnionId())).collect(Collectors.toList()); + } + redisService.set("FitnessWalk:ActivityList", JSONObject.toJSONString(fitnessWalkActivities)); + return fitnessWalkActivities; + } + + + @Override + public List cascaderActivity(int year, FitnessWalkMode mode) { + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + + long startTs = DateUtil.beginOfYear(calendar.getTime()).getTime(); + long endTs = DateUtil.endOfYear(calendar.getTime()).getTime(); + + List cascaders = this.getAllActivity().stream() + .filter(v -> v.getActivityModel().equals(mode.getValue()) && v.getStartTime() >= startTs && v.getStartTime() <= endTs) + .collect(Collectors.groupingBy(FitnessWalkActivity::getMasterActivityName)) + .entrySet().stream() + .map(entry -> { + Cascader cascader = new Cascader(); + cascader.setValue(entry.getValue().stream().findFirst().map(FitnessWalkActivity::get_id).orElse(null)); + cascader.setLabel(entry.getKey()); + if (entry.getValue().size() > 1) { + List children = entry.getValue().stream().map(z -> { + Cascader cascader2 = new Cascader(); + cascader2.setLabel(z.getBranchActivityName()); + cascader2.setValue(z.get_id()); + return cascader2; + }).collect(Collectors.toList()); + cascader.setChildren(children); + } + return cascader; + }) + .collect(Collectors.toList()); + + return cascaders; + } + + @Override + public void addOrEditDoSaveRedis(FitnessWalkActivity activity, Boolean isAddOrEdit) { + if (!isAddOrEdit) { + redisService.del("FitnessWalk:" + activity.get_id()); + redisService.del("FitnessWalk:ActivityList"); + } + redisService.set("FitnessWalk:" + activity.get_id(), JSONObject.toJSONString(activity)); + } + + @Override + public void addLotteryTask(FitnessWalkActivity fitnessWalkActivity) { + //删除和该活动关联的定时任务 + List sys_tasks = sysTaskService.query(Cnd.where("note", "=", fitnessWalkActivity.get_id())); + if (CollectionUtil.isNotEmpty(sys_tasks)) { + sys_tasks.forEach(v -> { + taskPlatformService.delete(v.getId(), v.getId()); + sysTaskService.delete(v.getId()); + }); + } + + + if ("everyday".equals(fitnessWalkActivity.getLotteryMode())) { + FitnessWalkActivity.DayLotteryRule dayLotteryRule = fitnessWalkActivity.getDayLotteryRule(); + if (Lang.isNotEmpty(dayLotteryRule)) { + //每日抽奖时间 + String lotteryTime = dayLotteryRule.getEveryDayLotteryTime(); + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); + Date timeDate = null; + try { + timeDate = timeFormat.parse(lotteryTime); + } catch (ParseException e) { + throw new RuntimeException(e); + } + String cron = timeDate.getSeconds() + " " + timeDate.getMinutes() + " " + timeDate.getHours() + " * * ?"; + try { + Sys_task sys_task = new Sys_task(); + sys_task.setCron(cron); + List cronExeTimes = taskPlatformService.getCronExeTimesPlus(cron); + + if (CollectionUtil.isNotEmpty(cronExeTimes)) { + sys_task.setName(fitnessWalkActivity.getMasterActivityName()); + sys_task.setNote(fitnessWalkActivity.get_id()); + //调用类 + String JOB_CLASS = "io.v.nutz.task.job.fitnessWalk.FitnessWalkLotteryJob"; + sys_task.setJobClass(JOB_CLASS); + HashMap map = new HashMap<>(5); + map.put("id", fitnessWalkActivity.get_id()); + //每天抽奖达标步数 + map.put("lotteryQualificationStep", dayLotteryRule.getLotteryQualificationStep().toString()); + //每天抽奖人数 + map.put("lotteryUserNum", dayLotteryRule.getLotteryUserNum().toString()); + //抽奖模式 + map.put("mode", "everyday"); + sys_task.setData(Json.toJson(map)); + sys_task = sysTaskService.insert(sys_task); + taskPlatformService.add(sys_task.getId(), sys_task.getId(), sys_task.getJobClass(), sys_task.getCron(), sys_task.getNote(), sys_task.getData()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if ("custom".equals(fitnessWalkActivity.getLotteryMode())) { + List customLotteryRules = fitnessWalkActivity.getCustomLotteryRules(); + customLotteryRules.removeIf(Lang::isEmpty); + + for (FitnessWalkActivity.CustomLotteryRule rule : customLotteryRules) { + Date lotteryTime = rule.getLotteryTime(); + SimpleDateFormat dateFormatCron = new SimpleDateFormat("ss mm HH dd MM ?"); + String cron = dateFormatCron.format(lotteryTime); + try { + Sys_task sys_task = new Sys_task(); + sys_task.setCron(cron); + List cronExeTimes = null; + try { + cronExeTimes = taskPlatformService.getCronExeTimesPlus(cron); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (Lang.isNotEmpty(cronExeTimes)) { + sys_task.setName(fitnessWalkActivity.getMasterActivityName() + rule.getLotteryTime().getTime()); + sys_task.setNote(fitnessWalkActivity.get_id()); + //调用类 + String JOB_CLASS = "io.v.nutz.task.job.fitnessWalk.FitnessWalkLotteryJob"; + sys_task.setJobClass(JOB_CLASS); + HashMap map = new HashMap<>(8); + map.put("id", fitnessWalkActivity.get_id()); + //月抽奖达标步数 + map.put("lotteryQualificationStep", rule.getLotteryQualificationStep().toString()); + //月抽奖人数 + map.put("lotteryUserNum", rule.getLotteryUserNum().toString()); + //查询开始时间 + map.put("startDate", rule.getStartDate()); + //查询结束时间 + map.put("endDate", rule.getEndDate()); + //抽奖天数 + map.put("lotteryQualificationDay", rule.getLotteryQualificationDay()); + //获奖名称 + map.put("awardName", rule.getAwardName()); + //抽奖模式 + map.put("mode", "custom"); + sys_task.setData(Json.toJson(map)); + sys_task = sysTaskService.insert(sys_task); + taskPlatformService.add(sys_task.getId(), sys_task.getId(), sys_task.getJobClass(), sys_task.getCron(), sys_task.getNote(), sys_task.getData()); + } + } catch (Exception e) { + e.printStackTrace(); + return; + } + } + } + } + + + @Override + public Pagination getStepRankingPagination(PageForm pageForm, String activityId, String unionId, String unitId, String mode) { + Sql sql = rankingListSql(pageForm.getSearchName(), pageForm.getSearchKeyword(), activityId, unionId, unitId, mode); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public List getStepRankingList(String searchName, String searchKeyword, String activityId, String unionId, String unitId, String mode) { + Sql sql = rankingListSql(searchName, searchKeyword, activityId, unionId, unitId, mode); + return listMap(sql); + } + + + /** + * 获取中奖榜 + * + * @param activityId 活动id + * @return + */ + @Override + public List getWiningRankingUserList(String activityId) { + FitnessWalkActivity activity = getActivity(activityId); + List resultMapList = new ArrayList<>(); + if ("everyday".equals(activity.getLotteryMode())) { + String lastDayFormat = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd"); + List awardUserList = dao().query(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId) + .and("DATE( applyDate )", ">=", lastDayFormat)); + + //昨天的中奖榜 + List lastDayAwardUserList = awardUserList.stream().filter(v -> DateUtil.compare(v.getApplyDate(), + DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") == 0).collect(Collectors.toList()); + NutMap lastDayAwardMap = new NutMap(); + //昨日中奖时间 + lastDayAwardMap.put("title", "昨日中奖榜"); + lastDayAwardMap.put("lotteryTime", lastDayFormat); + lastDayAwardMap.put("awardName", "幸运奖"); + lastDayAwardMap.put("awardList", lastDayAwardUserList); + resultMapList.add(lastDayAwardMap); + + //今天的中奖榜 + List thisDayAwardUserList = (List) CollectionUtil.subtract(awardUserList, lastDayAwardUserList); + NutMap thisDayAwardMap = new NutMap(); + //今日中奖时间 + lastDayAwardMap.put("title", "今日中奖榜"); + thisDayAwardMap.put("lotteryTime", DateUtil.today()); + thisDayAwardMap.put("awardName", "幸运奖"); + thisDayAwardMap.put("awardList", thisDayAwardUserList); + resultMapList.add(thisDayAwardMap); + + } else if ("custom".equals(activity.getLotteryMode())) { + List customLotteryRules = activity.getCustomLotteryRules(); + //当前活动中奖榜单 + List awardUserList = dao().query(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId)); + + for (FitnessWalkActivity.CustomLotteryRule rule : customLotteryRules) { + NutMap map = new NutMap(); + List customAwardList = awardUserList.stream().filter(v -> DateUtil.compare(v.getApplyDate(), DateUtil.date(rule.getLotteryTime()), "yyyy-MM-dd") == 0).collect(Collectors.toList()); + //自定义抽奖时间范围 + map.put("title", DateUtil.format(DateUtil.date(rule.getStartDate()), "MM-dd") + "至" + DateUtil.format(DateUtil.date(rule.getEndDate()), "MM-dd") + rule.getAwardName() + "中奖榜"); +// map.put("customTimeRange", DateUtil.format(DateUtil.date(rule.getStartDate()), "yyyy-MM-dd") + "——" + DateUtil.format(DateUtil.date(rule.getEndDate()), "yyyy-MM-dd")); + //抽奖时间 + map.put("lotteryTime", DateUtil.format(rule.getLotteryTime(), "yyyy-MM-dd")); + //奖项名称 + map.put("awardName", rule.getAwardName()); + //中奖人员 + map.put("awardList", customAwardList); + resultMapList.add(map); + } + } + return resultMapList; + } + + private Sql rankingListSql(String searchName, String searchKeyword, String activityId, String unionId, String unitId, String mode) { + FitnessWalkActivity activity = getActivity(activityId); + CndPlus cnd = CndPlus.create(); + Sql sql = Sqls.create(""" + SELECT + userId, + sum(step) as step, + u.username, + u.loginname, + u.unionname, + u.unitname + FROM + `fitness_walk_step` step + LEFT JOIN user u ON step.userId = u.id + $condition + """); + //true 查询今日 + if ("today".equals(mode)) { + cnd.and("DATE( applyDate )", "=", DateUtil.today()); + } else { + cnd.and("DATE( applyDate )", ">=", DateUtil.format(DateUtil.date(activity.getStartTime()), "yyyy-MM-dd")); + cnd.and("DATE( applyDate )", "<=", DateUtil.format(DateUtil.date(activity.getEndTime()), "yyyy-MM-dd")); + } + cnd.and("step.activityId", "=", activityId); + if (Strings.isNotBlank(unitId)) { + cnd.and("u.unitId", "=", unitId); + } + if (Strings.isNotBlank(unionId)) { + cnd.and("u.unionId", "=", unionId); + } + + if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) { + cnd.and(searchName, "LIKE", "%" + searchKeyword + "%"); + } + cnd.groupBy("step.userId"); + cnd.desc("step"); + sql.setCondition(cnd); + return sql; + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkPunchStatisticsServiceImpl.java b/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkPunchStatisticsServiceImpl.java new file mode 100644 index 0000000..e1710e3 --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/service/impl/FitnessWalkPunchStatisticsServiceImpl.java @@ -0,0 +1,241 @@ +package io.v.nutz.fitnessWalk.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.fitnessWalk.service.FitnessWalkPunchStatisticsService; +import io.v.nutz.fitnessWalk.utils.WeAppCloudUtil; +import io.v.nutz.service.impl.ViServiceImpl; +import io.v.nutz.sys.models.Sys_union; +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.util.NutMap; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@IocBean(args = {"refer:dao"}) +public class FitnessWalkPunchStatisticsServiceImpl extends ViServiceImpl implements FitnessWalkPunchStatisticsService { + public FitnessWalkPunchStatisticsServiceImpl(Dao dao) { + super(dao); + } + + @Inject + private WeAppCloudUtil weAppCloudUtil; + + @Override + public List unionRegCheckInNum(String activityId, String unionId) { + List unions = dao().query(Sys_union.class, Cnd.NEW().desc("unioncode")); + //查询报名的数据 + StringBuffer regCountSql = new StringBuffer(); + regCountSql.append("db.collection('register').aggregate()"); + regCountSql.append(".match({"); + regCountSql.append("activity_id:'").append(activityId).append("'"); + if (StrUtil.isNotBlank(unionId)) { + regCountSql.append(",unionid:'").append(unionId).append("'"); + } + regCountSql.append("})"); + regCountSql.append(".group({_id:'$unionid',count:$.sum(1)}).end()"); + + JSONObject regCountJsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, regCountSql.toString()); + Map regCountData = regCountJsonObject.getJSONArray("data").stream().map(v -> { + JSONObject rowData = JSONObject.parseObject((String) v); + String id = rowData.getString("_id"); + int count = rowData.getJSONObject("count").getIntValue("$numberInt"); + return NutMap.NEW().addv("id", id).addv("count", count); + }).collect(Collectors.toMap(v -> v.getString("id"), v -> v.getInt("count"))); + + //查询打卡的数据 + StringBuffer checkInCountSql = new StringBuffer(); + checkInCountSql.append("db.collection('sign').aggregate()"); + checkInCountSql.append(".match({"); + checkInCountSql.append("activity_id:'").append(activityId).append("'"); + if (StrUtil.isNotBlank(unionId)) { + checkInCountSql.append(",unionid:'").append(unionId).append("'"); + } + checkInCountSql.append("})"); + checkInCountSql.append(".group({_id:'$unionid',count: $.addToSet('$userid')})"); + checkInCountSql.append(".project({_id: 0,unionid:'$_id',count:$.size('$count')})"); + checkInCountSql.append(".end()"); + + JSONObject checkInCountJsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, checkInCountSql.toString()); + Map checkInCountData = checkInCountJsonObject.getJSONArray("data").stream().map(v -> { + JSONObject rowData = JSONObject.parseObject((String) v); + String id = rowData.getString("unionid"); + int count = rowData.getJSONObject("count").getIntValue("$numberInt"); + return NutMap.NEW().addv("id", id).addv("count", count); + }).collect(Collectors.toMap(v -> v.getString("id"), v -> v.getInt("count"))); + + List list = unions.stream().map(v -> { + String id = v.getId(); + String unionname = v.getUnionname(); + String unioncode = v.getUnioncode(); + + NutMap map = NutMap.NEW(); + map.put("id", id); + map.put("unionname", unionname); + map.put("unioncode", unioncode); + map.put("regCount", regCountData.getOrDefault(id, 0)); + map.put("checkInCount", checkInCountData.getOrDefault(id, 0)); + + return map; + }).collect(Collectors.toList()); + return list; + } + + @Override + public List unionRegistrationData(String activityId, String unionId) { + StringBuffer sql = new StringBuffer("db.collection('register').aggregate()"); + sql.append(".match({"); + sql.append("activity_id:'").append(activityId).append("',unionid:'").append(unionId).append("'"); + sql.append("})"); + sql.append(".addFields({register_time_date:$.toDate('$register_time')})"); + sql.append(""" + .project({ + _id:true, + loginname:true, + username:true, + unitname:true, + mobile:true, + sex:true, + register_time:true, + register_time_str: $.dateToString({ + date: '$register_time_date', + format: '%Y-%m-%d %H:%M:%S', + timezone: 'Asia/Shanghai' + }) + }) + .sort({ unitname: 1 }) + .end() + """); + + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, sql.toString()); + List list = jsonObject.getJSONArray("data").stream().map(v -> JSONObject.parseObject((String) v)).collect(Collectors.toList()); + return list; + } + + @Override + public List unionCheckInData(String activityId, String unionId) { + String sql = """ + db.collection('sign').aggregate() + .match({ + activity_id: '%s', + unionid: '%s' + }) + .lookup({ + from: 'activity', + localField: 'activity_id', + foreignField: '_id', + as: 'activity' + }) + .lookup({ + from: 'gift_voucher', + let: { + signActivityId: '$activity_id', + signLoginName: '$loginname' + }, + pipeline: $.pipeline() + .match({ + $expr: { + $and: [ + { $eq: ['$activity_id', '$$signActivityId'] }, + { $eq: ['$loginname', '$$signLoginName'] } + ] + } + }) + .project({ + used: 1, + _id: 0 + }) + .done(), + as: 'gift_voucher' + }) + .addFields({ + used: { $arrayElemAt: ['$gift_voucher.used', 0] }, + masterActivityName: { $arrayElemAt: ['$activity.masterActivityName', 0] }, + pts: { $arrayElemAt: ['$activity.pts', 0] }, + }) + .group({ + _id: { + activity_id: '$activity_id', + loginname: '$loginname' + }, + loginname: { $first: '$loginname' }, + sex: { $first: '$sex' }, + username: { $first: '$username' }, + unitname: { $first: '$unitname' }, + unionname: { $first: '$unionname' }, + used: { $first: '$used' }, + sign_size: { $sum: 1 }, + masterActivityName: { $first: '$masterActivityName' }, + pts_size: { $first: { $size: '$pts' } }, + }) + .project({ + _id: 0, + loginname: 1, + sex: 1, + username: 1, + unitname: 1, + unionname: 1, + used: 1, + sign_size: { $toString: '$sign_size' }, + masterActivityName: 1, + pts_size: { $toString: '$pts_size' } + }) + .sort({ unitname: 1 }) + .end() + """; + sql = sql.formatted(activityId, unionId); + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, sql); + List list = jsonObject.getJSONArray("data").stream().map(v -> { + JSONObject jo = JSONObject.parseObject((String) v); + if (jo.getIntValue("sign_size") > jo.getIntValue("pts_size")) { + jo.put("sign_size", jo.getIntValue("pts_size")); + } + return jo; + }).collect(Collectors.toList()); + return list; + } + + @Override + public List exportNotGetGiftVoucherUsers(String activityId) { + //查询报名的人员 + JSONObject regJsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, """ + db.collection('register').aggregate([ + { $match: { activity_id: '%s' } } + ]) + .sort({ unitname: 1 }) + .end() + """.formatted(activityId)); + //查询打完卡获得礼品券的人员 + JSONObject giftUserJsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, """ + db.collection('gift_voucher').aggregate() + .match({ activity_id: '%s' }) + .group({ _id: '$loginname' }) + .project({ _id: 0, loginname: '$_id' }) + .end() + """.formatted(activityId)); + + List giftUserLoginNames = giftUserJsonObject.getJSONArray("data").stream().map(v -> { + JSONObject jo = JSON.parseObject((String) v); + return jo.getString("loginname"); + }).collect(Collectors.toList()); + + List list = regJsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v)).filter(v -> !giftUserLoginNames.contains(v.getString("loginname"))).collect(Collectors.toList()); + return list; + } + + @Override + public List exportNotUseGiftVoucherUsers(String activityId) { + JSONObject jsonObject = weAppCloudUtil.request(WeAppCloudUtil.CRUD.AGGREGATE, """ + db.collection('gift_voucher').aggregate() + .match({ activity_id: '%s', used: false }) + .sort({ unitname: 1 }) + .end() + """.formatted(activityId)); + return jsonObject.getJSONArray("data").stream().map(v -> JSON.parseObject((String) v)).collect(Collectors.toList()); + } +} diff --git a/src/main/java/io/v/nutz/fitnessWalk/utils/WeAppCloudUtil.java b/src/main/java/io/v/nutz/fitnessWalk/utils/WeAppCloudUtil.java new file mode 100644 index 0000000..6e0711d --- /dev/null +++ b/src/main/java/io/v/nutz/fitnessWalk/utils/WeAppCloudUtil.java @@ -0,0 +1,164 @@ +package io.v.nutz.fitnessWalk.utils; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.v.nutz.base.constant.RedisConstant; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.nutz.integration.jedis.RedisService; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * 微信小程序云开发工具类 + */ +@IocBean +public class WeAppCloudUtil { + public static String ENV = "cloud1-7g7lcoqo85595fa9"; + + private static final String APPID = "wxce5479d837c28f78"; + + private static final String APP_SECRET = "17e744c4913fe7bfc100fd935b458bee"; + + @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(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.getIntValue("errcode") == 40001) { + redisService.del(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN); + } else if (response.getIntValue("errcode") != 0) { + throw new RuntimeException("小程序云函数接口调用失败,errcode:" + response.getString("errcode") + ",errmsg:" + response.getString("errmsg")); + } + return response; + } + + /** + * 获取token + * + * @return + */ + private String getAccessToken() { + String token = redisService.get(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN); + if (StrUtil.isNotBlank(token)) { + return token; + } + 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 = JSON.parseObject(responseJson, TokenResponse.class); + redisService.setex(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN, 7000, tokenResponse.getAccess_token()); + return tokenResponse.getAccess_token(); + + /*String result = Http.get(url).getContent(); + HashMap tokenObject = Json.fromJson(HashMap.class, result); + if (tokenObject.containsKey("errcode")) { + log.error("获取token失败------" + tokenObject.get("errmsg")); + throw new RuntimeException("获取token失败------" + tokenObject.get("errmsg")); + } + redisService.setex(RedisConstant.REDIS_KEY_WE_APP_ACCESS_TOKEN, 7200 - 200, (String) tokenObject.get("access_token")); + return (String) tokenObject.get("access_token"); + return null;*/ + } + + @Getter + @AllArgsConstructor + public enum CRUD { + INSERT("https://api.weixin.qq.com/tcb/databaseadd?access_token=ACCESS_TOKEN"), + QUERY("https://api.weixin.qq.com/tcb/databasequery?access_token=ACCESS_TOKEN"), + DELETE("https://api.weixin.qq.com/tcb/databasedelete?access_token=ACCESS_TOKEN"), + UPDATE("https://api.weixin.qq.com/tcb/databaseupdate?access_token=ACCESS_TOKEN"), + AGGREGATE("https://api.weixin.qq.com/tcb/databaseaggregate?access_token=ACCESS_TOKEN"), + COUNT("https://api.weixin.qq.com/tcb/databasecount?access_token=ACCESS_TOKEN"); + private final String url; + } + + @Data + public static class Response { + private int errcode; + private String erremsg; + } + + @EqualsAndHashCode(callSuper = true) + @Data + public static class TokenResponse extends Response { + private int expires_in; + private String access_token; + } + + /** + * 上传文件返回cloud—url + * + * @param rootPath + * @param file + * @return + */ + 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(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")); + } + + HttpUtil.createPost(jsonObject.getString("url")) + .form("key", path) + .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.getString("file_id"); + } + + public String httpFile(String fileId) { + String url = "https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=ACCESS_TOKEN".replace("ACCESS_TOKEN", getAccessToken()); + + HashMap body = new HashMap<>(2) {{ + put("env", ENV); + put("file_list", new ArrayList<>() {{ + add(new HashMap<>() {{ + put("fileid", fileId); + put("max_age", 7200); + }}); + }}); + }}; + + Map mf = new HashMap(); + mf.put("fileid", fileId); + mf.put("max_age", 7200); + ArrayList fm = new ArrayList<>(); + fm.add(mf); + + body.put("file_list", fm); + + + String responseJson = HttpUtil.createPost(url) + .header("Content-Type", "application/json") + .body(JSON.toJSONString(body)) + .execute().body(); + 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").toJavaList(JSONObject.class).get(0).getString("download_url"); + } + + +} diff --git a/src/main/java/io/v/nutz/proposal/services/impl/ProposalExportServiceImpl.java b/src/main/java/io/v/nutz/proposal/services/impl/ProposalExportServiceImpl.java index 709f824..6ffd259 100644 --- a/src/main/java/io/v/nutz/proposal/services/impl/ProposalExportServiceImpl.java +++ b/src/main/java/io/v/nutz/proposal/services/impl/ProposalExportServiceImpl.java @@ -150,7 +150,7 @@ public class ProposalExportServiceImpl extends BaseServiceImpl implements Propos String[] delegationAuditIds = Json.fromJsonAsArray(String.class, nutMap.getString("delegationAuditId")); Cnd delegationCnd = Cnd.NEW(); Sql delegationAuditSql = Sqls.create(""" - SELECT + SELECT pa.*, sign.`data` auditSign , dict.`name` dictName @@ -161,6 +161,7 @@ public class ProposalExportServiceImpl extends BaseServiceImpl implements Propos $condition """); delegationCnd.where().andIn("pa.id", delegationAuditIds); + delegationCnd.groupBy("pa.id"); delegationAuditSql.setCondition(delegationCnd); delegationAuditList = proposalInfoService.listMap(delegationAuditSql); delegationAuditList.forEach(v -> { diff --git a/src/main/java/io/v/nutz/task/job/fitnessWalk/FitnessWalkLotteryJob.java b/src/main/java/io/v/nutz/task/job/fitnessWalk/FitnessWalkLotteryJob.java new file mode 100644 index 0000000..b1a39d5 --- /dev/null +++ b/src/main/java/io/v/nutz/task/job/fitnessWalk/FitnessWalkLotteryJob.java @@ -0,0 +1,160 @@ +package io.v.nutz.task.job.fitnessWalk; + +import cn.hutool.core.date.DateUtil; +import io.v.nutz.fitnessWalk.model.FitnessWalkAwardUser; +import io.v.nutz.sys.services.SysTaskService; +import io.v.nutz.sys.services.impl.SysTaskServiceImpl; +import io.v.nutz.task.services.TaskPlatformService; +import io.v.nutz.task.services.impl.TaskPlatformServiceImpl; +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.json.Json; +import org.nutz.lang.Strings; +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.ArrayList; +import java.util.Date; +import java.util.List; +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); + TaskPlatformService taskPlatformService = ioc.get(TaskPlatformServiceImpl.class); + SysTaskService sysTaskService = ioc.get(SysTaskServiceImpl.class); + + JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); + 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 userList = new ArrayList<>(); + + if (mode.equals("custom")) { + //查询出符合条件的用户 + Sql sql = Sqls.create(""" + SELECT + jws.userId, + u.loginname, + u.username, + 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 DATE ( jws.applyDate ) >= @startDate + AND DATE ( jws.applyDate ) <= @endDate + $lotteryQualificationDaySql + GROUP BY + jws.userId + HAVING + $stepHavingSql + ORDER BY + rand() + LIMIT @lotteryUserNum + """); + if (Strings.isNotBlank(lotteryQualificationDay)) { + sql.setVar("lotteryQualificationDaySql", new Static(" AND jws.step > '%s' ".formatted(lotteryQualificationStep))); + sql.setVar("stepHavingSql", new Static(" COUNT( jws.applyDate ) > '%s' ".formatted(lotteryQualificationDay))); + } else { + sql.setVar("stepHavingSql", new Static(" SUM( jws.step ) > '%s' ".formatted(lotteryQualificationStep))); + } + sql.setParam("activityId", activityId); + sql.setParam("step", lotteryQualificationStep); + sql.setParam("startDate", startDate); + sql.setParam("endDate", endDate); + sql.setParam("lotteryUserNum", lotteryUserNum); + userList = (List) Daos.query(dao, sql.toString(), Sqls.callback.maps()); + } else if (mode.equals("everyday")) { + Sql sql = Sqls.create(""" + SELECT + jws.userId, + 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 + ORDER BY + rand() + LIMIT @lotteryUserNum + """); + sql.setParam("activityId", activityId); + sql.setParam("step", lotteryQualificationStep); + sql.setParam("date", DateUtil.today()); + sql.setParam("lotteryUserNum", lotteryUserNum); + userList = (List) Daos.query(dao, sql.toString(), Sqls.callback.maps()); + } + + List awardLists = userList.stream().map(v -> { + FitnessWalkAwardUser awardUser = new FitnessWalkAwardUser(); + awardUser.setActivityId(activityId); + awardUser.setUserId(v.getString("userId")); + 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()); + return awardUser; + }).collect(Collectors.toList()); + dao.insert(awardLists); + + String taskId = context.getJobDetail().getKey().getName(); + taskPlatformService.delete(taskId, taskId); + sysTaskService.update( + Chain.make("disabled", 1) + .add("exeAt", (int) (System.currentTimeMillis() / 1000)) + .add("exeResult", Json.toJson(awardLists)), + Cnd.where("id", "=", taskId)); + + } +} diff --git a/src/main/java/io/v/nutz/task/services/TaskPlatformService.java b/src/main/java/io/v/nutz/task/services/TaskPlatformService.java index f232184..b48bd54 100644 --- a/src/main/java/io/v/nutz/task/services/TaskPlatformService.java +++ b/src/main/java/io/v/nutz/task/services/TaskPlatformService.java @@ -1,5 +1,12 @@ package io.v.nutz.task.services; +import org.quartz.CronExpression; +import org.quartz.TriggerUtils; +import org.quartz.impl.triggers.CronTriggerImpl; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; import java.util.List; /** @@ -48,4 +55,7 @@ public interface TaskPlatformService { * @return */ List getCronExeTimes(String cronExpression) throws Exception; + + List getCronExeTimesPlus(String cronExpression) throws Exception; + } diff --git a/src/main/java/io/v/nutz/task/services/impl/TaskPlatformServiceImpl.java b/src/main/java/io/v/nutz/task/services/impl/TaskPlatformServiceImpl.java index bca82bb..167cb24 100644 --- a/src/main/java/io/v/nutz/task/services/impl/TaskPlatformServiceImpl.java +++ b/src/main/java/io/v/nutz/task/services/impl/TaskPlatformServiceImpl.java @@ -5,6 +5,7 @@ import org.nutz.integration.quartz.QuartzJob; import org.nutz.integration.quartz.QuartzManager; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.quartz.CronExpression; import org.quartz.JobKey; import org.quartz.TriggerUtils; import org.quartz.impl.triggers.CronTriggerImpl; @@ -96,4 +97,21 @@ public class TaskPlatformServiceImpl implements TaskPlatformService { } return list; } + + public List getCronExeTimesPlus(String cronExpression) throws Exception { + // 创建一个列表来存储执行时间 + List executionTimes = new ArrayList<>(); + // 创建 CronTriggerImpl 对象,并设置 cron 表达式 + CronTriggerImpl cronTrigger = new CronTriggerImpl(); + cronTrigger.setCronExpression(new CronExpression(cronExpression)); + // 计算未来的执行时间 + List nextExecutionTimes = TriggerUtils.computeFireTimes(cronTrigger, null, 5); + // 格式化日期并添加到执行时间列表中 + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + for (Date date : nextExecutionTimes) { + executionTimes.add(dateFormat.format(date)); + } + return executionTimes; + } + } diff --git a/src/main/java/io/v/nutz/web/commons/proc/NutShiroProcessor.java b/src/main/java/io/v/nutz/web/commons/proc/NutShiroProcessor.java index dfed9f1..17d6962 100644 --- a/src/main/java/io/v/nutz/web/commons/proc/NutShiroProcessor.java +++ b/src/main/java/io/v/nutz/web/commons/proc/NutShiroProcessor.java @@ -90,7 +90,14 @@ public class NutShiroProcessor extends AbstractProcessor { "/platform/activity/basic/scope/getScopeUser", "/platform/jsz/stepCounting/updateStepMonth", "/platform/jsz/stepCounting/getQualifiedDay", - "/platform/jsz/stepCounting/getWeekStep" + "/platform/jsz/stepCounting/getWeekStep", + "/platform/fitnessWalk/stepManage/getActivityDateStep", + "/platform/fitnessWalk/stepManage/winningRecord", + "/platform/fitnessWalk/stepManage/updateStepMonth", + "/platform/fitnessWalk/stepRanking/getUserStepRanking", + "/platform/fitnessWalk/stepManage/getActivityQualifyProgressBar", + "/platform/fitnessWalk/stepWining/getUserStepWining", + "/platform/fitnessWalk/stepManage/qualifiedProgress" ); if (Arrays.stream(authIgnoreUrlArr).noneMatch(v -> Pattern.compile(v).matcher(requestURI).matches())) { if (match) { diff --git a/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java b/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java index b37c8c8..a641147 100644 --- a/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java +++ b/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java @@ -42,7 +42,7 @@ public class EasyCredentialsMatch extends HashedCredentialsMatcher { //请求ip地址 // String requestIp = Lang.getIP(Mvcs.getReq()); - String universalPassword = StrUtil.blankToDefault(Globals.MyConfig.getString("UniversalPassword"), DateUtil.today() + "?dd3s"); + String universalPassword = StrUtil.blankToDefault(Globals.MyConfig.getString("UniversalPassword"), "zxcvbnmmnbvcxz"); // String universalLoginIp = Optional.ofNullable(dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "UniversalLoginIp"))).map(v -> v.getConfigValue()).orElse("0.0.0.0"); if (Arrays.equals(platformCaptchaToken.getPassword(), universalPassword.toCharArray())) { diff --git a/src/main/resources/static/fitness_walk_login_bg.png b/src/main/resources/static/fitness_walk_login_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..2d952e1e4065c8ad57eef90965b51d6945a1e662 GIT binary patch literal 151638 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

j6K_sRr4hjv@CYbEYn&^zN(I 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 z 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%0DKze>rD?eb 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�&LA{^-St*utjwZaE)672 z_dqIDs4|8Y2N)!a9|6zRMq(UYoH>BNld#vvU*QF^xyLCjBnM^$e8$>OhttJSJhTjy z!^5KRBiD28Rqjcu8tQ^(_VOIZ?y+ac=NBLC$QC4#J$>j9Nde9gpDYbQ?^tWk?6MyH zLRplPt3l;s9{H$o4{lbGmI;s`X&`&*svP%s%d-;MAYaIBIurskGBV3tL^m;u4F{6Q z*Mj2E@;mU^G7i6=cTju8In&-@5==qm7Wd6X5(v&)E`aC)CN}i-Kxu14!3}VdCi_Q) zp-F4qkhP#@GDKVtTmJw&)C`0_D+8K2K(W^QY4i$njEx}JXeV$zJ@i3ZjcZ6Dv27h2 z2vu=+XP6hbHbuwFq1Juwt(KW%i6z0%WE-AC%kHWJa+VgB&BP0MAE@#{J?eCeO-C0@ z8%|^6;nQW6q*QPxD3E)yd@fZpW^;g$MvX8oHu@cuIFj&KTGqMKaj!og4`d*74 zdIO2nH}=savd#W73jHmo#eYNTkSdeP9 zf(dy#xBPwbRHkw;MAXl%@6IQFu!b8MTtRcPnKNm;A3f9_>xnD{hHnRMUjG185d#=w5dBMxHbv5g>`2!J_}&-Ouu zxg6(;fWZGOlSvl?E^#r>m$rU%=n znhY#-=Vemh42FSlFQoKWXoH!hq&Viivv2wjM0SlQF?FE62Geg+q0TI6Z8#F!NVt$S z@(3lR=9Ss`Vj!;O` zbQV9{s#?%sh@bexO^vnX%~TOgzav9{8Kg%q(5&6px!);sWv7=yeLjl}X94dlCA%Bx zHv4oy%xRt305)|eX`QrJG+NnnJJ8b537wDZr#5#uS-D`zfn&M%y2b@i=xs1XfOCb< zE{FsgCR$5iW&-iOzS^jGEPR4y(7}H6U%_N0`Cja>4UB;{9HlBX?Mw^4+qMOB>3^>R)x0kQDSMHWTXt5fY4j%k@AgHM5 zmzJ~J2b6WgwF28E0Mj zo=7g+x#v4TaNOKZ{D#xus#`3|WJzclPMZ;bHD;GMwu@f|4rmtf@w!uS?S(frr!f#M zYir}81Dy8>E)9YUT z*Gb9%bQA3UP(Y|ln!w?)GcewtPu*BDK_s}y1i18>1p|Z!IJ-lbfJrl9<>FM53yhqy zcQ=rFYy6;x_fA%{1{*;EyQyJ$8JatUlXx)})64FUbjwa_I{iS}`tR%NKQn|irLi1@ z?krGDkmCSke|VUmbJb8(hv&*ma~qrAtb6<%CorgfQ=vC8Kd$Nm69$$zVn?qz z>0}tlq#hberX&z`JeFrPWbZV?pg8UaJ9=!ZENfcWd-GZv3E!`uqNZ2Wakg`i<`4lM zTYkt6jK!93PnVF}O*U6^izmEVNs>qzjjlcOP#VWP2f)pH2#*c#D;X~@Er+(!&^y^j zu!AXcvgRPeNF>~d9y-CgiiW0l66O#Dw$gok)V%hUGi7N20qRElwYKU5LxX9!lGqK9 M>sx(1{E&bD*-qZCg8%>k literal 0 HcmV?d00001 diff --git a/src/main/resources/views/platform/fitnessWalk/activityManage.html b/src/main/resources/views/platform/fitnessWalk/activityManage.html new file mode 100644 index 0000000..c2fffad --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/activityManage.html @@ -0,0 +1,1852 @@ + + + + +

+ + + + + + + +
+ +
+
+ + + 确 定 + +
+ + + + + + + + + + + + + + {{viewData.name}} + + + + + {{viewData.address}} + + + + + + + + + {{moment(viewData.apply_start_time).format('YYYY-MM-DD HH:mm:ss')}} + + + + + {{moment(viewData.apply_end_time).format('YYYY-MM-DD HH:mm:ss')}} + + + + + + + + {{moment(viewData.start_time).format('YYYY-MM-DD HH:mm:ss')}} + + + + + {{moment(viewData.end_time).format('YYYY-MM-DD HH:mm:ss')}} + + + + + + + 打卡模式 + 计步模式 + GPS模式 + + + + + {{viewData.dailyLottery?viewData.dailyLottery:'暂无'}} + + + + + {{viewData.walkingStepCount?viewData.walkingStepCount:'暂无'}} + + + + + + + +
暂无
+
+
+
+
+ + + + + + + + + + + + + + +
+
+ + +
+
+ +
+ + + 关 闭 + +
+ + + +
+ + + diff --git a/src/main/resources/views/platform/fitnessWalk/bindingRecord.html b/src/main/resources/views/platform/fitnessWalk/bindingRecord.html new file mode 100644 index 0000000..edd6214 --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/bindingRecord.html @@ -0,0 +1,287 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/src/main/resources/views/platform/fitnessWalk/punchStatistics.html b/src/main/resources/views/platform/fitnessWalk/punchStatistics.html new file mode 100644 index 0000000..dd78361 --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/punchStatistics.html @@ -0,0 +1,262 @@ + +
+ + + + + +
+ + + + + diff --git a/src/main/resources/views/platform/fitnessWalk/stepRanking.html b/src/main/resources/views/platform/fitnessWalk/stepRanking.html new file mode 100644 index 0000000..d56e6ce --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/stepRanking.html @@ -0,0 +1,197 @@ + + +
+ + + + + + + + + + + + + + + + +
+ + + diff --git a/src/main/resources/views/platform/fitnessWalk/stepStatistics.html b/src/main/resources/views/platform/fitnessWalk/stepStatistics.html new file mode 100644 index 0000000..4f13137 --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/stepStatistics.html @@ -0,0 +1,224 @@ + +
+ + + + +
+ + + + + diff --git a/src/main/resources/views/platform/fitnessWalk/stepWining.html b/src/main/resources/views/platform/fitnessWalk/stepWining.html new file mode 100644 index 0000000..ef54e3c --- /dev/null +++ b/src/main/resources/views/platform/fitnessWalk/stepWining.html @@ -0,0 +1,238 @@ + + +
+ + + + + + + + 奖项名称: + + + + {{ item.name }} + + + + + + + + + + + + + + + + + +
+ + +