From 63e2091cbba8dd194a23dd45808c1901441834dc Mon Sep 17 00:00:00 2001 From: zhouhefeng Date: Thu, 7 May 2026 10:27:43 +0800 Subject: [PATCH] commit --- .../FlowUnitPartySecretaryHandler.java | 71 ++++++++++--------- .../UnionReimburseApplyController.java | 2 +- .../UnionReimburseReviewController.java | 18 +---- .../service/UnionReimburseService.java | 10 ++- .../impl/UnionReimburseServiceImpl.java | 28 +++++++- .../unionReimburse/apply/index.html | 39 +++++----- .../unionReimburse/review/index.html | 57 ++++++++++----- 7 files changed, 132 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/budwk/app/flow/handler/FlowUnitPartySecretaryHandler.java b/src/main/java/com/budwk/app/flow/handler/FlowUnitPartySecretaryHandler.java index 9b71421c..7c2a3fdb 100644 --- a/src/main/java/com/budwk/app/flow/handler/FlowUnitPartySecretaryHandler.java +++ b/src/main/java/com/budwk/app/flow/handler/FlowUnitPartySecretaryHandler.java @@ -26,44 +26,45 @@ import java.util.List; */ public class FlowUnitPartySecretaryHandler implements AssignmentHandler { - @Override - public List assign(TaskModel model, Execution execution) { - String unitId = SecurityUtil.getUnitId(); + @Override + public List assign(TaskModel model, Execution execution) { + String unitId = SecurityUtil.getUnitId(); - SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); - Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY); + SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); + Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY); - View_user user = ServiceContext.find(Dao.class).fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId())); - List roles; - if(user.getUnionName().contains("行政")){ - List unitList = ServiceContext.find(Dao.class).query(Sys_unit.class, Cnd.where(Sys_unit::getUnionId, "=", user.getUnionId())); - List unitIds = unitList.stream().map(Sys_unit::getId).toList(); - roles = ServiceContext.find(Dao.class).query( - Sys_user_role.class, - Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) - .and(Sys_user_role::getUnitId, "in", unitIds) - ); - }else{ - roles = ServiceContext.find(Dao.class).query( - Sys_user_role.class, - Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) - .and(Sys_user_role::getUnitId, "=", unitId) - ); - } + View_user user = ServiceContext.find(Dao.class).fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId())); + List roles; - if (Lang.isEmpty(roles)) { - throw new RuntimeException("当前登录用户所在单位未设置单位党委书记,请联系校工会进行设置。"); - } - return roles.stream().map(Sys_user_role::getUserId).toList(); - } + roles = ServiceContext.find(Dao.class).query( + Sys_user_role.class, + Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) + .and(Sys_user_role::getUnitId, "=", unitId) + ); - @Override - public String getMessage() { - return "获取当前登录用户所在单位党委书记,若是行政就找出行政分下的党委书记。因为行政只有一个党委书记"; - } + if (Lang.isEmpty(roles)) { + List unitList = ServiceContext.find(Dao.class).query(Sys_unit.class, Cnd.where(Sys_unit::getUnionId, "=", user.getUnionId())); + List unitIds = unitList.stream().map(Sys_unit::getId).toList(); + roles = ServiceContext.find(Dao.class).query( + Sys_user_role.class, + Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) + .and(Sys_user_role::getUnitId, "in", unitIds) + ); + } - @Override - public int getOrder() { - return AssignmentHandler.super.getOrder(); - } + if (Lang.isEmpty(roles)) { + throw new RuntimeException("当前登录用户所在单位未设置单位党委书记,请联系校工会进行设置。"); + } + return roles.stream().map(Sys_user_role::getUserId).toList(); + } + + @Override + public String getMessage() { + return "获取当前登录用户所在单位党委书记"; + } + + @Override + public int getOrder() { + return AssignmentHandler.super.getOrder(); + } } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseApplyController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseApplyController.java index 644cee4b..10254b56 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseApplyController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseApplyController.java @@ -268,6 +268,6 @@ public class UnionReimburseApplyController { @ApiOperation("统一查询经费余额") @SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR) public Result getBudgetBalance(String reimburseFundSource, String clubId) { - return unionReimburseService.getBudgetBalance(reimburseFundSource, clubId); + return unionReimburseService.getBudgetBalance(reimburseFundSource, clubId, null); } } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseReviewController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseReviewController.java index a6d6de41..3965528d 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseReviewController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/controller/UnionReimburseReviewController.java @@ -12,7 +12,6 @@ import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse; import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService; 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; @@ -32,7 +31,6 @@ import java.util.List; @At("/platform/unionReimburse/review") @Ok("json:full") @Api("工会报销审核") -@Slf4j public class UnionReimburseReviewController { @Inject @@ -110,19 +108,7 @@ public class UnionReimburseReviewController { @Aop(TransAop.READ_COMMITTED) @SaCheckPermission(value = {"unionReimburse.review", "h5.unionReimburse.review"}, mode = SaMode.OR) @SLog(tag = "工会报销审核", msg = "一键审核工会报销") - public Result allReview() { - try { - List reimbursements = unionReimburseService.query(Cnd.where("stateId", "=", 2)); - for (UnionReimburse reimbursement : reimbursements) { - Result result = unionReimburseService.reviewApply(reimbursement.getId(), "通过", 3); - if (result.getCode() != 0) { - return result; - } - } - return Result.success("一键审核完成,共处理" + reimbursements.size() + "条记录"); - } catch (Exception e) { - log.error("一键审核失败", e); - return Result.error("一键审核失败: " + e.getMessage()); - } + public Result allReview(@Param("ids[]") String[] ids) { + return unionReimburseService.batchReviewApply(ids); } } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/UnionReimburseService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/UnionReimburseService.java index db5efe78..d2dfdcc5 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/UnionReimburseService.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/UnionReimburseService.java @@ -41,10 +41,18 @@ public interface UnionReimburseService extends BaseService { /** * 查询报销可用经费余额,同时校验是否已分配以及协会归属权限。 */ - Result getBudgetBalance(String reimburseFundSource, String clubId); + Result getBudgetBalance(String reimburseFundSource, String clubId, String unionId); /** * 审核报销,审核通过时扣减对应预算并新增预算使用详情。 */ Result reviewApply(String reimburseId, String reviewOpinion, int submitType); + + /** + * 批量审核选中的待审核报销申请。 + * + * @param reimburseIds 前端表格勾选的报销申请ID数组,只处理状态为待审核确认的数据 + * @return Result,成功时返回本次实际审核通过的记录数量,失败时返回具体错误原因 + */ + Result batchReviewApply(String[] reimburseIds); } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/impl/UnionReimburseServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/impl/UnionReimburseServiceImpl.java index 6d42fe24..24dcb0c3 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/impl/UnionReimburseServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/unionReimburse/service/impl/UnionReimburseServiceImpl.java @@ -244,7 +244,7 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl i * 按经费来源统一查询当前可用余额,未分配或权限不匹配时直接拦截。 */ @Override - public Result getBudgetBalance(String reimburseFundSource, String clubId) { + public Result getBudgetBalance(String reimburseFundSource, String clubId, String unionId) { if (StrUtil.isBlank(reimburseFundSource)) { return Result.error("请选择经费来源"); } @@ -257,8 +257,9 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl i return Result.success(formatMoney(outlayManageSchool.getTotalQuota().subtract(outlayManageSchool.getUsedQuota()))); } if ("UNION_REIMBURSE_FUND_SOURCE_2".equals(reimburseFundSource)) { + String queryUnionId = StrUtil.blankToDefault(unionId, SecurityUtil.getUnionId()); OutlayManageUnion outlayManageUnion = dao().fetch(OutlayManageUnion.class, - Cnd.where("unionId", "=", SecurityUtil.getUnionId()).and("year", "=", DateUtil.thisYear())); + Cnd.where("unionId", "=", queryUnionId).and("year", "=", DateUtil.thisYear())); if (outlayManageUnion == null) { return Result.error("分工会经费未分配"); } @@ -315,6 +316,27 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl i return Result.success(); } + /** + * 批量审核前只查询前端勾选且仍处于待审核确认状态的数据,避免误处理未勾选或状态已变化的申请。 + */ + @Override + public Result batchReviewApply(String[] reimburseIds) { + if (reimburseIds == null || reimburseIds.length == 0) { + return Result.error("请选择需要审核的报销申请"); + } + List reimbursements = this.query(Cnd.where("id", "in", reimburseIds).and("stateId", "=", 2)); + if (reimbursements.isEmpty()) { + return Result.error("所选记录中没有待审核的数据"); + } + for (UnionReimburse reimbursement : reimbursements) { + Result result = this.reviewApply(reimbursement.getId(), "通过", 3); + if (result.getCode() != 0) { + return result; + } + } + return Result.success("一键审核完成,共处理" + reimbursements.size() + "条记录"); + } + private void normalizeInvoiceDetails(UnionReimburse unionReimburse) { if (unionReimburse.getInvoiceDetails() == null) { unionReimburse.setInvoiceDetails(new ArrayList<>()); @@ -426,7 +448,7 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl i * 提交和审核前统一校验预算是否已分配、余额是否充足。 */ private Result validateFundSourceBeforeSubmit(UnionReimburse unionReimburse) { - Result balanceResult = getBudgetBalance(unionReimburse.getReimburseFundSource(), unionReimburse.getClubId()); + Result balanceResult = getBudgetBalance(unionReimburse.getReimburseFundSource(), unionReimburse.getClubId(), unionReimburse.getUnionId()); if (balanceResult == null || balanceResult.getCode() != 0) { return balanceResult == null ? Result.error("经费余额校验失败") : balanceResult; } diff --git a/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/apply/index.html b/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/apply/index.html index b1a3e1a3..f80b5f3e 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/apply/index.html +++ b/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/apply/index.html @@ -319,26 +319,6 @@ layout("/layouts/platform.html"){ - - - - - - - - - - - - - - - - - - - - item.id === this.formData.payer) + if (exists) { + return + } + // 远程下拉编辑回显时需要先补齐当前付款人选项,否则 el-select 只能显示已保存的 id。 + this.payerOptions.push({ + id: this.formData.payer, + userName: this.formData.payerName || "", + loginName: this.formData.payerLoginname || "", + unitName: this.formData.unitName || "暂无" + }) + }, createRemoteMethod(options) { return (keyword) => { this.selectQueryUser(keyword, options) @@ -1457,6 +1453,9 @@ layout("/layouts/platform.html"){ this.$axios.post("/platform/unionReimburse/apply/info", {id: this.bizId}).then(async (res) => { if (res.code === 0) { this.formData = this.ensureFormData(res.data) + this.appendCurrentPayerOption() + this.getUserBankHistory() + this.reimburseFundSourceChange() await this.selectQueryUser(this.formData.certifierLoginName, this.userOptions) this.rebuildInvoiceSummary() // this.chooseType = this.typeOptions.find(o => o.id === this.formData.type) diff --git a/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/review/index.html b/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/review/index.html index 30dae27b..f9f49f0e 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/review/index.html +++ b/src/main/resources/views/platform/zhgh/dayofficework/unionReimburse/review/index.html @@ -46,13 +46,17 @@ layout("/layouts/platform.html"){ - 一键审核 + 一键审核 已审核 未审核 - + + @@ -115,9 +119,9 @@ layout("/layouts/platform.html"){ 取消 - 退回到发起人 - 拒绝申请 - 同意申请 + 退回到发起人 + 拒绝申请 + 同意申请 @@ -144,6 +148,7 @@ layout("/layouts/platform.html"){ }, formData: {}, showApprovalForm: false, + multipleSelection: [], unionOptions: [], unitOptions: [] } @@ -161,23 +166,38 @@ layout("/layouts/platform.html"){ }) }, + handleSelectionChange(val) { + this.multipleSelection = val + }, + AllReview() { - this.$confirm('确定所选申请都已通过线下审核了吗?', '提示', { + if (!this.multipleSelection || this.multipleSelection.length === 0) { + this.$message.warning('请至少选择一条记录进行审核') + return + } + const ids = this.multipleSelection.map((item) => item.id) + this.$confirm('确定所选的 ' + ids.length + ' 条申请都已通过线下审核了吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' - }).then(async () => { - const resp = await $.post("/platform/unionReimburse/review/allReview"); - if (resp && resp.code === 0) { - this.pageForm.approval = true - this.pageData(); - this.$message.success(resp.msg || '一键审核成功') - } else { - this.$message.error(resp.msg || '一键审核失败') - } + }).then(() => { + this.formLoading = true + this.$axios.post("/platform/unionReimburse/review/allReview", { + ids: ids + }).then((res) => { + if (res.code === 0) { + this.multipleSelection = [] + this.pageData() + this.$message.success(res.msg || '一键审核成功') + } else { + this.$message.error(res.msg || '一键审核失败') + } + }).finally(() => { + this.formLoading = false + }) }).catch(() => { // 用户取消操作 - }); + }) }, openAudit(row) { @@ -199,8 +219,9 @@ layout("/layouts/platform.html"){ cancelButtonText: "取消", type: "warning" }).then(() => { + this.formLoading = true this.$axios.post("/platform/unionReimburse/review/reviewTask", { - data: JSON.stringify({...this.formData}), + data: JSON.stringify(Object.assign({}, this.formData)), submitType: val }).then((res) => { if (res.code === 0) { @@ -208,6 +229,8 @@ layout("/layouts/platform.html"){ this.$message.success(res.msg) this.doSearch() } + }).finally(() => { + this.formLoading = false }) }) }