commit
This commit is contained in:
+29
@@ -22,6 +22,7 @@ import com.budwk.app.zhgh.club.service.SysClubService;
|
|||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.service.ActivityBudgetService;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.service.ActivityBudgetService;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.template.ActivityBudgetTemp;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.template.ActivityBudgetTemp;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.vo.ActivityBudgetQuotaInfoVo;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -91,6 +92,10 @@ public class ActivityBudgetApplyController {
|
|||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@SLog( tag = "年度预算申报-预算申报", msg = "重新提交申请")
|
@SLog( tag = "年度预算申报-预算申报", msg = "重新提交申请")
|
||||||
public Result submitAgain(@Param("data") ActivityBudget activityBudget, @Param("taskId") Long taskId) {
|
public Result submitAgain(@Param("data") ActivityBudget activityBudget, @Param("taskId") Long taskId) {
|
||||||
|
Result quotaValidateResult = activityBudgetService.validateQuota(activityBudget);
|
||||||
|
if (quotaValidateResult.getCode() != 0) {
|
||||||
|
return quotaValidateResult;
|
||||||
|
}
|
||||||
activityBudgetService.insertOrUpdate(activityBudget);
|
activityBudgetService.insertOrUpdate(activityBudget);
|
||||||
|
|
||||||
Dict dict = Dict.create();
|
Dict dict = Dict.create();
|
||||||
@@ -100,6 +105,30 @@ public class ActivityBudgetApplyController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询预算额度占用情况。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. outlayManageSource:预算类型,当前仅分工会预算需要查询额度。
|
||||||
|
* 2. unionId:分工会ID。
|
||||||
|
* 3. applyDate:申报时间,用来确定预算所属年度。
|
||||||
|
* 返回值字段:
|
||||||
|
* 1. totalQuota:本年度总额度。
|
||||||
|
* 2. applyingQuota:申请中额度。
|
||||||
|
* 3. approvedQuota:已通过额度。
|
||||||
|
* 4. occupiedQuota:已占用额度。
|
||||||
|
* 5. remainQuota:剩余额度。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报参数
|
||||||
|
* @return 当前预算主体的额度统计
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ApiOperation("查询年度预算额度信息")
|
||||||
|
@SaCheckPermission("activity.budget.apply")
|
||||||
|
public Result getQuotaInfo(@Param("data") ActivityBudget activityBudget) {
|
||||||
|
ActivityBudgetQuotaInfoVo quotaInfoVo = activityBudgetService.getQuotaInfo(activityBudget);
|
||||||
|
return Result.success(quotaInfoVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("activity.budget.apply")
|
@SaCheckPermission("activity.budget.apply")
|
||||||
|
|||||||
+36
@@ -4,6 +4,7 @@ import com.budwk.app.base.param.PageForm;
|
|||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.vo.ActivityBudgetQuotaInfoVo;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
@@ -22,6 +23,41 @@ public interface ActivityBudgetService extends BaseService<ActivityBudget> {
|
|||||||
*/
|
*/
|
||||||
Result submit(ActivityBudget activityBudget);
|
Result submit(ActivityBudget activityBudget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验预算申报额度。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. activityBudget.outlayManageSource:预算类型,分工会/协会/校工会。
|
||||||
|
* 2. activityBudget.unionId:分工会预算时传对应分工会ID。
|
||||||
|
* 4. activityBudget.declareTotalBudgetMoney:本次申报金额。
|
||||||
|
* 5. activityBudget.applyDate:申报时间,用于判定所属年度;为空时按当前年份处理。
|
||||||
|
* 返回值:
|
||||||
|
* Result.success 表示可提交;当前仅分工会预算会触发年度额度校验;
|
||||||
|
* Result.error 表示超额或年度额度未配置,message 会直接返回给前端提示。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报数据
|
||||||
|
* @return 校验结果
|
||||||
|
*/
|
||||||
|
Result validateQuota(ActivityBudget activityBudget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询预算额度占用信息。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. activityBudget.outlayManageSource:预算类型;当前仅分工会预算需要返回额度占用信息。
|
||||||
|
* 2. activityBudget.unionId:分工会预算时用于定位对应年度额度记录。
|
||||||
|
* 3. activityBudget.applyDate:用于计算预算所属年度;为空时按当前年份处理。
|
||||||
|
* 返回值字段:
|
||||||
|
* 1. year:预算所属年度。
|
||||||
|
* 2. totalQuota:本年度总额度。
|
||||||
|
* 3. applyingQuota:申请中额度,除已通过和已拒绝外的流程金额总和。
|
||||||
|
* 4. approvedQuota:已通过额度。
|
||||||
|
* 5. occupiedQuota:当前已占用额度,除已拒绝外全部计入。
|
||||||
|
* 6. remainQuota:当前剩余额度。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报数据
|
||||||
|
* @return 预算额度统计信息
|
||||||
|
*/
|
||||||
|
ActivityBudgetQuotaInfoVo getQuotaInfo(ActivityBudget activityBudget);
|
||||||
|
|
||||||
NutMap findOne(String id);
|
NutMap findOne(String id);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+188
@@ -4,7 +4,9 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
|||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.model.Audit;
|
import com.budwk.app.base.model.Audit;
|
||||||
@@ -16,6 +18,7 @@ import com.budwk.app.flow.constant.FlowConst;
|
|||||||
import com.budwk.app.flow.engine.FlowEngine;
|
import com.budwk.app.flow.engine.FlowEngine;
|
||||||
import com.budwk.app.flow.entity.ProcessInstance;
|
import com.budwk.app.flow.entity.ProcessInstance;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
|
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||||
import com.budwk.app.sys.models.Sys_dict;
|
import com.budwk.app.sys.models.Sys_dict;
|
||||||
import com.budwk.app.sys.services.SysDictService;
|
import com.budwk.app.sys.services.SysDictService;
|
||||||
@@ -26,6 +29,8 @@ import com.budwk.app.zhgh.club.service.SysClubService;
|
|||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudget;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudgetDetails;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.models.ActivityBudgetDetails;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.service.ActivityBudgetService;
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.service.ActivityBudgetService;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.activityBudget.vo.ActivityBudgetQuotaInfoVo;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutlayManageUnion;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
@@ -37,6 +42,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
|||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -140,6 +146,10 @@ public class ActivityBudgetServiceImpl extends BaseServiceImpl<ActivityBudget> i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Result quotaValidateResult = validateQuota(activityBudget);
|
||||||
|
if (quotaValidateResult != null && quotaValidateResult.getCode() != 0) {
|
||||||
|
return quotaValidateResult;
|
||||||
|
}
|
||||||
//删除预算详情表
|
//删除预算详情表
|
||||||
if (StrUtil.isNotBlank(activityBudget.getId()) ) {
|
if (StrUtil.isNotBlank(activityBudget.getId()) ) {
|
||||||
dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
|
dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
|
||||||
@@ -227,6 +237,80 @@ public class ActivityBudgetServiceImpl extends BaseServiceImpl<ActivityBudget> i
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result validateQuota(ActivityBudget activityBudget) {
|
||||||
|
if (ObjectUtil.isEmpty(activityBudget) || StrUtil.isBlank(activityBudget.getOutlayManageSource())) {
|
||||||
|
return Result.error("预算类型不能为空");
|
||||||
|
}
|
||||||
|
if (!"ACTIVITY_BUDGET_TYPE_TWO".equals(activityBudget.getOutlayManageSource())) {
|
||||||
|
// 当前业务仅分工会预算保留年度额度校验,校工会和协会预算直接跳过。
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isEmpty(activityBudget.getDeclareTotalBudgetMoney())) {
|
||||||
|
return Result.error("预算金额不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityBudgetQuotaInfoVo quotaInfo = getQuotaInfo(activityBudget);
|
||||||
|
if (!quotaInfo.getSelectedTarget()) {
|
||||||
|
return Result.error(quotaInfo.getMessage());
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isEmpty(quotaInfo.getTotalQuota())) {
|
||||||
|
return Result.error(quotaInfo.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal remainQuota = quotaInfo.getRemainQuota();
|
||||||
|
BigDecimal declareTotalBudgetMoney = activityBudget.getDeclareTotalBudgetMoney();
|
||||||
|
if (remainQuota.compareTo(declareTotalBudgetMoney) < 0) {
|
||||||
|
return Result.error("本年度预算额度不足,剩余额度:" + remainQuota
|
||||||
|
+ "元,申请中额度:" + quotaInfo.getApplyingQuota()
|
||||||
|
+ "元,已通过额度:" + quotaInfo.getApprovedQuota() + "元");
|
||||||
|
}
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActivityBudgetQuotaInfoVo getQuotaInfo(ActivityBudget activityBudget) {
|
||||||
|
if (ObjectUtil.isEmpty(activityBudget)) {
|
||||||
|
activityBudget = new ActivityBudget();
|
||||||
|
}
|
||||||
|
String outlayManageSource = activityBudget.getOutlayManageSource();
|
||||||
|
Integer year = getBudgetYear(activityBudget);
|
||||||
|
ActivityBudgetQuotaInfoVo quotaInfo = new ActivityBudgetQuotaInfoVo();
|
||||||
|
quotaInfo.setYear(year);
|
||||||
|
quotaInfo.setNeedLimit("ACTIVITY_BUDGET_TYPE_TWO".equals(outlayManageSource));
|
||||||
|
quotaInfo.setSelectedTarget(true);
|
||||||
|
quotaInfo.setTotalQuota(null);
|
||||||
|
quotaInfo.setApplyingQuota(BigDecimal.ZERO);
|
||||||
|
quotaInfo.setApprovedQuota(BigDecimal.ZERO);
|
||||||
|
quotaInfo.setOccupiedQuota(BigDecimal.ZERO);
|
||||||
|
quotaInfo.setRemainQuota(BigDecimal.ZERO);
|
||||||
|
|
||||||
|
if (!"ACTIVITY_BUDGET_TYPE_TWO".equals(outlayManageSource)) {
|
||||||
|
return quotaInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal totalQuota = getCurrentYearTotalQuota(activityBudget, year, quotaInfo);
|
||||||
|
if (!quotaInfo.getSelectedTarget()) {
|
||||||
|
return quotaInfo;
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isEmpty(totalQuota)) {
|
||||||
|
quotaInfo.setMessage("该年度未配置预算额度,请先维护年度预算");
|
||||||
|
return quotaInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
NutMap quotaUseInfo = getQuotaUseInfo(activityBudget, year);
|
||||||
|
BigDecimal occupiedQuota = getMapBigDecimal(quotaUseInfo, "occupiedQuota");
|
||||||
|
BigDecimal approvedQuota = getMapBigDecimal(quotaUseInfo, "approvedQuota");
|
||||||
|
BigDecimal applyingQuota = getMapBigDecimal(quotaUseInfo, "applyingQuota");
|
||||||
|
|
||||||
|
quotaInfo.setTotalQuota(totalQuota);
|
||||||
|
quotaInfo.setOccupiedQuota(occupiedQuota);
|
||||||
|
quotaInfo.setApprovedQuota(approvedQuota);
|
||||||
|
quotaInfo.setApplyingQuota(applyingQuota);
|
||||||
|
quotaInfo.setRemainQuota(totalQuota.subtract(occupiedQuota));
|
||||||
|
return quotaInfo;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NutMap findOne(String id) {
|
public NutMap findOne(String id) {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
@@ -277,4 +361,108 @@ public class ActivityBudgetServiceImpl extends BaseServiceImpl<ActivityBudget> i
|
|||||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
|
||||||
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
|
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析预算所属年度,页面没有单独年度字段时默认取申报时间中的年份。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报数据
|
||||||
|
* @return 预算所属年度
|
||||||
|
*/
|
||||||
|
private Integer getBudgetYear(ActivityBudget activityBudget) {
|
||||||
|
if (ObjectUtil.isEmpty(activityBudget) || StrUtil.isBlank(activityBudget.getApplyDate())) {
|
||||||
|
return DateUtil.thisYear();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return DateUtil.parse(activityBudget.getApplyDate()).year();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return DateUtil.thisYear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前预算类型在所属年度的总额度配置。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报数据
|
||||||
|
* @param year 预算所属年度
|
||||||
|
* @param quotaInfo 返回前端的额度信息对象,用于补充缺失主体的提示
|
||||||
|
* @return 年度总额度;未配置时返回 null
|
||||||
|
*/
|
||||||
|
private BigDecimal getCurrentYearTotalQuota(ActivityBudget activityBudget, Integer year, ActivityBudgetQuotaInfoVo quotaInfo) {
|
||||||
|
String outlayManageSource = activityBudget.getOutlayManageSource();
|
||||||
|
if ("ACTIVITY_BUDGET_TYPE_TWO".equals(outlayManageSource)) {
|
||||||
|
String unionId = StrUtil.blankToDefault(activityBudget.getUnionId(), SecurityUtil.getUnionId());
|
||||||
|
if (StrUtil.isBlank(unionId)) {
|
||||||
|
quotaInfo.setSelectedTarget(false);
|
||||||
|
quotaInfo.setMessage("请选择分工会");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
OutlayManageUnion outlayManageUnion = dao().fetch(OutlayManageUnion.class,
|
||||||
|
Cnd.where("year", "=", year).and("unionId", "=", unionId));
|
||||||
|
return ObjectUtil.isEmpty(outlayManageUnion) ? null : outlayManageUnion.getTotalQuota();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计当前主体在本年度已经占用的预算。
|
||||||
|
* 统计规则:
|
||||||
|
* 1. 只统计已进入流程的申请;
|
||||||
|
* 2. 已拒绝不计入额度;
|
||||||
|
* 3. 其他状态全部计入占用额度;
|
||||||
|
* 4. 申请中额度 = 非已通过、非已拒绝的金额合计。
|
||||||
|
*
|
||||||
|
* @param activityBudget 预算申报数据
|
||||||
|
* @param year 预算所属年度
|
||||||
|
* @return occupiedQuota/applyingQuota/approvedQuota 统计结果
|
||||||
|
*/
|
||||||
|
private NutMap getQuotaUseInfo(ActivityBudget activityBudget, Integer year) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
IFNULL(SUM(ab.declareTotalBudgetMoney), 0) occupiedQuota,
|
||||||
|
IFNULL(SUM(CASE WHEN ins.state = @finishedState THEN ab.declareTotalBudgetMoney ELSE 0 END), 0) approvedQuota,
|
||||||
|
IFNULL(SUM(CASE WHEN ins.state != @finishedState AND ins.state != @rejectState THEN ab.declareTotalBudgetMoney ELSE 0 END), 0) applyingQuota
|
||||||
|
FROM
|
||||||
|
activity_budget ab
|
||||||
|
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
||||||
|
sql.setParam("rejectState", ProcessInstanceStateEnum.REJECT.getCode());
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.andEX("YEAR(ab.applyDate)", "=", year);
|
||||||
|
cnd.and("ab.outlayManageSource", "=", activityBudget.getOutlayManageSource());
|
||||||
|
cnd.and("ins.id", "IS NOT", null);
|
||||||
|
cnd.and("ins.state", "!=", ProcessInstanceStateEnum.REJECT.getCode());
|
||||||
|
if (StrUtil.isNotBlank(activityBudget.getId())) {
|
||||||
|
// 重新提交或编辑当前记录时,先排除本条数据,避免把旧记录金额重复计入占用额度。
|
||||||
|
cnd.and("ab.id", "!=", activityBudget.getId());
|
||||||
|
}
|
||||||
|
if ("ACTIVITY_BUDGET_TYPE_TWO".equals(activityBudget.getOutlayManageSource())) {
|
||||||
|
cnd.and("ab.unionId", "=", StrUtil.blankToDefault(activityBudget.getUnionId(), SecurityUtil.getUnionId()));
|
||||||
|
} else if ("ACTIVITY_BUDGET_TYPE_THREE".equals(activityBudget.getOutlayManageSource())) {
|
||||||
|
cnd.and("ab.clubId", "=", activityBudget.getClubId());
|
||||||
|
}
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
sql.setCallback(Sqls.callback.map());
|
||||||
|
execute(sql);
|
||||||
|
return (NutMap) sql.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一把数据库聚合结果转成 BigDecimal,避免前后端展示时出现 null。
|
||||||
|
*
|
||||||
|
* @param map 聚合结果
|
||||||
|
* @param key 字段名
|
||||||
|
* @return 对应金额,默认 0
|
||||||
|
*/
|
||||||
|
private BigDecimal getMapBigDecimal(NutMap map, String key) {
|
||||||
|
Object value = ObjectUtil.isEmpty(map) ? null : map.get(key);
|
||||||
|
if (ObjectUtil.isEmpty(value)) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
if (value instanceof BigDecimal) {
|
||||||
|
return (BigDecimal) value;
|
||||||
|
}
|
||||||
|
return new BigDecimal(String.valueOf(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.outlay.activityBudget.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhf
|
||||||
|
* @date 2026/4/20
|
||||||
|
* @description 预算申报额度信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ActivityBudgetQuotaInfoVo {
|
||||||
|
/**
|
||||||
|
* 预算所属年度。
|
||||||
|
*/
|
||||||
|
private Integer year;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前预算类型是否需要做额度限制。
|
||||||
|
*/
|
||||||
|
private Boolean needLimit = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已经选择了有效的预算主体。
|
||||||
|
* 分工会预算需要分工会ID,协会预算需要协会ID。
|
||||||
|
*/
|
||||||
|
private Boolean selectedTarget = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本年度总额度;未配置时为 null。
|
||||||
|
*/
|
||||||
|
private BigDecimal totalQuota;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前申请中额度。
|
||||||
|
*/
|
||||||
|
private BigDecimal applyingQuota = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前已通过额度。
|
||||||
|
*/
|
||||||
|
private BigDecimal approvedQuota = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前已占用额度,除已拒绝外全部计入。
|
||||||
|
*/
|
||||||
|
private BigDecimal occupiedQuota = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前剩余额度。
|
||||||
|
*/
|
||||||
|
private BigDecimal remainQuota = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前额度提示信息。
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
}
|
||||||
+44
@@ -16,12 +16,15 @@ import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
|||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.zhgh.club.model.SysClub;
|
import com.budwk.app.zhgh.club.model.SysClub;
|
||||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.model.OutlayManageClub;
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.model.OutlayManageClub;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.service.OutlayManageClubService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
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.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
@@ -49,6 +52,8 @@ public class OutlayManageClubController {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SysRoleService sysRoleService;
|
private SysRoleService sysRoleService;
|
||||||
|
@Inject
|
||||||
|
private OutlayManageClubService outlayManageClubService;
|
||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/club/manage/index.html")
|
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/club/manage/index.html")
|
||||||
@@ -89,6 +94,45 @@ public class OutlayManageClubController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询某个年度已经分配预算的协会ID。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. year:预算年度。
|
||||||
|
* 返回值说明:
|
||||||
|
* 1. 返回当前年度已存在预算分配记录的协会ID列表。
|
||||||
|
*
|
||||||
|
* @param year 预算年度
|
||||||
|
* @return 已分配预算的协会ID列表
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ApiOperation("查询某个年度已分配预算的协会ID")
|
||||||
|
@SaCheckPermission("outlay.outlayManage.club.manage")
|
||||||
|
public Result getAllocatedClubIds(Integer year) {
|
||||||
|
return Result.success(outlayManageClubService.getAllocatedClubIds(year));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动新增协会预算分配。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. outlayManageClub.year:预算年度。
|
||||||
|
* 2. outlayManageClub.clubId:协会ID。
|
||||||
|
* 3. outlayManageClub.totalQuota:分配总额度。
|
||||||
|
* 返回值说明:
|
||||||
|
* 1. 返回新增成功结果,失败时返回业务提示信息。
|
||||||
|
*
|
||||||
|
* @param outlayManageClub 新增分配数据
|
||||||
|
* @return 新增结果
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ApiOperation("手动新增协会预算分配")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@SaCheckPermission("outlay.outlayManage.club.manage")
|
||||||
|
@SLog(tag = "协会预算分配", msg = "手动新增了协会预算分配,年度:${args[0].year},协会:${args[0].clubId},总额度:${args[0].totalQuota}")
|
||||||
|
public Result addAllocation(OutlayManageClub outlayManageClub) {
|
||||||
|
outlayManageClubService.addAllocation(outlayManageClub);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ApiOperation("查看是否分配")
|
@ApiOperation("查看是否分配")
|
||||||
|
|||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.service;
|
||||||
|
|
||||||
|
import com.budwk.app.base.service.BaseService;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.model.OutlayManageClub;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhf
|
||||||
|
* @date 2026/4/20
|
||||||
|
* @description 协会预算分配公共方法
|
||||||
|
*/
|
||||||
|
public interface OutlayManageClubService extends BaseService<OutlayManageClub> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询某个年度已经分配过预算的协会ID列表。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. year:预算年度,查询该年度已存在的协会预算记录。
|
||||||
|
* 返回值说明:
|
||||||
|
* 1. 返回当前年度在 outlay_manage_club 表中已经存在的 clubId 集合。
|
||||||
|
* 2. 前端可基于该结果过滤“审核通过但未分配预算”的协会下拉。
|
||||||
|
*
|
||||||
|
* @param year 预算年度
|
||||||
|
* @return 已分配预算的协会ID列表
|
||||||
|
*/
|
||||||
|
List<String> getAllocatedClubIds(Integer year);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动新增协会预算分配。
|
||||||
|
* 参数说明:
|
||||||
|
* 1. outlayManageClub.year:预算年度。
|
||||||
|
* 2. outlayManageClub.clubId:协会ID。
|
||||||
|
* 3. outlayManageClub.totalQuota:本次分配的总额度。
|
||||||
|
* 返回值说明:
|
||||||
|
* 1. 返回已补全协会名称、协会编码后的预算分配实体。
|
||||||
|
* 2. 如果年度、协会、总额度为空,或该年度该协会已存在预算记录,则抛出业务异常。
|
||||||
|
*
|
||||||
|
* @param outlayManageClub 手动新增的预算分配数据
|
||||||
|
* @return 新增后的预算分配实体
|
||||||
|
*/
|
||||||
|
OutlayManageClub addAllocation(OutlayManageClub outlayManageClub);
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.budwk.app.base.exception.BaseException;
|
||||||
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
|
import com.budwk.app.zhgh.club.model.SysClub;
|
||||||
|
import com.budwk.app.zhgh.club.service.SysClubService;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.model.OutlayManageClub;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.club.service.OutlayManageClubService;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhf
|
||||||
|
* @date 2026/4/20
|
||||||
|
* @description 协会预算分配公共方法实现
|
||||||
|
*/
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class OutlayManageClubServiceImpl extends BaseServiceImpl<OutlayManageClub> implements OutlayManageClubService {
|
||||||
|
public OutlayManageClubServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SysClubService sysClubService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllocatedClubIds(Integer year) {
|
||||||
|
if (ObjectUtil.isEmpty(year)) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
List<OutlayManageClub> outlayManageClubList = query(Cnd.where("year", "=", year));
|
||||||
|
return outlayManageClubList.stream()
|
||||||
|
.map(OutlayManageClub::getClubId)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutlayManageClub addAllocation(OutlayManageClub outlayManageClub) {
|
||||||
|
if (ObjectUtil.isEmpty(outlayManageClub) || ObjectUtil.isEmpty(outlayManageClub.getYear())) {
|
||||||
|
throw new BaseException("预算年度不能为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(outlayManageClub.getClubId())) {
|
||||||
|
throw new BaseException("协会不能为空");
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isEmpty(outlayManageClub.getTotalQuota())) {
|
||||||
|
throw new BaseException("总额度不能为空");
|
||||||
|
}
|
||||||
|
if (outlayManageClub.getTotalQuota().compareTo(BigDecimal.ZERO) < 0) {
|
||||||
|
throw new BaseException("总额度不能小于0");
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = count(Cnd.where("year", "=", outlayManageClub.getYear()).and("clubId", "=", outlayManageClub.getClubId()));
|
||||||
|
if (count > 0) {
|
||||||
|
throw new BaseException("该年度该协会已分配预算,请勿重复新增");
|
||||||
|
}
|
||||||
|
|
||||||
|
SysClub sysClub = sysClubService.fetch(outlayManageClub.getClubId());
|
||||||
|
if (ObjectUtil.isEmpty(sysClub)) {
|
||||||
|
throw new BaseException("未找到对应协会信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
outlayManageClub.setClubName(sysClub.getClubName());
|
||||||
|
outlayManageClub.setClubCode(sysClub.getClubCode());
|
||||||
|
if (ObjectUtil.isEmpty(outlayManageClub.getUsedQuota())) {
|
||||||
|
outlayManageClub.setUsedQuota(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
return insert(outlayManageClub);
|
||||||
|
}
|
||||||
|
}
|
||||||
+119
-14
@@ -90,6 +90,17 @@ layout("/layouts/platform.html"){
|
|||||||
v-model="formData.declareTotalBudgetMoney"></el-input-number>
|
v-model="formData.declareTotalBudgetMoney"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="quotaInfo.needLimit" label="年度额度提示" :span="2">
|
||||||
|
<div v-if="quotaInfo.selectedTarget && quotaInfo.totalQuota !== null">
|
||||||
|
<div>本年度总额度:{{quotaInfo.totalQuota}}元,申请中额度:{{quotaInfo.applyingQuota}}元,已通过额度:{{quotaInfo.approvedQuota}}元,当前剩余额度:{{quotaInfo.remainQuota}}元</div>
|
||||||
|
<div v-if="isQuotaExceeded()" style="color: #F56C6C; margin-top: 6px;">
|
||||||
|
当前申报金额已超出剩余额度,请先调整预算金额。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else style="color: #E6A23C;">
|
||||||
|
{{quotaInfo.message}}
|
||||||
|
</div>
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="预算条目" span="2">
|
<el-descriptions-item label="预算条目" span="2">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
prop="budgetReimburseType" label="预算条目"
|
prop="budgetReimburseType" label="预算条目"
|
||||||
@@ -186,6 +197,16 @@ layout("/layouts/platform.html"){
|
|||||||
formData: {
|
formData: {
|
||||||
budgetDetails: []
|
budgetDetails: []
|
||||||
},
|
},
|
||||||
|
quotaInfo: {
|
||||||
|
needLimit: false,
|
||||||
|
selectedTarget: true,
|
||||||
|
totalQuota: null,
|
||||||
|
applyingQuota: 0,
|
||||||
|
approvedQuota: 0,
|
||||||
|
occupiedQuota: 0,
|
||||||
|
remainQuota: 0,
|
||||||
|
message: ""
|
||||||
|
},
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
editType: "apply"
|
editType: "apply"
|
||||||
}
|
}
|
||||||
@@ -200,57 +221,65 @@ layout("/layouts/platform.html"){
|
|||||||
return resp.data
|
return resp.data
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
init() {
|
async init() {
|
||||||
if (this.bizId) {
|
if (this.bizId) {
|
||||||
this.findOne(this.bizId).then(data => {
|
const data = await this.findOne(this.bizId)
|
||||||
this.formData = data
|
this.$set(this, "formData", data)
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.formData = {
|
this.$set(this, "formData", {
|
||||||
isSchoolBudget: false,
|
isSchoolBudget: false,
|
||||||
isRepeatReimburse: true,
|
isRepeatReimburse: true,
|
||||||
budgetDetails: [],
|
budgetDetails: [],
|
||||||
applyDate: this.$moment().format('YYYY-MM-DD'),
|
applyDate: this.$moment().format('YYYY-MM-DD'),
|
||||||
userName: this.$store.state.user.username,
|
userName: this.$store.state.user.username,
|
||||||
mobile: this.$store.state.user.mobile,
|
mobile: this.$store.state.user.mobile,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clubChange(val) {
|
clubChange(val) {
|
||||||
const club = this.clubOption.find(c => c.id === val)
|
const club = this.clubOption.find(c => c.id === val)
|
||||||
this.formData.helpUnitName = club.clubName
|
this.$set(this.formData, "helpUnitName", club ? club.clubName : "")
|
||||||
|
this.refreshQuotaInfo()
|
||||||
},
|
},
|
||||||
unionChange(id) {
|
unionChange(id) {
|
||||||
if (id) {
|
if (id) {
|
||||||
const union = this.unionList.find(c => c.id === id)
|
const union = this.unionList.find(c => c.id === id)
|
||||||
this.$set(this.formData, "helpUnitName", union.unionname)
|
this.$set(this.formData, "helpUnitName", union ? (union.name || union.unionname) : "")
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.formData, "helpUnitName", '')
|
this.$set(this.formData, "helpUnitName", '')
|
||||||
}
|
}
|
||||||
|
this.refreshQuotaInfo()
|
||||||
},
|
},
|
||||||
budgetTypeCodeChange(val) {
|
budgetTypeCodeChange(val) {
|
||||||
if (val === "ACTIVITY_BUDGET_TYPE_ONE") {
|
if (val === "ACTIVITY_BUDGET_TYPE_ONE") {
|
||||||
this.$set(this.formData, "helpUnitName", "校工会")
|
this.$set(this.formData, "helpUnitName", "校工会")
|
||||||
|
this.$set(this.formData, "unionId", "")
|
||||||
|
this.$set(this.formData, "clubId", "")
|
||||||
} else if (val === "ACTIVITY_BUDGET_TYPE_TWO") {
|
} else if (val === "ACTIVITY_BUDGET_TYPE_TWO") {
|
||||||
this.$set(this.formData, "helpUnitName", this.$store.state.user.union.name)
|
this.$set(this.formData, "helpUnitName", this.$store.state.user.union.name)
|
||||||
this.$set(this.formData, "unionId", this.$store.state.user.union.id)
|
this.$set(this.formData, "unionId", this.$store.state.user.union.id)
|
||||||
|
this.$set(this.formData, "clubId", "")
|
||||||
} else if (["ACTIVITY_BUDGET_TYPE_THREE"].includes(val)) {
|
} else if (["ACTIVITY_BUDGET_TYPE_THREE"].includes(val)) {
|
||||||
this.$set(this.formData, "helpUnitName", '')
|
this.$set(this.formData, "helpUnitName", '')
|
||||||
this.$set(this.formData, "clubId", '')
|
this.$set(this.formData, "clubId", '')
|
||||||
|
this.$set(this.formData, "unionId", "")
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.formData, "helpUnitName", "校工会")
|
this.$set(this.formData, "helpUnitName", "校工会")
|
||||||
|
this.$set(this.formData, "unionId", "")
|
||||||
|
this.$set(this.formData, "clubId", "")
|
||||||
}
|
}
|
||||||
if (val) {
|
if (val) {
|
||||||
const budgetType = this.budgetTypeOption.find(b => b.code === val)
|
const budgetType = this.budgetTypeOption.find(b => b.code === val)
|
||||||
this.$set(this.formData, "budgetTypeId", budgetType.code)
|
this.$set(this.formData, "budgetTypeId", budgetType.code)
|
||||||
}
|
}
|
||||||
|
this.refreshQuotaInfo()
|
||||||
},
|
},
|
||||||
async getActivityBudgetType() {
|
async getActivityBudgetType() {
|
||||||
const data = await this.$businessTool.getDictOptions("ACTIVITY_BUDGET_TYPE")
|
const data = await this.$businessTool.getDictOptions("ACTIVITY_BUDGET_TYPE")
|
||||||
let budgetTypeOption = []
|
let budgetTypeOption = []
|
||||||
if (this.$auth.hasRoleOr(['SYSADMIN'])) {
|
if (this.$auth.hasRoleOr(['SYSADMIN'])) {
|
||||||
this.budgetTypeOption = data
|
this.$set(this, "budgetTypeOption", data)
|
||||||
} else {
|
} else {
|
||||||
if (this.$auth.hasRoleOr(['SCHOOL_UNION_ADMIN', 'SCHOOL_UNION_CHAIRMAN', 'SCHOOL_UNION_VICE_CHAIRMAN'])) {
|
if (this.$auth.hasRoleOr(['SCHOOL_UNION_ADMIN', 'SCHOOL_UNION_CHAIRMAN', 'SCHOOL_UNION_VICE_CHAIRMAN'])) {
|
||||||
data.map(v => {
|
data.map(v => {
|
||||||
@@ -273,7 +302,7 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.budgetTypeOption = budgetTypeOption
|
this.$set(this, "budgetTypeOption", budgetTypeOption)
|
||||||
if (this.budgetTypeOption.length === 1){
|
if (this.budgetTypeOption.length === 1){
|
||||||
this.$set(this.formData, "outlayManageSource", this.budgetTypeOption[0].code)
|
this.$set(this.formData, "outlayManageSource", this.budgetTypeOption[0].code)
|
||||||
this.budgetTypeCodeChange(this.budgetTypeOption[0].code)
|
this.budgetTypeCodeChange(this.budgetTypeOption[0].code)
|
||||||
@@ -283,10 +312,81 @@ layout("/layouts/platform.html"){
|
|||||||
getSchoolBudget() {
|
getSchoolBudget() {
|
||||||
this.$axios.post("/platform/activity/budget/apply/getSchoolBudget").then((res) => {
|
this.$axios.post("/platform/activity/budget/apply/getSchoolBudget").then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.activityList = res.data
|
this.$set(this, "activityList", res.data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
clearQuotaInfo() {
|
||||||
|
this.$set(this, "quotaInfo", {
|
||||||
|
needLimit: false,
|
||||||
|
selectedTarget: true,
|
||||||
|
totalQuota: null,
|
||||||
|
applyingQuota: 0,
|
||||||
|
approvedQuota: 0,
|
||||||
|
occupiedQuota: 0,
|
||||||
|
remainQuota: 0,
|
||||||
|
message: ""
|
||||||
|
})
|
||||||
|
},
|
||||||
|
refreshQuotaInfo() {
|
||||||
|
const outlayManageSource = this.formData.outlayManageSource
|
||||||
|
if (!outlayManageSource || outlayManageSource !== "ACTIVITY_BUDGET_TYPE_TWO") {
|
||||||
|
this.clearQuotaInfo()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.formData.unionId) {
|
||||||
|
this.$set(this, "quotaInfo", {
|
||||||
|
needLimit: true,
|
||||||
|
selectedTarget: false,
|
||||||
|
totalQuota: null,
|
||||||
|
applyingQuota: 0,
|
||||||
|
approvedQuota: 0,
|
||||||
|
occupiedQuota: 0,
|
||||||
|
remainQuota: 0,
|
||||||
|
message: "请选择分工会"
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$axios.post("/platform/activity/budget/apply/getQuotaInfo", {
|
||||||
|
data: JSON.stringify({
|
||||||
|
id: this.formData.id,
|
||||||
|
applyDate: this.formData.applyDate,
|
||||||
|
outlayManageSource: this.formData.outlayManageSource,
|
||||||
|
unionId: this.formData.unionId,
|
||||||
|
clubId: this.formData.clubId
|
||||||
|
})
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$set(this, "quotaInfo", {
|
||||||
|
needLimit: res.data.needLimit,
|
||||||
|
selectedTarget: res.data.selectedTarget,
|
||||||
|
totalQuota: res.data.totalQuota,
|
||||||
|
applyingQuota: res.data.applyingQuota,
|
||||||
|
approvedQuota: res.data.approvedQuota,
|
||||||
|
occupiedQuota: res.data.occupiedQuota,
|
||||||
|
remainQuota: res.data.remainQuota,
|
||||||
|
message: res.data.message || ""
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$set(this, "quotaInfo", {
|
||||||
|
needLimit: true,
|
||||||
|
selectedTarget: false,
|
||||||
|
totalQuota: null,
|
||||||
|
applyingQuota: 0,
|
||||||
|
approvedQuota: 0,
|
||||||
|
occupiedQuota: 0,
|
||||||
|
remainQuota: 0,
|
||||||
|
message: res.message || "预算额度查询失败"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
isQuotaExceeded() {
|
||||||
|
if (!this.quotaInfo.needLimit || !this.quotaInfo.selectedTarget || this.quotaInfo.totalQuota === null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return Number(this.formData.declareTotalBudgetMoney || 0) > Number(this.quotaInfo.remainQuota || 0)
|
||||||
|
},
|
||||||
// 保存
|
// 保存
|
||||||
onSave() {
|
onSave() {
|
||||||
this.$confirm("您确定保存吗?", "提示", {
|
this.$confirm("您确定保存吗?", "提示", {
|
||||||
@@ -316,6 +416,8 @@ layout("/layouts/platform.html"){
|
|||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.$message.success("提交成功")
|
this.$message.success("提交成功")
|
||||||
commonUtil.pjaxPush('/platform/activity/budget/applyList')
|
commonUtil.pjaxPush('/platform/activity/budget/applyList')
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -333,6 +435,8 @@ layout("/layouts/platform.html"){
|
|||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.$message.success("提交成功")
|
this.$message.success("提交成功")
|
||||||
commonUtil.pjaxPush('/platform/activity/budget/applyList')
|
commonUtil.pjaxPush('/platform/activity/budget/applyList')
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -340,11 +444,12 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
this.init()
|
await this.init()
|
||||||
await this.getActivityBudgetType()
|
await this.getActivityBudgetType()
|
||||||
await this.getSchoolBudget()
|
await this.getSchoolBudget()
|
||||||
this.unionList = await this.$businessTool.listUnion(this.$store.state.user.union.id)
|
this.$set(this, "unionList", await this.$businessTool.listUnion(this.$store.state.user.union.id))
|
||||||
this.clubOption = await this.$businessTool.listCLubByRole()
|
this.$set(this, "clubOption", await this.$businessTool.listCLubByRole())
|
||||||
|
this.refreshQuotaInfo()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+120
-1
@@ -24,6 +24,9 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
<el-card shadow="never" class="mt10">
|
<el-card shadow="never" class="mt10">
|
||||||
<table-tool label="预算分配">
|
<table-tool label="预算分配">
|
||||||
|
<el-button @click="openAddDialog" size="small" type="primary">
|
||||||
|
新增分配
|
||||||
|
</el-button>
|
||||||
<template v-if="pageForm.year===$moment().format('YYYY')">
|
<template v-if="pageForm.year===$moment().format('YYYY')">
|
||||||
<el-button @click="issuedOutlay" size="small" type="primary" v-if="!isAllocation">年度分配
|
<el-button @click="issuedOutlay" size="small" type="primary" v-if="!isAllocation">年度分配
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -83,6 +86,40 @@ layout("/layouts/platform.html"){
|
|||||||
</el-table>
|
</el-table>
|
||||||
<!--#include("/layouts/pagination.html"){}#-->
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
</el-card>
|
</el-card>
|
||||||
|
<el-dialog title="新增分配" :visible.sync="addDialogVisible" width="520px">
|
||||||
|
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="90px">
|
||||||
|
<el-form-item label="年度" prop="year">
|
||||||
|
<el-date-picker
|
||||||
|
@change="addYearChange"
|
||||||
|
:picker-options="addYearPickerOptions"
|
||||||
|
placeholder="选择年度"
|
||||||
|
style="width: 100%" type="year"
|
||||||
|
v-model="addForm.year"
|
||||||
|
:clearable="false"
|
||||||
|
value-format="yyyy">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="协会" prop="clubId">
|
||||||
|
<el-select v-model="addForm.clubId" filterable clearable placeholder="请选择协会" style="width: 100%;">
|
||||||
|
<el-option v-for="item in addClubOption"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.clubName"
|
||||||
|
:value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="总额度" prop="totalQuota">
|
||||||
|
<el-input-number v-model="addForm.totalQuota"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
placeholder="请输入总额度"
|
||||||
|
style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="closeAddDialog">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitAddAllocation">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
</guava>
|
</guava>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,11 +139,70 @@ layout("/layouts/platform.html"){
|
|||||||
pageForm: {
|
pageForm: {
|
||||||
year: this.$moment().format("YYYY")
|
year: this.$moment().format("YYYY")
|
||||||
},
|
},
|
||||||
isAllocation: false
|
isAllocation: false,
|
||||||
|
addDialogVisible: false,
|
||||||
|
addClubOption: [],
|
||||||
|
addForm: {
|
||||||
|
year: this.$moment().format("YYYY"),
|
||||||
|
clubId: "",
|
||||||
|
totalQuota: undefined
|
||||||
|
},
|
||||||
|
addFormRules: {
|
||||||
|
year: [{required: true, message: '必填', trigger: ['change', 'blur']}],
|
||||||
|
clubId: [{required: true, message: '必填', trigger: ['change', 'blur']}],
|
||||||
|
totalQuota: [{required: true, message: '必填', trigger: ['change', 'blur']}]
|
||||||
|
},
|
||||||
|
addYearPickerOptions: {
|
||||||
|
disabledDate(time) {
|
||||||
|
const currentYear = Number(moment().format("YYYY"))
|
||||||
|
return time.getFullYear() < currentYear
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
methods: {
|
methods: {
|
||||||
|
openAddDialog() {
|
||||||
|
this.$set(this, "addDialogVisible", true)
|
||||||
|
this.$set(this, "addForm", {
|
||||||
|
year: this.pageForm.year,
|
||||||
|
clubId: "",
|
||||||
|
totalQuota: undefined
|
||||||
|
})
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.addFormRef) {
|
||||||
|
this.$refs.addFormRef.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.loadAvailableClubOption()
|
||||||
|
},
|
||||||
|
closeAddDialog() {
|
||||||
|
this.$set(this, "addDialogVisible", false)
|
||||||
|
},
|
||||||
|
addYearChange() {
|
||||||
|
this.$set(this.addForm, "clubId", "")
|
||||||
|
this.loadAvailableClubOption()
|
||||||
|
},
|
||||||
|
loadAvailableClubOption() {
|
||||||
|
if (!this.addForm.year) {
|
||||||
|
this.$set(this, "addClubOption", [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Promise.all([
|
||||||
|
this.$businessTool.listCLubByRole(),
|
||||||
|
this.$axios.post("/platform/outlay/outlayManage/clubManage/getAllocatedClubIds", {
|
||||||
|
year: this.addForm.year
|
||||||
|
})
|
||||||
|
]).then((res) => {
|
||||||
|
const allClubOption = res[0] || []
|
||||||
|
const allocatedClubIds = res[1].code === 0 ? res[1].data : []
|
||||||
|
const availableClubOption = allClubOption.filter(item => !allocatedClubIds.includes(item.id))
|
||||||
|
this.$set(this, "addClubOption", availableClubOption)
|
||||||
|
if (availableClubOption.length === 0) {
|
||||||
|
this.$message.warning("当前年度没有可新增分配的协会");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
doSubmit(row) {
|
doSubmit(row) {
|
||||||
this.$confirm('您确定要提交此条记录吗?', '提示', {
|
this.$confirm('您确定要提交此条记录吗?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
@@ -125,6 +221,29 @@ layout("/layouts/platform.html"){
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
submitAddAllocation() {
|
||||||
|
this.$refs.addFormRef.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$confirm('您确定要新增这条分配记录吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.$axios.post("/platform/outlay/outlayManage/clubManage/addAllocation", this.addForm)
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$message.success("新增成功");
|
||||||
|
this.closeAddDialog()
|
||||||
|
this.doSearch()
|
||||||
|
this.getIsAllocation()
|
||||||
|
} else {
|
||||||
|
this.$message.error(resp.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
resetOutlay() {
|
resetOutlay() {
|
||||||
this.$confirm('您确定要重置今年的记录吗?', '提示', {
|
this.$confirm('您确定要重置今年的记录吗?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
|
|||||||
Reference in New Issue
Block a user