condolence jug

This commit is contained in:
zhaoxinyu
2024-04-28 16:50:47 +08:00
parent 50f3c1c6e2
commit 9affbf3f04
32 changed files with 6098 additions and 3 deletions
@@ -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:";
}
@@ -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<Cascader> children;
}
@@ -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;
}
@@ -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<NutMap> 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();
}
}
}
@@ -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<Object> 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<String> 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<String, Object> 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<String> 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_task> 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_task> 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<DateTime> 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());
}
}
}
}
@@ -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 {
}
@@ -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<NutMap> 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<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId);
return Result.success(list);
}
@At
@Ok("json:full")
@RequiresPermissions("fitnessWalk.punchStatistics")
public Result unionCheckInData(String activityId, String unionId) {
List<JSONObject> 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<NutMap> list = fitnessWalkPunchStatisticsService.unionRegCheckInNum(activityId, null);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("分工会", "unionname", 20));
entities.add(new ExcelExportEntity("报名人数", "regCount", 20));
entities.add(new ExcelExportEntity("打卡人数", "checkInCount", 20));
try {
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<JSONObject> list = fitnessWalkPunchStatisticsService.unionRegistrationData(activityId, unionId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
entities.add(new ExcelExportEntity("报名时间", "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<JSONObject> 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<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
entities.add(new ExcelExportEntity("点位总数", "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<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotGetGiftVoucherUsers(activityId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
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<JSONObject> list = fitnessWalkPunchStatisticsService.exportNotUseGiftVoucherUsers(activityId);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("单位", "unitname", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20));
try {
ViTool.excelResponse(response, "导出未使用礼品券用户.xlsx");
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, list);
workbook.write(response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -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<NutMap> steps = Json.fromJsonAsList(NutMap.class, monthSteps);
/*//前一个月的时间
DateTime dateTime = DateUtil.offsetMonth(new Date(), -1);
String format = DateUtil.format(dateTime, "yyyyMM");
//上一个月的步数
List<NutMap> 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<FitnessWalkStep> 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<Date> 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<NutMap> thisMonthSteps = (List<NutMap>) CollectionUtil.subtract(steps,lastMonthSteps);*/
//判断数据是否完整 微信运动会在晚上10点多进行步数的更新 会导致31天前的步数获取变为0 所以这里去除掉第一个元素 即为31天前的数据 每次只保存最近30天的数据
if (Lang.isNotEmpty(steps) && steps.size() == 31) {
steps.remove(0);
}
//如果在活动开始之前进来了 就只保存近7天的数据 不然前台展示为空 不好看
List<FitnessWalkStep> 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<Date> 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<String, Object> map = new HashMap<>();
// List<Integer> userStepList = new ArrayList<>();
// List<Long> 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<FitnessWalkStep> 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<FitnessWalkActivity.CustomLotteryRule> customLotteryRules = activity.getCustomLotteryRules();
List<FitnessWalkStep> 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<NutMap> result = new ArrayList<>();
for (FitnessWalkActivity.CustomLotteryRule rule : customLotteryRules) {
NutMap nutMap = NutMap.NEW();
List<FitnessWalkStep> 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<FitnessWalkAwardUser> 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)));
}
}
@@ -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<NutMap> stepRankingList = fitnessWalkCommonService.getStepRankingList(searchName, searchKeyword, activityId, unionId, unitId, mode);
List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
no.setFormat("isAddIndex");
entityList.add(no);
entityList.add(new ExcelExportEntity("姓名", "username", 20));
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
entityList.add(new ExcelExportEntity("分工会", "unionname", 20));
entityList.add(new ExcelExportEntity("单位", "unitname", 20));
entityList.add(new ExcelExportEntity("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);
}
}
@@ -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<NutMap> exportList = baseService.listMap(sql);
List<ExcelExportEntity> 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();
}
}
}
@@ -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<NutMap> winingRankingUserList = fitnessWalkCommonService.getWiningRankingUserList(activityId);
List<ExcelExportEntity> 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<NutMap> awardList = map.getAsList("awardList", NutMap.class);
awardList.forEach(v->v.setv("applyDate",DateUtil.format(v.getTime("applyDate"),"yyyy-MM-dd")));
zipOutputStream.putNextEntry(new ZipEntry(map.getString("title") + ".xls"));
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, awardList);
workbook.write(zipOutputStream);
zipOutputStream.closeEntry();
}
zipOutputStream.flush();
zipOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -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<PunchLotteryPrize> punchLotteryPrizes;
private Boolean showGiftTicket;
private List<Pts> pts;
private List<Point> linePoints;
private List<Point> linePoints2;
//是否按顺序签到
private Boolean isOrderSignIn;
//是否多条线路
private Boolean isMultipleLines;
//抽奖模式 none无 everyday每天 monthly每月 custom自定义
private String lotteryMode;
//每月抽奖模式抽奖时间
private List<Date> everyMonthLotteryTime;
//自定义模式抽奖抽奖时间规则
private List<CustomLotteryRule> customLotteryRules;
//每日模式抽奖抽奖时间规则
private DayLotteryRule dayLotteryRule;
//随机图片数组
private List<String> randomPics;
private List<String> 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<String> 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;
}
}
@@ -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;
}
@@ -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;
}
@@ -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<FitnessWalkActivity> getAllActivity();
/**
* 级联活动
*/
List<Cascader> 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<NutMap> getStepRankingList(String searchName, String searchKeyword, String activityId, String unionId, String unitId, String mode);
/**
* 获取中奖榜
*
* @param activityId 活动id
* @return
*/
List<NutMap> getWiningRankingUserList(String activityId);
}
@@ -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<NutMap> unionRegCheckInNum(String activityId, String unionId);
List<JSONObject> unionRegistrationData(String activityId, String unionId);
List<JSONObject> unionCheckInData(String activityId, String unionId);
List<JSONObject> exportNotGetGiftVoucherUsers(String activityId);
List<JSONObject> exportNotUseGiftVoucherUsers(String activityId);
}
@@ -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<String> 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<String> 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<FitnessWalkActivity> getAllActivity() {
List<FitnessWalkActivity> 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<Cascader> 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<Cascader> 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<Cascader> 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_task> 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<String> 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<String, Object> 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<FitnessWalkActivity.CustomLotteryRule> 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<String> 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<String, Object> 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<NutMap> 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<NutMap> getWiningRankingUserList(String activityId) {
FitnessWalkActivity activity = getActivity(activityId);
List<NutMap> resultMapList = new ArrayList<>();
if ("everyday".equals(activity.getLotteryMode())) {
String lastDayFormat = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd");
List<FitnessWalkAwardUser> awardUserList = dao().query(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId)
.and("DATE( applyDate )", ">=", lastDayFormat));
//昨天的中奖榜
List<FitnessWalkAwardUser> 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<FitnessWalkAwardUser> thisDayAwardUserList = (List<FitnessWalkAwardUser>) 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<FitnessWalkActivity.CustomLotteryRule> customLotteryRules = activity.getCustomLotteryRules();
//当前活动中奖榜单
List<FitnessWalkAwardUser> awardUserList = dao().query(FitnessWalkAwardUser.class, Cnd.where("activityId", "=", activityId));
for (FitnessWalkActivity.CustomLotteryRule rule : customLotteryRules) {
NutMap map = new NutMap();
List<FitnessWalkAwardUser> 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;
}
}
@@ -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<NutMap> unionRegCheckInNum(String activityId, String unionId) {
List<Sys_union> 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<String, Integer> 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<String, Integer> 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<NutMap> 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<JSONObject> 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<JSONObject> list = jsonObject.getJSONArray("data").stream().map(v -> JSONObject.parseObject((String) v)).collect(Collectors.toList());
return list;
}
@Override
public List<JSONObject> 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<JSONObject> 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<JSONObject> 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<String> giftUserLoginNames = giftUserJsonObject.getJSONArray("data").stream().map(v -> {
JSONObject jo = JSON.parseObject((String) v);
return jo.getString("loginname");
}).collect(Collectors.toList());
List<JSONObject> 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<JSONObject> 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());
}
}
@@ -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<String, Object> 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<Object, Object> 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<String, String>();
mf.put("fileid", fileId);
mf.put("max_age", 7200);
ArrayList<Map> 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");
}
}
@@ -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 -> {
@@ -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<NutMap> 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<NutMap>) 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<NutMap>) Daos.query(dao, sql.toString(), Sqls.callback.maps());
}
List<FitnessWalkAwardUser> 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));
}
}
@@ -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<String> getCronExeTimes(String cronExpression) throws Exception;
List<String> getCronExeTimesPlus(String cronExpression) throws Exception;
}
@@ -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<String> getCronExeTimesPlus(String cronExpression) throws Exception {
// 创建一个列表来存储执行时间
List<String> executionTimes = new ArrayList<>();
// 创建 CronTriggerImpl 对象,并设置 cron 表达式
CronTriggerImpl cronTrigger = new CronTriggerImpl();
cronTrigger.setCronExpression(new CronExpression(cronExpression));
// 计算未来的执行时间
List<Date> 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;
}
}
@@ -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) {
@@ -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())) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

File diff suppressed because it is too large Load Diff
@@ -0,0 +1,287 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">姓名工号:</div>
<div class="search-item-option">
<el-input placeholder="请输入关键字查询" v-model="pageForm.keyWord"></el-input>
</div>
</div>
<div class="search-item">
<div class="search-item-label">所属工会:</div>
<div class="search-item-option">
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择院级工会"
style="width: 100%">
<el-option
v-for="item in unionList"
:key="item.id"
:label="item.unionname"
:value="item.id">
</el-option>
</el-select>
</div>
</div>
<div class="search-query">
<el-button icon="el-icon-search" type="primary" @click="doSearch"></el-button>
</div>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="绑定列表">
<template #func>
<el-dropdown @command="dropdownCommand">
<el-button size="medium" type="danger">
批量删除&emsp;
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'delete2'}">
删除已选
</el-dropdown-item>
<el-dropdown-item :command="{type:'delete3'}">
全部删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</table-tool>
<el-table :data="tableData" style="width: 100%" row-key="_id" @sort-change="pageOrder"
v-loading="tabLoading" @selection-change="handleSelectionChange">
<el-table-column :reserve-selection="true"
type="selection"
width="55">
</el-table-column>
<el-table-column align="center" header-align="center" label="序号" width="60" type="index">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column label="工号" prop="loginname" header-align="center"
align="center"></el-table-column>
<el-table-column label="姓名" prop="username" header-align="center"
align="center"></el-table-column>
<el-table-column label="openid" prop="openid" header-align="center"
align="center"></el-table-column>
<el-table-column align="center" header-align="center" label="操作" fixed="right" width="240px">
<template scope="{row}">
<el-button type="danger" @click="doDelete(row._id)" size="mini"
icon="el-icon-delete"></el-button>
</template>
</el-table-column>
</el-table>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</el-card>
</guava>
</div>
<script>
const vue = new Vue({
el: '#app',
data() {
return {
v: "index",
stepActive: 0,
tabLoading: false,
subDis: false,
formData: {},
tableData: [],
pageForm: {
searchName: "name",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: ""
},
multipleSelection: [],
unionList: []
}
},
methods: {
dropdownCommand: function (command) {
const {type, data} = command
if (type == 'delete2') {
this.doDelete2()
} else if (type == 'delete3') {
this.doDelete3()
}
},
async doDelete(id) {
this.$confirm('是否确定删除!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" == a) {//确认后再执行
const {
code,
data,
msg
} = await $.post(loc() + "/delete", {ids: JSON.stringify([id])})
if (code == 0) {
this.$message({
message: msg,
type: 'success'
});
this.pageData()
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}
}
})
},
async doDelete2() {
if (!this.multipleSelection.length) {
this.$notify({
title: '提示',
message: '请先勾选需要删除的人员!',
type: 'warning'
});
return
}
this.$confirm('是否确定删除!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" === a) {//确认后再执行
const arr = this.multipleSelection.map(v => {
return v._id
})
const {
code,
data,
msg
} = await $.post(loc() + "/delete", {ids: JSON.stringify(arr)})
if (code == 0) {
this.multipleSelection = []
this.$message({
message: msg,
type: 'success'
});
this.pageData()
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}
}
})
},
async doDelete3() {
this.$confirm('是否确定删除全部登录记录!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" == a) {//确认后再执行
const {code, data, msg} = await $.post(loc() + "/deleteAll")
if (code == 0) {
this.multipleSelection = []
this.$message({
message: msg,
type: 'success'
});
this.pageData()
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}
}
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
doSearch() {
this.tabKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageData()
},
pageOrder(column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange(val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange(val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData() {//加载分页数据
sublime.showLoadingbar();//显示loading
this.tabLoading = true
$.post(loc() + "/pageData", this.pageForm, (data) => {
sublime.closeLoadingbar();//关闭loading
this.tabLoading = false
if (data.code == 0) {
this.tableData = data.data.list;
this.pageForm.totalCount = data.data.totalCount;
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
},
async created() {
this.pageData();
if ("${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')}" === 'true') {
this.unionList = await getUnionList(null)
} else {
this.unionList = await getUnionList("${@shiro.getPrincipalProperty('unit').getUnionid()}")
}
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,262 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">年份:</div>
<div class="search-item-option">
<el-date-picker
:clearable="false"
placeholder="选择年"
style="width: 100%"
@change="getCascadersActivity"
type="year" v-model="pageForm.year"
value-format="yyyy">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">活动:</div>
<div class="search-item-option">
<el-cascader
style="width: 100%"
@change="doSearch"
v-model="pageForm.activityId"
:options="activityOptions"
:props="{ checkStrictly: true,emitPath:false}"
clearable></el-cascader>
</div>
</div>
<div class="search-query">
<el-button @click="doSearch" icon="el-icon-search" type="primary"></el-button>
</div>
</div>
</el-card>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="参与列表">
<template #func>
<el-button @click="window.open(loc()+'/exportUnionRegCheckInNum?activityId='+pageForm.activityId)"
class="ml10"
size="small"
type="primary"
icon="el-icon-download">
导出报名及打卡人数
</el-button>
<el-button @click="window.open(loc()+'/exportNotGetGiftVoucherUsers?activityId='+pageForm.activityId)"
class="ml10"
size="small"
type="primary"
icon="el-icon-download">
导出未取得礼品券人员
</el-button>
<el-button @click="window.open(loc()+'/exportNotGetGiftVoucherUsers?activityId='+pageForm.activityId)"
class="ml10"
size="small"
type="primary"
icon="el-icon-download">
导出未使用礼品券用户
</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize" show-summary>
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
width="80px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
</el-table-column>
<el-table-column label="操作" width="300px">
<template scope="{row}">
<el-button @click="viewReg(row)" size="mini" type="primary">查看报名情况</el-button>
<el-button @click="viewCheckIn(row)" size="mini" type="primary">查看打卡情况</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
<template #view>
<el-card shadow="never" v-if="viewIndex==='regTableShow'">
<template #header>
<div style="display: flex;justify-content: space-between;align-items: center">
<h4 style="color: rgb(24, 103, 176);">
{{viewUnion.unionname}}
</h4>
<el-button type="primary" size="mini" icon="el-icon-download"
@click="exportRegUsers">
导出名单
</el-button>
</div>
</template>
<el-table :data="regTableData" style="width: 100%" row-key="_id" max-height="600px">
<el-table-column label="工号" prop="loginname"></el-table-column>
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitname" show-overflow-tooltip></el-table-column>
<el-table-column label="电话" prop="mobile"></el-table-column>
<el-table-column label="报名时间" prop="register_time_str"></el-table-column>
</el-table>
</el-card>
<el-card shadow="never" v-else-if="viewIndex==='checkInTableShow'">
<template #header>
<div style="display: flex;justify-content: space-between;align-items: center">
<h4 style="color: rgb(24, 103, 176);">
{{viewUnion.unionname}}
</h4>
<el-button type="primary" size="mini" icon="el-icon-download"
@click="exportCheckInUsers">
导出名单
</el-button>
</div>
</template>
<el-table :data="regTableData" style="width: 100%" row-key="_id" max-height="600px">
<el-table-column label="工号" prop="loginname"></el-table-column>
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitname" show-overflow-tooltip></el-table-column>
<el-table-column label="电话" prop="mobile"></el-table-column>
<el-table-column label="点位总数" prop="pts_size"></el-table-column>
<el-table-column label="已打卡点位数" prop="sign_size"></el-table-column>
<el-table-column label="礼品券" prop="used">
<template scope="{row}">
<span v-if="row.used==null" class="text-danger">未取得</span>
<span v-else-if="row.used" class="text-success">已使用</span>
<span v-else-if="!row.used" class="text-warning">未使用</span>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
</guava>
</div>
<script>
let vue = new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{label: '分工会', prop: 'unionname'},
{label: '报名人数', prop: 'regCount'},
{label: '打卡人数', prop: 'checkInCount'},
],
unionOptions: [],
unitOptions: [],
pageForm: {
unionId: '',
unitId: '',
activityDate: [],
year: new Date().getFullYear() + '',
},
activityOptions: [],
regTableData: [],
checkInTableData: [],
viewIndex: '',
viewUnion: {}
}
},
methods: {
viewReg({id, unionname}) {
this.viewUnion.unionId = id
this.viewUnion.unionname = unionname
this.$refs.guava.view()
this.viewIndex = 'regTableShow'
$.get(loc() + '/unionRegistrationData', {
unionId: id,
activityId: this.pageForm.activityId
}).then(res => {
if (res.code === 0) {
this.regTableData = res.data
} else {
this.$message.error(res.msg)
}
})
},
viewCheckIn({id, unionname}) {
this.viewUnion.unionId = id
this.viewUnion.unionname = unionname
this.$refs.guava.view()
this.viewIndex = 'checkInTableShow'
$.get(loc() + '/unionCheckInData', {
unionId: id,
activityId: this.pageForm.activityId
}).then(res => {
if (res.code === 0) {
this.regTableData = res.data
} else {
this.$message.error(res.msg)
}
})
},
exportExcel() {
const {hdid, unionId, unitId, activityDate} = this.pageForm
let activityDate1 = []
if (activityDate && activityDate.length > 0) {
activityDate1 = JSON.stringify(activityDate)
}
window.open(loc() + '/exportExcel?hdid=' + hdid + '&unionId=' + unionId + '&unitId=' + unitId + '&activityDate=' + activityDate1)
},
activityDateChange() {
},
async unionChange(val) {
this.pageForm.unitId = null
this.unitOptions = await getUnits(val)
this.doSearch()
},
pageData() {
$.post(loc() + '/pageData', this.pageForm).then(res => {
if (res.code === 0) {
this.tableData = res.data
} else {
this.$message.error(res.msg)
}
})
},
async getCascadersActivity() {
const {code, data} = await $.get(loc() + '/getCascadersActivity', {year: this.pageForm.year})
this.activityOptions = data
if (this.activityOptions && this.activityOptions.length > 0) {
this.pageForm.activityId = this.activityOptions[0].value
this.pageData()
} else {
this.tableData = []
}
},
exportCheckInUsers() {
window.open(loc() + '/exportCheckInUsers?unionId=' + this.viewUnion.unionId + '&activityId=' + this.pageForm.activityId)
},
exportRegUsers(){
window.open(loc() + '/exportRegUsers?unionId=' + this.viewUnion.unionId + '&activityId=' + this.pageForm.activityId)
}
},
async created() {
this.unionOptions = await getUnions(null)
this.unitOptions = await getUnits(null)
await this.getCascadersActivity()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,197 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">年份:</div>
<div class="search-item-option">
<el-date-picker style="width: 100%"
class="mr5"
:picker-options="pickerOptions"
v-model="pageForm.year" :clearable="false"
type="year"
value-format="yyyy" @change="getAllActivity"
placeholder="选择年">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">活动:</div>
<div class="search-item-option">
<el-cascader
style="width: 100%"
@change="doSearch()"
v-model="pageForm.activityId"
:options="activityOptions"
:props="{ checkStrictly: true,emitPath:false}"
:clearable="false"></el-cascader>
</div>
</div>
<div class="search-item">
<div class="search-item-label">姓名工号:</div>
<div class="search-item-option">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
style="width: 100%" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 110px;">
<el-option label="姓名" value="u.username"></el-option>
<el-option label="工号" value="u.loginname"></el-option>
</el-select>
</el-input>
</div>
</div>
<template v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')}">
<div class="search-item">
<div class="search-item-label">所属工会:</div>
<div class="search-item-option">
<el-select @change="unionChange" clearable filterable style="width: 100%"
placeholder="请选择所属工会" v-model="pageForm.unionId">
<el-option
:key="item.id"
:label="item.unionname"
:value="item.id"
v-for="item in unionOptions">
</el-option>
</el-select>
</div>
</div>
<div class="search-item">
<div class="search-item-label">所属单位:</div>
<div class="search-item-option">
<el-select @change="doSearch" clearable filterable style="width: 100%"
placeholder="请选择所属单位" v-model="pageForm.unitId">
<el-option
:key="item.id"
:label="item.name"
:value="item.id"
v-for="item in unitOptions">
</el-option>
</el-select>
</div>
</div>
</template>
<div class="search-query">
<el-button @click="doSearch" icon="el-icon-search" type="primary"></el-button>
</div>
</div>
</el-card>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="排行榜">
<template #func>
<el-radio-group v-model="pageForm.mode" size="small" @change="doSearch">
<el-radio-button label="today">今日排行榜</el-radio-button>
<el-radio-button label="all">总排行榜</el-radio-button>
</el-radio-group>
<el-button @click="exportExcel" class="ml10" size="small" type="primary">导出{{pageForm.mode == 'today' ? '今日排行榜' : '总排行榜'}}</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize">
<el-table-column :index="indexMethod" align="center" header-align="center" label="排名" type="index"
width="80px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</guava>
</div>
<script>
const vue = new Vue({
el: '#app',
mixins:[initTableMixins],
data() {
return {
pickerOptions: {
disabledDate(time) {
return (
time.getFullYear() > new Date().getFullYear()
);
}
},
pageForm: {
year: new Date().getFullYear() + '',
mode:'today',
searchName:'u.username',
unionId:'',
unitId:''
},
unionOptions: [],
unitOptions: [],
activityOptions: [],
tableColumns: [
{label: '姓名', prop: 'username'},
{label: '工号', prop: 'loginname'},
{label: '分工会', prop: 'unionname', sortable: true},
{label: '单位', prop: 'unitname'},
{label: '步数', prop: 'step', sortable: true},
],
}
},
methods: {
exportExcel(){
const {searchName,searchKeyword,activityId,unionId,unitId,mode} = this.pageForm
window.open( loc() + '/exportExcel?searchName=' + searchName + '&searchKeyword=' + searchKeyword +
'&activityId=' + activityId +'&unionId=' + unionId + '&unitId=' + unitId + '&mode=' + mode)
},
async getAllActivity() {
this.pageForm.activityId = ''
this.activityOptions = []
const {data} = await $.get('/platform/fitnessWalk/activityManage/getAllActivity', this.pageForm)
if (data == null || data.length === 0) {
this.tableData = []
return
} else {
this.activityOptions = data.filter(item => item.activityModel === 'stepCount')
}
if (this.activityOptions) {
this.pageForm.activityId = this.activityOptions[0]._id
}
},
async unionChange(val) {
this.pageForm.unitId = null
this.unitOptions = await getUnits(val)
this.doSearch()
},
async getCascadersActivity() {
const {code, data} = await $.get(loc() + '/getCascadersActivity', {year: this.pageForm.year})
this.activityOptions = data
if (this.activityOptions && this.activityOptions.length > 0) {
this.pageForm.activityId = this.activityOptions[0].value
this.doSearch()
} else {
this.tableData = []
}
}
},
async created() {
this.unionOptions = await getUnions(null)
this.unitOptions = await getUnits(null)
await this.getCascadersActivity()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,224 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">年份:</div>
<div class="search-item-option">
<el-date-picker
:clearable="false"
placeholder="选择年"
style="width: 100%"
@change="getCascadersActivity"
type="year" v-model="pageForm.year"
value-format="yyyy">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">活动:</div>
<div class="search-item-option">
<el-cascader
style="width: 100%"
@change="doSearch();getActivityById()"
v-model="pageForm.activityId"
:options="activityOptions"
:props="{ checkStrictly: true,emitPath:false}"
:clearable="false"></el-cascader>
</div>
</div>
<div class="search-item">
<div class="search-item-label">日期范围:</div>
<div class="search-item-option">
<el-date-picker
end-placeholder="结束日期"
range-separator="至"
start-placeholder="开始日期"
type="daterange"
style="width: 100%"
@change="activityDateChange"
value-format="yyyy-MM-dd"
v-model="pageForm.activityDate">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">姓名工号:</div>
<div class="search-item-option">
<el-input v-model="pageForm.searchKeyword" max="20" placeholder="请输入工号或者姓名查询" clearable></el-input>
</div>
</div>
<template v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')}">
<div class="search-item">
<div class="search-item-label">所属工会:</div>
<div class="search-item-option">
<el-select @change="unionChange" clearable filterable style="width: 100%"
placeholder="请选择所属工会" v-model="pageForm.unionId">
<el-option
:key="item.id"
:label="item.unionname"
:value="item.id"
v-for="item in unionOptions">
</el-option>
</el-select>
</div>
</div>
<div class="search-item">
<div class="search-item-label">所属单位:</div>
<div class="search-item-option">
<el-select @change="doSearch" clearable filterable style="width: 100%"
placeholder="请选择所属单位" v-model="pageForm.unitId">
<el-option
:key="item.id"
:label="item.name"
:value="item.id"
v-for="item in unitOptions">
</el-option>
</el-select>
</div>
</div>
</template>
<div class="search-query">
<el-button @click="doSearch" icon="el-icon-search" type="primary"></el-button>
</div>
</div>
</el-card>
<el-card class="mt20" shadow="never">
<table-tool :app="this" label="步数列表">
<template #func>
<el-button @click="exportExcel" class="ml10" size="small" type="primary">导出</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize">
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
width="80px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop==='registerNum'">
<el-link @click="openView(row.id)" type="primary">
{{row.registerNum}}
</el-link>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
</div>
<script>
let vue = new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{label: '姓名', prop: 'username'},
{label: '工号', prop: 'loginname'},
{label: '单位', prop: 'unitname'},
{label: '分工会', prop: 'unionname', sortable: true},
{label: '当前步数', prop: 'step', sortable: true},
{label: '日期', prop: 'prizeData', sortable: true}
],
unionOptions: [],
unitOptions: [],
pageForm: {
unionId: '',
unitId: '',
activityDate: [],
activityId: null,
year: new Date().getFullYear() + '',
},
activityOptions: [],
activityDatePickerOptions: {
disabledDate: time => {
return (
time <= moment(this.activityInfo.endTime) || time >= moment(this.activityInfo.startTime)
);
}
},
activityInfo:{},
}
},
methods: {
exportExcel() {
const {activityId, unionId, unitId, activityDate} = this.pageForm
let activityDate1 = []
if (activityDate && activityDate.length > 0) {
activityDate1 = JSON.stringify(activityDate)
}
window.open(loc() + '/exportExcel?activityId=' + activityId + '&unionId=' + unionId + '&unitId=' + unitId + '&activityDate=' + activityDate1)
},
activityDateChange() {
// this.$set(this.pageForm, "activityDate", [])
},
async unionChange(val) {
this.pageForm.unitId = null
this.unitOptions = await getUnits(val)
this.doSearch()
},
async getCascadersActivity() {
const {code, data} = await $.get(loc() + '/getCascadersActivity', {year: this.pageForm.year})
this.activityOptions = data
if (this.activityOptions && this.activityOptions.length > 0) {
this.pageForm.activityId = this.activityOptions[0].value
this.doSearch()
} else {
this.tableData = []
}
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
let pageForm = clone(this.pageForm)
if (pageForm.activityDate && pageForm.activityDate.length > 0) {
pageForm.activityDate = JSON.stringify(pageForm.activityDate)
}
$.post(loc() + "/pageData", pageForm, (data) => {
sublime.closeLoadingbar();
this.tableLoading = false
if (data.code === 0) {
this.tableData = data.data.list;
this.pageForm.totalCount = data.data.totalCount;
} else {
this.$message.error(data.msg);
}
}, "json");
},
async getActivityById(){
const resp = await $.get('/platform/fitnessWalk/activityManage/findOne',{id:this.pageForm.activityId})
if (resp.code === 0){
this.activityInfo = resp.data
}
}
},
async created() {
this.unionOptions = await getUnions(null)
this.unitOptions = await getUnits(null)
await this.getCascadersActivity()
await this.getActivityById();
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,238 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.query-row {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.query-row:not(:last-child) {
border-bottom: 1px dashed rgb(230, 230, 230);
}
.query-row-title {
width: 120px;
}
</style>
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">年份:</div>
<div class="search-item-option">
<el-date-picker style="width: 100%"
class="mr5"
:picker-options="pickerOptions"
v-model="pageForm.year" :clearable="false"
type="year"
value-format="yyyy" @change="getAllActivity"
placeholder="选择年">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">活动:</div>
<div class="search-item-option">
<el-cascader
style="width: 100%"
@change="doSearch()"
v-model="pageForm.activityId"
:options="activityOptions"
:props="{ checkStrictly: true,emitPath:false}"
:clearable="false"></el-cascader>
</div>
</div>
<!--<div class="search-item">
<div class="search-item-label">姓名工号:</div>
<div class="search-item-option">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
style="width: 100%" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 110px;">
<el-option label="姓名" value="u.username"></el-option>
<el-option label="工号" value="u.loginname"></el-option>
</el-select>
</el-input>
</div>
</div>
<template v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('H04')||@shiro.hasRole('A06')}">
<div class="search-item">
<div class="search-item-label">所属工会:</div>
<div class="search-item-option">
<el-select @change="unionChange" clearable filterable style="width: 100%"
placeholder="请选择所属工会" v-model="pageForm.unionId">
<el-option
:key="item.id"
:label="item.unionname"
:value="item.id"
v-for="item in unionOptions">
</el-option>
</el-select>
</div>
</div>
<div class="search-item">
<div class="search-item-label">所属单位:</div>
<div class="search-item-option">
<el-select @change="doSearch" clearable filterable style="width: 100%"
placeholder="请选择所属单位" v-model="pageForm.unitId">
<el-option
:key="item.id"
:label="item.name"
:value="item.id"
v-for="item in unitOptions">
</el-option>
</el-select>
</div>
</div>
</template>-->
<div class="search-query">
<el-button @click="doSearch" icon="el-icon-search" type="primary"></el-button>
</div>
</div>
</el-card>
<el-card class="mt10" shadow="never" style="height: 80px">
<el-row type="flex" align="middle" class="query-row">
<el-col class="query-row-title">奖项名称:</el-col>
<el-col class="query-row-content">
<el-radio-group v-model="changKeyItem" @change="subsectionChange(changKeyItem)" size="small">
<el-radio
style="margin-right: 10px;cursor: pointer"
border
v-for="item in subsectionList"
:key="item.value"
:label="item.name">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-col>
</el-row>
</el-card>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="中奖榜">
<template #func>
<el-button @click="exportUserStepWining" class="ml10" size="small" type="primary">导出中奖名单</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize">
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
width="80px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns">
</el-table-column>
</el-table>
</el-card>
</guava>
</div>
<script>
const vue = new Vue({
el: '#app',
mixins:[initTableMixins],
data() {
return {
pickerOptions: {
disabledDate(time) {
return (
time.getFullYear() > new Date().getFullYear()
);
}
},
pageForm: {
year: new Date().getFullYear() + '',
mode:'today',
searchName:'u.username',
activityId:null
},
unionOptions: [],
unitOptions: [],
activityOptions: [],
tableColumns: [
{label: '姓名', prop: 'username'},
// {label: '工号', prop: 'loginname'},
{label: '分工会', prop: 'unionName', sortable: true},
{label: '单位', prop: 'unitName'},
{label: '奖项名称', prop: 'awardName'},
],
allDataList:[],
subsectionList:[],
subsectionIndex: 0,
changKeyItem:'',
}
},
methods: {
exportUserStepWining(){
window.open( loc() + '/exportUserStepWining?activityId=' + this.pageForm.activityId)
},
async getAllActivity() {
this.pageForm.activityId = ''
this.activityOptions = []
const {data} = await $.get('/platform/fitnessWalk/activityManage/getAllActivity', this.pageForm)
if (data == null || data.length === 0) {
this.tableData = []
return
} else {
this.activityOptions = data.filter(item => item.activityModel === 'stepCount')
}
if (this.activityOptions) {
this.pageForm.activityId = this.activityOptions[0]._id
}
},
async unionChange(val) {
this.pageForm.unitId = null
this.unitOptions = await getUnits(val)
this.doSearch()
},
subsectionChange(key) {
const data = this.allDataList.find(item => item.title === key)
this.tableData = data.awardList
},
async pageData(){
const resp = await $.post(loc() + '/getUserStepWining',this.pageForm)
if (resp.code === 0){
this.allDataList = resp.data
this.subsectionList = resp.data.map(v => {
return {
name: v.title,
key: v.title
}
})
this.tableData = this.allDataList[0].awardList
this.changKeyItem = this.allDataList[0].title
}
},
async getCascadersActivity() {
const {code, data} = await $.get(loc() + '/getCascadersActivity', {year: this.pageForm.year})
this.activityOptions = data
if (this.activityOptions && this.activityOptions.length > 0) {
this.pageForm.activityId = this.activityOptions[0].value
this.doSearch()
} else {
this.tableData = []
}
},
},
async created() {
this.unionOptions = await getUnions(null)
this.unitOptions = await getUnits(null)
await this.getCascadersActivity()
}
})
</script>
<!--#
}
#-->