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 0000000..2d952e1 Binary files /dev/null and b/src/main/resources/static/fitness_walk_login_bg.png differ 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 }} + + + + + + + + + + + + + + + + + +
+ + +