This commit is contained in:
2025-07-31 15:35:08 +08:00
parent bcca78d121
commit ac02be1aec
139 changed files with 14203 additions and 539 deletions
@@ -0,0 +1,114 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.integral.controller.IntegralManageController;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.activityBudget.template.ActivityBudgetTemp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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 org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/21 11:30
* @description 预算申报
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算申报")
@At("/platform/activity/budget/apply")
public class ActivityBudgetApplyController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/apply/index.html")
@SaCheckPermission("activity.budget.apply")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/apply/form.html")
@SaCheckPermission("activity.budget.apply")
public void form() {
}
@At
@ApiOperation("提交年度预算申报")
@SaCheckPermission("activity.budget.apply")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApply", tag = "年度预算申报-预算申报", msg = "提交年度预算申报")
public Result doSubmit(@Param("activityBudget") ActivityBudget activityBudget, Boolean flag) {
return activityBudgetService.doSubmit(activityBudget, flag);
}
@At
@ApiOperation("查询校工会申报的年度预算")
@SaCheckPermission("activity.budget.apply")
public Result getSchoolBudget() {
Sql sql = Sqls.create("""
SELECT
ab.*
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ins.state = 20
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_ONE'
""").setParam("year", DateUtil.thisYear());
List<NutMap> budgetList = activityBudgetService.listMap(sql);
return Result.success(budgetList);
}
@At
@Ok("void")
@ApiOperation("下载导入的模版")
@SaCheckPermission("activity.budget.apply")
public void downloadImport(HttpServletResponse response) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
EasyExcel.write(byteArrayOutputStream, ActivityBudgetTemp.class)
.sheet("预算申报模版")
.doWrite(ArrayList::new);
CommonDownloadUtil.download("预算申报模版.xlsx", byteArrayOutputStream.toByteArray(), response);
} catch (Exception e) {
log.error("下载福利名单导入模版失败", e);
}
}
}
@@ -0,0 +1,167 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.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 org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
* @author zhf
* @date 2025/7/24 11:46
* @description 我的申报
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "我的预算申报")
@At("/platform/activity/budget/applyList")
public class ActivityBudgetApplyListController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/applyList/index.html")
@SaCheckPermission("activity.budget.applyList")
public void index() {
}
@At("/view")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/view/index.html")
@SaCheckPermission("activity.budget.applyList")
public void view() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.applyList")
public Result pageData(PageForm pageForm, Integer year, String activityMatter) {
Sql sqlByApplyList = activityBudgetService.getSqlByApplyList(pageForm, year, activityMatter, Cnd.NEW());
Pagination pagination = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sqlByApplyList);
return Result.success(pagination);
}
@At
@ApiOperation("批量删除申报数据")
@SaCheckPermission("activity.budget.applyList")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "删除了${ids.length}条数据,${ids}")
public Result batchDelete(@Param("ids[]") @Valid String[] ids) {
if (ObjectUtil.isNotEmpty(ids)) {
activityBudgetService.clear(Cnd.where("id", "in", ids));
activityBudgetService.dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "in", ids));
List<ProcessInstance> instanceList = activityBudgetService.dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", ids));
if (ObjectUtil.isNotEmpty(instanceList)) {
List<Long> instanceIds = instanceList.stream().map(ProcessInstance::getId).toList();
activityBudgetService.dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instanceIds));
activityBudgetService.dao().clear(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", ids));
}
}
return Result.success();
}
@At
@ApiOperation("删除一条申报数据")
@SaCheckPermission("activity.budget.applyList")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "删除了一条条数据,${id}")
public Result doDelete(String id) {
activityBudgetService.dao().delete(ActivityBudget.class, id);
activityBudgetService.dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", id));
ProcessInstance instance = activityBudgetService.dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", id));
if (ObjectUtil.isNotEmpty(instance)) {
activityBudgetService.dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
activityBudgetService.dao().delete(ProcessInstance.class, instance.getId());
}
return Result.success();
}
@At
@ApiOperation("提交申报数据")
@SaCheckPermission("activity.budget.applyList")
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "提交了${ids.length}条数据,${ids}")
public Result batchSubmit(@Valid @Param("ids[]") String[] ids) {
List<ActivityBudget> budgetList = activityBudgetService.query(Cnd.where("id", "in", ids));
List<ActivityBudget> budgets = budgetList.stream().filter(a ->
ObjectUtil.isEmpty(a.getDeclareTotalBudgetMoney())
|| ObjectUtil.isEmpty(a.getHelpUnitName())
|| ObjectUtil.isEmpty(a.getOutlayManageSource())).toList();
List<String> names = budgets.stream().map(ActivityBudget::getActivityMatter).toList();
if (ObjectUtil.isNotEmpty(names)) {
return Result.error("请完善活动预算信息【:" + StrUtil.join(",", names) + "");
}
budgetList.forEach(b -> {
b.setTotalBudgetMoney(b.getDeclareTotalBudgetMoney());
b.setAuditState(1);
});
activityBudgetService.update(budgetList);
return Result.success();
}
@At
@ApiOperation("查询单个预算详细信息")
@SaCheckPermission("activity.budget.applyList")
public Result findOne(String id) {
return Result.success(activityBudgetService.findOne(id));
}
@At
@ApiOperation("查询申报的金额")
@SaCheckPermission("activity.budget.applyList")
public Result getApplyMoney(Integer year, String activityMatter) {
Cnd cnd = Cnd.NEW();
cnd.andEX("info.isSchoolBudget", "=", 0);
cnd.andEX("ins.state", "=", 20);
Sql sql = activityBudgetService.getSqlByApplyList(null, year, activityMatter, cnd);
sql.setCondition(cnd);
List<NutMap> list = activityBudgetService.listMap(sql);
double declareTotalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("declareTotalBudgetMoney")).sum();
double totalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("totalBudgetMoney")).sum();
return Result.success(Map.of("declareTotalBudgetMoney", declareTotalBudgetMoney, "totalBudgetMoney", totalBudgetMoney));
}
@At
@Ok("void")
@SaCheckPermission("activity.budget.applyList")
public void doExport(@Valid Integer year, String activityMatter, HttpServletResponse response) {
activityBudgetService.doExport(year, activityMatter, response);
}
}
@@ -0,0 +1,129 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import 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.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetApplyStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
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.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author zhf
* @date 2025/7/24 17:28
* @description
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算汇总")
@At("/platform/activity/budget/applyStatistics")
public class ActivityBudgetApplyStatisticsController {
@Inject
private ActivityBudgetApplyStatisticsService activityBudgetService;
@Inject
private SysDictService sysDictService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/applyStatistics/index.html")
@SaCheckPermission("activity.budget.applyStatistics")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.applyStatistics")
public Result pageData(PageForm pageForm, Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, activityMatter);
Pagination pagination = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("查询预算有多少钱")
@SaCheckPermission("activity.budget.applyStatistics")
public Result getApplyMoney(Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, activityMatter);
List<NutMap> list = activityBudgetService.listMap(sql);
list = list.stream().filter(v -> !v.getBoolean("isSchoolBudget")).toList();
double declareTotalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("declareTotalBudgetMoney")).sum();
double totalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("totalBudgetMoney")).sum();
return Result.success(Map.of("declareTotalBudgetMoney", declareTotalBudgetMoney, "totalBudgetMoney", totalBudgetMoney));
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("activity.budget.applyStatistics")
public void doExport(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource, HttpServletResponse response) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, null);
List<NutMap> mapList = activityBudgetService.listMap(sql);
List<Sys_dict> dictList = sysDictService.getSubListByCode("ACTIVITY_BUDGET_TYPE");
mapList.forEach(map -> {
Sys_dict dict = dictList.stream().filter(d -> d.getCode().equals(map.getString("outlayManageSource"))).findFirst().orElse(null);
map.put("outlayManageSource", dict.getName());
});
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
entities.add(new ExcelExportEntity("申报人姓名", "userName", 20));
entities.add(new ExcelExportEntity("申报人工号", "loginName", 20));
entities.add(new ExcelExportEntity("联系方式", "mobile", 20));
entities.add(new ExcelExportEntity("申报类型", "outlayManageSource", 20));
entities.add(new ExcelExportEntity("申报单位", "helpUnitName", 20));
entities.add(new ExcelExportEntity("事项", "activityMatter", 20));
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("申报预算金额", "declareTotalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExcelExportEntity draftCodeEntity2 = new ExcelExportEntity("审核预算金额", "totalBudgetMoney", 20);
draftCodeEntity2.setType(10);
entities.add(draftCodeEntity2);
entities.add(new ExcelExportEntity("申报时间", "applyDate", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
@At
@ApiOperation("删除申报记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("activity.budget.applyStatistics")
@SLog(type = "activity.budget.applyStatistics", tag = "删除申报记录", msg = "删除申报记录:${args[0]}")
public Result doDelete(String id) {
activityBudgetService.doDelete(id);
return Result.success();
}
}
@@ -0,0 +1,97 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetQueryStatisticsService;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
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.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/24 16:35
* @description
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算汇总")
@At("/platform/activity/budget/queryStatistics")
public class ActivityBudgetQueryStatisticsController {
@Inject
private ActivityBudgetQueryStatisticsService statisticsService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/queryStatistics/index.html")
@SaCheckPermission("activity.budget.queryStatistics")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.queryStatistics")
public Result pageData(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource) {
return Result.success(statisticsService.getDataByBudgetTypeCode(year, clubId, unionId, outlayManageSource));
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("activity.budget.queryStatistics")
public void doExport(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource, HttpServletResponse response) {
List<NutMap> mapList = statisticsService.getDataByBudgetTypeCode(year, clubId, unionId, outlayManageSource);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")){
mapList.forEach(m->{
if (StrUtil.isEmpty(m.getString("unionName"))){
m.put("unionName",m.getString("unitName"));
m.put("unionCode",m.getString("unionId"));
}
});
}
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
if (List.of("ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
entities.add(new ExcelExportEntity("事项", "activityMatter", 50));
}else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
entities.add(new ExcelExportEntity("编码", "unionCode", 20));
entities.add(new ExcelExportEntity("分工会", "unionName", 20));
}else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
entities.add(new ExcelExportEntity("编码", "clubCode", 20));
entities.add(new ExcelExportEntity("协会名称", "clubName", 20));
}
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("预算金额", "totalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
}
@@ -0,0 +1,116 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
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.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
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.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;
/**
* @author zhf
* @date 2025/7/29 10:59
* @description 校工会审核
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "校工会审核年度预算申报")
@At("/platform/activity/budget/schoolAudit")
public class ActivityBudgetSchoolAuditController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/schoolAudit/index.html")
@SaCheckPermission("activity.budget.schoolAudit")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/schoolAudit/form.html")
@SaCheckPermission("activity.budget.schoolAudit")
public void form() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.schoolAudit")
public Result pageData(PageForm pageForm,
Integer year,
String unionId,
String clubId,
Boolean approval,
String outlayManageSource,
String activityMatter) {
Sql sql = Sqls.create("""
SELECT
info.*,
YEAR(info.applyDate) year,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariale
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_budget info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "b6f29037-972d-4b97-8677-c3b3672ef0dc");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
cnd.andEX("info.unionId", "=", unionId);
cnd.andEX("info.outlayManageSource", "=", outlayManageSource);
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
cnd.desc("t.createdAt");
cnd.andEX("YEAR(info.applyDate)", "=", year);
cnd.and(Cnd.likeEX("info.activityMatter", activityMatter));
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.applyDate");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination<NutMap> pageVO = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -0,0 +1,130 @@
package com.budwk.app.zhgh.outlay.activityBudget.interceptor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
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.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
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.json.Json;
import java.util.List;
/**
* @author zhf
* @date 2025/7/28 17:01
* @description 活动预算申报提交后置拦截器
*/
public class OutlayActBudgetApplyPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
ActivityBudget activityBudget = Json.fromJson(ActivityBudget.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
if (StrUtil.isEmpty(activityBudget.getId())) {
activityBudget.setUserId(SecurityUtil.getUserId());
activityBudget.setLoginName(SecurityUtil.getUserLoginname());
activityBudget.setUserName(SecurityUtil.getUserUsername());
//查询分工会这个项目有没有申报过
// if (List.of("ACTIVITY_BUDGET_TYPE_TWO").contains(activityBudget.getBudgetTypeCode())) {
// int activityMatterCount = dao.count(ActivityBudget.class, Cnd.where("activityMatter", "=",
// activityBudget.getActivityMatter()).and("unionId", "=", SecurityUtil.getUnionId()));
// if (activityMatterCount > 0) {
// return Result.error(activityBudget.getActivityMatter() + "已填写申请!");
// }
// }
}
//删除预算详情表
if (StrUtil.isNotBlank(activityBudget.getId())) {
dao.clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
}
if (List.of("superadmin").contains(SecurityUtil.getUserLoginname())) {
//如果是超级管理员就可以直接提交不用审核
activityBudget.setTotalBudgetMoney(activityBudget.getDeclareTotalBudgetMoney());
ActivityBudget budget = null;
if (StrUtil.isNotBlank(activityBudget.getId())) {
budget = dao.fetch(ActivityBudget.class, activityBudget.getId());
}
//如果申报的是校工会预算
if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool outlayManageSchool = dao.fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(outlayManageSchool)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
//如果传过来有预算Id,代表是修改的,那么就减去原来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
//直接修改为现在传过来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(outlayManageSchool);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//如果申报的是分工会预算
OutlayManageUnion outlayManageUnion = dao.fetch(OutlayManageUnion.class,
Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", activityBudget.getUnionId()));
if (ObjectUtil.isNotEmpty(outlayManageUnion)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(outlayManageUnion);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_THREE")) {
//如果不等于校工会预算才往表里面加预算
//代表协会可能用的是校工会的预算
// if (!activityBudget.getIsSchoolBudget()) {
// jf_club jfClub = dao.fetch(jf_club.class, Cnd.where("year", "=", DateUtil.getYear())
// .and("club_id", "=", activityBudget.getClubId()));
// if (ObjectUtil.isNotEmpty(jfClub)) {
// if (StrUtil.isNotBlank(activityBudget.getId())) {
// jfClub.setTotalQuota(jfClub.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
// }
// jfClub.setTotalQuota(jfClub.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
// dao.updateIgnoreNull(jfClub);
// }
// }
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_FOUR")) {
// 更新其他经费表
// JfOther jfOther = dao.fetch(JfOther.class, Cnd.where("year", "=", DateUtil.getYear()));
// if (ObjectUtil.isNotEmpty(jfOther)) {
// if (StrUtil.isNotBlank(activityBudget.getId())) {
// jfOther.setTotalQuota(jfOther.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
// }
// jfOther.setTotalQuota(jfOther.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
// dao.updateIgnoreNull(jfOther);
// }
}
}
dao.insertOrUpdate(activityBudget);
// for (ActivityBudgetDetails details : activityBudget.getBudgetDetails()) {
// details.setBudgetId(activityBudget.getId());
// }
// //添加预算详情表
// dao.insert(activityBudget.getBudgetDetails());
execution.getArgs().set(FlowConst.FORM_DATA,Json.toJson(activityBudget));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", activityBudget.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,35 @@
package com.budwk.app.zhgh.outlay.activityBudget.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.outlay.activityBudget.models.ActivityBudget;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
/**
* @author zhf
* @date 2025/7/28 17:01
* @description 活动预算申报提交后置拦截器
*/
public class OutlayActBudgetSchoolPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
NutMap activityBudget = Json.fromJson(NutMap.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
dao.update(ActivityBudget.class, Chain.make("totalBudgetMoney", execution.getArgs().getStr("tf_totalBudgetMoney")),
Cnd.where("id", "=", activityBudget.getString("id")));
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(activityBudget));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", activityBudget.getString("id")), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,140 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @ClassName ActivityBudget
* @Description TODO
* @Author zhf
* @Date 2024/12/3 10:09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算")
public class ActivityBudget extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("用户姓名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String userName;
@Column
@Comment("用户工号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String loginName;
@Column
@Comment("联系方式")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String mobile;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String activityDate;
@Column
@Comment("活动事项")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String activityMatter;
@Column
@Comment("活动内容")
@ColDefine(type = ColType.TEXT)
private String activityContent;
@Column
@Comment("预算金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalBudgetMoney;
@Column
@Comment("申报金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal declareTotalBudgetMoney;
@Column
@Comment("预算类型")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String outlayManageSource;
@Column
@Comment("创建人工会")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("创建人所属社团")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String clubId;
@Column
@Comment("举办单位")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String helpUnitName;
@Column
@Comment("申报时间")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String applyDate;
@Column
@Comment("校工会审核")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String schoolAuditId;
@Column
@Comment("签字")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String applySign;
@Column
@Comment("审核状态")
@Default("0")
@ColDefine(type = ColType.INT)
private Integer auditState;
@Column
@Comment("是否属于校工会预算")
@Default("0")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isSchoolBudget;
@Column
@Comment("是否可以重复报销")
@Default("1")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isRepeatReimburse;
@Column
@Comment("校工会预算")
@ColDefine(type = ColType.VARCHAR,width = 32)
private String schoolBudgetId;
@Many(field = "budgetId")
private List<ActivityBudgetDetails> budgetDetails;
private Audit schoolAudit;
private List<Audit> allocationEditAuditList;
}
@@ -0,0 +1,58 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @ClassName ActivityBudgetDetails
* @Description TODO
* @Author zhf
* @Date 2024/12/3 10:15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget_details")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算记录详情")
public class ActivityBudgetDetails extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("申报id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetId;
@Column
@Comment("类别")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String detailName;
@Column
@Comment("预算金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal budgetMoney;
@Column
@Comment("金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal money;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
private Integer detailsOrder;
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* @ClassName ActivityBudgetType
* @Description TODO
* @Author zhf
* @Date 2024/12/3 14:55
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget_type")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算类型")
public class ActivityBudgetType extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("类型")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetTypeName;
@Column
@Comment("金额")
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
private Double budgetTypeMoney;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String note;
@Column
@Comment("年度")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
private Integer location;
}
@@ -0,0 +1,12 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
import com.budwk.app.base.service.BaseService;
import org.nutz.dao.sql.Sql;
public interface ActivityBudgetApplyStatisticsService extends BaseService {
Sql getsql(Integer year, String unionId,String clubId, String outlayManageSource,String activityMatter);
void doDelete(String id);
}
@@ -0,0 +1,11 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
import com.budwk.app.base.service.BaseService;
import org.nutz.lang.util.NutMap;
import java.util.List;
public interface ActivityBudgetQueryStatisticsService extends BaseService {
List<NutMap> getDataByBudgetTypeCode(Integer year, String clubId, String unionId, String outlayManageSource);
}
@@ -0,0 +1,28 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
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.outlay.activityBudget.models.ActivityBudget;
import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Sql;
import javax.servlet.http.HttpServletResponse;
public interface ActivityBudgetService extends BaseService<ActivityBudget> {
Sql getSqlByApplyList(PageForm pageForm, Integer year, String activityMatter, Cnd cnd);
/**
* 提交年度预算申报
* @param activityBudget
* @param flag
*/
Result doSubmit(ActivityBudget activityBudget, Boolean flag);
ActivityBudget findOne(String id);
void doExport(Integer year, String activityMatter, HttpServletResponse response);
}
@@ -0,0 +1,100 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.entity.ProcessTaskActor;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetApplyStatisticsService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
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.IocBean;
import java.util.List;
/**
* @ClassName ActivityBudgetApplyStatisticsServiceImpl
* @Description TODO
* @Author zhf
* @Date 2025/3/5 下午8:21
*/
@IocBean(args = {"refer:dao"})
public class ActivityBudgetApplyStatisticsServiceImpl extends BaseServiceImpl implements ActivityBudgetApplyStatisticsService {
public ActivityBudgetApplyStatisticsServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getsql(Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = Sqls.create("""
SELECT
YEAR(ab.applyDate) year,
ab.*,
ins.id AS instanceId,
ins.businessNo
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(activityMatter)) {
cnd.andEX("ab.activityMatter", "like", "%" + activityMatter + "%");
}
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.andEX("ab.unionId", "=", unionId);
/* if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
cnd.andEX("ab.isSchoolBudget", "=", 0);
}*/
cnd.andEX("ab.clubId", "=", clubId);
cnd.andEX("ab.outlayManageSource", "=", outlayManageSource);
cnd.andEX("ins.state", "=", 20);
cnd.desc("ab.applyDate");
sql.setCondition(cnd);
return sql;
}
@Override
public void doDelete(String id) {
ActivityBudget budget = dao().fetch(ActivityBudget.class, id);
if (budget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool school = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(school)) {
school.setTotalQuota(school.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
updateIgnoreNull(school);
}
} else if (budget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
// 更新分工会活动经费表
OutlayManageUnion union = dao().fetch(OutlayManageUnion.class, Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", budget.getUnionId()));
if (ObjectUtil.isNotEmpty(union)) {
union.setTotalQuota(union.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
updateIgnoreNull(union);
}
}
//查出流程实例
ProcessInstance instance = dao().fetch(ProcessInstance.class, Cnd.where("businessNo", "=", id));
if (ObjectUtil.isNotEmpty(instance)) {
//查询流程任务
List<ProcessTask> taskList = dao().query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
List<Long> taskIds = taskList.stream().map(ProcessTask::getId).toList();
//删除流程任务下面所有的人员
dao().clear(ProcessTask.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "in", taskIds));
//删除流程任务
dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
//删除流程实例
dao().delete(ProcessInstance.class, instance.getId());
//删除预算
dao().delete(ActivityBudget.class, id);
}
}
}
@@ -0,0 +1,90 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetQueryStatisticsService;
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.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.List;
@IocBean(args = {"refer:dao"})
public class ActivityBudgetQueryStatisticsServiceImpl extends BaseServiceImpl implements ActivityBudgetQueryStatisticsService {
public ActivityBudgetQueryStatisticsServiceImpl(Dao dao) {
super(dao);
}
@Override
public List<NutMap> getDataByBudgetTypeCode(Integer year, String clubId, String unionId, String outlayManageSource) {
if (List.of("ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
Sql sql = Sqls.create("""
SELECT
@year `year`,
ab.activityMatter,
ab.totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.andEX("ab.outlayManageSource", "=", outlayManageSource);
cnd.andEX("wpi.state", "=", 20);
sql.setCondition(cnd);
return listMap(sql);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//分工会
Sql sql = Sqls.create("""
SELECT
@year `year`,
un.unionCode,
un.name AS unionName,
ab.unionId,
COALESCE ( SUM( ab.totalBudgetMoney ), 0 ) AS totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN sys_union un ON ab.unionId = un.id
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("ab.unionId", "=", unionId);
cnd.andEX("ab.isSchoolBudget", "=", 0);
cnd.andEX("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_TWO");
cnd.andEX("wpi.state", "=", 20);
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.groupBy("ab.unionId");
cnd.asc("un.unionCode");
sql.setCondition(cnd);
return listMap(sql);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
/* Sql sql = Sqls.create("""
SELECT
@year `year`,
sc.`code` AS clubCode,
sc.`name` AS clubName,
COALESCE ( SUM( ab.totalBudgetMoney ), 0 ) AS totalBudgetMoney
FROM
sys_club sc
LEFT JOIN activity_budget ab ON ab.clubId = sc.id
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_THREE'
AND ab.auditState = 4
AND YEAR(ab.applyDate)=@year
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("sc.id", "=", clubId);
cnd.groupBy("sc.id");
cnd.asc("sc.`code`");
sql.setCondition(cnd);
return listMap(sql);*/
}
return new ArrayList<>();
}
}
@@ -0,0 +1,249 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
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.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import org.apache.poi.ss.usermodel.Workbook;
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.Lang;
import org.nutz.lang.util.NutMap;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/21 11:32
* @description
*/
@IocBean(args = {"refer:dao"})
public class ActivityBudgetServiceImpl extends BaseServiceImpl<ActivityBudget> implements ActivityBudgetService {
public ActivityBudgetServiceImpl(Dao dao) {
super(dao);
}
@Inject
private SysDictService sysDictService;
@Override
public Sql getSqlByApplyList(PageForm pageForm, Integer year, String activityMatter,Cnd cnd) {
Sql sql = Sqls.create("""
SELECT
info.*,
YEAR(info.applyDate) year,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariale
FROM
activity_budget 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
""");
if (StrUtil.isNotBlank(activityMatter)) {
cnd.andEX("info.activityMatter", "like", "%" + activityMatter + "%");
}
SqlExpressionGroup group = new SqlExpressionGroup();
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_ADMIN.name())) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
group1.or("info.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_TWO");
group1.and("info.unionId", "=", SecurityUtil.getUnionId());
group.or(group1);
}
/*if (ShiroUtil.hasAnyRoles("club01,club05")) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
SqlExpressionGroup group2 = new SqlExpressionGroup();
group2.or("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_THREE");
group2.or("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_FOUR");
List<String> clubIds = this.getClubsByRole().stream().map(v -> v.getString("id")).toList();
group1.and("ab.clubId", "in", clubIds);
group1.and(group2);
group.or(group1);
}*/
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
group1.and("info.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_ONE");
group1.or("info.loginName", "=", SecurityUtil.getUserLoginname());
group.or(group1);
}
cnd.and(group);
cnd.andEX("YEAR(info.applyDate)", "=", year);
cnd.desc("info.applyDate");
sql.setCondition(cnd);
return sql;
}
@Override
public Result doSubmit(ActivityBudget activityBudget, Boolean flag) {
if (flag) {
activityBudget.setAuditState(1);
}
if (StrUtil.isEmpty(activityBudget.getId())) {
activityBudget.setUserId(SecurityUtil.getUserId());
activityBudget.setLoginName(SecurityUtil.getUserLoginname());
activityBudget.setUserName(SecurityUtil.getUserUsername());
//查询分工会这个项目有没有申报过
if (List.of("ACTIVITY_BUDGET_TYPE_TWO").contains(activityBudget.getOutlayManageSource())) {
int activityMatterCount = count(Cnd.where("activityMatter", "=",
activityBudget.getActivityMatter()).and("unionId", "=", SecurityUtil.getUnionId()));
if (flag && activityMatterCount > 0) {
return Result.error(activityBudget.getActivityMatter() + "已填写申请!");
}
}
}
//删除预算详情表
if (StrUtil.isNotBlank(activityBudget.getId()) ) {
dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
}
if (List.of("superadmin").contains(SecurityUtil.getUserLoginname())) {
//如果是超级管理员就可以直接提交不用审核
if (flag) {
activityBudget.setAuditState(4);
activityBudget.setTotalBudgetMoney(activityBudget.getDeclareTotalBudgetMoney());
ActivityBudget budget = null;
if (StrUtil.isNotBlank(activityBudget.getId())) {
budget = fetch(activityBudget.getId());
}
//如果申报的是校工会预算
if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool outlayManageSchool = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(outlayManageSchool)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
//如果传过来有预算Id,代表是修改的,那么就减去原来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
//直接修改为现在传过来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
updateIgnoreNull(outlayManageSchool);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//如果申报的是分工会预算
OutlayManageUnion outlayManageUnion = dao().fetch(OutlayManageUnion.class,
Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", activityBudget.getUnionId()));
if (ObjectUtil.isNotEmpty(outlayManageUnion)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
updateIgnoreNull(outlayManageUnion);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_THREE")) {
//如果不等于校工会预算才往表里面加预算
//代表协会可能用的是校工会的预算
if (!activityBudget.getIsSchoolBudget()) {
/* jf_club jfClub = dao.fetch(jf_club.class, Cnd.where("year", "=", DateUtil.getYear())
.and("club_id", "=", activityBudget.getClubId()));
if (ObjectUtil.isNotEmpty(jfClub)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
jfClub.setTotalQuota(jfClub.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
jfClub.setTotalQuota(jfClub.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(jfClub);
}*/
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_FOUR")) {
// 更新其他经费表
/*JfOther jfOther = dao.fetch(JfOther.class, Cnd.where("year", "=", DateUtil.getYear()));
if (ObjectUtil.isNotEmpty(jfOther)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
jfOther.setTotalQuota(jfOther.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
jfOther.setTotalQuota(jfOther.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(jfOther);
}*/
}
}
}
insertOrUpdate(activityBudget);
for (ActivityBudgetDetails details : activityBudget.getBudgetDetails()) {
details.setBudgetId(activityBudget.getId());
}
//添加预算详情表
insert(activityBudget.getBudgetDetails());
return Result.success();
}
@Override
public ActivityBudget findOne(String id) {
ActivityBudget activityBudget = fetchLinks(fetch(id), "budgetDetails", Cnd.NEW().asc("detailsOrder"));
activityBudget.setSchoolAudit(dao().fetch(Audit.class, Cnd.where("id", "=", activityBudget.getSchoolAuditId())));
// activityBudget.setAllocationEditAuditList(dao().query(Audit.class, Cnd.where("parentId", "=", activityBudget.getId())));
return activityBudget;
}
@Override
public void doExport(Integer year, String activityMatter, HttpServletResponse response) {
Sql sql = getSqlByApplyList(null, year, activityMatter,Cnd.NEW());
List<NutMap> mapList = listMap(sql);
List<Sys_dict> dictList = sysDictService.getSubListByCode("ACTIVITY_BUDGET_TYPE");
mapList.forEach(map -> {
Sys_dict dict = dictList.stream().filter(d -> d.getCode().equals(map.getString("outlayManageSource"))).findFirst().orElse(null);
map.put("outlayManageSource", dict.getName());
});
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
entities.add(new ExcelExportEntity("申报人姓名", "userName", 20));
entities.add(new ExcelExportEntity("申报人工号", "loginName", 20));
entities.add(new ExcelExportEntity("联系方式", "mobile", 20));
entities.add(new ExcelExportEntity("申报类型", "outlayManageSource", 20));
entities.add(new ExcelExportEntity("申报单位", "helpUnitName", 20));
entities.add(new ExcelExportEntity("事项", "activityMatter", 20));
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("申报预算金额", "declareTotalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExcelExportEntity draftCodeEntity2 = new ExcelExportEntity("审核预算金额", "totalBudgetMoney", 20);
draftCodeEntity2.setType(10);
entities.add(draftCodeEntity2);
entities.add(new ExcelExportEntity("申报时间", "applyDate", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
}
@@ -0,0 +1,55 @@
package com.budwk.app.zhgh.outlay.activityBudget.template;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.budwk.app.base.model.ExcelImportError;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @ClassName ActivityBudgetTemp
* @Description TODO
* @Author zhf
* @Date 2025/3/12 上午11:13
*/
@Data
@EqualsAndHashCode
@ContentRowHeight(20) // 内容行高
@HeadRowHeight(20) // 表头行高
@ColumnWidth(25)
public class ActivityBudgetTemp extends ExcelImportError {
@ExcelProperty("活动时间")
private String activityDate;
@ExcelProperty("活动项目名称")
private String activityMatter;
@ExcelProperty("活动内容概述")
private String activityContent;
@ExcelProperty("联系方式")
private String mobile;
@ExcelProperty("预算类型(请在下拉菜单中选择)")
private String outlayManageSource;
@ExcelProperty("审核预算")
private String totalBudgetMoney;
@ExcelProperty("预算金额")
private String declareTotalBudgetMoney;
@ExcelProperty("审核意见")
private String auditOpinion;
@ExcelProperty("申报单位(仅社团申报时可在下拉菜单中选择,其他类型不用填写)")
private String helpUnitName;
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.outlay.outlayManage.model;
import com.budwk.app.base.model.BaseModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 17:36
* @description 经费使用详情
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_use_detail")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("经费使用详情")
public class OutlayUseDetail extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("预算Id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String outlayManageId;
@Column
@Comment("项目")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String projectName;
@Column
@Comment("调整金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal adjustMoney;
@Column
@Comment("调整事由")
@ColDefine(type = ColType.TEXT)
private String adjustReason;
@Column
@Comment("调整人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustUserId;
@Column
@Comment("调整人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustUserName;
@Column
@Comment("调整人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustLoginName;
@Column
@Comment("活动人数")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String activityNumber;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR)
private String activityTime;
}
@@ -0,0 +1,125 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.aspose.slides.internal.og.bas;
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.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
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.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.math.BigDecimal;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 14:37
* @description 校工会经费预算管理
*/
@IocBean
@At("/platform/outlay/outlayManage/schoolManage")
@Ok("json:full")
@Slf4j
@Api(tags = "校工会经费预算管理")
public class OutlayManageSchoolController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/school/manage/index.html")
@SaCheckPermission("outlay.outlayManage.school.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.school.manage")
public Result pageData(PageForm pageForm, Integer year) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT * FROM `outlay_manage_school` $condition
""");
cnd.andEX("year", "=", year);
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("修改预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "修改了预算分配的金额:${args[0]},id:${args[1]}")
public Result doSubmit(String totalQuota, String id) {
OutlayManageSchool outlayManageSchool = baseService.dao().fetch(OutlayManageSchool.class, id);
outlayManageSchool.setTotalQuota(new BigDecimal(totalQuota));
baseService.updateIgnoreNull(outlayManageSchool);
return Result.success();
}
@At
@ApiOperation("查看是否分配")
@SaCheckPermission("outlay.outlayManage.school.manage")
public Result getIsAllocationOutlay(Integer year) {
int count = baseService.dao().count(OutlayManageSchool.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("重置预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "重置了预算分配的金额:${args[0]}")
public Result resetOutlay(Integer year) {
int count = baseService.dao().clear(OutlayManageSchool.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("下发预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "下发预算的金额:${args[0]}")
public Result issuedOutlay() {
Sql sql = Sqls.create("""
SELECT
totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_ONE'
AND wpi.state = 20
""").setParam("year",DateUtil.thisYear());
List<NutMap> budgetList = baseService.listMap(sql);
BigDecimal totalBudgetMoney = budgetList.stream()
.map(v->new BigDecimal(v.getString("totalBudgetMoney"))) // 提取 money 属性
.reduce(BigDecimal.ZERO, BigDecimal::add);
OutlayManageSchool outlayManageSchool = new OutlayManageSchool();
outlayManageSchool.setYear(DateUtil.thisYear());
outlayManageSchool.setTotalQuota(totalBudgetMoney);
baseService.insert(outlayManageSchool);
return Result.success();
}
}
@@ -0,0 +1,128 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
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.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.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
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.Cnd;
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.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 15:59
* @description 校工会预算使用明细
*/
@IocBean
@At("/platform/outlay/outlayManage/schoolUseDetail")
@Ok("json:full")
@Slf4j
@Api(tags = "校工会预算使用明细")
public class OutlayManageSchoolUseDetailController {
@Inject
private BaseService baseService;
@Inject
private OutlayUseDetailService outlayUseDetailService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/school/useDetail/index.html")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result pageData(PageForm pageForm, String outlayManageId,String projectName) {
Sql sql = Sqls.create("""
select * from outlay_use_detail $condition
""");
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(projectName)) {
cnd.and("projectName", "LIKE", "%" + projectName + "%");
}
cnd.and("outlayManageId", "=", outlayManageId);
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("查询校工会所有的预算")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result getOutlayManageList() {
List<OutlayManageSchool> schoolList = baseService.dao().query(OutlayManageSchool.class, Cnd.NEW().desc("year"));
return Result.success(schoolList);
}
@At
@ApiOperation("查询报销了有多少钱")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result getApplyMoney(String outlayManageId,String projectName) {
OutlayManageSchool school = baseService.dao().fetch(OutlayManageSchool.class, Cnd.where("id", "=", outlayManageId));
if (StrUtil.isEmpty(outlayManageId)){
return Result.success(Map.of("totalMoney", 0, "totalQuota", school.getTotalQuota(), "usedQuota", school.getUsedQuota()));
}
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotEmpty(projectName)){
cnd.and("projectName", "LIKE", "%" + projectName + "%");
}
cnd.and("outlayManageId", "=", outlayManageId);
List<OutlayUseDetail> newList = baseService.dao().query(OutlayUseDetail.class, cnd);
BigDecimal totalMoney = newList.stream()
.map(OutlayUseDetail::getAdjustMoney)
.filter(Objects::nonNull) // 避免 null 值导致计算错误
.reduce(BigDecimal.ZERO, BigDecimal::add);
return Result.success(Map.of("totalMoney", totalMoney, "totalQuota", school.getTotalQuota(), "usedQuota", school.getUsedQuota()));
}
@At
@ApiOperation("删除校工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.school.useDetail")
@SLog(tag = "校工会预算使用详情", msg = "删除了校工会预算使用详情:${args[0]}")
public Result doDeleteDetail(String id) {
outlayUseDetailService.doDeleteDetail(id,"school");
return Result.success();
}
@At
@ApiOperation("编辑校工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.school.useDetail")
@SLog(tag = "校工会预算使用详情", msg = "编辑了校工会预算使用详情:${args[0]}")
public Result doEditDetail(OutlayUseDetail outlayUseDetail) {
outlayUseDetailService.doEditDetail(outlayUseDetail,"school");
return Result.success();
}
}
@@ -0,0 +1,46 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 14:31
* @description 校工会经费管理
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_manage_school")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("校工会经费管理")
public class OutlayManageSchool extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("年份")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("总额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalQuota;
@Column
@Comment("已使用额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal usedQuota;
}
@@ -0,0 +1,16 @@
package com.budwk.app.zhgh.outlay.outlayManage.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
public interface OutlayUseDetailService extends BaseService<OutlayUseDetail> {
/**
* 删除预算详情表数据
* @param id 详情的id
* @param outlayType 预算类型/school/union/club等
*/
void doDeleteDetail(String id,String outlayType);
void doEditDetail(OutlayUseDetail outlayUseDetail,String outlayType);
}
@@ -0,0 +1,71 @@
package com.budwk.app.zhgh.outlay.outlayManage.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/25 11:30
* @description
*/
@IocBean(args = {"refer:dao"})
public class OutlayUseDetailServiceImpl extends BaseServiceImpl<OutlayUseDetail> implements OutlayUseDetailService {
public OutlayUseDetailServiceImpl(Dao dao) {
super(dao);
}
@Override
public void doDeleteDetail(String id, String outlayType) {
//更新预算表的金额
updateOutlayManage(id, null,outlayType,false);
//更新完删除
delete(id);
}
@Override
public void doEditDetail(OutlayUseDetail outlayUseDetail,String outlayType) {
updateOutlayManage(outlayUseDetail.getId(), outlayUseDetail,outlayType,true);
update(outlayUseDetail);
}
/**
* 更新预算表
*
* @param id
* @param outlayType
*/
private void updateOutlayManage(String id, OutlayUseDetail outlayUseDetail,String outlayType,Boolean isEdit) {
//找到是哪一条的预算详情
OutlayUseDetail detail = fetch(id);
//拿到预算详情的调整金额
if (outlayType.equals("school")) {
//找到预算分配的记录
OutlayManageSchool manageSchool = dao().fetch(OutlayManageSchool.class, detail.getOutlayManageId());
manageSchool.setUsedQuota(manageSchool.getUsedQuota().subtract(detail.getAdjustMoney()));
if (isEdit){
//如果是修改,就先减去原来的值在加上现在新的值
manageSchool.setUsedQuota(manageSchool.getUsedQuota().add(outlayUseDetail.getAdjustMoney()));
}
update(manageSchool);
} else if (outlayType.equals("union")) {
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class, detail.getOutlayManageId());
manageUnion.setUsedQuota(manageUnion.getUsedQuota().subtract(detail.getAdjustMoney()));
if (isEdit){
//如果是修改,就先减去原来的值在加上现在新的值
manageUnion.setUsedQuota(manageUnion.getUsedQuota().add(outlayUseDetail.getAdjustMoney()));
}
update(manageUnion);
}
}
}
@@ -0,0 +1,143 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
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.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
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.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.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 17:17
* @description 分工会经费预算管理
*/
@IocBean
@At("/platform/outlay/outlayManage/unionManage")
@Ok("json:full")
@Slf4j
@Api(tags = "分工会经费预算管理")
public class OutlayManageUnionController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/union/manage/index.html")
@SaCheckPermission("outlay.outlayManage.union.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.union.manage")
public Result pageData(PageForm pageForm, Integer year) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT * FROM `outlay_manage_union` $condition
""");
cnd.andEX("year", "=", year);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("unionId", "=", SecurityUtil.getUnionId());
}
cnd.asc("unionCode");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("修改预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "修改了预算分配的金额:${args[0]},id:${args[1]}")
public Result doSubmit(String totalQuota, String id) {
OutlayManageUnion outlayManageUnion = baseService.dao().fetch(OutlayManageUnion.class, id);
outlayManageUnion.setTotalQuota(new BigDecimal(totalQuota));
baseService.updateIgnoreNull(outlayManageUnion);
return Result.success();
}
@At
@ApiOperation("查看是否分配")
@SaCheckPermission("outlay.outlayManage.union.manage")
public Result getIsAllocationOutlay(Integer year) {
int count = baseService.dao().count(OutlayManageUnion.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("重置预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "重置了预算分配的金额:${args[0]}")
public Result resetOutlay(Integer year) {
int count = baseService.dao().clear(OutlayManageUnion.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("下发预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "根据申报的金额修改本年的预算预算")
public Result issuedOutlay() {
Sql sql = Sqls.create("""
SELECT
unionId,
totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_TWO'
AND wpi.state = 20
""").setParam("year", DateUtil.thisYear());
List<NutMap> budgetList = baseService.listMap(sql);
List<Sys_union> unionList = baseService.dao().query(Sys_union.class, Cnd.NEW());
List<OutlayManageUnion> insertUnionList = new ArrayList<>();
unionList.forEach(v -> {
BigDecimal totalBudgetMoney = budgetList.stream()
.filter(budget -> budget.getString("unionId").equals(v.getId()))
.map(budget -> new BigDecimal(budget.getString("totalBudgetMoney"))) // 提取 money 属性
.reduce(BigDecimal.ZERO, BigDecimal::add);
OutlayManageUnion outlayManageUnion = new OutlayManageUnion();
outlayManageUnion.setYear(DateUtil.thisYear());
outlayManageUnion.setUnionName(v.getName());
outlayManageUnion.setUnionCode(v.getUnionCode());
outlayManageUnion.setUnionId(v.getId());
outlayManageUnion.setTotalQuota(totalBudgetMoney);
insertUnionList.add(outlayManageUnion);
});
baseService.insert(insertUnionList);
return Result.success();
}
}
@@ -0,0 +1,117 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.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.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
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.Cnd;
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.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @author zhf
* @date 2025/7/21 17:19
* @description 分工会预算使用明细
*/
@IocBean
@At("/platform/outlay/outlayManage/unionUseDetail")
@Ok("json:full")
@Slf4j
@Api(tags = "分工会预算使用明细")
public class OutlayManageUnionUseDetailController {
@Inject
private BaseService baseService;
@Inject
private OutlayUseDetailService outlayUseDetailService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/union/useDetail/index.html")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public Result pageData(PageForm pageForm,
Integer year,
String unionId) {
Sql sql = Sqls.create("""
select * from outlay_manage_union $condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("totalQuota", "IS NOT", null);
cnd.and("year", "=", year);
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("unionId", "=", unionId);
} else {
cnd.and("unionId", "=", SecurityUtil.getUnionId());
}
if (Strings.isNotBlank(pageForm.getPageOrderBy()) && Strings.isNotBlank(pageForm.getPageOrderName())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.asc("unionCode");
}
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("某个分工会预算使用详情")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public Result detailInfo(PageForm pageForm, String outlayManageId) {
Sql sql = Sqls.create("""
select * from outlay_use_detail where outlayManageId=@outlayManageId
""").setParam("outlayManageId", outlayManageId);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("删除分工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.union.useDetail")
@SLog(tag = "分工会预算使用详情", msg = "删除了分工会预算使用详情:${args[0]}")
public Result doDeleteDetail(String id) {
outlayUseDetailService.doDeleteDetail(id,"union");
return Result.success();
}
@At
@ApiOperation("编辑分工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.union.useDetail")
@SLog(tag = "分工会预算使用详情", msg = "编辑了分工会预算使用详情:${args[0]}")
public Result doEditDetail(OutlayUseDetail outlayUseDetail) {
outlayUseDetailService.doEditDetail(outlayUseDetail,"union");
return Result.success();
}
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 17:22
* @description 分工会经费管理
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_manage_union")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("分工会经费管理")
public class OutlayManageUnion extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("年份")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("总额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalQuota;
@Column
@Comment("已使用额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal usedQuota;
@Column
@Comment("院级工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("院级工会名称")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionName;
@Column
@Comment("院级工会code")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionCode;
}
@@ -0,0 +1,80 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.outlay.outlayReimburse.service.OutlayReimburseApplyListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @author zhf
* @date 2025/7/30 15:22
* @description 我的报销
*/
@IocBean
@At("/platform/outlay/reimburse/apply")
@Ok("json:full")
@Api("我的报销")
public class OutlayReimburseApplyListController {
@Inject
private OutlayReimburseApplyListService outlayReimburseApplyListService;
@At("/index")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/apply/index.html")
@SaCheckPermission("outlay.reimburse.apply")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/apply/form.html")
@SaCheckPermission("outlay.reimburse.apply")
public void form() {
}
@At("/view")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/view/index.html")
@SaCheckPermission("outlay.reimburse.apply")
public void view() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.reimburse.apply")
public Result pageData(PageForm pageForm) {
return Result.success();
}
@At
@ApiOperation("获取预算金额或活动")
@SaCheckPermission("outlay.reimburse.apply")
public Result getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id) {
return Result.success(outlayReimburseApplyListService.getBudgetMoneyOrActivity(outlayManageSource, clubId, unionId, id));
}
@At
@ApiOperation("查询这个预算已经报销了的金额")
@SaCheckPermission("outlay.reimburse.apply")
public Result getBxMoneyByBudgetId(String budgetId) {
return Result.success(outlayReimburseApplyListService.getBxMoneyByActivityId(budgetId));
}
@At
@ApiOperation("判断这个报销的记录预算是否充足")
@SaCheckPermission("outlay.reimburse.apply")
public Result bxAddValidate(String budgetId, String money, String outlayManageSource,String clubId) {
return outlayReimburseApplyListService.bxAddValidate(budgetId,money, outlayManageSource,clubId);
}
}
@@ -0,0 +1,34 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.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.democratic.suggestionBox.models.SuggestionBox;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
/**
* @author zhf
* @date 2025/7/30 15:58
* @description
*/
public class OutlayReimburseApplyPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
OutlayReimburse outlayReimburse = Json.fromJson(OutlayReimburse.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
dao.insertOrUpdate(outlayReimburse);
execution.getArgs().set("outlayManageSource", outlayReimburse.getOutlayManageSource());
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(outlayReimburse));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", outlayReimburse.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,16 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.interceptor;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
/**
* @author zhf
* @date 2025/7/30 16:02
* @description
*/
public class OutlayReimburseSchoolZxAuditPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
}
}
@@ -0,0 +1,124 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author zhf
* @date 2025/7/30 14:53
* @description 经费报销
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_reimburse")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("经费报销")
public class OutlayReimburse extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("经办人id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("经办人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userName;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String loginName;
@Column
@Comment("经办人电话")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String mobile;
@Column
@Comment("单位")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String unitName;
@Column
@Comment("单位id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@Column
@Comment("工会")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String unionName;
@Column
@Comment("工会id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("社团id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String clubId;
@Column
@Comment("报销经费来源")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String outlayManageSource;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String activityTime;
@Column
@Comment("支付内容")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String paymentContent;
@Column
@Comment("金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal money;
@Column
@Comment("活动事项")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String activityMatter;
@Column
@Comment("年度预算id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetId;
@Column
@Comment("申请时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String applyTime;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Column
@Comment("经办人签字")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String userSign;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.service;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
public interface OutlayReimburseApplyListService extends BaseService<OutlayReimburse> {
/**
* 获取预算金额或活动
*
* @param outlayManageSource
* @param clubId
* @param unionId
* @param id
* @return
*/
NutMap getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id);
/**
* 查询这个预算已经报销了的金额
* @param budgetId
* @return
*/
BigDecimal getBxMoneyByActivityId(String budgetId);
/**
* 判断这个报销的记录预算是否充足
* @param budgetId
* @param money
* @param outlayManageSource
* @param clubId
* @return
*/
Result bxAddValidate(String budgetId, String money, String outlayManageSource,String clubId);
}
@@ -0,0 +1,260 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import com.budwk.app.zhgh.outlay.outlayReimburse.service.OutlayReimburseApplyListService;
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.IocBean;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/30 17:38
* @description
*/
@IocBean(args = {"refer:dao"})
public class OutlayReimburseApplyListServiceImpl extends BaseServiceImpl<OutlayReimburse> implements OutlayReimburseApplyListService {
public OutlayReimburseApplyListServiceImpl(Dao dao) {
super(dao);
}
@Override
public NutMap getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id) {
String sqlStr = """
SELECT
ab.id,
ab.schoolBudgetId,
ab.totalBudgetMoney,
ab.isRepeatReimburse,
ab.activityMatter
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
$condition
""";
//找出可以重复报销的预算,并且是今年的预算
Sql sql = Sqls.create(sqlStr);
Cnd cnd = Cnd.NEW();
cnd.and("YEAR(ab.applyDate)", "=", DateUtil.thisYear());
cnd.and("isRepeatReimburse", "=", true);
cnd.and("ins.state", "=", 20);
sql.setCondition(cnd);
List<NutMap> budgetList = listMap(sql);
List<String> budgetIds = budgetList.stream().map(budget -> budget.getString("id")).toList();
//找出已经报销了的年度预算id,排除可以重复报销的预算
List<OutlayReimburse> outlayReimburseList = dao().query(OutlayReimburse.class,
Cnd.NEW().andEX(OutlayReimburse::getId, "!=", id)
.and(OutlayReimburse::getBudgetId, "not in", budgetIds)
.and(OutlayReimburse::getBudgetId, "is not", null));
List<String> outlayReimburseIds = outlayReimburseList.stream().map(OutlayReimburse::getBudgetId).toList();
//找出可以报销的预算
Sql sql1 = Sqls.create(sqlStr);
Cnd cnd1 = Cnd.NEW();
cnd1.and("YEAR(ab.applyDate)", "=", DateUtil.thisYear());
cnd1.and("ab.isRepeatReimburse", "=", true);
cnd1.and("ab.outlayManageSource", "=", outlayManageSource);
cnd1.and("ins.state", "=", 20);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
cnd1.and("unionId", "=", StrUtil.isNotBlank(unionId) ? unionId : SecurityUtil.getUnionId());
} else if (List.of("ACTIVITY_BUDGET_TYPE_THREE").contains(outlayManageSource)) {
cnd1.and("clubId", "=", clubId);
}
cnd1.andEX("ab.id", "not in", outlayReimburseIds);
sql1.setCondition(cnd1);
List<NutMap> canBudgetList = listMap(sql1);
//查询每个活动预算下面,有没有关联的子活动预算
canBudgetList.forEach(budget -> {
//找出来这一条活动预算有没有子预算,如果有子预算那么这一条预算肯定是校工会的预算
List<NutMap> twoLevelBudgetList = budgetList.stream().filter(b -> StrUtil.isNotBlank(b.getString("schoolBudgetId"))
&& b.getString("schoolBudgetId").equals(budget.getString("id"))).toList();
if (!twoLevelBudgetList.isEmpty()) {
//找出所有子预算的和
BigDecimal totalBudgetMoney = twoLevelBudgetList.stream().map(twoLevelBudget -> new BigDecimal(twoLevelBudget.getString("totalBudgetMoney"))).reduce(BigDecimal.ZERO, BigDecimal::add);
budget.put("twoLevelTotalBudgetMoney", totalBudgetMoney);
budget.put("twoLevelBudgetList", twoLevelBudgetList);
} else {
budget.put("twoLevelTotalBudgetMoney", 0);
budget.put("twoLevelBudgetList", List.of());
}
});
NutMap map = new NutMap();
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool school = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
map.put("budgetMoney", school.getTotalQuota().subtract(school.getUsedQuota()));
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
OutlayManageUnion union = dao().fetch(OutlayManageUnion.class, Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", StrUtil.isNotBlank(unionId) ? unionId : SecurityUtil.getUnionId()));
map.put("budgetMoney", ObjectUtil.isNotEmpty(union) ? union.getTotalQuota().subtract(union.getUsedQuota()) : 0);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
}
map.put("activityList", canBudgetList);
return map;
}
@Override
public BigDecimal getBxMoneyByActivityId(String budgetId) {
Sql sql = Sqls.create("""
SELECT
rei.money
FROM
`outlay_reimburse` rei
LEFT JOIN wf_process_instance ins ON ins.businessNo = rei.id
WHERE
rei.budgetId = @budgetId
AND ins.state = 20
""").setParam("budgetId", budgetId);
List<NutMap> reiList = listMap(sql);
BigDecimal totalMoney = reiList.stream()
.map(rei -> new BigDecimal(rei.getString("money")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return totalMoney;
}
@Override
public Result bxAddValidate(String budgetId, String money, String outlayManageSource, String clubId) {
BigDecimal moneyBig = new BigDecimal(money);
if (StrUtil.isAllEmpty(budgetId, outlayManageSource)) {
return Result.error("参数错误");
}
if (List.of("ACTIVITY_BUDGET_TYPE_TWO", "ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
ActivityBudget budget = dao().fetch(ActivityBudget.class, budgetId);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//判断是否可以重复报
if (budget.getIsRepeatReimburse()) {
//1.查询已经报销了的总金额
BigDecimal bXMoney = getBxMoneyByActivityId(budgetId);
if (budget.getIsSchoolBudget()) {
//如果是分工会进来并且报销的活动是校会预算
// 1. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = bXMoney.add(moneyBig);
// 2. 判断是否超出预算
if (totalReimbursement.compareTo(budget.getTotalBudgetMoney()) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
} else {
//如果是自己的项目就能超20%
//1.算出现在还能报销多少钱
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
// 2. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = bXMoney.add(moneyBig);
// 3. 判断是否超出预算的 20%
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//分工会进来报销自己的预算
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱
//判断是否超出预算的 20%
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
if (moneyBig.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//如果是校工会进来
//如果报销的项目是可以重复报销的
if (budget.getIsRepeatReimburse()) {
//这个预算已经报销了多少钱
BigDecimal totalMoney = getBxMoneyByActivityId(budgetId);
//查出这个活动有没有跟其他预算关联,如果跟其他预算关联了,代表当前这条预算是分工会也能报校工会也能报,
// schoolBudgetId字段不为空就代表这条预算是使用的校工会的金额
List<ActivityBudget> budgetList = dao().query(ActivityBudget.class,
Cnd.where("schoolBudgetId", "=", budgetId));
if (ObjectUtil.isNotEmpty(budgetList) && !budgetList.isEmpty()) {
//如果报销的项目是分工会也能报校工会也能报,就要减去所有已分配分工会的钱在算能报销多少钱。
//1.减去分工会可以报的那一部分预算,比如校工会这个预算有1000,分工会可以报100.那么校工会只能报900
//找出分配给分工会的预算是多少钱
BigDecimal unionTotalMoney = budgetList.stream()
.map(ActivityBudget::getTotalBudgetMoney)
.filter(Objects::nonNull) // 避免 null 值导致计算错误
.reduce(BigDecimal.ZERO, BigDecimal::add);
//找出能报销多少钱,校工会预算1000-分工会可以报的预算unionTotalMoney=校工会目前可以使用的预算
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().subtract(unionTotalMoney);
//已报销加上现在的钱
BigDecimal totalReimbursement = totalMoney.add(moneyBig);
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
} else {
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱,判断是否超出预算的 20%
//1.算出现在还能报销多少钱
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
//2. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = totalMoney.add(moneyBig);
// 3. 判断是否超出预算的 20%
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱,判断是否超出预算的 20%
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
if (moneyBig.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
}
}
return null;
}
}