diff --git a/src/main/java/io/v/nutz/sickHelp/controller/SickHelpMedicalInsController.java b/src/main/java/io/v/nutz/sickHelp/controller/SickHelpMedicalInsController.java index a105ba7..c5bcd13 100644 --- a/src/main/java/io/v/nutz/sickHelp/controller/SickHelpMedicalInsController.java +++ b/src/main/java/io/v/nutz/sickHelp/controller/SickHelpMedicalInsController.java @@ -12,12 +12,16 @@ import cn.hutool.core.util.StrUtil; import cn.wizzer.framework.base.Result; import io.v.nutz.base.page.Pagination; import io.v.nutz.modules.models.PageForm; +import io.v.nutz.sickHelp.constant.SickHelpStateEnum; +import io.v.nutz.sickHelp.model.SickFundMember; import io.v.nutz.sickHelp.model.SickHelp; import io.v.nutz.sickHelp.model.SickHelpMedicalIns; import io.v.nutz.sickHelp.service.SickHelpImportService; +import io.v.nutz.sys.models.User; import io.v.nutz.sys.services.SysUserService; import io.v.nutz.util.ViTool; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; @@ -371,6 +375,196 @@ public class SickHelpMedicalInsController { return Result.success(list); } + /** + * 查询可重新关联的大病互助会员。 + */ + @At + @RequiresPermissions(value = {"sickHelp.medicalIns", "sickHelp.list"}, logical = Logical.OR) + public Result queryRebindUser(String query) { + Sql sql = Sqls.create(""" + SELECT + m.loginName AS loginname, + m.userName AS username, + COALESCE(NULLIF(u.birthday, ''), m.birthday) AS birthday, + COALESCE(NULLIF(u.unitname, ''), m.unitName) AS unitname, + COALESCE(NULLIF(u.idcard, ''), m.idcard) AS idcard + FROM sick_fund_member m + LEFT JOIN `user` u ON u.loginname = m.loginName + $condition + LIMIT 0,20 + """); + Cnd cnd = Cnd.NEW(); + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("m.loginName", query); + seg.orLike("m.userName", query); + seg.orLike("m.idcard", query); + seg.orLike("u.idcard", query); + cnd.and(seg); + sql.setCondition(cnd); + List list = sysUserService.listMap(sql); + return Result.success(list); + } + + /** + * 获取重新关联人员所需的医保数据。 + */ + @At + @RequiresPermissions(value = {"sickHelp.medicalIns", "sickHelp.list"}, logical = Logical.OR) + public Result findRebindSource(String medicalInsId, Integer year, String loginName) { + SickHelpMedicalIns medicalIns = null; + if (StrUtil.isNotBlank(medicalInsId)) { + medicalIns = dao.fetch(SickHelpMedicalIns.class, medicalInsId); + } else if (year != null && StrUtil.isNotBlank(loginName)) { + List list = dao.query(SickHelpMedicalIns.class, + Cnd.where("year", "=", year).and("loginName", "=", StrUtil.trim(loginName))); + if (list.size() > 1) { + return Result.error("该年度、工号存在多条医保数据,请先核对"); + } + if (!list.isEmpty()) { + medicalIns = list.get(0); + } + } + if (medicalIns == null) { + return Result.error("未找到对应的医保数据"); + } + return Result.success(medicalIns); + } + + /** + * 重新关联医保人员,并同步处理尚未进入审核流程的补助台账。 + */ + @At + @RequiresPermissions(value = {"sickHelp.medicalIns", "sickHelp.list"}, logical = Logical.OR) + @Aop(TransAop.READ_COMMITTED) + public Result rebindUser(String medicalInsId, String loginName, String ecbx) { + if (StrUtil.isBlank(medicalInsId)) { + return Result.error("医保数据id为空"); + } + if (StrUtil.isBlank(loginName)) { + return Result.error("请选择需要重新关联的人员"); + } + if (StrUtil.isBlank(ecbx)) { + return Result.error("请输入正确的学校二次报销金额"); + } + + BigDecimal ecbxMoney; + try { + ecbxMoney = new BigDecimal(StrUtil.trim(ecbx)); + } catch (NumberFormatException e) { + return Result.error("学校二次报销金额格式不正确"); + } + if (ecbxMoney.compareTo(BigDecimal.ZERO) < 0) { + return Result.error("学校二次报销金额不能小于0"); + } + + SickHelpMedicalIns medicalIns = dao.fetch(SickHelpMedicalIns.class, medicalInsId); + if (medicalIns == null) { + return Result.error("医保数据不存在或已被删除"); + } + if (medicalIns.getYear() == null || medicalIns.getSxzf() == null || medicalIns.getLxzf() == null) { + return Result.error("医保年度或金额不完整,请先核对医保数据"); + } + if (ecbxMoney.compareTo(medicalIns.getSxzf()) > 0) { + return Result.error("学校二次报销金额不能大于医保四项之和"); + } + + String targetLoginName = StrUtil.trim(loginName); + SickFundMember targetMember = dao.fetch(SickFundMember.class, + Cnd.where("loginName", "=", targetLoginName)); + if (targetMember == null) { + return Result.error("所选人员不在大病互助会员库中"); + } + User targetUser = dao.fetch(User.class, Cnd.where("loginname", "=", targetLoginName)); + String targetUserName = StrUtil.isNotBlank(targetMember.getUserName()) + ? targetMember.getUserName() + : targetUser == null ? null : targetUser.getUsername(); + if (StrUtil.isBlank(targetUserName)) { + return Result.error("所选人员姓名为空,请先维护人员数据"); + } + + String targetIdCard = targetUser != null && StrUtil.isNotBlank(targetUser.getIdcard()) + ? targetUser.getIdcard() : targetMember.getIdcard(); + String medicalIdCard = normalizeIdCard(medicalIns.getIdCard()); + String normalizedTargetIdCard = normalizeIdCard(targetIdCard); + if (StrUtil.isNotBlank(medicalIdCard) && StrUtil.isNotBlank(normalizedTargetIdCard) + && !medicalIdCard.equals(normalizedTargetIdCard)) { + return Result.error("医保身份证号与所选人员身份证号不一致,禁止重新关联"); + } + + SickHelpMedicalIns sameMedicalIns = dao.fetch(SickHelpMedicalIns.class, + Cnd.where("year", "=", medicalIns.getYear()) + .and("loginName", "=", targetLoginName) + .and("id", "!=", medicalIns.getId())); + if (sameMedicalIns != null) { + return Result.error("所选人员本年度已有医保数据,禁止重复关联"); + } + + String oldLoginName = StrUtil.trim(medicalIns.getLoginName()); + SickHelp oldSickHelp = StrUtil.isBlank(oldLoginName) ? null + : dao.fetch(SickHelp.class, Cnd.where("year", "=", medicalIns.getYear()) + .and("loginName", "=", oldLoginName)); + if (oldSickHelp != null + && (!SickHelpStateEnum.DTJ.getStateCode().equals(oldSickHelp.getStateCode()) + || Boolean.TRUE.equals(oldSickHelp.getIsMeetRequirements()) + || Boolean.TRUE.equals(oldSickHelp.getIsAccept()))) { + return Result.error("原补助记录已进入申请或审核流程,不能直接重新关联人员"); + } + + SickHelp targetSickHelp = dao.fetch(SickHelp.class, + Cnd.where("year", "=", medicalIns.getYear()).and("loginName", "=", targetLoginName)); + if (targetSickHelp != null && (oldSickHelp == null || !targetSickHelp.getId().equals(oldSickHelp.getId()))) { + return Result.error("所选人员本年度已有补助记录,禁止重复关联"); + } + + BigDecimal selfPayMoney = medicalIns.getSxzf().subtract(ecbxMoney); + SickHelp calculatedSickHelp = null; + if (selfPayMoney.compareTo(BigDecimal.valueOf(10000)) > 0) { + SickHelp sickHelp = new SickHelp(); + sickHelp.setYear(medicalIns.getYear()); + sickHelp.setLoginName(targetLoginName); + sickHelp.setUserName(targetUserName); + sickHelp.setMedicalFourTotalMoney(medicalIns.getSxzf()); + sickHelp.setSelfPayTotalMoney(medicalIns.getLxzf()); + sickHelp.setSchoolSecondSubsidyMoney(ecbxMoney); + sickHelp.setSelfPayMoney(selfPayMoney); + calculatedSickHelp = sickHelpImportService.checkData(List.of(sickHelp)).get(0); + if (!Boolean.TRUE.equals(calculatedSickHelp.getValid())) { + return Result.error(String.join("、", calculatedSickHelp.getValidMsg())); + } + } + + medicalIns.setLoginName(targetLoginName); + medicalIns.setUserName(targetUserName); + medicalIns.setEcbx(ecbxMoney); + medicalIns.setCalc(calculatedSickHelp == null || calculatedSickHelp.getSubsidyMoney() == null + ? BigDecimal.ZERO : calculatedSickHelp.getSubsidyMoney()); + dao.update(medicalIns, "loginName|userName|ecbx|calc"); + + if (oldSickHelp != null) { + dao.delete(SickHelp.class, oldSickHelp.getId()); + } + if (calculatedSickHelp != null) { + calculatedSickHelp.setId(null); + calculatedSickHelp.setStateCode(SickHelpStateEnum.DTJ.getStateCode()); + dao.insert(calculatedSickHelp); + } + + if (calculatedSickHelp == null) { + return Result.success("重新关联成功;修正后的个人支付金额不超过10000元,原补助汇总已删除"); + } + return Result.success("重新关联成功;补助汇总已按正确人员重新计算"); + } + + /** + * 身份证号标准化,避免空格和字母大小写导致匹配失败。 + */ + private String normalizeIdCard(String idCard) { + if (StrUtil.isBlank(idCard)) { + return null; + } + return idCard.replaceAll("\\s+", "").toUpperCase(); + } + /** * 检查是否还有错误的医保数据 diff --git a/src/main/resources/views/platform/sickHelp/list/index.html b/src/main/resources/views/platform/sickHelp/list/index.html index ed0886f..674c3d7 100644 --- a/src/main/resources/views/platform/sickHelp/list/index.html +++ b/src/main/resources/views/platform/sickHelp/list/index.html @@ -181,8 +181,9 @@ layout("/layouts/platform.html"){ - + @@ -257,12 +258,18 @@ layout("/layouts/platform.html"){ +