# Conflicts:
#	src/main/resources/views/platform/zhgh/staffbenefit/excellentRecuperation/activityList/basicForm.js
This commit is contained in:
2025-09-04 09:46:18 +08:00
336 changed files with 28657 additions and 24235 deletions
@@ -1,15 +1,25 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityDeclareInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import com.budwk.app.zhgh.staffmanage.member.models.MemberChangeRecord;
import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
@@ -22,8 +32,11 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
/**
* @version 1.0
@@ -43,6 +56,8 @@ public class ActivityDeclareApplyController {
@Inject
private FlowEngine flowEngine;
@Inject
private FlowCommonService flowCommonService;
@Inject
private ActivityDeclareService activityDeclareService;
@At("")
@@ -57,84 +72,73 @@ public class ActivityDeclareApplyController {
public void form() {
}
@At
@SaCheckPermission("activityDeclare.apply")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/apply/view.html")
public void view() {
}
@At
@ApiOperation("活动申报,我的申请列表")
@SaCheckPermission("activityDeclare.apply")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.startTime,
info.endTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(SELECT MAX(id) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'startTask') AS startTaskId
FROM
activity_declare_info info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
@At
@ApiOperation("活动申报,查看活动申报")
@SaCheckPermission("activityDeclare.apply")
public Result findOne(@Valid String id) {
ActivityDeclareInfo info = dao.fetch(ActivityDeclareInfo.class, id);
return Result.success().addData(info);
}
@At
@ApiOperation("删除活动申报")
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("保存申请")
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "删除活动申报id: ${args[0]}")
public Result onDelete(@Valid String id) {
dao.clear(ActivityDeclareInfo.class, Cnd.where("id", "=", id));
// 删除流程相关
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
@SLog(tag = "活动申报", msg = "保存申请,申请人: ${args[0].username}")
public Result save(@Param("data") ActivityDeclareInfo activityDeclareInfo) {
// 计算预算总金额
double sum = activityDeclareInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getBudgetPrice(), 0D))
.sum();
activityDeclareInfo.setBudgetMoney(new BigDecimal(sum));
dao.insertOrUpdate(activityDeclareInfo);
return Result.success();
}
@At
@ApiOperation("提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "提交申请,申请人: ${args[0].username}")
public Result submit(@Param("data") ActivityDeclareInfo activityDeclareInfo){
activityDeclareInfo.setYear(ObjectUtil.defaultIfNull(activityDeclareInfo.getYear(), DateUtil.thisYear()));
// 计算预算总金额
double sum = activityDeclareInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getBudgetPrice(), 0D))
.sum();
activityDeclareInfo.setBudgetMoney(new BigDecimal(sum));
// 保存数据
dao.insertOrUpdate(activityDeclareInfo);
// 开启流程实例
Dict args = Dict.create();
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, activityDeclareInfo);
args.set("type", activityDeclareInfo.getActivityType());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("HDSB", activityDeclareInfo.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}
@At
@ApiOperation("重新提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "重新提交申请,申请人: ${args[0].username}")
public Result submitAgain(@Param("data") ActivityDeclareInfo activityDeclareInfo, @Param("taskId") Long taskId) {
activityDeclareInfo.setYear(ObjectUtil.defaultIfNull(activityDeclareInfo.getYear(), DateUtil.thisYear()));
// 计算预算总金额
double sum = activityDeclareInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getBudgetPrice(), 0D))
.sum();
activityDeclareInfo.setBudgetMoney(new BigDecimal(sum));
dao.insertOrUpdate(activityDeclareInfo);
Dict dict = Dict.create();
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
dict.set("type", activityDeclareInfo.getActivityType());
flowCommonService.executeTask(dict);
return Result.success();
}
}
@@ -1,17 +1,28 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -50,7 +61,67 @@ public class ActivityDeclareBranchUnionController {
@ApiOperation("分工会审核列表")
@SaCheckPermission("activityDeclare.branchUnion")
public Result pageData(CommonPageParam pageParam) {
return Result.success();
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_declare_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "54f481d7-3239-4cd2-882d-e1cc18ea86eb");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -19,6 +34,8 @@ import org.nutz.mvc.annotation.Ok;
@At("/platform/activityDeclare/clubPrincipal")
public class ActivityDeclareClubPrincipalController {
@Inject
private ActivityDeclareService activityDeclareService;
@At("")
@SaCheckPermission("activityDeclare.clubPrincipal")
@@ -31,4 +48,72 @@ public class ActivityDeclareClubPrincipalController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/clubprincipal/form.html")
public void form() {
}
@At
@ApiOperation("活动申报,协会负责人审核列表")
@SaCheckPermission("activityDeclare.clubPrincipal")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_declare_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "06d5979b-b52f-4df1-8974-087568322cd6");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -0,0 +1,296 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.BpmProcessConstant;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.bpm.vo.BpmTaskApprovalRecordVo;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.vo.ProcessTaskVO;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityDeclareInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.ActivityBudgetVO;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
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.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
/**
* @version 1.0
* @Author zzr
* @nameActivityDeclareMineController
* @Date 2025/8/26 10:14
* @注释
*/
@Slf4j
@IocBean
@Ok("json")
@ApiOperation("我的活动申报")
@At("/platform/activityDeclare/mine")
public class ActivityDeclareMineController {
@Inject
private Dao dao;
@Inject
private FlowEngine flowEngine;
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@Inject
private ActivityDeclareService activityDeclareService;
@At("")
@SaCheckPermission("activityDeclare.mine")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/mine/index.html")
public void index() {
}
@At
@ApiOperation("活动申报,我的申请列表")
@SaCheckPermission("activityDeclare.mine")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
FROM
activity_declare_info info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_MEMBER_ADMIN.name())) {
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
cnd.and("info.unionId", "=", SecurityUtil.getUnionId());
} else {
cnd.and("info.userId", "=", SecurityUtil.getUserId());
}
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
@At
@ApiOperation("活动申报,查看活动申报")
@SaCheckPermission("activityDeclare.mine")
public Result findOne(@Valid String id) {
ActivityDeclareInfo info = dao.fetch(ActivityDeclareInfo.class, id);
return Result.success().addData(info);
}
@At
@ApiOperation("删除活动申报")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("activityDeclare.mine")
@SLog(tag = "活动申报", msg = "删除活动申报id: ${args[0]}")
public Result onDelete(@Valid String id) {
dao.clear(ActivityDeclareInfo.class, Cnd.where("id", "=", id));
// 删除流程相关
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
// 如果有报销的流程,也一并删除
ActivityReimbursementInfo reimbursementInfo = dao.fetch(ActivityReimbursementInfo.class, Cnd.where("declareId", "=", id));
if (Lang.isNotEmpty(reimbursementInfo)) {
dao.clear(ActivityReimbursementInfo.class, Cnd.where("id", "=", reimbursementInfo.getId()));
// 删除流程相关
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(reimbursementInfo.getId());
}
return Result.success();
}
@At
@Ok("void")
@SaCheckPermission("activityDeclare.mine")
@SLog(tag = "活动申报", msg = "导出活动申报表")
public void doExportDeclare(@Valid String id, HttpServletResponse response) {
HashMap<String, Object> docData = new HashMap<>();
Sql sql = Sqls.create("""
SELECT
info.*,
ins.id AS instanceId
FROM
`activity_declare_info` info
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
WHERE
ins.state = 20 AND info.id = @id
""").setParam("id", id);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap info = (NutMap) sql.getResult();
String activityContent = info.getString("activityContent");
info.put("activityContent", sysOfficeTemplateUtil.convertRichTextToDocText(activityContent));
docData.put("schoolName", Globals.AppName);
docData.put("info", info);
List<ProcessTaskVO> doneTaskVos = new ArrayList<>();
List<ProcessTask> doneTaskList = flowEngine.processTaskService().getDoneTaskList(info.getLong("instanceId"), null);
for (ProcessTask doneTask : doneTaskList) {
ProcessTaskVO taskVO = flowEngine.processTaskService().findById(doneTask.getId());
doneTaskVos.add(taskVO);
}
// 分工会审核
doneTaskVos.stream().filter(task -> "分工会审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("fgh", approval);
});
// 协会负责人审核
doneTaskVos.stream().filter(task -> "协会负责人审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xh", approval);
});
// 校工会负责人审核
doneTaskVos.stream().filter(task -> "校工会负责人审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xfzr", approval);
});
// 校工会主席审核
doneTaskVos.stream().filter(task -> "校工会主席审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xzx", approval);
});
String budgetsStr = info.getString("budgets");
List<ActivityBudgetVO> list = JSONUtil.parseArray(budgetsStr).toList(ActivityBudgetVO.class);
for (int i = 0; i < list.size(); i++) {
list.get(i).setRanking(i + 1);
}
docData.put("budgets", list);
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder()
.bind("budgets", policy)
.build();
String fileName = Globals.AppName + "" + info.getString("activityName") + "】申报表.docx";
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("activity_declare"), config).render(docData).writeAndClose(byteArrayOutputStream);
CommonDownloadUtil.download(fileName, byteArrayOutputStream.toByteArray(), response);
} catch (IOException e) {
log.error("活动申报表导出失败,id:{},错误信息:{}", id, e.getMessage());
}
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -19,6 +34,9 @@ import org.nutz.mvc.annotation.Ok;
@At("/platform/activityDeclare/schoolPrincipal")
public class ActivityDeclareSchoolPrincipalController {
@Inject
private ActivityDeclareService activityDeclareService;
@At("")
@SaCheckPermission("activityDeclare.schoolPrincipal")
@@ -31,4 +49,72 @@ public class ActivityDeclareSchoolPrincipalController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/schoolprincipal/form.html")
public void form() {
}
@At
@ApiOperation("活动申报,校工会负责人审核列表")
@SaCheckPermission("activityDeclare.schoolPrincipal")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_declare_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "5b511275-143f-4ecd-8eff-7c8ad1456b1b");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.service.ActivityDeclareService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -19,6 +34,9 @@ import org.nutz.mvc.annotation.Ok;
@At("/platform/activityDeclare/schoolUnion")
public class ActivityDeclareSchoolUnionController {
@Inject
private ActivityDeclareService activityDeclareService;
@At("")
@SaCheckPermission("activityDeclare.schoolUnion")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/schoolunion/index.html")
@@ -30,4 +48,71 @@ public class ActivityDeclareSchoolUnionController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/declare/schoolunion/form.html")
public void form() {
}
@At
@ApiOperation("活动申报,校工会审核列表")
@SaCheckPermission("activityDeclare.schoolUnion")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_declare_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "81428a9b-63c0-44b8-a28c-17d282c2cc8e");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityDeclareService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,5 +1,17 @@
package com.budwk.app.zhgh.activity.declarereimbursement.declare.interceptor;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityDeclareInfo;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
/**
* @version 1.0
* @Author zzr
@@ -7,5 +19,21 @@ package com.budwk.app.zhgh.activity.declarereimbursement.declare.interceptor;
* @Date 2025/8/1 11:05
* @注释
*/
public class ActivityDeclareInterceptor {
public class ActivityDeclareInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
Dao dao = ServiceContext.find(Dao.class);
ActivityDeclareInfo declareInfo = Json.fromJson(ActivityDeclareInfo.class, formDataStr);
declareInfo.setYear(DateUtil.thisYear());
// 设置流程变量
execution.getArgs().set("type", declareInfo.getActivityType());
dao.insertOrUpdate(declareInfo);
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(declareInfo));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", declareInfo.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -2,12 +2,13 @@ package com.budwk.app.zhgh.activity.declarereimbursement.declare.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.ActivityBudget;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.ActivityBudgetVO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@@ -90,14 +91,14 @@ public class ActivityDeclareInfo extends BaseModel {
private String activityAddress;
@Column
@Comment("活动开始时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String startTime;
@Comment("活动计划开始时间")
@ColDefine(type = ColType.DATETIME)
private Date planStartTime;
@Column
@Comment("活动结束时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String endTime;
@Comment("活动计划结束时间")
@ColDefine(type = ColType.DATETIME)
private Date planEndTime;
@Column
@Comment("活动类型")
@@ -105,7 +106,7 @@ public class ActivityDeclareInfo extends BaseModel {
private String activityType;
@Column
@Comment("活动内容")
@Comment("活动方案及简介")
@ColDefine(type = ColType.TEXT)
private String activityContent;
@@ -122,6 +123,10 @@ public class ActivityDeclareInfo extends BaseModel {
@Column
@Comment("活动经费预算")
@ColDefine(type = ColType.MYSQL_JSON)
private List<ActivityBudget> budgets;
private List<ActivityBudgetVO> budgets;
@Column
@Comment("预算总金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal budgetMoney;
}
@@ -1,12 +1,22 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityDeclareInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
@@ -19,11 +29,16 @@ import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
@@ -43,6 +58,8 @@ public class ActivityReimbursementApplyController {
@Inject
private FlowEngine flowEngine;
@Inject
private FlowCommonService flowCommonService;
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@@ -57,75 +74,164 @@ public class ActivityReimbursementApplyController {
public void form() {
}
@At
@SaCheckPermission("activityReimbursement.apply")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/apply/view.html")
public void view() {
@ApiOperation("保存申请")
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "保存申请,申请人: ${args[0].username}")
public Result save(@Param("data") ActivityReimbursementInfo activityReimbursementInfo) {
if (StrUtil.isBlank(activityReimbursementInfo.getDeclareId())) {
activityReimbursementInfo.setDeclareId(activityReimbursementInfo.getDeclareId());
}
// 计算实际总金额
double sum = activityReimbursementInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getActualPrice(), 0D))
.sum();
activityReimbursementInfo.setActualMoney(new BigDecimal(sum));
dao.insertOrUpdate(activityReimbursementInfo);
return Result.success();
}
@At
@ApiOperation("活动报销,我的申请列表")
@SaCheckPermission("activityDeclare.apply")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
@ApiOperation("提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "提交申请,申请人: ${args[0].username}")
public Result submit(@Param("data") ActivityReimbursementInfo activityReimbursementInfo){
if (StrUtil.isBlank(activityReimbursementInfo.getDeclareId())) {
activityReimbursementInfo.setDeclareId(activityReimbursementInfo.getDeclareId());
}
activityReimbursementInfo.setYear(ObjectUtil.defaultIfNull(activityReimbursementInfo.getYear(), DateUtil.thisYear()));
// 计算实际总金额
double sum = activityReimbursementInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getActualPrice(), 0D))
.sum();
activityReimbursementInfo.setActualMoney(new BigDecimal(sum));
dao.insertOrUpdate(activityReimbursementInfo);
// 开启流程实例
Dict args = Dict.create();
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, activityReimbursementInfo);
args.set("type", activityReimbursementInfo.getActivityType());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("HDBX", activityReimbursementInfo.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}
@At
@ApiOperation("重新提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动申报", msg = "重新提交申请,申请人: ${args[0].username}")
public Result submitAgain(@Param("data") ActivityReimbursementInfo activityReimbursementInfo, @Param("taskId") Long taskId) {
if (StrUtil.isBlank(activityReimbursementInfo.getDeclareId())) {
activityReimbursementInfo.setDeclareId(activityReimbursementInfo.getDeclareId());
}
activityReimbursementInfo.setYear(ObjectUtil.defaultIfNull(activityReimbursementInfo.getYear(), DateUtil.thisYear()));
// 计算实际总金额
double sum = activityReimbursementInfo.getBudgets().stream()
.mapToDouble(v -> ObjectUtil.defaultIfNull(v.getActualPrice(), 0D))
.sum();
activityReimbursementInfo.setActualMoney(new BigDecimal(sum));
dao.insertOrUpdate(activityReimbursementInfo);
Dict dict = Dict.create();
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
flowCommonService.executeTask(dict);
return Result.success();
}
@At
@ApiOperation("获取当前用户活动报销")
@SaCheckPermission("activityReimbursement.apply")
public Result getActivityReimbursementByUser(String id) {
if (StrUtil.isNotBlank(id)) {
ActivityReimbursementInfo reimbursementInfo = dao.fetch(ActivityReimbursementInfo.class, id);
ActivityDeclareInfo info = dao.fetch(ActivityDeclareInfo.class, reimbursementInfo.getDeclareId());
return Result.success().addData(List.of(info));
}
// 查询已经报销成功的记录
Sql reiSql = Sqls.create("""
SELECT
info.id,
info.userName,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.startTime,
info.endTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(SELECT MAX(id) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'startTask') AS startTaskId
info.declareId
FROM
activity_reimbursement_info info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
WHERE
userId = @userId
AND ins.state IN (10, 20)
""").setParam("userId", SecurityUtil.getUserId());
reiSql.setCallback(Sqls.callback.strList());
dao.execute(reiSql);
List<String> reiDecIdList = reiSql.getList(String.class);
Sql sql = Sqls.create("select declareId from activity_reimbursement_info where userId = @userId").setParam("userId", SecurityUtil.getUserId());
sql.setCallback(Sqls.callback.strList());
dao.execute(sql);
List<String> declareIdList = sql.getList(String.class);
Sql applySql = Sqls.create("""
SELECT
info.*
FROM
activity_declare_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
if (Lang.isNotEmpty(declareIdList)) {
cnd.and("info.id", "not in", declareIdList);
}
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
if (Lang.isNotEmpty(reiDecIdList)) {
cnd.and("info.id", "not in", reiDecIdList);
}
cnd.and("info.userId", "=", SecurityUtil.getUserId());
cnd.and("ins.state", "=", 20);
applySql.setCondition(cnd);
List<NutMap> resultList = activityReimbursementService.listMap(applySql);
return Result.success().addData(resultList);
}
@At
@ApiOperation("删除活动报销")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.apply.submit")
@SLog(tag = "活动报销", msg = "删除活动报销id: ${args[0]}")
public Result onDelete(@Valid String id) {
dao.clear(ActivityReimbursementInfo.class, Cnd.where("id", "=", id));
// 删除流程相关
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
@ApiOperation("获取收款人卡号")
@SaCheckPermission("activityReimbursement.apply")
public Result getCardNumberByPayeeId(String username) {
Sql sql = Sqls.create("""
SELECT
JT.bankName,
JT.bankCardNum
FROM
activity_reimbursement_info AS info,
JSON_TABLE(
budgets,
'$[*]' COLUMNS(
username VARCHAR(255) PATH '$.username',
bankName VARCHAR(255) PATH '$.bankName',
bankCardNum VARCHAR(255) PATH '$.bankCardNum'
)
) AS JT
WHERE
JT.username = @username
ORDER BY info.applyTime DESC LIMIT 1
""").setParam("username", username);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap map = (NutMap) sql.getResult();
return Result.success().addData(map);
}
}
@@ -0,0 +1,274 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.activity.declarereimbursement.enums.ActivityDeclareReimbursement;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
* @Author zzr
* @nameActivityReimbursementBoardController
* @Date 2025/8/26 16:10
* @注释
*/
@IocBean
@Ok("json")
@ApiOperation("活动报销图表展示")
@At("/platform/activityReimbursement/board")
public class ActivityReimbursementBoardController {
@Inject
private Dao dao;
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.board")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/board/index.html")
public void index() {
}
@At
@ApiOperation("获取参与人数和活动报销经费数据")
@SaCheckPermission("activityReimbursement.board")
public Result getNumData(Integer startYear, Integer endYear){
Sql schoolSignNum = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, false).setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name());
Sql unionSignNum = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, false).setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name());
Sql clubSignNum = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, false).setParam("type", ActivityDeclareReimbursement.CLUB.name());
Sql schoolActivityMoney = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name());
Sql unionActivityMoney = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name());
Sql clubActivityMoney = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.CLUB.name());
HashMap result = new HashMap() {{
put("schoolSignNum", activityReimbursementService.listMap(schoolSignNum).stream().mapToInt(v->v.getInt("activityNum")).sum());
put("unionSignNum", activityReimbursementService.listMap(unionSignNum).stream().mapToInt(v->v.getInt("activityNum")).sum());
put("clubSignNum", activityReimbursementService.listMap(clubSignNum).stream().mapToInt(v->v.getInt("activityNum")).sum());
put("schoolActivityMoney", activityReimbursementService.count(schoolActivityMoney));
put("unionActivityMoney", activityReimbursementService.count(unionActivityMoney));
put("clubActivityMoney", activityReimbursementService.count(clubActivityMoney));
}};
return Result.success(result);
}
@At
@ApiOperation("获取活动的类型数量柱状图")
@SaCheckPermission("activityReimbursement.board")
public Result getActivityTypeChart(Integer startYear, Integer endYear){
Sql sql = Sqls.create("""
SELECT
count(1)
FROM
activity_reimbursement_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
WHERE
ins.state = 30
AND info.activityType = @type
AND info.`year` = @year
""");
List<NutMap> list = new ArrayList<>();
if (startYear == null || endYear == null) {
int nowYear = DateUtil.thisYear();
startYear = nowYear - 9;
endYear = nowYear;
}
for (int i = startYear; i <= endYear; i++) {
final int year = i;
list.add(new NutMap() {{
put("year", year);
put("type", "校工会活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name()).setParam("year", year)));
}});
list.add(new NutMap() {{
put("year", year);
put("type", "分工会活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name()).setParam("year", year)));
}});
list.add(new NutMap() {{
put("year", year);
put("type", "社团活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.CLUB.name()).setParam("year", year)));
}});
}
return Result.success().addData(list);
}
@At
@ApiOperation("获取活动的类型数量饼图")
@SaCheckPermission("activityReimbursement.board")
public Result getActivityTypePieNum(Integer startYear, Integer endYear){
Sql sql = Sqls.create("""
SELECT
count(1)
FROM
activity_reimbursement_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
WHERE
ins.state = 30
AND activityType = @type
AND `year` <= @startYear
AND `year` >= @endYear
""").setParam("startYear", startYear).setParam("endYear", endYear);
List<NutMap> list = new ArrayList<>();
list.add(new NutMap() {{
put("type", "校工会活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name())));
}});
list.add(new NutMap() {{
put("type", "分工会活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name())));
}});
list.add(new NutMap() {{
put("type", "社团活动");
put("num", activityReimbursementService.count(sql.setParam("type", ActivityDeclareReimbursement.CLUB.name())));
}});
return Result.success(list);
}
@At
@ApiOperation("获取活动的经费统计图")
@SaCheckPermission("activityReimbursement.board")
public Result getActivityMoneyChart(Integer startYear, Integer endYear){
Sql sql = Sqls.create("""
SELECT
IFNULL(sum(info.actualMoney), 0) money
FROM
activity_reimbursement_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
WHERE
ins.state = 30
AND info.activityType = @type
AND info.`year` = @year
""");
List<NutMap> list = new ArrayList<>();
if (startYear == null || endYear == null) {
int nowYear = DateUtil.thisYear();
startYear = nowYear - 9;
endYear = nowYear;
}
for (int i = startYear; i <= endYear; i++) {
final int year = i;
list.add(new NutMap() {{
put("year", year);
put("type", "校工会费用");
put("num", activityReimbursementService.list(sql.setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name()).setParam("year", year)).get(0).getDouble("money"));
}});
list.add(new NutMap() {{
put("year", year);
put("type", "分工会费用");
put("num", activityReimbursementService.list(sql.setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name()).setParam("year", year)).get(0).getDouble("money"));
}});
list.add(new NutMap() {{
put("year", year);
put("type", "社团费用");
put("num", activityReimbursementService.list(sql.setParam("type", ActivityDeclareReimbursement.CLUB.name()).setParam("year", year)).get(0).getDouble("money"));
}});
}
return Result.success(list);
}
@At
@ApiOperation("获取活动的经费饼图")
@SaCheckPermission("activityReimbursement.board")
public Result getActivityMoneyPieNum(Integer startYear, Integer endYear){
Sql schoolSql = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.SCHOOL_UNION.name());
Sql unionSql = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.BRANCH_UNION.name());
Sql clubSql = activityReimbursementService.getActivityUserNumAndMoneySql(startYear, endYear, true).setParam("type", ActivityDeclareReimbursement.CLUB.name());
List<NutMap> list = new ArrayList<>();
list.add(new NutMap() {{
put("type", "校工会费用");
put("num", activityReimbursementService.count(schoolSql));
}});
list.add(new NutMap() {{
put("type", "分工会费用");
put("num", activityReimbursementService.count(unionSql));
}});
list.add(new NutMap() {{
put("type", "社团费用");
put("num", activityReimbursementService.count(clubSql));
}});
return Result.success().addData(list);
}
@At
@ApiOperation("所有工会的报销费用或活动数统计")
@SaCheckPermission("activityReimbursement.board")
public Result allUnionActivityAndMoney(Integer year, Boolean isUnionMoney){
Sql sql = Sqls.create("""
SELECT
su.`name` AS unionname,
$unionSql
FROM
sys_union su
LEFT JOIN activity_reimbursement_info info ON su.id = info.unionId
AND info.activityType = "BRANCH_UNION"
AND info.`year` = @year
GROUP BY
su.`name`
ORDER BY
su.unionCode ASC
""").setParam("year", year);
sql.setVar("unionSql", isUnionMoney ? new Static(" COALESCE(SUM(info.actualMoney), 0) AS money ") : new Static(" count(info.id) as money "));
List<NutMap> list = activityReimbursementService.listMap(sql);
return Result.success(list);
}
@At
@ApiOperation("所有协会的报销费用或活动数统计")
@SaCheckPermission("activityReimbursement.board")
public Result allClubActivityAndMoney(Integer year, Boolean isClubMoney) {
Sql sql = Sqls.create("""
SELECT
sc.clubName,
$clubSql
FROM
sys_club sc
LEFT JOIN activity_reimbursement_info info ON sc.id = info.clubId
AND info.`year` = @year
AND info.activityType = "CLUB"
GROUP BY
sc.id
ORDER BY
sc.clubCode ASC
""").setParam("year", year);
sql.setVar("clubSql", isClubMoney ? new Static(" COALESCE(SUM(info.actualMoney), 0) AS money ") : new Static(" count(info.id) as money "));
List<NutMap> list = activityReimbursementService.listMap(sql);
return Result.success(list);
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -15,10 +30,13 @@ import org.nutz.mvc.annotation.Ok;
*/
@IocBean
@Ok("json")
@ApiOperation("活动报,分工会管理员审核")
@ApiOperation("活动报,分工会管理员审核")
@At("/platform/activityReimbursement/branchUnion")
public class ActivityReimbursementBranchUnionController {
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.branchUnion")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/branchunion/index.html")
@@ -30,4 +48,72 @@ public class ActivityReimbursementBranchUnionController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/branchunion/form.html")
public void form() {
}
@At
@ApiOperation("活动报销,分工会审核列表")
@SaCheckPermission("activityReimbursement.branchUnion")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_reimbursement_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "1e4cc473-beae-427d-b9dc-c1c4d0eb07c8");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -15,10 +30,12 @@ import org.nutz.mvc.annotation.Ok;
*/
@IocBean
@Ok("json")
@ApiOperation("活动报,协会负责人审核")
@ApiOperation("活动报,协会负责人审核")
@At("/platform/activityReimbursement/clubPrincipal")
public class ActivityReimbursementClubPrincipalController {
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.clubPrincipal")
@@ -31,4 +48,73 @@ public class ActivityReimbursementClubPrincipalController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/clubprincipal/form.html")
public void form() {
}
@At
@ApiOperation("活动报销,协会负责人审核列表")
@SaCheckPermission("activityReimbursement.clubPrincipal")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_reimbursement_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "5afcf810-7a8b-4896-9aa7-c99995e0856b");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -0,0 +1,379 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.convert.NumberWordFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.vo.ProcessTaskVO;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.ActivityBudgetVO;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
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.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
/**
* @version 1.0
* @Author zzr
* @nameActivityReimbursementMineController
* @Date 2025/8/26 11:16
* @注释
*/
@IocBean
@Ok("json")
@Slf4j
@ApiOperation("我的活动报销")
@At("/platform/activityReimbursement/mine")
public class ActivityReimbursementMineController {
@Inject
private Dao dao;
@Inject
private FlowEngine flowEngine;
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.mine")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/mine/index.html")
public void index() {
}
@At
@ApiOperation("活动报销,我的申请列表")
@SaCheckPermission("activityReimbursement.mine")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.declareId,
info.userName,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.startTime,
info.endTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
FROM
activity_reimbursement_info info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_MEMBER_ADMIN.name())) {
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
cnd.and("info.unionId", "=", SecurityUtil.getUnionId());
} else {
cnd.and("info.userId", "=", SecurityUtil.getUserId());
}
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
// cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
@At
@ApiOperation("活动报销,查看活动报销")
@SaCheckPermission("activityReimbursement.mine")
public Result findOne(@Valid String id) {
ActivityReimbursementInfo info = dao.fetch(ActivityReimbursementInfo.class, id);
return Result.success().addData(info);
}
@At
@ApiOperation("删除活动报销")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("activityReimbursement.mine")
@SLog(tag = "活动报销", msg = "删除活动报销id: ${args[0]}")
public Result onDelete(@Valid String id) {
dao.clear(ActivityReimbursementInfo.class, Cnd.where("id", "=", id));
// 删除流程相关
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
}
@At
@Ok("void")
@SaCheckPermission("activityReimbursement.mine")
@SLog(tag = "活动报销", msg = "导出报销凭证")
public void doExportReimbursement(@Valid String id, HttpServletResponse response) {
HashMap<String, Object> docData = new HashMap<>();
Sql sql = Sqls.create("""
SELECT
info.*,
ins.id AS instanceId
FROM
`activity_reimbursement_info` info
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
WHERE
ins.state = 20 AND info.id = @id
""").setParam("id", id);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap info = (NutMap) sql.getResult();
String activityContent = info.getString("activityContent");
if (activityContent != null) {
// 检查是否以<p>标签开头并以</p>标签结尾
if (activityContent.startsWith("<p>") && activityContent.endsWith("</p>")) {
// 去除最外层的<p>和</p>标签
activityContent = activityContent.substring(3, activityContent.length() - 4);
}
// 对处理后的内容进行富文本转换
info.put("activityContent", sysOfficeTemplateUtil.convertRichTextToDocText(activityContent));
}
double actualMoneyNum = info.getDouble("actualMoney");
// 分离整数和小数部分
long integerPart = (long) actualMoneyNum;
int decimalPartValue = (int) Math.round((actualMoneyNum - integerPart) * 100);
// 转换整数部分为中文大写
String integerChinese = NumberChineseFormatter.format(integerPart, true) + "";
// 处理小数部分
String decimalChinese = "";
int jiao = decimalPartValue / 10;
int fen = decimalPartValue % 10;
if (jiao > 0) {
decimalChinese += NumberChineseFormatter.format(jiao, true) + "";
}
if (fen > 0) {
decimalChinese += NumberChineseFormatter.format(fen, true) + "";
}
// 如果没有小数部分,添加"整"字
if (decimalChinese.isEmpty()) {
decimalChinese = "";
}
// 组合结果
String actualMoneyChinese = integerChinese + decimalChinese;
info.put("actualMoney", actualMoneyChinese);
docData.put("schoolName", Globals.AppName);
docData.put("info", info);
// 使用BigDecimal确保精确处理
BigDecimal bd = BigDecimal.valueOf(actualMoneyNum).setScale(2, RoundingMode.HALF_UP);
String moneyStr = bd.toPlainString();
// 分割整数和小数部分
String[] parts = moneyStr.split("\\.");
String integerPartStr = parts[0];
String decimalPartStr = parts.length > 1 ? parts[1] : "00";
// 确保小数部分是两位
if (decimalPartStr.length() < 2) {
decimalPartStr = String.format("%-2s", decimalPartStr).replace(' ', '0');
} else if (decimalPartStr.length() > 2) {
decimalPartStr = decimalPartStr.substring(0, 2);
}
// 处理小数部分(角和分)
int jiaoDigit = 0, fenDigit = 0;
if (decimalPartStr.length() >= 1) jiaoDigit = Character.getNumericValue(decimalPartStr.charAt(0));
if (decimalPartStr.length() >= 2) fenDigit = Character.getNumericValue(decimalPartStr.charAt(1));
// 处理整数部分(各位数值)
String reversed = new StringBuilder(integerPartStr).reverse().toString();
String[] units = {"", "十位", "百位", "千位", "万位", "十万位", "百万位"};
Map<String, Integer> digits = new HashMap<>();
for (int i = 0; i < reversed.length(); i++) {
if (i >= units.length) break;
digits.put(units[i], Character.getNumericValue(reversed.charAt(i)));
}
// 按照one到nine的顺序设置字段(从百万位到分位)
Map<String, Object> digitFields = new HashMap<>();
// one: 百万位
digitFields.put("one", digits.getOrDefault("百万位", 0));
// two: 十万位
digitFields.put("two", digits.getOrDefault("十万位", 0));
// three: 万位
digitFields.put("three", digits.getOrDefault("万位", 0));
// four: 千位
digitFields.put("four", digits.getOrDefault("千位", 0));
// five: 百位
digitFields.put("five", digits.getOrDefault("百位", 0));
// six: 十位
digitFields.put("six", digits.getOrDefault("十位", 0));
// seven: 元位
digitFields.put("seven", digits.getOrDefault("", 0));
// eight: 角
digitFields.put("eight", jiaoDigit);
// nine: 分
digitFields.put("nine", fenDigit);
// 将数字字段添加到info中
info.putAll(digitFields);
List<ProcessTaskVO> doneTaskVos = new ArrayList<>();
List<ProcessTask> doneTaskList = flowEngine.processTaskService().getDoneTaskList(info.getLong("instanceId"), null);
for (ProcessTask doneTask : doneTaskList) {
ProcessTaskVO taskVO = flowEngine.processTaskService().findById(doneTask.getId());
doneTaskVos.add(taskVO);
}
// 分工会审核
doneTaskVos.stream().filter(task -> "分工会审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("fgh", approval);
});
// 协会负责人审核
doneTaskVos.stream().filter(task -> "协会负责人审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xh", approval);
});
// 校工会负责人审核
doneTaskVos.stream().filter(task -> "校工会负责人审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xfzr", approval);
});
// 校工会主席审核
doneTaskVos.stream().filter(task -> "校工会主席审核".equals(task.getDisplayName()))
.max(Comparator.comparing(ProcessTaskVO::getCreatedAt))
.ifPresent(v -> {
Dict taskFormData = v.getTaskFormData();
HashMap<String, Object> approval = new HashMap<>();
approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日"));
approval.put("user", taskFormData.getStr("tf_userName"));
if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) {
approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign")));
}
approval.put("opinion", taskFormData.getStr("tf_opinion"));
docData.put("xzx", approval);
});
String budgetsStr = info.getString("budgets");
List<ActivityBudgetVO> list = JSONUtil.parseArray(budgetsStr).toList(ActivityBudgetVO.class);
for (int i = 0; i < list.size(); i++) {
list.get(i).setRanking(i + 1);
}
docData.put("budgets", list);
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder()
.bind("budgets", policy)
.build();
String fileName = Globals.AppName + "" + info.getString("activityName") + "】报销凭证表.docx";
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("activity_reimbursement_voucher"), config).render(docData).writeAndClose(byteArrayOutputStream);
CommonDownloadUtil.download(fileName, byteArrayOutputStream.toByteArray(), response);
} catch (IOException e) {
log.error("报销凭证表导出失败,id:{},错误信息:{}", id, e.getMessage());
}
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -15,10 +30,12 @@ import org.nutz.mvc.annotation.Ok;
*/
@IocBean
@Ok("json")
@ApiOperation("活动报,校工会负责人审核")
@ApiOperation("活动报,校工会负责人审核")
@At("/platform/activityReimbursement/schoolPrincipal")
public class ActivityReimbursementSchoolPrincipalController {
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.schoolPrincipal")
@@ -31,4 +48,72 @@ public class ActivityReimbursementSchoolPrincipalController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/schoolprincipal/form.html")
public void form() {
}
@At
@ApiOperation("活动报销,校工会负责人审核列表")
@SaCheckPermission("activityReimbursement.schoolPrincipal")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_reimbursement_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "6dd2e8b3-fd0d-4b35-bb2a-1eef227cba96");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,11 +1,26 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import com.budwk.app.zhgh.activity.declarereimbursement.vo.CommonPageParam;
import io.swagger.annotations.ApiOperation;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @version 1.0
* @Author zzr
@@ -15,10 +30,13 @@ import org.nutz.mvc.annotation.Ok;
*/
@IocBean
@Ok("json")
@ApiOperation("活动报,校工会审核")
@ApiOperation("活动报,校工会审核")
@At("/platform/activityReimbursement/schoolUnion")
public class ActivityReimbursementSchoolUnionController {
@Inject
private ActivityReimbursementService activityReimbursementService;
@At("")
@SaCheckPermission("activityReimbursement.schoolUnion")
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/schoolunion/index.html")
@@ -30,4 +48,72 @@ public class ActivityReimbursementSchoolUnionController {
@Ok("beetl:/platform/zhgh/activity/declarereimbursement/reimbursement/schoolunion/form.html")
public void form() {
}
@At
@ApiOperation("活动报销,校工会审核列表")
@SaCheckPermission("activityReimbursement.schoolUnion")
public Result pageData(CommonPageParam pageParam) {
Sql sql = Sqls.create("""
SELECT
info.id,
info.userName,
info.mobile,
info.loginName,
info.applyTime,
info.activityName,
info.activityAddress,
info.planStartTime,
info.planEndTime,
info.declareUnitName,
info.activityType,
info.activityContent,
info.activityNumber,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_reimbursement_info info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.");
cnd.and("t.taskName", "=", "47bfdf53-288c-4352-a403-0653483b54eb");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageParam.getAudit()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageParam.getPageOrderName(), pageParam.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
return Result.success().addData(pagination);
}
}
@@ -1,5 +1,16 @@
package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.interceptor;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
/**
* @version 1.0
* @Author zzr
@@ -7,5 +18,21 @@ package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.intercept
* @Date 2025/8/1 11:05
* @注释
*/
public class ActivityReimbursementInterceptor {
public class ActivityReimbursementInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
Dao dao = ServiceContext.find(Dao.class);
ActivityReimbursementInfo reimbursementInfo = Json.fromJson(ActivityReimbursementInfo.class, formDataStr);
reimbursementInfo.setDeclareId(reimbursementInfo.getId());
// 设置流程变量
execution.getArgs().set("type", reimbursementInfo.getActivityType());
dao.insertOrUpdate(reimbursementInfo);
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(reimbursementInfo));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", reimbursementInfo.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -5,7 +5,10 @@ import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityD
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
@@ -20,11 +23,32 @@ import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class ActivityReimbursementInfo extends ActivityDeclareInfo {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("申报id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String declareId;
@Column
@Comment("实际总金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal actualMoney;
@Column
@Comment("活动开始时间")
@ColDefine(type = ColType.DATETIME)
private Date startTime;
@Column
@Comment("活动结束时间")
@ColDefine(type = ColType.DATETIME)
private Date endTime;
@Column
@Comment("发票")
@ColDefine(type = ColType.MYSQL_JSON)
@@ -2,6 +2,7 @@ package com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import org.nutz.dao.sql.Sql;
/**
* @version 1.0
@@ -11,4 +12,7 @@ import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.Act
* @注释
*/
public interface ActivityReimbursementService extends BaseService<ActivityReimbursementInfo> {
Sql getActivityUserNumAndMoneySql(Integer startYear, Integer endYear, Boolean isActivityMoney);
}
@@ -4,6 +4,8 @@ import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.models.ActivityReimbursementInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.reimbursement.service.ActivityReimbursementService;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
/**
@@ -18,4 +20,37 @@ public class ActivityReimbursementServiceImpl extends BaseServiceImpl<ActivityRe
public ActivityReimbursementServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getActivityUserNumAndMoneySql(Integer startYear, Integer endYear, Boolean isActivityMoney) {
if (isActivityMoney) {
return Sqls.create("""
SELECT
SUM(info.actualMoney)
FROM
activity_reimbursement_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
WHERE
ins.state = 30
AND info.activityType = @type
AND info.`year` >= @startYear
AND info.`year` <= @endYear
""")
.setParam("startYear", startYear).setParam("endYear", endYear);
} else {
return Sqls.create("""
SELECT
info.activityNumber AS activityNum
FROM
activity_reimbursement_info info
LEFT JOIN wf_process_instance ins ON info.id = ins.businessNo
WHERE
ins.state = 30
AND info.activityType = @type
AND info.`year` >= @startYear
AND info.`year` <= @endYear
""").setParam("startYear", startYear).setParam("endYear", endYear);
}
}
}
@@ -13,7 +13,9 @@ import lombok.Data;
*/
@Data
@ApiModel("费用预算")
public class ActivityBudget {
public class ActivityBudgetVO {
private Integer ranking;
@ApiModelProperty(value = "名称")
private String name;
@@ -5,7 +5,6 @@ import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.declarereimbursement.declare.models.ActivityDeclareInfo;
import com.budwk.app.zhgh.activity.declarereimbursement.enums.ActivityDeclareReimbursement;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@@ -23,7 +22,7 @@ import org.nutz.dao.util.cri.SqlExpressionGroup;
@Data
@ApiModel("通用分页参数")
@EqualsAndHashCode(callSuper = true)
public class CommonPageParam extends PageForm<ActivityDeclareInfo> {
public class CommonPageParam extends PageForm {
private Integer year;
@@ -51,10 +50,10 @@ public class CommonPageParam extends PageForm<ActivityDeclareInfo> {
RoleConstant.BRANCH_UNION_ADMIN.name(),
RoleConstant.BRANCH_UNION_OPERATOR.name())) {
cnd.and(prefix + "unionid", "=", SecurityUtil.getUnionId());
}
if (AuthUtil.hasRoleOr(RoleConstant.CLUB_MANAGER.name(), RoleConstant.CLUB_PRESIDENT.name())) {
} else if (AuthUtil.hasRoleOr(RoleConstant.CLUB_MANAGER.name(), RoleConstant.CLUB_PRESIDENT.name())) {
// cnd.and(prefix + "clubId", "=", );
} else {
cnd.andEX(prefix + "userId", "=", SecurityUtil.getUserId());
}
} else {
cnd.andEX(prefix + "unionId", "=", this.getUnionId());
@@ -40,7 +40,7 @@ public class FamilyUserServiceImpl extends BaseServiceImpl<FamilyBlackList> impl
u.unionname,
tsuc.courseName,
tsuu.state,
( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId $var) tourseTotal,
( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId $var) courseTotal,
( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount,
if(tsubl.isDisabled=1,true,false) isDisabled,
group_CONCAT( tsuc.courseName ) AS courseNames
@@ -0,0 +1,24 @@
package com.budwk.app.zhgh.activity.literacy.constant;
import com.budwk.app.base.annotation.DictEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Author JyuHsin
* @Date 2022/11/18
* @Description
*/
@Getter
@DictEnum(key = "ColumnFormTypeEnum", name = "控件类型")
@AllArgsConstructor
public enum ColumnFormTypeEnum {
INPUT("INPUT", "输入框"),
SELECT("SELECT", "选择框"),
//RADIO("RADIO", "单选框"),//选项数组
FILE("FILE", "文件");
private String code;
private String description;
}
@@ -0,0 +1,96 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zxy
* @Description 新建活动
* @createTime 2022年03月07日 10:16:00
*/
@Slf4j
@IocBean
@Api(tags = "新建品牌活动")
@At("/platform/literacy/manage/activity")
public class LiteracyActivityAddController {
@Inject
private Dao dao;
@Inject
private LiteracyActivityService literacySignUpActivityManageService;
@At
@Ok("json:full")
@ApiOperation("品牌活动新增/修改")
@SaCheckPermission("literacy.manage.activity")
@SLog(tag = "品牌活动-活动管理", msg = "新增/修改活动")
public Result doHandle(LiteracyActivity activity) {
if (StrUtil.isBlank(activity.getId())) {
literacySignUpActivityManageService.add(activity, null);
} else {
literacySignUpActivityManageService.edit(activity);
}
return Result.success();
}
@At
@Ok("json:full")
@ApiOperation("获取分工会人数限制")
@SaCheckPermission("literacy.manage.activity")
public Result getUnionLimit(@Param(value = "activityScopeId") String activityScopeId) {
Sql sql = Sqls.create("""
SELECT
gh.id,
gh.name,
gh.unioncode,
(select count(1) from `vw_user` where unionid = gh.id $cnd) as teacherCount,
NULL as ratio,
NULL as limitCount
FROM
sys_union gh
order by gh.unioncode
""");
if (StrUtil.isNotBlank(activityScopeId)) {
sql.setVar("cnd", "AND id in (select userId from activity_user_scope where groupId = '" + activityScopeId + "')");
}
List<NutMap> list = literacySignUpActivityManageService.listMap(sql);
return Result.success().addData(list);
}
@At
@Ok("json:full")
@ApiOperation("获取报名人员数量")
@SaCheckPermission("literacy.manage.activity")
public Result getRegisterUserCount(@Param(value = "courseId") String courseId) {
return Result.success().addData(dao.count(LiteracyUser.class, Cnd.where("courseId", "=", courseId)));
}
@At
@Ok("json:full")
@ApiOperation("获取历史活动列表")
@SaCheckPermission("literacy.manage.activity")
public Result getHistoricalActList() {
List<LiteracyActivity> query = dao.query(LiteracyActivity.class, Cnd.NEW().desc("activityStartTime"));
return Result.success().addData(query);
}
}
@@ -0,0 +1,176 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivityCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
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 org.nutz.mvc.annotation.Param;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "活动报名")
@At("/platform/literacy/manage/apply")
public class LiteracyActivityApplyController {
@Inject
private LiteracyActivityService literacyActivityService;
@Inject
private SysDictService dictService;
@Inject
private LiteracyActivityStatisticsService statisticsService;
@At("")
@SaCheckPermission("literacy.manage.apply")
@Ok("beetl:/platform/zhgh/activity/literacy/apply/index.html")
public void index() {
}
@At
@ApiOperation("活动查询")
@SaCheckPermission("literacy.manage.apply")
public Result activityData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "activityType") Integer activityType) {
Cnd cnd = Cnd.NEW();
cnd.andEX("`year`", "=", year);
//查询报名中
if (activityType == 2) {
cnd.and(new Static("now() > activitySignUpStartTime and now() < activitySignUpEndTime"));
}//查询已结束的
else if (activityType == 3) {
cnd.and(new Static("now() > activityEndTime"));
}
if (AuthUtil.hasRole("H04") && !AuthUtil.hasRoleOr("sysadmin, A06")) {
cnd.and("activityMode", "=", 2).and("createdBy", "=", SecurityUtil.getUserId());
}
Pagination pagination = literacyActivityService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
List<LiteracyActivity> literacyActivities = pagination.getList();
Map<String, String> literacyTypeMap = dictService.getSubListByCode("LITERACY_SIGNUP_TYPE").stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName));
literacyActivities.forEach(v -> v.setLiteracyType(literacyTypeMap.get(v.getLiteracyType())));
return Result.success(pagination);
}
@At
@ApiOperation("分活动查询")
@SaCheckPermission("literacy.manage.apply")
public Result pageData(PageForm pageForm,
@Param(value = "courseTypeId") String courseTypeId,
@Param(value = "activityId") String activityId,
@Param(value = "assortTypes") String[] assortTypes) {
Sql sql = Sqls.create("""
SELECT
tsuc.id,
tsuc.activityId,
tsuc.courseName,
tsuc.coursePeopleNumber,
tsuc.courseLocation,
tsuc.courseType,
tsuc.courseLocationCoordinates,
tsuc.courseReservedNumber,
tsuc.courseInstructor,
tsuc.campus,
tsuc.unionLimit,
tsuc.isMobileSign,
tsuc.signType,
tsuc.isReceiveGift,
tsuc.giftType,
tsuc.reserveMode,
tsuc.waitingNum,
tsuc.assort,
type.typeName,
tsuc.courseIsLimitApply
FROM
`literacy_course` tsuc
LEFT JOIN literacy_type type ON type.id = tsuc.courseType
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("type.id", "=", courseTypeId);
cnd.and("tsuc.activityId", "=", activityId);
if(Lang.isNotEmpty(assortTypes)) {
cnd.and("tsuc.assort", "in", assortTypes);
}
List<LiteracyCourse> courseArray = literacyActivityService.dao().query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId));
courseArray = literacyActivityService.filterCourseByHostUnion(courseArray);
cnd.and("tsuc.id", "in", courseArray.stream().map(LiteracyCourse::getId).toList());
cnd.asc("tsuc.orderNum");
cnd.asc("type.code");
sql.setCondition(cnd);
Pagination pagination = literacyActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> courseList = pagination.getList();
courseList.forEach(c -> {
c.put("hasRegisterNum", statisticsService.queryCourseCount(c.getString("id"), c.getString("courseType")));
c.put("hasWaitingNum", statisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType")));
//当前用户是否报过
c.put("isSign", literacyActivityService.isSignCourseByUser(c.getString("id"), SecurityUtil.getUserId()));
if(StrUtil.isNotBlank(c.getString("unionLimit"))) {
List<NutMap> unionLimit = Json.fromJsonAsList(NutMap.class, c.getString("unionLimit"));
if(Lang.isNotEmpty(unionLimit)) {
NutMap nutMap = unionLimit.stream().filter(o -> o.getString("id").equals(SecurityUtil.getUnionId())).findFirst().orElse(null);
if(nutMap != null) {
c.put("coursePeopleNumber", nutMap.getInt("limitCount"));
}
}
}
});
return Result.success(pagination);
}
@At
@ApiOperation("获取分活动时间")
@SaCheckPermission("literacy.manage.apply")
public Result getCourseTime(String id) {
List<LiteracyActivityCourse> list = literacyActivityService.dao().query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", id));
return Result.success(list);
}
@At
@ApiOperation("查询分类标识集合")
@SaCheckPermission("literacy.manage.apply")
public Result queryCourseAssort(String activityId) {
List<LiteracyCourse> courseList = literacyActivityService.dao().query(LiteracyCourse.class, Cnd.where(LiteracyCourse::getActivityId, "=", activityId).asc(LiteracyCourse::getOrderNum));
if(Lang.isEmpty(courseList)) {
return Result.success(new ArrayList<>());
}
List<String> assortList = courseList.stream().map(LiteracyCourse::getAssort).filter(StrUtil::isNotBlank).toList();
return Result.success(assortList);
}
}
@@ -0,0 +1,144 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.zhgh.activity.literacy.models.*;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.nutz.dao.Chain;
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 org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.trans.Trans;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description 培训报名 活动管理
* @createTime 2022年02月23日 09:57:00
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "活动管理")
@At("/platform/literacy/manage/activity")
public class LiteracyActivityController {
@Inject
private LiteracyActivityService literacySignUpActivityManageService;
@Inject
private Dao dao;
@At("")
@SaCheckPermission("literacy.manage.activity")
@Ok("beetl:/platform/zhgh/activity/literacy/manage/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("literacy.manage.activity")
public Result pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "activityName") String activityName) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
cnd.and(Cnd.likeEX("activityName", activityName));
cnd.orderBy("createdAt", "desc");
return Result.success().addData(literacySignUpActivityManageService.pageData(pageForm, cnd));
}
@At
@ApiOperation("活动删除")
@SaCheckPermission("literacy.manage.activity")
@SLog(tag = "品牌活动-活动管理", msg = "删除活动")
public Result onDelete(String id) {
Trans.exec(() -> {
literacySignUpActivityManageService.delete(id);
dao.clear(LiteracyCourse.class, Cnd.where("activityId", "=", id));
dao.clear(LiteracyActivityCourse.class, Cnd.where("activityId", "=", id));
dao.clear(LiteracyUser.class, Cnd.where("activityId", "=", id));
dao.clear(LiteracyUserCourse.class, Cnd.where("activityId", "=", id));
dao.clear(LiteracyActivity.class, Cnd.where("id", "=", id));
dao.clear(LiteracyTypeLimit.class, Cnd.where("activityId", "=", id));
dao.delete(Sys_home_activity.class, id);
});
return Result.success();
}
@At
@ApiOperation("活动状态变更")
@SaCheckPermission("literacy.manage.activity")
public Result activityStatusChange(LiteracyActivity activity) {
literacySignUpActivityManageService.updateActivityStatus(activity);
dao.update(Sys_home_activity.class,
Chain.make("enable", !activity.isDisabled()),
Cnd.where("id", "=", activity.getId()));
return Result.success();
}
@At
@ApiOperation("查询单个活动")
@SaCheckPermission("literacy.manage.activity")
public Result findOne(@Param("id") @NotNull String id) {
NutMap dataMap = literacySignUpActivityManageService.findOne(id, null, "");
String activityStartTime = dataMap.getString("activityStartTime");
String activityEndTime = dataMap.getString("activityEndTime");
if(StrUtil.isNotBlank(activityStartTime) && StrUtil.isNotBlank(activityEndTime)) {
dataMap.put("activityTime", List.of(activityStartTime, activityEndTime));
} else {
dataMap.put("activityTime", new ArrayList<>());
}
String activitySignUpStartTime = dataMap.getString("activitySignUpStartTime");
String activitySignUpEndTime = dataMap.getString("activitySignUpEndTime");
if(StrUtil.isNotBlank(activitySignUpStartTime) && StrUtil.isNotBlank(activitySignUpEndTime)) {
dataMap.put("activitySignTime", List.of(activitySignUpStartTime, activitySignUpEndTime));
} else {
dataMap.put("activitySignTime", new ArrayList<>());
}
List<NutMap> courseList = dataMap.getList("courseList", NutMap.class);
//查询所有的课程类型
List<LiteracyType> literacySignUpTypeList = dao.query(LiteracyType.class, Cnd.NEW());
Map<String, String> typeMap = literacySignUpTypeList.stream().collect(Collectors.toMap(LiteracyType::getId, LiteracyType::getTypeName));
courseList.forEach(v -> {
List<NutMap> courseTimeList = v.getList("courseTimeList", NutMap.class);
//选择课程日期 下拉框
List<String> setUpCourseData = courseTimeList.stream().map(cd -> cd.getString("courseDate")).distinct().collect(Collectors.toList());
v.put("setUpCourseData", setUpCourseData);
courseTimeList.forEach(ct -> {
String courseStartTime = DateUtil.format(ct.getTime("courseStartTime"), "HH:mm");
String courseEndTime = DateUtil.format(ct.getTime("courseEndTime"), "HH:mm");
ct.put("courseStartTime", courseStartTime);
ct.put("courseEndTime", courseEndTime);
});
v.put("courseTypeName", typeMap.get(v.getString("courseType")));
});
return Result.success().addData(dataMap);
}
}
@@ -0,0 +1,167 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.EnumUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyMobileSignColumn;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.entity.annotation.ColType;
import org.nutz.dao.sql.Sql;
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.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.util.List;
/**
* @Author JyuHsin
* @Date 2022/9/22
* @Description
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "活动类型管理")
@At("/platform/literacy/manage/type")
public class LiteracyTypeController {
@Inject
private Dao dao;
@Inject
private BaseService baseService;
@At("")
@SaCheckPermission("literacy.manage.type")
@Ok("beetl:/platform/zhgh/activity/literacy/type/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("literacy.manage.type")
public Result pageData(PageForm pageForm,
@Param(value = "typeName") String typeName) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
select * from literacy_type $condition
""");
if (Strings.isNotBlank(typeName)) {
cnd.and("typeName", "like", "%" + typeName + "%");
}
if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.asc("xh");
}
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = pagination.getList();
list.forEach(item -> {
Cnd c = Cnd.NEW();
c.and("typeId", "=", item.getString("id"));
c.asc("columnIndex");
List<LiteracyMobileSignColumn> signColumns = dao.query(LiteracyMobileSignColumn.class, c);
item.put("literacyMobileSignColumnList", signColumns);
});
return Result.success().addData(pagination);
}
@At
@ApiOperation("活动类型新增")
@SaCheckPermission("literacy.manage.type")
@SLog(tag = "品牌活动-类型管理", msg = "活动类型新增")
public Result doAdd(@Param("data") String data) throws Exception {
LiteracyType type = Json.fromJson(LiteracyType.class, data);
int count = dao.count(LiteracyType.class, Cnd.where("code", "=", type.getCode()));
if (count > 0) {
return Result.error("编码重复!");
}
int totalCount = dao.count(LiteracyType.class);
type.setXh(totalCount + 1);
dao.insertWith(type, "literacyMobileSignColumnList");
return Result.success();
}
@At
@ApiOperation("活动类型修改")
@SaCheckPermission("literacy.manage.type")
@SLog(tag = "品牌活动-类型管理", msg = "活动类型修改")
public Result doEdit(LiteracyType type) {
int count = dao.count(LiteracyType.class, Cnd.where("code", "=", type.getCode()).and("id", "!=", type.getId()));
if (count > 0) {
return Result.error("编码重复!");
}
dao.update(type);
dao.clear(LiteracyMobileSignColumn.class, Cnd.where("typeId", "=", type.getId()));
dao.insertLinks(type, "literacyMobileSignColumnList");
return Result.success();
}
@At
@ApiOperation("活动类型删除")
@SaCheckPermission("literacy.manage.type")
@SLog(tag = "品牌活动-类型管理", msg = "活动类型删除")
public Object doDelete(@Param(value = "id") String id) {
dao.clear(LiteracyType.class, Cnd.where("id", "=", id));
dao.clear(LiteracyMobileSignColumn.class, Cnd.where("typeId", "=", id));
return Result.success();
}
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("排序号变更")
@SaCheckPermission("literacy.manage.type")
public Object xhChange(String id, Integer xh, boolean toDown) {
if (toDown) {
LiteracyType next = dao.fetch(LiteracyType.class, Cnd.where("xh", "=", xh + 1));
next.setXh(next.getXh() - 1);
dao.update(next);
dao.update(LiteracyType.class, Chain.make("xh", xh + 1), Cnd.where("id", "=", id));
} else {
LiteracyType pre = dao.fetch(LiteracyType.class, Cnd.where("xh", "=", xh - 1));
pre.setXh(pre.getXh() + 1);
dao.update(pre);
dao.update(LiteracyType.class, Chain.make("xh", xh - 1), Cnd.where("id", "=", id));
}
return Result.success();
}
@At
@ApiOperation("获取所有类型")
@SaCheckLogin
public Result getAllType(@Param(value = "id") String id) {
List<LiteracyType> literacyTypeList = dao.query(LiteracyType.class, Cnd.NEW().andEX("id", "=", id).asc("xh"));
dao.fetchLinks(literacyTypeList, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
return Result.success().addData(literacyTypeList);
}
@At
@ApiOperation("自定义表单字段类型")
@SaCheckPermission("literacy.manage.type")
public Result getColumnType() {
List<String> names = EnumUtil.getNames(ColType.class);
names.add("JSON");
return Result.success(names);
}
}
@@ -0,0 +1,179 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivityCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUserCourse;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.ArrayList;
import java.util.List;
/**
* @Author JyuHsin
* @Date 2022/9/21
* @Description 人员调整
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "品牌活动人员调整")
@At("/platform/literacy/manage/userAdjust")
public class LiteracyUserAdjustController {
@Inject
private Dao dao;
@Inject
private BaseService baseService;
@Inject
private LiteracyActivityService literacyActivityManageService;
@Inject
private LiteracyActivityStatisticsService literacyActivityStatisticsService;
@At("")
@SaCheckPermission("literacy.manage.activity.adjust")
@Ok("beetl:/platform/zhgh/activity/literacy/userAdjust/index.html")
public void index() {
}
/**
* 活动list
* @param year 年度
* @return
*/
@At
@ApiOperation("活动列表")
@SaCheckPermission("literacy.manage.activity.adjust")
public Result activityList(@Param(value = "year") Integer year) {
List<LiteracyActivity> activityList = dao.query(LiteracyActivity.class, Cnd.NEW().andEX("year", "=", year).andEX("isDisabled", "=", false).desc("activityStartTime"));
return Result.success(activityList);
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("literacy.manage.activity.adjust")
public Result pageData(PageForm pageForm,
@Param(value = "activityId") String activityId) {
Pagination pagination = literacyActivityStatisticsService.pageData(pageForm, activityId);
return Result.success(pagination);
}
@At
@ApiOperation("子活动查询")
@SaCheckPermission("literacy.manage.activity.adjust")
public Result getCourse(String activityId) {
Sql sql = Sqls.create("""
SELECT
tsuc.id,
tsuc.courseName,
tsuc.coursePeopleNumber,
tsuc.courseType,
tsuc.courseLocation,
tsuc.courseInstructor,
tsuc.courseReservedNumber,
tsuc.waitingNum,
tsuc.reserveMode
FROM
`literacy_course` tsuc
WHERE
tsuc.activityId = @activityId
ORDER BY courseName asc
""");
sql.setParam("activityId", activityId);
List<NutMap> courseList = baseService.listMap(sql);
courseList.forEach(c -> {
c.put("registerNum", literacyActivityStatisticsService.queryCourseCount(c.getString("id"), c.getString("courseType")));
c.put("hasWaitingNum", literacyActivityStatisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType")));
});
return Result.success(courseList);
}
@At
@ApiOperation("报名用户列表")
@SaCheckPermission("literacy.manage.activity.adjust")
public Result registerUserList(@Param("courseId") String courseId,
@Param(value = "unionId") String unionId,
@Param(value = "unitId") String unitId,
@Param(value = "searchName") String searchName,
@Param(value = "searchKeyword") String searchKeyword) {
List<NutMap> list = literacyActivityStatisticsService.registerUserList(courseId, unionId, unitId, searchName, searchKeyword);
return Result.success(list);
}
@At
@ApiOperation("人员调整")
@SaCheckPermission("literacy.manage.activity.adjust")
@SLog(tag = "品牌活动-人员调整", msg = "人员调整")
public Result adjust(String activityId, String oldCourseId, String newCourseId, String userId) {
Cnd oldCnd = Cnd.where("activityId", "=", activityId)
.and("courseId", "=", oldCourseId).and("userId", "=", userId);
Cnd newCnd = Cnd.where("activityId", "=", activityId)
.and("courseId", "=", newCourseId).and("userId", "=", userId);
//旧的报名信息
LiteracyUser oldliteracyUser = dao.fetch(LiteracyUser.class, oldCnd);
oldliteracyUser.setCourseId(newCourseId);
oldliteracyUser.setSignUpTime(DateUtil.date());
dao.update(oldliteracyUser);
//新的课程的信息,上课时间
List<LiteracyActivityCourse> activityCourseList = dao.query(LiteracyActivityCourse.class, Cnd.where("activityId", "=", activityId)
.and("courseId", "=", newCourseId));
//先清楚旧的信息
dao.clear(LiteracyUserCourse.class, oldCnd);
//添加新的信息
List<LiteracyUserCourse> literacyUserCourseList = new ArrayList<>();
activityCourseList.forEach(item -> {
LiteracyUserCourse course = new LiteracyUserCourse();
course.setActivityCourseId(activityId);
course.setCourseId(newCourseId);
course.setUserId(userId);
course.setCourseStartTime(item.getCourseStartTime());
course.setCourseEndTime(item.getCourseEndTime());
course.setActivityCourseId(item.getId());
literacyUserCourseList.add(course);
});
dao.insert(literacyUserCourseList);
return Result.success();
}
@At
@ApiOperation("删除报名人员")
@SaCheckPermission("literacy.manage.activity.adjust")
@SLog(tag = "品牌活动-人员调整", msg = "删除报名人员")
public Result deleteSignUser(String activityId, String courseId, String userId) {
//删除
Cnd cnd = Cnd.NEW();
cnd.and("activityId", "=", activityId);
cnd.and("courseId", "=", courseId);
cnd.and("userId", "=", userId);
dao.clear(LiteracyUser.class, cnd);
dao.clear(LiteracyUserCourse.class, cnd);
return Result.success();
}
}
@@ -0,0 +1,347 @@
package com.budwk.app.zhgh.activity.literacy.controller.manage;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyBlackListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
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.cri.SqlExpressionGroup;
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.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description 人员管理
* @createTime 2022年03月07日 14:27:00
*/
@IocBean
@Ok("json:full")
@Api(tags = "亲子活动人员黑名单")
@At("/platform/literacy/userManage")
public class LiteracyUserBlackListManageController {
@Inject
private Dao dao;
@Inject
private LiteracyBlackListService literacyBlackListService;
@At("")
@SaCheckPermission("literacy.user.activity")
@Ok("beetl:/platform/zhgh/activity/literacy/userManage/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("literacy.user.activity")
public Result pageData(PageForm pageForm,
@Param(value = "activityId") String activityId,
@Param(value = "courseId") String courseId,
@Param(value = "year") Integer year,
@Param(value = "userKeyWord") String userKeyWord) {
Cnd cnd = Cnd.NEW();
cnd.andEX("tsuu.activityId", "=", activityId);
cnd.andEX("tsuu.courseId", "=", courseId);
cnd.andEX("act.year", "=", year);
if (StrUtil.isNotBlank(userKeyWord)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
cnd.and(seg.andLike("u.username", userKeyWord).orLike("u.loginname", userKeyWord));
}
if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
Pagination pagination = literacyBlackListService.pageData(pageForm, cnd, activityId, courseId);
return Result.success(pagination);
}
@At
@ApiOperation("报名人员处理")
@SaCheckPermission("literacy.user.activity")
@SLog(tag = "品牌活动-人员管理", msg = "报名人员处理")
public Result doHandleUser(@Param("userId") String userId) {
literacyBlackListService.doHandleUser(userId);
return Result.success();
}
@At
@ApiOperation("根据活动Id获取子活动")
@SaCheckPermission("literacy.user.activity")
public Result getCourseByActivityId(@Param("activityId") String activityId) {
List<LiteracyCourse> list = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId));
return Result.success(list);
}
@At
@ApiOperation("获取子活动具体时间")
@SaCheckPermission("literacy.user.activity")
public Result attendClassRecord(String userId) {
literacyBlackListService.attendClassRecord(userId);
return Result.success();
}
@At
@ApiOperation("获取候补人员")
@SaCheckPermission("literacy.user.activity")
public Result getReserveUser(String courseId) {
Sql sql = Sqls.create("""
SELECT
uc.* ,
(select signUpTime from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime,
(select state from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state,
u.username,
u.loginname,
u.mobile,
u.unitName,
u.unionName
FROM
literacy_user_course uc LEFT JOIN `vw_user` u on uc.userId = u.id
WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 2 order by signUpTime desc
""").setParam("courseId", courseId);
return Result.success(literacyBlackListService.listMap(sql));
}
@At
@ApiOperation("补充人员")
@SaCheckPermission("literacy.user.activity")
@SLog(tag = "品牌活动-人员管理", msg = "补充人员")
public Result reserveSingUp(String[] ids, String courseId) {
//先查询这个课程有多少个未签到的人员
Sql sql = Sqls.create("""
SELECT
uc.* ,
(select signUpTime from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime,
(select state from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state
FROM
literacy_user_course uc
WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 1 order by signUpTime desc
""").setParam("courseId", courseId);
List<NutMap> list = literacyBlackListService.listMap(sql);
if(ids.length > list.size()) {
return Result.error("您选择了" + ids.length + "位,未签到人员只有" + list.size() + "");
}
//ids的长度为几,就搞几个
List<NutMap> mapList = list.subList(0, ids.length);
List<String> idList = mapList.stream().map(o -> o.getString("userId")).collect(Collectors.toList());
//将这几个没签到的设置为4
dao.update(LiteracyUser.class, Chain.make("state", 4), Cnd.where("courseId", "=", courseId)
.and("userId", "in", idList));
//将补充的设置为1
dao.update(LiteracyUser.class, Chain.make("state", 1), Cnd.where("courseId", "=", courseId)
.and("userId", "in", ids));
return Result.success();
}
@At
@Ok("void")
@ApiOperation("导出签到人员")
public void exportSignPerson(@Param(value = "activityId") String activityId,
HttpServletResponse response) {
LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId);
Sql sql = Sqls.create("""
SELECT
uc.*,
DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel,
DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel,
DATE_FORMAT(uc.attendTime, '%Y-%m-%d %H:%i:%s') as attendTimeExcel,
u.username,
u.loginname,
u.unitName,
u.unionName,
u.sex
FROM
literacy_user_course uc
left join literacy_course course on uc.courseId = course.id
left join `vw_user` u on u.id = uc.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("uc.activityId", "=", activityId);
cnd.and("course.isMobileSign", "=", true);
cnd.desc("isAttend").desc("attendTime");
sql.setCondition(cnd);
List<NutMap> userList = literacyBlackListService.listMap(sql);
List<LiteracyCourse> courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId));
List<Map<String, Object>> sheetsList = new ArrayList<>();
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22));
excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22));
excelCommonExportEntity.add(new ExcelExportEntity("是否签到", "isAttend", 20));
excelCommonExportEntity.add(new ExcelExportEntity("签到时间", "attendTimeExcel", 22));
for (LiteracyCourse c : courseList) {
String courseId = c.getId();
String courseName = c.getCourseName();
List<NutMap> v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList());
ExportParams userExportParams = new ExportParams();
userExportParams.setSheetName(courseName);
List<ExcelExportEntity> currentEntities = new ArrayList<>(excelCommonExportEntity);
for (NutMap userSignData : v) {
if(!userSignData.getBoolean("isAttend")) {
userSignData.put("isAttend", "未签到");
userSignData.put("attendTimeExcel", "未签到");
}else {
userSignData.put("isAttend", "已签到");
}
}
Map<String, Object> userExportMap = new HashMap<>();
userExportMap.put("name", courseName);
userExportMap.put("title", userExportParams);
userExportMap.put("entity", currentEntities);
userExportMap.put("data", v);
sheetsList.add(userExportMap);
}
try {
String fileName = activity.getActivityName() + "签到人员名单.xls";
String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", disposition);
Workbook workbook = new HSSFWorkbook();
for (Map<String, Object> map : sheetsList) {
ExcelExportService service = new ExcelExportService();
service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List<ExcelExportEntity>) map.get("entity"),(Collection<?>) map.get("data"));
}
workbook.write(response.getOutputStream());
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@At
@Ok("void")
@ApiOperation("导出领取人员")
public void exportGiftPerson(@Param(value = "activityId") String activityId,
HttpServletResponse response) {
LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId);
Sql sql = Sqls.create("""
SELECT
uc.*,
DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel,
DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel,
DATE_FORMAT(uc.receiveTime, '%Y-%m-%d %H:%i:%s') as receiveTimeExcel,
u.username,
u.loginname,
u.unitName,
u.unionName,
u.sex
FROM
literacy_user_course uc
left join literacy_course course on uc.courseId = course.id
left join `vw_user` u on u.id = uc.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("uc.activityId", "=", activityId);
cnd.and("course.isReceiveGift", "=", true).and("course.giftType" ,"=", 1);
cnd.desc("isReceive").desc("receiveTime");
sql.setCondition(cnd);
List<NutMap> userList = literacyBlackListService.listMap(sql);
List<LiteracyCourse> courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId));
List<Map<String, Object>> sheetsList = new ArrayList<>();
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22));
excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22));
excelCommonExportEntity.add(new ExcelExportEntity("是否领取", "isReceive", 20));
excelCommonExportEntity.add(new ExcelExportEntity("领取时间", "receiveTimeExcel", 22));
for (LiteracyCourse c : courseList) {
String courseId = c.getId();
String courseName = c.getCourseName();
List<NutMap> v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList());
ExportParams userExportParams = new ExportParams();
userExportParams.setSheetName(courseName);
List<ExcelExportEntity> currentEntities = new ArrayList<>(excelCommonExportEntity);
for (NutMap userSignData : v) {
if(!userSignData.getBoolean("isReceive")) {
userSignData.put("isReceive", "未领取");
userSignData.put("receiveTimeExcel", "未领取");
}else {
userSignData.put("isReceive", "已领取");
}
}
Map<String, Object> userExportMap = new HashMap<>();
userExportMap.put("name", courseName);
userExportMap.put("title", userExportParams);
userExportMap.put("entity", currentEntities);
userExportMap.put("data", v);
sheetsList.add(userExportMap);
}
try {
String fileName = activity.getActivityName() + "礼品领取人员名单.xls";
String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", disposition);
Workbook workbook = new HSSFWorkbook();
for (Map<String, Object> map : sheetsList) {
ExcelExportService service = new ExcelExportService();
service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List<ExcelExportEntity>) map.get("entity"),(Collection<?>) map.get("data"));
}
workbook.write(response.getOutputStream());
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,373 @@
package com.budwk.app.zhgh.activity.literacy.controller.mobile;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.activity.literacy.models.*;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.Static;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.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 java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description TODO
* @createTime 2022年02月25日 13:44:00
*/
@IocBean
@Ok("json:full")
@Api(tags = "亲子活动移动端")
@At("/platform/mobile/literacyActivity")
public class MLiteracyActivityController {
private static final String REDIS_KEY_PREFIX = "m_literacy_activity";
private final ReentrantLock lock = new ReentrantLock(true);
@Inject
private Dao dao;
@Inject
private LiteracyActivityService literacyActivityService;
@Inject
private RedisService redisService;
@Inject
private LiteracyActivityStatisticsService statisticsService;
@At("/literacyList")
@Ok("beetl:/platform/zhghh5/activity/literacy/literacyList/index.html")
@SaCheckPermission("h5.literacy.sign")
public void literacyList() {
}
@At("/literacyInfo")
@Ok("beetl:/platform/zhghh5/activity/literacy/literacyInfo/index.html")
@SaCheckPermission("h5.literacy.sign")
public void literacyInfo() {
}
@At("/activityInfo")
@Ok("beetl:/platform/zhghh5/activity/literacy/activityInfo/index.html")
@SaCheckPermission("h5.literacy.sign")
public void activityInfo() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("h5.literacy.sign")
public Result pageData(PageForm pageForm,
@Param(value = "activityStatus") int activityStatus,
@Param(value = "year") Integer year,
@Param(value = "activityType") Integer activityType) {
Pagination pagination = literacyActivityService.mPageData(pageForm, year, activityStatus, activityType);
return Result.success(pagination);
}
/**
* @param id 活动id
* @param tabIndex 0全部 1我的
* @return
*/
@At
@ApiOperation("查询单个活动")
@SaCheckPermission("h5.literacy.sign")
public Result findOne(@Param("id") String id,
@Param(value = "tabIndex") Integer tabIndex,
@Param(value = "fromMode") String fromMode) {
Cnd cnd = Cnd.NEW();
if (tabIndex > 0) {
List<LiteracyUser> mySignCourseList = dao.query(LiteracyUser.class, Cnd.where("userId", "=", SecurityUtil.getUserId()).and("activityId", "=", id));
List<String> mySignCourseIdList = mySignCourseList.stream().map(LiteracyUser::getCourseId).collect(Collectors.toList());
cnd.and("id", "in", mySignCourseIdList);
}
NutMap nutMap = literacyActivityService.findOne(id, cnd, fromMode);
List<LiteracyCourse> courseList = nutMap.getAsList("courseList", LiteracyCourse.class);
courseList.forEach(v -> {
if (v.getCourseIsLimitApply() != null && v.getCourseIsLimitApply() && v.getIsSign()) {
LiteracyActivityCourse course = dao.fetch(LiteracyActivityCourse.class, Cnd.where("courseId", "=", v.getId()));
v.setCourseTimeName(DateUtil.format(course.getCourseStartTime(), "HH:mm") + "" + DateUtil.format(course.getCourseEndTime(), "HH:mm") + "");
}
});
return Result.success(nutMap);
}
@At
@ApiOperation("查询子活动时间段")
@SaCheckPermission("h5.literacy.sign")
public Object getCourseTimeSelectList(String courseId) {
// 查课程的时间段
List<LiteracyActivityCourse> courseList = dao.query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", courseId));
// 查课程的报名人数
List<LiteracyUserCourse> applyUserList = dao.query(LiteracyUserCourse.class, Cnd.where("courseId", "=", courseId));
// 按照课程下面时间段去分组
Map<String, List<LiteracyUserCourse>> collectMap = applyUserList.stream().collect(Collectors.groupingBy(LiteracyUserCourse::getActivityCourseId));
List<NutMap> list = courseList.stream().map(v -> {
String id = v.getId();
NutMap nutMap = NutMap.NEW();
List<LiteracyUserCourse> literacyUserCourses = collectMap.get(id);
int remainingNum = v.getCourseLimitNum() != null ? v.getCourseLimitNum() : 0;
if (Lang.isNotEmpty(literacyUserCourses)) {
remainingNum = v.getCourseLimitNum() - literacyUserCourses.size();
}
nutMap.put("remainingNum", remainingNum);
nutMap.put("text", DateUtil.format(v.getCourseStartTime(), "HH:mm") + "" + DateUtil.format(v.getCourseEndTime(), "HH:mm") + "段(剩" + remainingNum + ")");
nutMap.put("value", id);
return nutMap;
}).filter(v-> v.getInt("remainingNum") != 0).toList();
return Result.success(list);
}
@At
@ApiOperation("活动报名")
@SaCheckPermission("h5.literacy.sign")
@SLog(tag = "品牌活动-活动报名", msg = "活动报名")
public Result doSignUp(LiteracyUser literacyUser) {
try {
lock.lock();
boolean courseByUser = literacyActivityService.isSignCourseByUser(literacyUser.getCourseId(), SecurityUtil.getUserId());
if(courseByUser) {
return Result.error("您已报过该活动");
}
//判断人数
int number = 0;
LiteracyCourse course = literacyActivityService.dao().fetch(LiteracyCourse.class, literacyUser.getCourseId());
LiteracyType type = literacyActivityService.dao().fetch(LiteracyType.class, course.getCourseType());
if(type != null) {
if(type.getIsBringFamily() && type.getIsAddFamily()) {
List<NutMap> mobileColumnsValue = literacyUser.getMobileColumnsValue();
NutMap map = mobileColumnsValue.stream().filter(o -> "xdqsrs".equals(o.getString("columnCode"))).findAny().orElse(null);
number = map != null ? map.getInt("columnValue") : 0;
}
}
boolean signFull = literacyActivityService.isSignFull(course, number);
if(signFull) {
return Result.error("当前报名人数已满");
}
boolean signFullByUnionId = literacyActivityService.isSignFullByUnionId(course, number);
if(signFullByUnionId) {
return Result.error("该活动您所在的分工会名额不足");
}
literacyActivityService.doSignUp(literacyUser);
return Result.success("报名成功");
} catch (Exception e) {
e.printStackTrace();
return Result.success("报名失败");
} finally {
lock.unlock();
}
}
@At
@ApiOperation("取消报名")
@SaCheckPermission("h5.literacy.sign")
@SLog(tag = "品牌活动-活动报名", msg = "取消报名")
public Result cancelSignUp(@Param("activityId") String activityId, @Param("courseId") String courseId) {
String userId = SecurityUtil.getUserId();
//取消分两种情况
//第一种没有设置分工会人数限制,那么将候补的人按时间倒叙往上补
//第二种如果设置了分工会人数限制,那么只将本分工会的候补人员按照时间倒叙往上补,如果本分工会没有候补人员,则名额空出来,由校工会手动调整
LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId);
LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId);
LiteracyType type = dao.fetch(LiteracyType.class, course.getCourseType());
//如果是正常报名取消了,将候补报名的按时间倒叙第一个改为正常报名
Cnd cnd = Cnd.where("activityId", "=", activityId).and("courseId", "=", courseId)
.and("state", "=", 2);
//如果设置了分工会报名人数限制,则只查本分工会
if (Lang.isNotEmpty(course.getUnionLimit())) {
cnd.and(new Static(" userId in (select id from user where unionid = '%s')".formatted(SecurityUtil.getUnionId())));
}
cnd.asc("signUpTime");
if (!type.getIsBringFamily() && course.getReserveMode() == 2) {
List<LiteracyUser> signUpUsers = dao.query(LiteracyUser.class, cnd);
int thisSignUpUserCount = dao.count(LiteracyUser.class,
Cnd.where("activityId", "=", activityId)
.and("courseId", "=", courseId).and("userId", "=", userId)
.and("state", "in", List.of(1, 3)));
if (!signUpUsers.isEmpty() && thisSignUpUserCount > 0) {
LiteracyUser literacyUser = signUpUsers.get(0);
literacyUser.setState(1);
dao.update(literacyUser);
Sys_user user = dao.fetch(Sys_user.class, literacyUser.getUserId());
//msgApi.sendTextMsg("【" + activity.getActivityName() + "】已候补成功,请按时参加活动!", user.getLoginname());
}
}
//删除报名记录
dao.clear("literacy_user_course", Cnd.where("activityId", "=", activityId)
.and("courseId", "=", courseId).and("userId", "=", userId));
dao.clear("literacy_user", Cnd.where("activityId", "=", activityId)
.and("courseId", "=", courseId).and("userId", "=", userId));
return Result.success();
}
@At
@ApiOperation("签到")
@SaCheckPermission("h5.literacy.sign")
@SLog(tag = "品牌活动-活动报名", msg = "签到")
public Result doQd(@Param("id") String id, @Param("courseId") String courseId, @Param("point") Double[] points) {
LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId);
List<Double> coursePoints = course.getCourseLocationCoordinates();
// if (Lang.isNotEmpty(coursePoints)) {
// //需要签到
// if (ArrayUtil.isEmpty(points) || ArrayUtil.hasNull(points)) {
// return Result.error().addMsg("请获取当前的坐标信息");
// }
// Double[] coursePointArray = coursePoints.toArray(new Double[]{});
// float distance = AMapUtils.calculateLineDistance(new LatLng(points[0], points[1]), new LatLng(coursePointArray[0], coursePointArray[1]));
//
// if (distance > 500) {
// return Result.error().addMsg("请到签到点位附近签到");
// }
// }
literacyActivityService.doQd(id);
return Result.success();
}
/**
* 签到信息
*
* @param activityId
* @return
*/
@At
@ApiOperation("获取签到信息")
@SaCheckPermission("h5.literacy.sign")
public Result getQdInfoList(@Param("activityId") String activityId) {
List<NutMap> list = literacyActivityService.qdInfoByUserId(SecurityUtil.getUserId(), activityId);
return Result.success(list);
}
@At
@ApiOperation("验证是否能报名")
@SaCheckPermission("h5.literacy.sign")
public Result validateSignUp(String courseId,
@Param(value = "currentFamilyNumber") Integer currentFamilyNumber) {
try {
lock.lock();
if(StrUtil.isBlank(courseId)) {
return Result.error("报名信息为空");
}
currentFamilyNumber = currentFamilyNumber != null ? currentFamilyNumber : 0;
LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId);
LiteracyActivity activity = dao.fetch(LiteracyActivity.class, course.getActivityId());
//判断时间
if(DateUtil.compare(new Date(), activity.getActivitySignUpStartTime(), "yyyy-MM-dd HH:mm:ss") < 0) {
return Result.error("报名未开始");
}
if(DateUtil.compare(new Date(), activity.getActivitySignUpEndTime(), "yyyy-MM-dd HH:mm:ss") > 0) {
return Result.error("报名已结束");
}
//判断活动组别
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getActivityGroupId()).and("userId", "=", SecurityUtil.getUserId()));
if(count == 0) {
return Result.error("抱歉,您没有此次活动的权限");
}
//判断是否报名
boolean courseByUser = literacyActivityService.isSignCourseByUser(courseId, SecurityUtil.getUserId());
if(courseByUser) {
return Result.error("抱歉,您已经报名");
}
//判断活动人数
boolean signFull = literacyActivityService.isSignFull(course, currentFamilyNumber);
if(signFull) {
return Result.error("名额剩余数量不足");
}
//判断活动限制
boolean signCourse = literacyActivityService.isSignCourse(course, activity);
if(!signCourse) {
if(activity.getRestrictLimit() != 3) {
return Result.error("您选择的类型已达上限,不能再报该类型的了");
} else {
return Result.error(activity.getActivityName() + "限制报" + activity.getLimitNum() + "个活动,已达上限");
}
}
//判断分工会人数限制
boolean signFullByUnionId = literacyActivityService.isSignFullByUnionId(course, currentFamilyNumber);
if(signFullByUnionId) {
return Result.error("您所在的分工会名额不足");
}
return Result.success();
}catch (Exception e) {
e.printStackTrace();
return Result.error("报名失败");
} finally {
lock.unlock();
}
}
@At
@ApiOperation("验证子活动是否能报名")
@SaCheckPermission("h5.literacy.sign")
public Object validateSourceSignUp(String activityCourseId, String courseId) {
try {
lock.lock();
// 该时间段下已报名的人数
int count = dao.count(LiteracyUserCourse.class, Cnd.where("activityCourseId", "=", activityCourseId)
.and("courseId", "=", courseId));
// 获取改时间段下的活动课程限制报名人数
LiteracyActivityCourse course = dao.fetch(LiteracyActivityCourse.class, activityCourseId);
Integer courseLimitNum = course.getCourseLimitNum();
// 报名加上自己,如果大于了限制人数,那就无法报名
if (count + 1 > courseLimitNum) {
return Result.error("该时间段名额已报满,请选择其他时段报名");
} else {
return Result.success();
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("报名失败");
} finally {
lock.unlock();
}
}
@At
@ApiOperation("二维码签到")
@SaCheckPermission("h5.literacy.sign")
@SLog(tag = "品牌活动-活动报名", msg = "二维码签到")
public Result codeSign(String id, String codeCourseId, String clickCourseId) {
if(StrUtil.isBlank(codeCourseId) || StrUtil.isBlank(clickCourseId)) {
return Result.error("签到失败,没有获取到扫描信息");
}
if(!codeCourseId.equals(clickCourseId)) {
return Result.error("签到失败,二维码与您当前签到信息不符");
}
dao.update(LiteracyUserCourse.class, Chain.make("isAttend", true)
.add("attendTime", new Date()), Cnd.where("id", "=", id));
return Result.success();
}
}
@@ -0,0 +1,201 @@
package com.budwk.app.zhgh.activity.literacy.controller.mobile;
import lombok.extern.slf4j.Slf4j;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* 品牌活动扫码
*/
@IocBean
@At("/platform/mobile/literacyActivityScannerQrCode")
@Ok("json:full")
@Slf4j
public class MLiteracyActivityScannerQrCodeController {
/*@Inject
private WxTokenUtil;
@Inject
private literacyActivityService literacyActivityService;
@Inject
private Dao dao;
@At("")
@Ok("beetl:/mobile/scannerQrCode.html")
public void scannerQrCode() {
}
*//**
* 微信js验证
*
* @param url
* @return
*//*
@At("/auth/sign")
@ViReturn
@RequiresAuthentication
public Object wxAuthSign(String url) {
String jsapi_ticket = wxTokenUtil.jsTicket();
return sign(jsapi_ticket, url);
}
*//**
* 二维码信息
*
* @param userId 用户id
* @param signId 签到记录id
* @param activityId 活动id
* @return
*//*
@At("/qrCodeInfo")
@RequiresAuthentication
public Object qrCodeInfo(@Param("userId") String userId, @Param("signId") String signId, @Param("activityId") String activityId) {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(signId) || StrUtil.isBlank(activityId)) {
return Result.error("参数错误");
}
try {
// Sql activitySql = Sqls.create("select activityName,cover from literacy_activity where id = @activityId");
// activitySql.setParam("activityId",activityId);
// NutMap activityMap = (NutMap) Daos.query(dao, activitySql.toString(), Sqls.callback.map());
Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId");
signSql.setParam("signId", signId);
NutMap attendInfo = (NutMap) Daos.query(dao, signSql.toString(), Sqls.callback.map());
Sql userSql = Sqls.create("select id,username,loginname,unitname,unionname,sex from `user` where id = @userId");
userSql.setParam("userId", userId);
NutMap userMap = (NutMap) Daos.query(dao, userSql.toString(), Sqls.callback.map());
return Result.success(Map.of("signInfo", attendInfo, "userInfo", userMap));
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("获取信息失败");
}
}
@At("/signInfo")
@RequiresAuthentication
public Object signInfo(@Param("signId") String signId) {
if (StrUtil.isBlank(signId)) {
return Result.error("参数错误");
}
try {
Sql signSql = Sqls.create("select isAttend,attendTime from literacy_user_course where id = @signId");
signSql.setParam("signId", signId);
NutMap signInfo = literacyActivityService.fetch(signSql);
return Result.success(signInfo);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("获取信息失败");
}
}
*//**
* 发放礼品
*
* @param signId
* @return
*//*
@At("/grantGiftByQrCode")
@RequiresAuthentication
public Object grantGiftByQrCode(@Param("signId") String signId) {
if (StrUtil.isBlank(signId)) {
return Result.error("参数错误");
}
try {
Chain chain = Chain.make("isReceive", 1);
chain.add("receiveTime", new Date());
chain.add("giftScannerCodeUserId", ShiroUtil.getPrincipalProperty("id"));
dao.update(literacyUserCourse.class, chain, Cnd.where("id", "=", signId));
Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId");
signSql.setParam("signId", signId);
NutMap signInfo = literacyActivityService.fetch(signSql);
return Result.success(signInfo);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("获取信息失败");
}
}
*//**
* 二维码扫描确认签到
*
* @param signId
* @return
*//*
@At("/confirmSignByQrCode")
@RequiresAuthentication
public Object confirmSignByQrCode(@Param("signId") String signId) {
if (StrUtil.isBlank(signId)) {
return Result.error("参数错误");
}
try {
Chain chain = Chain.make("isAttend", 1);
chain.add("attendTime", new Date());
chain.add("signScannerCodeUserId", ShiroUtil.getPrincipalProperty("id"));
dao.update(literacyUserCourse.class, chain, Cnd.where("id", "=", signId));
Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId");
signSql.setParam("signId", signId);
NutMap signInfo = literacyActivityService.fetch(signSql);
return Result.success(signInfo);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("获取信息失败");
}
}
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"&timestamp=" + timestamp +
"&url=" + url;
System.out.println(string1);
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}*/
}
@@ -0,0 +1,254 @@
package com.budwk.app.zhgh.activity.literacy.controller.statistics;
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.afterturn.easypoi.excel.export.ExcelExportService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyMobileSignColumn;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyType;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
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.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 org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description 培训报名 统计
* @createTime 2022年02月23日 09:57:00
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "品牌活动统计")
@At("/platform/literacy/statistics/activity")
public class LiteracyActivityStatisticsController {
@Inject
private LiteracyActivityService literacyActivityManageService;
@Inject
private LiteracyActivityStatisticsService literacyActivityStatisticsService;
@Inject
private Dao dao;
@At("")
@SaCheckPermission("literacy.statistics.activity")
@Ok("beetl:/platform/zhgh/activity/literacy/statistics/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("literacy.statistics.activity")
public Result pageData(PageForm pageForm,
@Param(value = "activityId") String activityId) {
Pagination pagination = literacyActivityStatisticsService.pageData(pageForm, activityId);
return Result.success(pagination);
}
/**
* 活动list
*
* @param year 年度
* @return
*/
@At
@ApiOperation("活动列表")
@SaCheckPermission("literacy.statistics.activity")
public Result activityList(@Param(value = "year") Integer year) {
List<LiteracyActivity> list = dao.query(LiteracyActivity.class, Cnd.NEW().andEX("year", "=", year).desc("activityStartTime"));
return Result.success(list);
}
/**
* 培训班报名人员list
*
* @param courseId
* @return
*/
@At
@ApiOperation("报名人员列表")
@SaCheckPermission("literacy.statistics.activity")
public Result registerUserList(@Param(value = "courseId") String courseId) {
return Result.success(literacyActivityStatisticsService.registerUserList(courseId));
}
@At
@ApiOperation("报名动态列")
@SaCheckPermission("literacy.statistics.activity")
public Object getTaleColumnInfo(@Param(value = "courseId") String courseId) {
return Result.success(literacyActivityStatisticsService.getTaleColumnInfo(courseId));
}
/**
* 培训班上课签到信息
*
* @param courseId
* @return
*/
@At
@ApiOperation("获取签到信息")
@SaCheckPermission("literacy.statistics.activity")
public Result getSignInfo(@Param("courseId") String courseId) {
return Result.success(literacyActivityStatisticsService.getSignInfo(courseId));
}
@At
@ApiOperation("开放报名")
@SaCheckPermission("literacy.statistics.activity")
public Result signChange(@Param("courseId") String courseId, @Param("openOtherUnion") Boolean openOtherUnion) {
dao.update(LiteracyCourse.class, Chain.make("openOtherUnion", openOtherUnion)
, Cnd.where("id", "=", courseId));
return Result.success();
}
@At
@Ok("void")
@ApiOperation("导出签到名单")
@SaCheckPermission("literacy.statistics.activity")
public void exportSignUser(@Param(value = "activityId") String activityId,
HttpServletResponse response) throws IOException {
try {
LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId);
Sql sql = Sqls.create("""
SELECT
ts.*,
CONCAT(DATE_FORMAT(ac.courseStartTime, '%H:%i:%s'),'至',DATE_FORMAT(ac.courseEndTime, '%H:%i:%s')) AS courseTime,
u.username,
u.loginname,
u.sex,
ifnull(ts.mobile, u.mobile) as mobile,
u.birthday,
tsc.courseName
FROM
literacy_user ts
left join literacy_activity_course ac on ts.activityCourseId = ac.id
left join `vw_user` u on u.id = ts. userId
left join literacy_course tsc on tsc.id = ts.courseId
WHERE
ts.activityId = @activityId
""").setParam("activityId", activityId);
List<NutMap> userList = literacyActivityManageService.listMap(sql);
List<LiteracyCourse> courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId));
List<LiteracyType> literacyTypeList = dao.query(LiteracyType.class, Cnd.NEW());
dao.fetchLinks(literacyTypeList, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
Map<String, LiteracyType> typeMap = literacyTypeList.stream().collect(Collectors.toMap(LiteracyType::getId, o -> o));
List<Map<String, Object>> sheetsList = new ArrayList<>();
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
excelCommonExportEntity.add(new ExcelExportEntity("手机号", "mobile", 20));
excelCommonExportEntity.add(new ExcelExportEntity("生日", "birthday", 20));
excelCommonExportEntity.add(new ExcelExportEntity("报名时段", "courseTime", 20));
for (LiteracyCourse c : courseList) {
String k = c.getCourseName();
List<NutMap> v = userList.stream().filter(x -> x.getString("courseName").equals(k)).collect(Collectors.toList());
ExportParams userExportParams = new ExportParams();
userExportParams.setSheetName(k);
userExportParams.setType(ExcelType.HSSF);
List<ExcelExportEntity> currentEntities = new ArrayList<>();
currentEntities.addAll(excelCommonExportEntity);
LiteracyType signUpType = typeMap.get(c.getCourseType());
if (Lang.isNotEmpty(signUpType.getLiteracyMobileSignColumnList())) {
for (LiteracyMobileSignColumn column : signUpType.getLiteracyMobileSignColumnList()) {
ExcelExportEntity entity = new ExcelExportEntity();
entity.setName(column.getColumnName());
entity.setKey(column.getColumnCode());
entity.setWidth(20);
if (column.getColumnFormType().equals("FILE")) {
entity.setType(2);
entity.setExportImageType(2);
}
currentEntities.add(entity);
}
}
for (NutMap userSignData : v) {
String mobileColumnsValueStr = userSignData.getString("mobileColumnsValue");
if (StrUtil.isNotBlank(mobileColumnsValueStr)) {
List<NutMap> mobileColumnsValue = Json.fromJsonAsList(NutMap.class, mobileColumnsValueStr);
for (NutMap cv : mobileColumnsValue) {
if (!"FILE".equals(cv.getString("columnFormType"))) {
userSignData.put(cv.getString("columnCode"), cv.getString("columnValue"));
} else {
if (StrUtil.isNotBlank(cv.getString("columnValue"))) {
List<JSONObject> columnValue = Json.fromJsonAsList(JSONObject.class, cv.getString("columnValue"));
if (columnValue.size() == 1) {
JSONObject sysFile = columnValue.get(0);
Sys_file file = dao.fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", sysFile.get("url")));
byte[] imageBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
if (imageBytes.length > 0) {
userSignData.put(cv.getString("columnCode"), imageBytes);
}
}
}
}
}
}
}
Map<String, Object> userExportMap = new HashMap<>();
userExportMap.put("name", k);
userExportMap.put("title", userExportParams);
userExportMap.put("entity", currentEntities);
userExportMap.put("data", v);
sheetsList.add(userExportMap);
}
Workbook workbook = new HSSFWorkbook();
for (Map<String, Object> map : sheetsList) {
ExcelExportService service = new ExcelExportService();
service.createSheetForMap(workbook, (ExportParams) map.get("title"), (List<ExcelExportEntity>) map.get("entity"), (Collection<?>) map.get("data"));
}
workbook.write(response.getOutputStream());
workbook.close();
CommonDownloadUtil.download(activity.getActivityName() + "报名人员名单" + ".xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,136 @@
package com.budwk.app.zhgh.activity.literacy.models;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.services.SysHomeConvert;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.Lang;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author zxy
* @Description 培训报名活动
* @createTime 2022年02月23日 08:57:00
*/
@Table
@Data
@Accessors(chain = true)
public class LiteracyActivity extends BaseModel implements Serializable, SysHomeConvert {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("活动名称")
private String activityName;
@Column
@ColDefine(type = ColType.INT)
@Comment("年度")
private Integer year;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动报名开始时间")
private Date activitySignUpStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动报名开始时间")
private Date activitySignUpEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动开始时间")
private Date activityStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动结束时间")
private Date activityEndTime;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否禁用")
private boolean isDisabled;
@Column
@ColDefine(customType = "longtext")
@Comment("活动介绍")
private String introduce;
@Column
@ColDefine(type = ColType.INT, width = 10)
@Comment("活动限制标识")
private Integer restrictLimit;
@Column
@ColDefine(type = ColType.INT, width = 10)
@Comment("活动限制报名个数")
private Integer limitNum;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("活动封面")
private String cover;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("微信群二维码")
private String wechat;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("上课前是否通知")
private boolean notice;
@Column
@Comment("活动范围Id")
@ColDefine(type = ColType.INT, width = 32)
private Integer activityGroupId;
@Column
@Comment("活动范围名称")
@ColDefine(type = ColType.VARCHAR, width = 40)
private String activityGroupName;
/**
* 所有的培训班
*/
@Many(field = "activityId")
private List<LiteracyCourse> courseList;
@Many(field = "activityId")
private List<LiteracyTypeLimit> typeLimits;
@Column
@Comment("活动类型")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String literacyType;
@Override
public Sys_home_activity covertToSysHomeActivity() {
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(this.getId());
sysHomeActivity.setName(this.getActivityName());
sysHomeActivity.setCover(this.getCover());
sysHomeActivity.setUrl("/platform/literacy/manage/apply");
sysHomeActivity.setH5Url("/platform/mobile/literacyActivity/literacyList");
if (Lang.isNotEmpty(this.getActivitySignUpStartTime())) {
sysHomeActivity.setStartDate(this.getActivitySignUpStartTime());
sysHomeActivity.setEndDate(this.getActivitySignUpEndTime());
}
sysHomeActivity.setAllowUserGroupId(this.getActivityGroupId());
sysHomeActivity.setEnable(!this.isDisabled());
sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName());
return sysHomeActivity;
}
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
/**
* @author zxy
* @Description 活动下的课程
* @createTime 2022年02月23日 09:26:00
*/
@Table
@Data
@Accessors(chain = true)
public class LiteracyActivityCourse {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动ID")
private String activityId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("课程ID")
private String courseId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("课程开始时间")
private Date courseStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("课程结束时间")
private Date courseEndTime;
@Column
@ColDefine(type = ColType.DATE)
@Comment("课程时间")
private Date courseDate;
@Column
@ColDefine(type = ColType.INT, width = 4)
@Comment("限制人数")
private Integer courseLimitNum;
private Integer hasRegisterNum;
}
@@ -0,0 +1,31 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @author zxy
* @Description 黑名单
* @createTime 2022年03月07日 14:32:00
*/
@Table
@Data
public class LiteracyBlackList {
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("用户id")
private String userId;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否禁用")
private Boolean isDisabled;
}
@@ -0,0 +1,160 @@
package com.budwk.app.zhgh.activity.literacy.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import java.io.Serializable;
import java.util.List;
/**
* @author zxy
* @Description 培训班信息
* @createTime 2022年02月23日 09:04:00
*/
@Table
@Data
@Accessors(chain = true)
public class LiteracyCourse extends BaseModel implements Serializable {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("活动ID")
private String activityId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("课程名称")
private String courseName;
@Column
@ColDefine(type = ColType.INT)
@Comment("课程人数")
private int coursePeopleNumber;
@Column
@ColDefine(type = ColType.INT)
@Default(value = "0")
@Comment("预留名额")
private int courseReservedNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("课程地点")
private String courseLocation;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("课程类型")
private String courseType;
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("课程地点坐标")
private List<Double> courseLocationCoordinates;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("课程讲师")
private String courseInstructor;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("校区")
private String campus;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("报名人数是否限制")
private Boolean courseIsLimitApply;
@Column
@ColDefine(type = ColType.INT)
@Comment("序号")
private int orderNum;
@Many(field = "courseId")
private List<LiteracyActivityCourse> courseTimeList;
//已报人数
private Integer hasRegisterNum;
private Boolean isBringFamily;
private Boolean isAddFamily;
//是否报过该课程
private Boolean isSign;
//还能报该类型的课程吗
private Boolean canSignThisCourseType;
@Column
@Comment("分工会人数限制")
@ColDefine(type = ColType.MYSQL_JSON)
private List<NutMap> unionLimit;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("移动端是否签到")
private boolean isMobileSign;
@Column
@ColDefine(type = ColType.INT)
@Comment("签到方式 1.扫描二维码签到 2.被扫 3.gps签到")
private Integer signType;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("移动端是否签收礼品")
private boolean isReceiveGift;
@Column
@ColDefine(type = ColType.INT)
@Comment("领取礼品方式 1.扫描二维码 2.线下")
private Integer giftType;
@Column
@ColDefine(type = ColType.INT)
@Comment("预留名额方式 1.报名人员减少模式 2.报名人数不变模式")
private Integer reserveMode;
@Column
@Comment("承办工会")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String hostUnionId;
@Column
@Comment("对内报名时间")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String interTime;
@Column
@Comment("是否开放给其他工会")
@ColDefine(type = ColType.BOOLEAN, width = 4)
private Boolean openOtherUnion;
@Column
@Comment("分类标识")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String assort;
@Column
@ColDefine(type = ColType.INT)
@Default(value = "0")
@Comment("候补名额数")
private Integer waitingNum;
//候补已报人数
private Integer hasWaitingNum;
private String courseTimeName;
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.List;
@Table("literacy_mobile_sign_column")
@Data
public class LiteracyMobileSignColumn {
private static final long serialVersionUID = 1L;
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
/**
* train_sign_up_type id
*/
@Column
@Comment("类型id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String typeId;
@Column
@Comment("字段名称")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String columnName;
@Column
@Comment("字段编码")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String columnCode;
@Column
@Comment("字段值")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String columnValue;
@Column
@Comment("字段类型")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String columnType;
@Column
@Comment("下拉框的值")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> selectValues;
@Column
@Comment("是否必填")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isRequired;
@Column
@Comment("控件类型")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String columnFormType;
@Column
@Comment("文件个数")
@ColDefine(type = ColType.INT)
private Integer fileNumber;
@Column
@Comment("文件类型")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> fileType;
@Column
@Comment("序号")
@ColDefine(type = ColType.INT, width = 1)
private Integer columnIndex;
}
@@ -0,0 +1,68 @@
package com.budwk.app.zhgh.activity.literacy.models;
import com.budwk.app.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.Serial;
import java.io.Serializable;
import java.util.List;
/**
* TODO
*
* @author 赵欣雨
* @date 2020/8/18 9:16
*/
@Data
@Table("literacy_type")
@EqualsAndHashCode(callSuper = true)
public class LiteracyType extends BaseModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("类型编码")
@ColDefine(type = ColType.VARCHAR, width = 80)
private String code;
@Column
@Comment("类型名称")
@ColDefine(type = ColType.VARCHAR, width = 80)
private String typeName;
@Column
@Comment("序号")
@ColDefine(type = ColType.INT, width = 1)
private Integer xh;
@Column
@Comment("是否携带家属")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isBringFamily;
@Column
@Comment("家属纳入总人数")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isAddFamily;
@Column
@Comment("本人纳入总人数")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean selfAddFamily;
@Many(field = "typeId")
private List<LiteracyMobileSignColumn> literacyMobileSignColumnList;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* @Author JyuHsin
* @Date 2022/9/22
* @Description
*/
@Table("literacy_type_limit")
@Data
public class LiteracyTypeLimit implements Serializable {
private static final long serialVersionUID = 1L;
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("活动id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String activityId;
@Column
@Comment("活动类型id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String typeId;
@Column
@Comment("限制个数")
@ColDefine(type = ColType.INT, width = 10)
private int limitNum;
}
@@ -0,0 +1,88 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author zxy
* @Description 报名人员 报名记录
* @createTime 2022年02月23日 09:34:00
*/
@Table
@Data
@Accessors(chain = true)
@TableIndexes({@Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSEID", fields = {"courseId"}, unique = false)})
public class LiteracyUser implements Serializable {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动ID")
private String activityId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("课程ID")
private String courseId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("用户ID")
private String userId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工会ID")
private String unionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("单位ID")
private String unitId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("工会")
private String unionName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("单位")
private String unitName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("联系方式")
private String mobile;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名时间")
private Date signUpTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动课程时段id")
private String activityCourseId;
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("手机端报名字段和值")
private List<NutMap> mobileColumnsValue;
@Column
@ColDefine(type = ColType.INT)
@Comment("用户报名状态(1.正常 2.待报名成功 3.也是正常,但是是从2变为1的 4.废弃[就是没签到的意思])")
private Integer state;
}
@@ -0,0 +1,89 @@
package com.budwk.app.zhgh.activity.literacy.models;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
/**
* @author zxy
* @Description 用户课程表
* @createTime 2022年02月23日 09:38:00
*/
@Table
@Data
@Accessors(chain = true)
@TableIndexes({
@Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSE_USERID", fields = {"userId"}, unique = false),
@Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSE_COURSEID", fields = {"courseId"}, unique = false)
})
public class LiteracyUserCourse implements Serializable {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动ID")
private String activityId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("课程ID")
private String courseId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("用户ID")
private String userId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("课程开始时间")
private Date courseStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("课程结束时间")
private Date courseEndTime;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否上课")
private boolean isAttend;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("上课打卡时间")
private Date attendTime;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否领取礼品")
private Boolean isReceive;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("领取礼品时间")
private Date receiveTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("签到扫码人员id(二维码模式)")
private String signScannerCodeUserId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("礼品扫码人员id(二维码模式)")
private String giftScannerCodeUserId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("关联literacy_sign_up_activity_course表的id")
private String activityCourseId;
}
@@ -0,0 +1,129 @@
package com.budwk.app.zhgh.activity.literacy.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* @author zxy
* @Description TODO
* @createTime 2022年02月23日 17:14:00
*/
public interface LiteracyActivityService extends BaseService<LiteracyActivity> {
/**
* 添加活动
*
* @param activity 活动信息
* @param course 培训班信息
*/
void add(LiteracyActivity activity, LiteracyCourse course);
/**
* 编辑活动
*
* @param activity 活动信息
*/
void edit(LiteracyActivity activity);
/**
* 更新活动状态
*
* @param activity 活动信息
*/
void updateActivityStatus(LiteracyActivity activity);
/**
* 查询单条活动信息
*
* @param id 活动ID
* @return 返回的数据与前端符合
*/
NutMap findOne(String id, Cnd cnd, String fromMode);
/**
* pc分页查询
*
* @param pageForm
* @param cnd
* @return
*/
Pagination pageData(PageForm pageForm, Cnd cnd);
/**
* 手机端分页查询
*
* @param pageForm 分页
* @param year 年度
* @param activityStatus 报名状态 0全部 1进行中 2结束
* @return
*/
Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType);
/**
* 手机端报名
*
* @param trainSignUpUser 活动ID
*/
void doSignUp(LiteracyUser trainSignUpUser) throws Exception;
/**
* 异步插入每个报名成功人员的课程数据
*
* @param activityId
* @param courseId
* @param userId
*/
void asyncInsertUserCourse(String activityId, String courseId, String userId);
/**
* 该培训班每个分工会名额是否报满
* @return
*/
boolean isSignFullByUnionId(LiteracyCourse course, Integer currentFamilyNumber);
/**
* 该培训班是否报满
*/
boolean isSignFull(LiteracyCourse course, Integer currentFamilyNumber);
/**
* 还能报该类型的培训班吗 比如书画班最多报一项 健身班两项
* @return
*/
boolean isSignCourse(LiteracyCourse course, LiteracyActivity activity);
/**
* 当前用户是否已报过该培训班
*
* @param courseId
* @param userId
* @return
*/
boolean isSignCourseByUser(String courseId, String userId);
/**
* 手机端签到
*
* @param id 每个培训班每节课每个用户的记录ID
*/
void doQd(String id);
/**
* 某个用户的签到信息
*
* @param userId 用户id
* @param activityId 活动id
*/
List<NutMap> qdInfoByUserId(String userId, String activityId);
List<LiteracyCourse> filterCourseByHostUnion(List<LiteracyCourse> courseList);
}
@@ -0,0 +1,68 @@
package com.budwk.app.zhgh.activity.literacy.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
/**
* @author zxy
* @Description 报名统计service
* @createTime 2022年03月03日 10:00:00
*/
public interface LiteracyActivityStatisticsService extends BaseService<LiteracyUser> {
/**
* 统计分页
*
* @param pageForm
* @param activityId
* @return
*/
Pagination pageData(PageForm pageForm, String activityId);
/**
* 该课程下的报名人员信息
*
* @param courseId
* @return
*/
List<NutMap> registerUserList(String courseId);
List<NutMap> getTaleColumnInfo(String courseId);
/**
* 该课程下的报名人员信息
*
* @param courseId
* @return
*/
List<NutMap> registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword);
/**
* 获取每个课程的签到情况
*
* @param courseId
* @return k->每个培训班每节课的上课时间 v->上课记录list
*/
Map<String, List<NutMap>> getSignInfo(String courseId);
/**
* 报名人员list 导出
* @param activityId
* @return
*/
List<NutMap> baoMingUserList(String activityId);
int queryCourseCount(String courseId, String courseType);
int queryCourseWaitCount(String courseId, String courseType);
int queryCourseCount(String courseId, String courseType, String unionId);
int queryCourseWaitCount(String courseId, String courseType, String unionId);
}
@@ -0,0 +1,43 @@
package com.budwk.app.zhgh.activity.literacy.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyBlackList;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* @author zxy
* @Description TODO
* @createTime 2022年03月07日 14:29:00
*/
public interface LiteracyBlackListService extends BaseService<LiteracyBlackList> {
/**
* 分页
*
* @param pageForm 分页
* @return Pagination
*/
Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId);
/**
* 拉黑、解封用户
*
* @param userId
*/
void doHandleUser(String userId);
/**
* 上课记录
*
* @param userId
* @return
*/
List<NutMap> attendClassRecord(String userId);
}
@@ -0,0 +1,473 @@
package com.budwk.app.zhgh.activity.literacy.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.literacy.models.*;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.async.Async;
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.cri.Static;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description TODO
* @createTime 2022年02月23日 17:14:00
*/
@Slf4j
@IocBean(args = {"refer:dao"})
public class LiteracyActivityServiceImpl extends BaseServiceImpl<LiteracyActivity> implements LiteracyActivityService {
@Inject
private LiteracyActivityStatisticsService statisticsService;
public LiteracyActivityServiceImpl(Dao dao) {
super(dao);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void add(LiteracyActivity activity, LiteracyCourse course) {
dao().insert(activity);
//插入类型限制
List<LiteracyTypeLimit> typeLimits = activity.getTypeLimits();
typeLimits.forEach(v -> v.setActivityId(activity.getId()));
dao().insert(typeLimits);
List<LiteracyCourse> courseList = activity.getCourseList();
for (LiteracyCourse v : courseList) {
v.setActivityId(activity.getId());
v.setOpenOtherUnion(false);
dao().insert(v);
this.setCourseTimeAndInsert(v);
}
if (!activity.isDisabled()) {
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
dao().insertOrUpdate(sysHomeActivity);
}
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void edit(LiteracyActivity activity) {
//修改活动
update(activity);
//修改类型限制
List<LiteracyTypeLimit> typeLimits = activity.getTypeLimits();
typeLimits.forEach(v -> v.setActivityId(activity.getId()));
if(Lang.isNotEmpty(typeLimits)) {
insertOrUpdate(typeLimits);
}
List<LiteracyCourse> courseList = activity.getCourseList();
courseList.forEach(v -> {
v.setActivityId(activity.getId());
dao().insertOrUpdate(v);
if (Lang.isNotEmpty(v.getCourseTimeList())) {
this.setCourseTimeAndInsert(v);
}
});
//查询原来的活动
List<LiteracyCourse> oldCourseList = dao().query(LiteracyCourse.class, Cnd.where("activityId", "=", activity.getId()));
//原来的培训班id
List<String> oldCourseIdList = oldCourseList.stream().map(LiteracyCourse::getId).toList();
//原来的上课时间
List<LiteracyActivityCourse> oldActCourseTimeList = dao().query(LiteracyActivityCourse.class, Cnd.where("activityId", "=", activity.getId()));
//现在的上课时间
List<String> nowCourseTimeListId = new ArrayList<>();
activity.getCourseList().forEach(v -> {
if (v.getCourseTimeList() != null) {
nowCourseTimeListId.addAll(v.getCourseTimeList().stream().map(LiteracyActivityCourse::getId).toList());
}
});
List<String> deleteCourseTimeListId = oldActCourseTimeList.stream().map(LiteracyActivityCourse::getId).filter(id -> !nowCourseTimeListId.contains(id)).collect(Collectors.toList());
List<String> courseIdList = courseList.stream().map(LiteracyCourse::getId).collect(Collectors.toList());
//删除关联的培训班
List<String> deleteIdList = oldCourseIdList.stream().filter(v -> !courseIdList.contains(v)).collect(Collectors.toList());
dao().clear(LiteracyCourse.class, Cnd.where("id", "in", deleteIdList));
dao().clear(LiteracyActivityCourse.class, Cnd.where("id", "in", deleteCourseTimeListId));
dao().clear(LiteracyUser.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
dao().clear(LiteracyUserCourse.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
//查询修改过培训时间的记录
Sql tsuucSql = Sqls.create("""
SELECT
tsuuc.id,
tsuac.courseStartTime,
tsuac.courseEndTime
FROM
`literacy_user_course` tsuuc
LEFT JOIN literacy_activity_course tsuac ON tsuac.id = tsuuc.activityCourseId
where tsuuc.courseStartTime != tsuac.courseStartTime or tsuuc.courseEndTime != tsuac.courseEndTime
""");
List<NutMap> tsuucList = listMap(tsuucSql);
tsuucList.forEach(v -> {
Chain chain = Chain.make("courseStartTime", v.getTime("courseStartTime"));
chain.add("courseEndTime", v.getTime("courseEndTime"));
Cnd cnd = Cnd.where("id", "=", v.getString("id"));
dao().update("literacy_user_course", chain, cnd);
});
if (!activity.isDisabled()) {
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
dao().insertOrUpdate(sysHomeActivity);
} else {
dao().delete(Sys_home_activity.class, activity.getId());
}
}
private void setCourseTimeAndInsert(LiteracyCourse course) {
course.getCourseTimeList().forEach(courseTime -> {
Calendar calendar = Calendar.getInstance();
calendar.setTime(courseTime.getCourseDate());
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(courseTime.getCourseStartTime());
startCalendar.set(year, month, day);
courseTime.setCourseStartTime(startCalendar.getTime());
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(courseTime.getCourseEndTime());
endCalendar.set(year, month, day);
courseTime.setCourseEndTime(endCalendar.getTime());
courseTime.setActivityId(course.getActivityId());
courseTime.setCourseId(course.getId());
dao().insertOrUpdate(courseTime);
});
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateActivityStatus(LiteracyActivity activity) {
updateIgnoreNull(activity);
}
@Override
public NutMap findOne(String id, Cnd cnd, String fromMode) {
if (Lang.isEmpty(cnd)) {
cnd = Cnd.NEW();
}
cnd.asc("orderNum").asc("campus").desc("courseLocation").asc("courseType").asc("courseName");
List<LiteracyCourse> courseArray = dao().query(LiteracyCourse.class, cnd.and("activityId", "=", id));
if (StrUtil.isNotBlank(fromMode) && "mobile".equals(fromMode)) {
courseArray = this.filterCourseByHostUnion(courseArray);
}
LiteracyActivity activity = fetchLinks(dao().fetch(LiteracyActivity.class, id), "^(conditionStructure|typeLimits)$");
activity.setCourseList(courseArray);
List<LiteracyCourse> courseList = activity.getCourseList();
courseList.forEach(c -> {
if (StrUtil.isNotBlank(c.getCourseType())) {
dao().fetchLinks(c, "^(courseTimeList)$", Cnd.NEW().asc("courseStartTime"));
int courseCount = statisticsService.queryCourseCount(c.getId(), c.getCourseType());
c.setHasRegisterNum(courseCount);
int courseWaitCount = statisticsService.queryCourseWaitCount(c.getId(), c.getCourseType());
c.setHasWaitingNum(courseWaitCount);
//当前用户是否报过
c.setIsSign(isSignCourseByUser(c.getId(), SecurityUtil.getUserId()));
}
});
return Lang.obj2nutmap(activity);
}
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd) {
Pagination pagination = listPageLinks(pageForm.getPageNumber(), pageForm.getPageSize(), cnd, "^(courseList)$");
return pagination;
}
@Override
public Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
switch (activityStatus) {
case 2 -> {
cnd.and(new Static("activitySignUpStartTime < now()"));
cnd.and(new Static("activitySignUpEndTime > now()"));
}
case 3 -> {
cnd.and(new Static("activityStartTime < now()"));
cnd.and(new Static("activityEndTime > now()"));
}
case 4 -> cnd.and(new Static("activityEndTime < now()"));
case 5 -> cnd.and(new Static("activityStartTime < now()"));
case 6 -> cnd.and(new Static("activityStartTime > now()"));
}
if (activityType != null && activityType == 1) {
cnd.and(new Static("id in (select activityId from literacy_user where userId = '%s')".formatted(SecurityUtil.getUserId())));
}
cnd.and("isDisabled", "=", 0);
cnd.orderBy("activityEndTime", "desc");
cnd.orderBy("isDisabled", "desc");
cnd.orderBy("createdAt", "desc");
return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void doSignUp(LiteracyUser literacyUser) throws Exception {
String userId = SecurityUtil.getUserId();
//查询课程
LiteracyCourse course = dao().fetch(LiteracyCourse.class, literacyUser.getCourseId());
LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType());
//如果这个课程的预留名额方式为报名人数不变
if (course.getReserveMode() == 2) {
//如果当前报名+已报小于这个课程限制人数
//课程已报人数
int normalCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType());
//+1是算自己
int hasRegisterNum = type.getSelfAddFamily() ? normalCount + 1 : 0;
literacyUser.setState((hasRegisterNum + course.getCourseReservedNumber()) > course.getCoursePeopleNumber() ? 2 : 1);
} else {
literacyUser.setState(1);
}
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
literacyUser.setUnionId(SecurityUtil.getUnionId());
literacyUser.setUnionName(user.getUnionName());
literacyUser.setUnitId(SecurityUtil.getUnitId());
literacyUser.setUnitName(user.getUnitName());
literacyUser.setUserId(userId);
literacyUser.setSignUpTime(new Date());
dao().insert(literacyUser);
if (StrUtil.isNotBlank(literacyUser.getActivityCourseId())) {
LiteracyActivityCourse fetch = dao().fetch(LiteracyActivityCourse.class, literacyUser.getActivityCourseId());
LiteracyUserCourse userCourse = new LiteracyUserCourse();
userCourse.setActivityId(literacyUser.getActivityId());
userCourse.setCourseId(literacyUser.getCourseId());
userCourse.setUserId(literacyUser.getUserId());
userCourse.setCourseStartTime(fetch.getCourseStartTime());
userCourse.setCourseEndTime(fetch.getCourseEndTime());
userCourse.setAttend(false);
userCourse.setAttendTime(null);
userCourse.setActivityCourseId(fetch.getId());
dao().insert(userCourse);
} else {
asyncInsertUserCourse(literacyUser.getActivityId(), literacyUser.getCourseId(), literacyUser.getUserId());
}
}
@Async
@Override
public void asyncInsertUserCourse(String activityId, String courseId, String userId) {
log.info("异步插入{}的上课信息,课程ID为{},活动ID为{}", userId, courseId, activityId);
List<LiteracyActivityCourse> courseList = dao().query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", courseId));
List<LiteracyUserCourse> list = new ArrayList<>();
courseList.forEach(v -> {
LiteracyUserCourse userCourse = new LiteracyUserCourse();
userCourse.setActivityId(activityId);
userCourse.setCourseId(courseId);
userCourse.setUserId(userId);
userCourse.setCourseStartTime(v.getCourseStartTime());
userCourse.setCourseEndTime(v.getCourseEndTime());
userCourse.setAttend(false);
userCourse.setAttendTime(null);
userCourse.setActivityCourseId(v.getId());
list.add(userCourse);
});
dao().insert(list);
}
/**
* 该培训班每个分工会名额是否报满
* @return
*/
@Override
public boolean isSignFullByUnionId(LiteracyCourse course, Integer currentFamilyNumber) {
List<NutMap> unionLimit = course.getUnionLimit();
if (Lang.isEmpty(unionLimit)) {
return false;
}
String unionId = SecurityUtil.getUnionId();
NutMap unionLimitMap = unionLimit.stream().filter(v -> v.getString("id").equals(unionId)).findAny().orElse(null);
if (Lang.isEmpty(unionLimitMap)) {
return true;
}
LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType());
//分工会限制人数
int limitCount = unionLimitMap.getInt("limitCount");
//该课程已经报名的总人数
int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType(), unionId);
int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType());
//+1是算自己
int current = type.getSelfAddFamily() ? 1 : 0;
currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0;
//如果还有正常名额
if(limitCount - hasSignCount > 0) {
return (hasSignCount + current + currentFamilyNumber) > limitCount;
} else {
return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum();
}
}
@Override
public boolean isSignFull(LiteracyCourse course, Integer currentFamilyNumber) {
//课程限制人数
int coursePeopleNumber = course.getCoursePeopleNumber();
if (coursePeopleNumber == 0) {
return true;
}
//查询课程对应的类型
LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType());
//课程已报人数
int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType());
int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType());
//+1是算自己
int current = type.getSelfAddFamily() ? 1 : 0;
currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0;
//如果还有正常名额
if(coursePeopleNumber - hasSignCount > 0) {
return (hasSignCount + current + currentFamilyNumber + course.getCourseReservedNumber()) > coursePeopleNumber;
} else {
return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum();
}
}
@Override
public boolean isSignCourse(LiteracyCourse course, LiteracyActivity activity) {
//培训班类型
String courseType = course.getCourseType();
Sql sql = Sqls.create("""
SELECT
count( tsus.id )
FROM
`literacy_user` tsus
LEFT JOIN literacy_course tsuc ON tsuc.id = tsus.courseId
WHERE
tsuc.courseType = @courseType
AND tsus.userId = @userId
AND tsus.activityId = @activityId
""");
sql.setParam("courseType", courseType);
sql.setParam("activityId", activity.getId());
sql.setParam("userId", SecurityUtil.getUserId());
int hasRegisterNum = count(sql);
//第一种无限制报名
if (activity.getRestrictLimit() == null || activity.getRestrictLimit() == 1) {
return true;
} else if (activity.getRestrictLimit() == 2) {
LiteracyTypeLimit literacyTypeLimit = dao().fetch(LiteracyTypeLimit.class, Cnd.where("typeId", "=", courseType).and("activityId", "=", activity.getId()));
if (literacyTypeLimit == null) {
return true;
}
//此类型的班最多可报几项
int personMaxRegisterNum = literacyTypeLimit.getLimitNum();
if (personMaxRegisterNum == 0) {
return true;
}
return hasRegisterNum < personMaxRegisterNum;
} else if (activity.getRestrictLimit() == 3) {
//第三种,限制报几个,不跟类型挂钩
int aCount = dao().count(LiteracyUser.class, Cnd.where("activityId", "=", activity.getId()).and("userId", "=", SecurityUtil.getUserId()));
return aCount < activity.getLimitNum();
}
return false;
}
@Override
public boolean isSignCourseByUser(String courseId, String userId) {
return dao().count(LiteracyUser.class, Cnd.where("courseId", "=", courseId).and("userId", "=", userId)) > 0;
}
@Override
public void doQd(String id) {
NutMap updateMap = NutMap.NEW();
updateMap.put("isAttend", true);
updateMap.put("attendTime", new Date());
dao().update(LiteracyUserCourse.class, Chain.from(updateMap), Cnd.where("id", "=", id));
}
@Override
public List<NutMap> qdInfoByUserId(String userId, String activityId) {
Sql sql = Sqls.create("""
SELECT
c.*,
t.courseLocationCoordinates,
t.isMobileSign,
t.signType,
t.isReceiveGift,
t.giftType,
(select state from literacy_user su where su.activityId = c.activityId and su.courseId = c.courseId and su.userId = c.userId) as state
FROM
`literacy_user_course` c
LEFT JOIN literacy_course t ON t.id = c.courseId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("c.activityId", "=", activityId);
cnd.and("c.userId", "=", userId);
cnd.asc("c.courseStartTime");
sql.setCondition(cnd);
return listMap(sql);
}
@Override
public List<LiteracyCourse> filterCourseByHostUnion(List<LiteracyCourse> courseList) {
if (Lang.isEmpty(courseList)) {
return new ArrayList<>();
}
return courseList.stream().filter(o -> {
if (StrUtil.isBlank(o.getInterTime()) || o.getOpenOtherUnion() == null || o.getOpenOtherUnion()) {
return true;
} else {
if (SecurityUtil.getUnionId().equals(o.getHostUnionId())) {
return true;
} else {
int compare = cn.hutool.core.date.DateUtil.compare(cn.hutool.core.date.DateUtil.date(), cn.hutool.core.date.DateUtil.parse(o.getInterTime()), "yyyy-MM-dd HH:mm");
return compare >= 0;
}
}
}).toList();
}
}
@@ -0,0 +1,260 @@
package com.budwk.app.zhgh.activity.literacy.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyMobileSignColumn;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyType;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService;
import lombok.extern.slf4j.Slf4j;
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.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @author zxy
* @Description TODO
* @createTime 2022年03月03日 10:02:00
*/
@IocBean(args = {"refer:dao"})
@Slf4j
public class LiteracyActivityStatisticsServiceImpl extends BaseServiceImpl<LiteracyUser> implements LiteracyActivityStatisticsService {
public LiteracyActivityStatisticsServiceImpl(Dao dao) {
super(dao);
}
@Override
public Pagination pageData(PageForm pageForm, String activityId) {
Sql sql = Sqls.create("""
SELECT
tsuc.id,
tsuc.courseName,
tsuc.coursePeopleNumber,
tsuc.courseReservedNumber,
type.typeName as courseType,
tsuc.courseLocation,
tsuc.courseInstructor,
tsuc.reserveMode,
tsuc.isMobileSign,
tsuc.hostUnionId,
tsuc.interTime,
tsuc.waitingNum,
tsuc.openOtherUnion,
tsuc.courseType as cType
FROM
`literacy_course` tsuc
LEFT JOIN
literacy_type type on tsuc.courseType = type.id
WHERE
tsuc.activityId = @activityId
ORDER BY tsuc.orderNum
""");
sql.setParam("activityId", activityId);
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> courseList = pagination.getList();
courseList.forEach(c -> {
c.put("registerNum", queryCourseCount(c.getString("id"), c.getString("cType")));
c.put("hasWaitingNum", queryCourseWaitCount(c.getString("id"), c.getString("cType")));
});
return pagination;
}
@Override
public List<NutMap> registerUserList(String courseId) {
Sql sql = Sqls.create("""
SELECT
u.loginname,
u.username,
u.sex,
tsuu.unionId,
tsuu.unionName,
tsuu.unitId,
tsuu.unitName,
ifnull(tsuu.mobile, u.mobile) as mobile,
tsuu.signUpTime,
tsuu.state,
tsuu.mobileColumnsValue
FROM
literacy_user tsuu
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
$condition
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("tsuu.courseId", "=", courseId);
sql.setCondition(cnd);
List<NutMap> list = listMap(sql);
list.forEach(o -> {
List<NutMap> mobileColumnsValue = Json.fromJsonAsList(NutMap.class, o.getString("mobileColumnsValue"));
if(Lang.isNotEmpty(mobileColumnsValue)) {
mobileColumnsValue.forEach(m -> {
o.put(m.getString("columnCode"), m.getString("columnValue"));
});
}
});
return list;
}
@Override
public List<NutMap> getTaleColumnInfo(String courseId) {
LiteracyCourse course = dao().fetch(LiteracyCourse.class, courseId);
LiteracyType upType = dao().fetch(LiteracyType.class, course.getCourseType());
dao().fetchLinks(upType, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
List<LiteracyMobileSignColumn> columnList = upType.getLiteracyMobileSignColumnList();
List<NutMap> columnTableList = columnList.stream().map(o -> NutMap.NEW().setv("label", o.getColumnName()).setv("prop", o.getColumnCode())).collect(Collectors.toList());
return columnTableList;
}
@Override
public List<NutMap> registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword) {
Sql sql = Sqls.create("""
SELECT
tsuu.id,
u.id as userId,
u.loginname,
u.username,
u.unitname,
u.unionname,
u.sex,
ifnull(tsuu.mobile, u.mobile) as mobile,
tsuu.signUpTime,
tsuu.state
FROM
literacy_user tsuu
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
$condition
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("tsuu.courseId", "=", courseId);
cnd.andEX("u.unionid", "=", unionId);
cnd.andEX("u.unitid", "=", unitId);
if (StrUtil.isNotBlank(searchKeyword)) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.andLike("username", searchKeyword).orLike("loginname", searchKeyword);
cnd.and(group);
}
sql.setCondition(cnd);
return listMap(sql);
}
@Override
public Map<String, List<NutMap>> getSignInfo(String courseId) {
Sql sql = Sqls.create("""
SELECT
tsuuc.courseStartTime,
tsuuc.courseEndTime,
tsuuc.isAttend,
tsuuc.attendTime,
u.username,
u.loginname,
u.unitname,
u.unionname
FROM
`literacy_user_course` tsuuc
LEFT JOIN `vw_user` u ON u.id = tsuuc.userId
WHERE
tsuuc.courseId = @courseId
""");
sql.setParam("courseId", courseId);
List<NutMap> list = listMap(sql);
Map<String, List<NutMap>> courseTimeMap = list.stream().map(v -> {
String courseTime = v.getString("courseStartTime") + "" + v.getString("courseEndTime");
v.put("courseTime", courseTime);
return v;
}).collect(Collectors.groupingBy(v -> v.getString("courseTime")));
// 使用Stream API进行降序排序
Map<String, List<NutMap>> sortedDataMap = courseTimeMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
return sortedDataMap;
}
@Override
public List<NutMap> baoMingUserList(String activityId) {
Sql sql = Sqls.create("""
SELECT
u.loginname,
u.username,
u.unitname,
u.unionname,
u.sex,
u.mobile,
uc.courseName,
uc.campus
FROM
`literacy_user` uu
RIGHT JOIN literacy_course uc ON uc.id = uu.courseId
LEFT JOIN `vw_user` u ON u.id = uu.userId
WHERE
uc.activityId = @activityId
ORDER BY u.unitCode,u.unioncode,u.sex
""");
sql.setParam("activityId", activityId);
return listMap(sql);
}
@Override
public int queryCourseCount(String courseId, String courseType) {
return this.queryCourseCount(courseId, courseType, null);
}
@Override
public int queryCourseWaitCount(String courseId, String courseType) {
return this.queryCourseWaitCount(courseId, courseType, null);
}
@Override
public int queryCourseCount(String courseId, String courseType, String unionId) {
return this.calcSignCount(courseId, courseType, unionId, List.of(1, 3));
}
@Override
public int queryCourseWaitCount(String courseId, String courseType, String unionId) {
return this.calcSignCount(courseId, courseType, unionId, List.of(2));
}
private int calcSignCount(String courseId, String courseType, String unionId, List<Integer> stateList) {
if(StrUtil.isBlank(courseId) || StrUtil.isBlank(courseType)) {
return 0;
}
LiteracyType type = dao().fetch(LiteracyType.class, courseType);
AtomicInteger hasRegisterNum = new AtomicInteger();
List<LiteracyUser> signUpUsers = dao().query(LiteracyUser.class, Cnd.where("courseId", "=", courseId)
.and("state", "in", stateList)
.andEX("unionId", "=", unionId));
signUpUsers.forEach(item -> {
if (type.getSelfAddFamily()) {
hasRegisterNum.getAndIncrement();
}
if(type.getIsBringFamily() && type.getIsAddFamily()) {
List<NutMap> mobileColumnsValue = item.getMobileColumnsValue();
NutMap map = mobileColumnsValue.stream().filter(o -> "xdqsrs".equals(o.getString("columnCode"))).findAny().orElse(null);
int number = map != null ? map.getInt("columnValue") : 0;
hasRegisterNum.addAndGet(number);
}
});
return hasRegisterNum.get();
}
}
@@ -0,0 +1,103 @@
package com.budwk.app.zhgh.activity.literacy.service.impl;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.literacy.models.LiteracyBlackList;
import com.budwk.app.zhgh.activity.literacy.service.LiteracyBlackListService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* @author zxy
* @Description TODO
* @createTime 2022年03月07日 14:29:00
*/
@IocBean(args = {"refer:dao"})
public class LiteracyUserServiceImpl extends BaseServiceImpl<LiteracyBlackList> implements LiteracyBlackListService {
public LiteracyUserServiceImpl(Dao dao) {
super(dao);
}
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId) {
Sql sql = Sqls.create("""
SELECT
u.id AS userId,
u.username,
u.loginname,
ifnull(tsuu.mobile, u.mobile) as mobile,
u.unitname,
u.unionname,
tsuc.courseName,
tsuu.state,
( SELECT count( 1 ) FROM literacy_user_course WHERE userId = tsuu.userId $var) courseTotal,
( SELECT count( 1 ) FROM literacy_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount,
if(tsubl.isDisabled=1,true,false) isDisabled,
group_CONCAT( tsuc.courseName ) AS courseNames
FROM
`literacy_user` tsuu
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
LEFT JOIN literacy_activity act on act.id = tsuu.activityId
LEFT JOIN literacy_course tsuc ON tsuc.id = tsuu.courseId
LEFT JOIN literacy_black_list tsubl on tsubl.userId = tsuu.userId
$condition
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 )
""");
cnd.groupBy("tsuu.userId");
Criteria varCnd = Cnd.cri();
varCnd.where().setTop(false);
varCnd.where().andEX("activityId", "=", activityId);
varCnd.where().andEX("courseId", "=", courseId);
if (!varCnd.where().isEmpty()) {
sql.vars().set("var", "and " + varCnd.toSql(null));
}
sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public void doHandleUser(String userId) {
LiteracyBlackList blackRecord = dao().fetch(LiteracyBlackList.class, Cnd.where("userId", "=", userId));
if (Lang.isEmpty(blackRecord)) {
LiteracyBlackList blackList = new LiteracyBlackList();
blackList.setUserId(userId);
blackList.setIsDisabled(true);
dao().insert(blackList);
} else {
// blackRecord.setIsDisabled(!blackRecord.getIsDisabled());
// dao().update(blackRecord);
dao().delete(blackRecord);
}
}
@Override
public List<NutMap> attendClassRecord(String userId) {
Sql sql = Sqls.create("""
SELECT
c.courseName,
uc.courseStartTime,
courseEndTime,
uc.isAttend,
uc.attendTime
FROM
`literacy_user_course` uc
LEFT JOIN literacy_course c ON c.id = uc.courseId
WHERE
uc.userId = @userId
""");
sql.setParam("userId", userId);
return listMap(sql);
}
}
@@ -40,7 +40,7 @@ public class TrainSignUpUserServiceImpl extends BaseServiceImpl<TrainSignUpBlack
u.unionname,
tsuc.courseName,
tsuu.state,
( SELECT count( 1 ) FROM train_sign_up_user_course WHERE userId = tsuu.userId $var) tourseTotal,
( SELECT count( 1 ) FROM train_sign_up_user_course WHERE userId = tsuu.userId $var) courseTotal,
( SELECT count( 1 ) FROM train_sign_up_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount,
if(tsubl.isDisabled=1,true,false) isDisabled,
group_CONCAT( tsuc.courseName ) AS courseNames