bug整改

This commit is contained in:
2026-04-25 11:41:14 +08:00
parent 14a150a335
commit 9b92c29197
11 changed files with 486 additions and 28 deletions
@@ -3,8 +3,12 @@ package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutLayAllocateUnion;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionAllocateImportVo;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.mvc.upload.TempFile;
import java.math.BigDecimal;
import java.util.List;
/**
* 分工会季度额度分配服务。
@@ -35,6 +39,43 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
*/
Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year);
/**
* 判断某年某季度是否已经做过额度分配。
*
* <p>只要当前季度记录中存在分配额度大于 0 的有效记录,
* 就认为该季度已经分配过额度,前端据此决定是否提示再次分配。</p>
*
* @param quarterly 要检查的季度,例如 1/2/3/4
* @param year 要检查的年份
* @return true 已分配过;false 未分配
*/
boolean hasAllocated(Integer quarterly, Integer year);
/**
* 解析导入文件并返回预览数据。
*
* @param file Excel 文件
* @return 解析后的预览数据
*/
List<OutlayUnionAllocateImportVo> readImportExcel(TempFile file);
/**
* 根据导入数据按分工会逐条分配季度额度。
*
* @param importList 导入预览数据
* @param quarterly 当前季度
* @param year 当前年度
* @return 导入分配结果
*/
Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year);
/**
* 导出分工会额度导入模板。
*
* @return 模板工作簿
*/
Workbook exportImportTemplate();
/**
* 重置当前季度的分配记录。
*
@@ -1,20 +1,36 @@
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.date.DateUtil;
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.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 org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.mvc.upload.TempFile;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 分工会季度额度分配实现。
@@ -57,6 +73,140 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
return Result.success();
}
@Override
public boolean hasAllocated(Integer quarterly, Integer year) {
if (quarterly == null || year == null) {
return false;
}
int count = dao().count(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false)
.and("allocateMoney", ">", BigDecimal.ZERO));
return count > 0;
}
@Override
public List<OutlayUnionAllocateImportVo> readImportExcel(TempFile file) {
String extName = FileUtil.extName(file.getFile());
if (!"xlsx".equalsIgnoreCase(extName) && !"xls".equalsIgnoreCase(extName)) {
throw Lang.makeThrow("请上传xlsx或xls格式文件");
}
List<OutlayUnionAllocateImportVo> importList = ExcelImportUtil.importExcel(file.getFile(),
OutlayUnionAllocateImportVo.class, new ImportParams());
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
Map<String, Sys_union> unionMap = new HashMap<>();
for (Sys_union union : unionList) {
unionMap.put(union.getUnionCode(), union);
}
Set<String> duplicateUnionCodeSet = new LinkedHashSet<>();
Set<String> existUnionCodeSet = new LinkedHashSet<>();
for (OutlayUnionAllocateImportVo item : importList) {
if (StrUtil.isBlank(item.getUnionCode())) {
continue;
}
if (!existUnionCodeSet.add(item.getUnionCode())) {
duplicateUnionCodeSet.add(item.getUnionCode());
}
}
for (int i = 0; i < importList.size(); i++) {
OutlayUnionAllocateImportVo item = importList.get(i);
item.setRowNum(i + 2);
if (StrUtil.isBlank(item.getUnionCode())) {
item.setErrMsg("工会编码不能为空");
continue;
}
if (item.getAllocateMoney() == null) {
item.setErrMsg("分配额度不能为空");
continue;
}
if (item.getAllocateMoney().compareTo(BigDecimal.ZERO) < 0) {
item.setErrMsg("分配额度不能小于0");
continue;
}
Sys_union union = unionMap.get(item.getUnionCode());
if (Lang.isEmpty(union)) {
item.setErrMsg("工会编码不存在");
continue;
}
item.setUnionName(union.getName());
if (duplicateUnionCodeSet.contains(item.getUnionCode())) {
item.setErrMsg("工会编码重复");
}
}
return importList;
}
@Override
public Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year) {
if (importList == null || importList.isEmpty()) {
return Result.error("请先上传导入数据");
}
List<OutLayAllocateUnion> allocateUnionList = dao().query(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getQuarterly, "=", quarterly)
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
return Result.error("当前季度没有分配记录!");
}
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
Map<String, Sys_union> unionMap = new HashMap<>();
for (Sys_union union : unionList) {
unionMap.put(union.getUnionCode(), union);
}
Map<String, OutLayAllocateUnion> allocateUnionMap = new HashMap<>();
for (OutLayAllocateUnion allocateUnion : allocateUnionList) {
allocateUnionMap.put(allocateUnion.getUnionId(), allocateUnion);
}
List<String> errorList = new ArrayList<>();
for (OutlayUnionAllocateImportVo item : importList) {
if (StrUtil.isBlank(item.getUnionCode())) {
errorList.add("" + item.getRowNum() + "行:工会编码不能为空");
continue;
}
if (item.getAllocateMoney() == null) {
errorList.add("" + item.getRowNum() + "行:分配额度不能为空");
continue;
}
if (item.getAllocateMoney().compareTo(BigDecimal.ZERO) < 0) {
errorList.add("" + item.getRowNum() + "行:分配额度不能小于0");
continue;
}
if (StrUtil.isNotBlank(item.getErrMsg())) {
errorList.add("" + item.getRowNum() + "行:" + item.getErrMsg());
continue;
}
Sys_union union = unionMap.get(item.getUnionCode());
if (Lang.isEmpty(union)) {
errorList.add("" + item.getRowNum() + "行:工会编码不存在");
continue;
}
if (!allocateUnionMap.containsKey(union.getId())) {
errorList.add("" + item.getRowNum() + "行:当前季度未生成该分工会分配记录");
}
}
if (!errorList.isEmpty()) {
return Result.error(String.join("", errorList));
}
for (OutlayUnionAllocateImportVo item : importList) {
Sys_union union = unionMap.get(item.getUnionCode());
OutLayAllocateUnion allocateUnion = allocateUnionMap.get(union.getId());
// 导入分配与手工分配保持同一套金额同步规则,确保季度表和年度预算表数据一致。
applyAllocateMoney(allocateUnion, item.getAllocateMoney());
}
return Result.success("导入分配成功");
}
@Override
public Workbook exportImportTemplate() {
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("工会编码", "unionCode", 20));
entityList.add(new ExcelExportEntity("分配额度", "allocateMoney", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
return ExcelExportUtil.exportExcel(exportParams, entityList, new ArrayList<>());
}
@Override
public Result deleteAllocateRecord() {
int currentQuarter = getCurrentQuarter();
@@ -1,5 +1,6 @@
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;
@@ -12,9 +13,11 @@ 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;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
@@ -22,11 +25,17 @@ import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import org.nutz.mvc.annotation.AdaptBy;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@@ -107,6 +116,59 @@ public class OutlayManageUnionAllocateController {
return outlayManageUnionAllocateService.doBatchAllocate(allocateMoney, quarterly, year);
}
@At
@ApiOperation("校验当前季度是否已分配额度")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result hasAllocated(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
return Result.success(outlayManageUnionAllocateService.hasAllocated(quarterly, year));
}
@At
@POST
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@ApiOperation("读取导入分配Excel")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result readImportExcel(TempFile file) {
try {
return Result.success(outlayManageUnionAllocateService.readImportExcel(file));
} catch (Exception e) {
log.error("读取分工会额度导入文件失败", e);
return Result.error(e.getMessage());
}
}
@At
@ApiOperation("导入分配分工会额度")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-季度预算分配", msg = "导入分配分工会额度")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doImportAllocate(String data,
@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
if (StrUtil.isBlank(data) || quarterly == null || year == null) {
return Result.error("参数错误!");
}
List<OutlayUnionAllocateImportVo> importList = Json.fromJsonAsList(OutlayUnionAllocateImportVo.class, data);
return outlayManageUnionAllocateService.doImportAllocate(importList, quarterly, year);
}
@At
@Ok("void")
@ApiOperation("下载导入分配模板")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public void downloadImportTemplate(HttpServletResponse response) {
try {
Workbook workbook = outlayManageUnionAllocateService.exportImportTemplate();
CommonDownloadUtil.download("分工会额度导入模板.xlsx", workbook, response);
} catch (Exception e) {
log.error("下载分工会额度导入模板失败", e);
}
}
@At
@ApiOperation("重置预算季度记录")
@@ -84,6 +84,9 @@ public class DifficultHelpApplyController {
public Result getIsCanPlay() {
//获取申请次数,不想再写一个接口, are you ok? .and("zt", "=", 600)
int applyCount = dao.count(DifficultHelpInfo.class, Cnd.where("proxyUserId", "=", SecurityUtil.getUserId()));
// 页面初始化时需要先判断当前登录人本年度是否已经申请过,避免重复进入新增申请。
boolean hasCurrentYearApply = dao.count(DifficultHelpInfo.class, Cnd.where("userId", "=", SecurityUtil.getUserId())
.and("YEAR(applyTime)", "=", DateUtil.getYear())) > 0;
Sys_config startConfig = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "DifficultyApplyStartTime"));
Sys_config endConfig = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "DifficultyApplyEndTime"));
if(startConfig != null && endConfig != null) {
@@ -98,9 +101,9 @@ public class DifficultHelpApplyController {
int endResult = cn.hutool.core.date.DateUtil.compare(cn.hutool.core.date.DateUtil.parse(today), cn.hutool.core.date.DateUtil.parse(end));
String time = startConfig.getConfigValue().replace("-", "") + "日-" + endConfig.getConfigValue().replace("-", "") + "";
return Result.success(Map.of("applyCount", applyCount,"time", time, "result", startResult >=0 && endResult <= 0));
return Result.success(Map.of("applyCount", applyCount,"time", time, "result", startResult >=0 && endResult <= 0, "hasCurrentYearApply", hasCurrentYearApply));
} else {
return Result.success(Map.of("applyCount", applyCount,"time", "", "result", false));
return Result.success(Map.of("applyCount", applyCount,"time", "", "result", false, "hasCurrentYearApply", hasCurrentYearApply));
}
}
@@ -110,6 +113,10 @@ public class DifficultHelpApplyController {
@SLog(tag = "困难补助申请", msg = "保存申请,填写人: ${args[0].proxyUserName}")
public Result save(@Param("data") DifficultHelpInfo difficultHelpInfo) {
difficultHelpInfo.setApplyTime(ObjectUtil.defaultIfNull(difficultHelpInfo.getApplyTime(), new Date()));
difficultHelpCommonService.refreshApplyCount(difficultHelpInfo);
if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) {
return Result.error("该人员本年度已申请困难帮扶,不能重复申请");
}
dao.insertOrUpdate(difficultHelpInfo);
return Result.success();
}
@@ -122,6 +129,10 @@ public class DifficultHelpApplyController {
@SLog(tag = "困难补助申请", msg = "提交申请,填写人: ${args[0].proxyUserName}")
public Result submit(@Param("data") DifficultHelpInfo difficultHelpInfo){
difficultHelpInfo.setApplyTime(new Date());
difficultHelpCommonService.refreshApplyCount(difficultHelpInfo);
if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) {
return Result.error("该人员本年度已申请困难帮扶,不能重复申请");
}
dao.insertOrUpdate(difficultHelpInfo);
// 开启流程实例
@@ -146,6 +157,10 @@ public class DifficultHelpApplyController {
@SLog(tag = "困难补助申请", msg = "重新提交申请,填写人: ${args[0].proxyUserName}")
public Result submitAgain(@Param("data") DifficultHelpInfo difficultHelpInfo, @Param("taskId") Long taskId) {
difficultHelpInfo.setApplyTime(ObjectUtil.defaultIfNull(difficultHelpInfo.getApplyTime(), new Date()));
difficultHelpCommonService.refreshApplyCount(difficultHelpInfo);
if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) {
return Result.error("该人员本年度已申请困难帮扶,不能重复申请");
}
dao.insertOrUpdate(difficultHelpInfo);
Dict dict = Dict.create();
@@ -7,6 +7,7 @@ import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPag
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.upload.TempFile;
import java.util.Date;
import java.util.List;
/**
@@ -26,4 +27,21 @@ public interface DifficultHelpCommonService extends BaseService<DifficultHelpInf
NutMap handlingMoneyImport(TempFile file, Boolean isFlag);
List<NutMap> getYearPayList(DifficultHelpPageParam pageForm);
/**
* 校验同一受补助人同一年是否已存在申请记录。
*
* @param userId 受补助人id
* @param applyTime 申请时间
* @param excludeRecordId 排除的当前记录id,编辑/重新提交时使用
* @return true 已存在同年申请记录
*/
boolean hasAppliedInYear(String userId, Date applyTime, String excludeRecordId);
/**
* 新申请时按历史总申请次数重新计算申请次数字段,已有记录则保留原值。
*
* @param difficultHelpInfo 申请信息
*/
void refreshApplyCount(DifficultHelpInfo difficultHelpInfo);
}
@@ -50,6 +50,38 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
@Inject
private ManyAddOrRenewUtil manyAddOrRenewUtil;
@Override
public boolean hasAppliedInYear(String userId, Date applyTime, String excludeRecordId) {
if (StrUtil.isBlank(userId) || applyTime == null) {
return false;
}
Cnd cnd = Cnd.where("userId", "=", userId);
cnd.and("YEAR(applyTime)", "=", DateUtil.year(applyTime));
if (StrUtil.isNotBlank(excludeRecordId)) {
cnd.and("id", "<>", excludeRecordId);
}
// 按受补助人和申请年份校验,确保同一个人每年只能保留一条申请记录。
return dao().count(DifficultHelpInfo.class, cnd) > 0;
}
@Override
public void refreshApplyCount(DifficultHelpInfo difficultHelpInfo) {
if (difficultHelpInfo == null || StrUtil.isBlank(difficultHelpInfo.getUserId())) {
return;
}
if (StrUtil.isNotBlank(difficultHelpInfo.getId())) {
DifficultHelpInfo dbInfo = dao().fetch(DifficultHelpInfo.class, difficultHelpInfo.getId());
if (dbInfo != null) {
// 已存在的申请记录沿用原申请次数,避免编辑或重新提交时重复累加。
difficultHelpInfo.setApplyCount(dbInfo.getApplyCount());
return;
}
}
int historyApplyCount = dao().count(DifficultHelpInfo.class, Cnd.where("userId", "=", difficultHelpInfo.getUserId()));
// 新申请记录按历史总申请次数 + 1 重新计算申请次数,不使用前端传入值。
difficultHelpInfo.setApplyCount(historyApplyCount + 1);
}
@Override
public List<NutMap> getYearPayList(DifficultHelpPageParam pageForm) {
// 1. 生成年份列表