This commit is contained in:
2026-04-25 14:51:03 +08:00
parent 9b92c29197
commit e8e39c128c
4 changed files with 184 additions and 88 deletions
@@ -77,12 +77,26 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
Workbook exportImportTemplate();
/**
* 重置当前季度的分配记录。
* 重置指定年度季度的分配记录。
*
* <p>重置时会先回滚 outlay_manage_union.totalQuota
* 再将当前季度的 outlay_allocate_union 记录标记删除。</p>
* <p>页面支持切换年度和季度,所以重置动作必须严格使用前端当前选择值
* 不能再按系统当前自然季度处理,否则会出现页面筛选季度和实际重置季度不一致的问题。</p>
*
* @param quarterly 要重置的季度,例如 1/2/3/4
* @param year 要重置的年份
* @return Result 成功时返回 success;失败时返回错误信息
*/
Result deleteAllocateRecord();
Result deleteAllocateRecord(Integer quarterly, Integer year);
/**
* 按指定年度季度生成分工会预算记录。
*
* <p>生成前会先校验该年度季度是否已存在有效记录;
* 若已存在,则直接提示前端需要先重置后再重新生成。</p>
*
* @param quarterly 要生成的季度,例如 1/2/3/4
* @param year 要生成的年份
* @return Result 成功时返回 success;失败时返回错误信息
*/
Result doAllocateRecord(Integer quarterly, Integer year);
}
@@ -60,6 +60,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
@Override
public Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year) {
Result validateResult = validateCurrentQuarterOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
List<OutLayAllocateUnion> allocateUnionList = dao().query(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
@@ -139,6 +143,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
@Override
public Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year) {
Result validateResult = validateCurrentQuarterOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
if (importList == null || importList.isEmpty()) {
return Result.error("请先上传导入数据");
}
@@ -208,11 +216,17 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
}
@Override
public Result deleteAllocateRecord() {
int currentQuarter = getCurrentQuarter();
public Result deleteAllocateRecord(Integer quarterly, Integer year) {
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
Result validateResult = validateCurrentQuarterOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
List<OutLayAllocateUnion> allocateUnionList = dao().query(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", currentQuarter)
.and(OutLayAllocateUnion::getYear, "=", DateUtil.thisYear())
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
return Result.error("当前季度还未分配,无法重置!");
@@ -223,12 +237,38 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
}
dao().update(OutLayAllocateUnion.class, Chain.make("delFlag", true),
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", currentQuarter)
.and(OutLayAllocateUnion::getYear, "=", DateUtil.thisYear())
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
return Result.success();
}
@Override
public Result doAllocateRecord(Integer quarterly, Integer year) {
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
Result validateResult = validateCurrentQuarterOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
int count = dao().count(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (count > 0) {
return Result.error("当前季度已分配,如需重新分配请点击重置分配记录!");
}
// 第一季度需要承接上一年度剩余额度,其余季度承接当年预算额度,确保生成记录时的分配前额度准确。
Integer sourceYear = quarterly == 1 ? year - 1 : year;
List<OutlayManageUnion> outlayManageUnionList = dao().query(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getYear, "=", sourceYear));
List<OutLayAllocateUnion> insertList = buildAllocateUnionList(outlayManageUnionList, quarterly, year);
insert(insertList);
return Result.success();
}
/**
* 按“先回退旧额度,再写入新额度”的方式同步季度记录和年度预算表。
*
@@ -239,7 +279,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
BigDecimal oldAllocateMoney = defaultValue(allocateUnion.getAllocateMoney());
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getUnionId, "=", allocateUnion.getUnionId())
.and(OutlayManageUnion::getYear, "=", DateUtil.thisYear()));
.and(OutlayManageUnion::getYear, "=", allocateUnion.getYear()));
if (Lang.isEmpty(manageUnion)) {
manageUnion = buildManageUnion(allocateUnion, newAllocateMoney);
@@ -265,7 +305,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
private void rollbackAllocateMoney(OutLayAllocateUnion allocateUnion) {
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getUnionId, "=", allocateUnion.getUnionId())
.and(OutlayManageUnion::getYear, "=", DateUtil.thisYear()));
.and(OutlayManageUnion::getYear, "=", allocateUnion.getYear()));
if (Lang.isEmpty(manageUnion)) {
return;
}
@@ -285,7 +325,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
private OutlayManageUnion buildManageUnion(OutLayAllocateUnion allocateUnion, BigDecimal allocateMoney) {
Sys_union union = dao().fetch(Sys_union.class, allocateUnion.getUnionId());
OutlayManageUnion manageUnion = new OutlayManageUnion();
manageUnion.setYear(DateUtil.thisYear());
manageUnion.setYear(allocateUnion.getYear());
manageUnion.setUnionId(allocateUnion.getUnionId());
manageUnion.setTotalQuota(defaultValue(allocateUnion.getAllocateHeadMoney()).add(allocateMoney));
manageUnion.setUsedQuota(BigDecimal.ZERO);
@@ -314,4 +354,54 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
private int getCurrentQuarter() {
return DateUtil.month(DateUtil.date()) / 3 + 1;
}
/**
* 预算季度记录相关操作只能针对当前自然季度执行。
*
* @param quarterly 前端传入的目标季度
* @return Result 不允许操作时返回错误结果;允许操作时返回 null
*/
private Result validateCurrentQuarterOperation(Integer quarterly) {
if (quarterly == null) {
return Result.error("参数错误!");
}
int currentQuarter = getCurrentQuarter();
if (!quarterly.equals(currentQuarter)) {
return Result.error("当前仅允许操作第" + currentQuarter + "季度数据,请切换后再操作!");
}
return null;
}
/**
* 按目标年度季度初始化要生成的分工会分配记录。
*
* @param outlayManageUnionList 用于计算“分配前额度”的年度预算数据
* @param quarterly 目标季度
* @param year 目标年度
* @return List<OutLayAllocateUnion> 待插入的季度分配记录
*/
private List<OutLayAllocateUnion> buildAllocateUnionList(List<OutlayManageUnion> outlayManageUnionList, Integer quarterly, Integer year) {
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
List<OutLayAllocateUnion> insertList = new ArrayList<>();
for (Sys_union union : unionList) {
OutLayAllocateUnion allocateUnion = new OutLayAllocateUnion();
allocateUnion.setYear(year);
allocateUnion.setQuarterly(quarterly);
allocateUnion.setUnionId(union.getId());
allocateUnion.setAllocateMoney(BigDecimal.ZERO);
OutlayManageUnion outlayManageUnion = outlayManageUnionList.stream()
.filter(o -> o.getUnionId().equals(union.getId()))
.findFirst()
.orElse(null);
if (Lang.isNotEmpty(outlayManageUnion)) {
BigDecimal surplusMoney = defaultValue(outlayManageUnion.getTotalQuota())
.subtract(defaultValue(outlayManageUnion.getUsedQuota()));
allocateUnion.setAllocateHeadMoney(surplusMoney);
} else {
allocateUnion.setAllocateHeadMoney(BigDecimal.ZERO);
}
insertList.add(allocateUnion);
}
return insertList;
}
}
@@ -2,17 +2,13 @@ package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.controller;
import com.budwk.app.base.utils.CommonDownloadUtil;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionAllocateService;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutLayAllocateUnion;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutlayManageUnion;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionAllocateImportVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -37,7 +33,6 @@ import org.nutz.mvc.annotation.AdaptBy;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
@@ -175,70 +170,23 @@ public class OutlayManageUnionAllocateController {
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-季度预算分配", msg = "重置预算季度记录")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result deleteAllocateRecord() {
return outlayManageUnionAllocateService.deleteAllocateRecord();
public Result deleteAllocateRecord(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
return outlayManageUnionAllocateService.deleteAllocateRecord(quarterly, year);
}
@At
@ApiOperation("预算季度记录生成")
@SLog(tag = "分工会预算-季度预算分配", msg = "生成了预算分配记录")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doAllocateRecord() {
int quarter = DateUtil.month(DateUtil.date()) / 3 + 1;
// 查询当前季度
int count = baseService.dao().count(OutLayAllocateUnion.class, Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarter)
.and(OutLayAllocateUnion::getYear, "=", DateUtil.thisYear())
.and(OutLayAllocateUnion::getDelFlag, "=", 0));
if (count > 0) {
return Result.error("当前季度已分配,如需重新分配请点击重置分配记录!");
public Result doAllocateRecord(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
List<OutlayManageUnion> outlayManageUnionList;
if (quarter == 1) {
//如果是第一季度,查询去年剩余额度
outlayManageUnionList = baseService.dao().query(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getYear, "=", DateUtil.thisYear() - 1));
} else {
//非第一季度
outlayManageUnionList = baseService.dao().query(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getYear, "=", DateUtil.thisYear()));
}
List<OutLayAllocateUnion> insertList = this.initOutLayAllocateUnion(outlayManageUnionList);
baseService.insert(insertList);
return Result.success();
return outlayManageUnionAllocateService.doAllocateRecord(quarterly, year);
}
/**
* 初始化需要添加的数据
*
* @param outlayManageUnionList
* @return
*/
public List<OutLayAllocateUnion> initOutLayAllocateUnion(List<OutlayManageUnion> outlayManageUnionList) {
int quarter = DateUtil.month(DateUtil.date()) / 3 + 1;
List<Sys_union> unionList = baseService.dao().query(Sys_union.class, Cnd.NEW());
List<OutLayAllocateUnion> insertList = new ArrayList<>();
for (Sys_union union : unionList) {
OutLayAllocateUnion allocateUnion = new OutLayAllocateUnion();
allocateUnion.setYear(DateUtil.thisYear());
allocateUnion.setQuarterly(quarter);
allocateUnion.setUnionId(union.getId());
allocateUnion.setAllocateMoney(BigDecimal.ZERO);
//根据院级工会ID查询
OutlayManageUnion outlayManageUnion = outlayManageUnionList.stream().filter(o -> o.getUnionId().equals(union.getId())).findFirst().orElse(null);
if (Lang.isNotEmpty(outlayManageUnion)) {
BigDecimal surplusMoney = outlayManageUnion.getTotalQuota().subtract(outlayManageUnion.getUsedQuota());
allocateUnion.setAllocateHeadMoney(surplusMoney);
} else {
allocateUnion.setAllocateHeadMoney(BigDecimal.ZERO);
}
insertList.add(allocateUnion);
}
return insertList;
}
}
@@ -186,6 +186,36 @@ layout("/layouts/platform.html"){
}
},
methods: {
/**
* 确认提示文案优先展示页面当前筛选季度。
* 未选择季度时再回退到系统当前自然季度,避免提示文案与用户当前查看条件不一致。
*/
getPromptQuarter() {
return this.pageForm.quarterly || this.$moment().quarter()
},
/**
* 季度记录生成、重置记录都要按页面当前筛选的年度和季度执行。
* 这里统一封装请求参数,避免前后端再次出现“提示季度”和“实际执行季度”不一致的问题。
*/
getCurrentQuarterParams() {
return {
quarterly: this.pageForm.quarterly || this.$moment().quarter(),
year: this.pageForm.year
}
},
/**
* 生成、重置、一键分配都只允许操作当前自然季度。
* 这里统一做前端入口校验,避免同类判断分散在多个按钮方法里难维护。
*/
validateCurrentQuarterAction(actionName) {
const currentQuarter = this.$moment().quarter()
const selectedQuarter = Number(this.getCurrentQuarterParams().quarterly)
if (selectedQuarter !== currentQuarter) {
this.$message.warning('当前仅允许操作第' + currentQuarter + '季度' + actionName + ',请切换后再操作')
return false
}
return true
},
doEdit(row) {
this.$confirm('确定要给【' + row.unionName + '】分配预算吗?', '提示', {
confirmButtonText: '确定',
@@ -207,13 +237,21 @@ layout("/layouts/platform.html"){
})
},
deleteAllocateRecord() {
this.$confirm('确定要重置【第' + this.$moment().quarter() + '季度】的预算记录吗?', '提示', {
if (!this.validateCurrentQuarterAction('记录重置')) {
return
}
// 重置动作以当前列表是否已有记录为前置条件,避免用户在空列表场景下误操作。
if (this.tableData.length === 0) {
this.$message.warning('当前列表无可重置记录')
return
}
this.$confirm('确定要重置【第' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord").then((resp) => {
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
@@ -224,13 +262,16 @@ layout("/layouts/platform.html"){
})
},
doAllocateRecord() {
this.$confirm('确定要生成【第' + this.$moment().quarter() + '季度】的预算记录吗?', '提示', {
if (!this.validateCurrentQuarterAction('记录生成')) {
return
}
this.$confirm('确定要生成【第' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord").then((resp) => {
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
@@ -241,18 +282,21 @@ layout("/layouts/platform.html"){
})
},
showBatchAllocateDialog() {
if (!this.validateCurrentQuarterAction('一键分配')) {
return
}
if (this.tableData.length === 0) {
this.$message.warning('当前没有可分配的工会记录,请先生成季度记录')
return
}
const quarter = this.$moment().quarter()
const currentParams = this.getCurrentQuarterParams()
const openDialog = () => {
this.resetBatchAllocateForm()
this.batchAllocateDialogVisible = true
}
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/hasAllocated", {
quarterly: quarter,
year: this.pageForm.year
quarterly: currentParams.quarterly,
year: currentParams.year
}).then((resp) => {
if (resp.code !== 0) {
return
@@ -305,7 +349,7 @@ layout("/layouts/platform.html"){
this.$set(this.batchAllocateForm, "importPreviewList", [])
},
doBatchAllocate() {
const quarter = this.$moment().quarter()
const currentParams = this.getCurrentQuarterParams()
if (this.batchAllocateForm.allocateMode === "uniform") {
if (!this.batchAllocateForm.allocateMoney || this.batchAllocateForm.allocateMoney <= 0) {
this.$message.warning('请输入有效的分配额度')
@@ -314,8 +358,8 @@ layout("/layouts/platform.html"){
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doBatchAllocate", {
allocateMoney: this.batchAllocateForm.allocateMoney,
quarterly: quarter,
year: this.pageForm.year
quarterly: currentParams.quarterly,
year: currentParams.year
}).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
@@ -339,8 +383,8 @@ layout("/layouts/platform.html"){
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doImportAllocate", {
data: JSON.stringify(this.batchAllocateForm.importPreviewList),
quarterly: quarter,
year: this.pageForm.year
quarterly: currentParams.quarterly,
year: currentParams.year
}).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)