From a17140fbd24b883839a921f5c57aa56925ebf229 Mon Sep 17 00:00:00 2001 From: zhangrui Date: Thu, 23 Jul 2026 11:57:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BB=E7=96=97=E4=BA=92=E5=8A=A9=E8=A1=A5?= =?UTF-8?q?=E5=8A=A9=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sms/impl/jshvc/SmsJshvcServiceImpl.java | 13 +- .../MedicalMutualAidApplyFormController.java | 86 ++ .../MedicalMutualAidAuditController.java | 127 +++ .../MedicalMutualAidMineApplyController.java | 143 +++ .../MedicalMutualAidSummaryController.java | 71 ++ .../apply/model/MutualApply.java | 269 +++++ .../apply/model/MutualApplySubsidy.java | 86 ++ .../service/MedicalMutualAidApplyService.java | 130 +++ .../MedicalMutualAidApplyServiceImpl.java | 999 ++++++++++++++++++ .../MedicalMutualAidConfigController.java | 158 +++ .../config/model/MutualBonus.java | 48 + .../config/model/MutualConfig.java | 97 ++ .../config/model/MutualMemberConfig.java | 35 + .../config/model/MutualRatio.java | 58 + .../MedicalMutualAidConfigService.java | 109 ++ .../MedicalMutualAidConfigServiceImpl.java | 263 +++++ .../MedicalDiseaseTypeController.java | 76 ++ .../H5MedicalDiseaseTypeController.java | 76 ++ .../medical/model/MedicalDiseaseType.java | 52 + .../service/MedicalDiseaseTypeService.java | 36 + .../impl/MedicalDiseaseTypeServiceImpl.java | 67 ++ .../db/medical_disease_type_create.sql | 15 + .../db/medical_mutual_apply_create.sql | 71 ++ .../menu/init_medical_disease_type_menu.sql | 51 + .../medical_mutual_aid_apply_form.docx | Bin 0 -> 13492 bytes .../~$dical_mutual_aid_apply_form.docx | Bin 0 -> 162 bytes .../medicalMutualAid/apply/audit/index.html | 221 ++++ .../medicalMutualAid/apply/audit/review.html | 275 +++++ .../medicalMutualAid/apply/form/index.html | 258 +++++ .../medicalMutualAid/apply/mine/form.html | 281 +++++ .../medicalMutualAid/apply/mine/index.html | 213 ++++ .../medicalMutualAid/apply/summary/index.html | 200 ++++ .../medicalMutualAid/config/index.html | 689 ++++++++++++ .../medical/diseaseType/index.html | 131 +++ .../medical/diseaseType/index.html | 210 ++++ 35 files changed, 5607 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidApplyFormController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidAuditController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidMineApplyController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidSummaryController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApply.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApplySubsidy.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/MedicalMutualAidApplyService.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/impl/MedicalMutualAidApplyServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/controller/MedicalMutualAidConfigController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualBonus.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualConfig.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualMemberConfig.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualRatio.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/MedicalMutualAidConfigService.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/impl/MedicalMutualAidConfigServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDiseaseTypeController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/h5controller/H5MedicalDiseaseTypeController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/model/MedicalDiseaseType.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDiseaseTypeService.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDiseaseTypeServiceImpl.java create mode 100644 src/main/resources/db/medical_disease_type_create.sql create mode 100644 src/main/resources/db/medical_mutual_apply_create.sql create mode 100644 src/main/resources/db/menu/init_medical_disease_type_menu.sql create mode 100644 src/main/resources/templates/medicalMutualAid/medical_mutual_aid_apply_form.docx create mode 100644 src/main/resources/templates/medicalMutualAid/~$dical_mutual_aid_apply_form.docx create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/review.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/form/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/form.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/summary/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/config/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html create mode 100644 src/main/resources/views/platform/zhghh5/staffbenefit/medicalMutualAid/medical/diseaseType/index.html diff --git a/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java b/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java index 9b31e3f..1827742 100644 --- a/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java +++ b/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java @@ -27,14 +27,13 @@ import java.util.Map; @IocBean public class SmsJshvcServiceImpl implements SmsService { - private static final String APPID = "1430576717768122368"; - private static final String APP_SECRET = "19A0ACB03FBQHL4R4XQD"; - private static final String TOKEN_URL = "https://gateway.jshvc.edu.cn/token/gateway/accessToken"; - private static final String MSG_URL = "https://gateway.jshvc.edu.cn/mp/restful/v2/message/send"; - private static final String REDIS_KEY_MSG_ACCESS_TOKEN = "msg:token:"; + private static final String APPID = ""; + private static final String APP_SECRET = ""; + private static final String TOKEN_URL = ""; + private static final String MSG_URL = ""; + private static final String REDIS_KEY_MSG_ACCESS_TOKEN = ""; - - @Inject + @Inject private RedisService redisService; @Override diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidApplyFormController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidApplyFormController.java new file mode 100644 index 0000000..c86a776 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidApplyFormController.java @@ -0,0 +1,86 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model.MutualApply; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.MedicalMutualAidApplyService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +/** + * 互助金申请页面控制器,负责申请表单页面入口和表单保存、提交接口。 + */ +@IocBean +@At("/platform/medicalMutualAid/apply") +@Api("互助金申请") +@Ok("json:full") +public class MedicalMutualAidApplyFormController { + + @Inject + private MedicalMutualAidApplyService medicalMutualAidApplyService; + + /** + * 打开互助金申请页面。 + */ + @At("/form") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/form/index.html") + @SaCheckPermission("medicalMutualAid.apply.form") + public void index() { + } + + /** + * 查询申请页初始化数据。 + * + * @return 当前用户占位信息和疾病下拉数据 + */ + @At("/form/initApplyData") + @ApiOperation("查询互助金申请初始化数据") + @SaCheckPermission("medicalMutualAid.apply.form") + public Result initApplyData() { + return Result.success(medicalMutualAidApplyService.initApplyData()); + } + + /** + * 查询申请详情,用于我的申请查看和编辑复用申请表单页面。 + * + * @param id 申请ID + * @return 申请主表详情 + */ + @At("/form/detail") + @ApiOperation("查询互助金申请详情") + @SaCheckPermission("medicalMutualAid.apply.form") + public Result detail(@Param("id") Long id) { + return Result.success(medicalMutualAidApplyService.applyDetail(id)); + } + + /** + * 保存草稿。 + * + * @param apply 申请表单 + * @return 保存后的申请数据 + */ + @At("/form/saveDraft") + @ApiOperation("保存互助金申请草稿") + @SaCheckPermission("medicalMutualAid.apply.form") + public Result saveDraft(MutualApply apply) { + return Result.success(medicalMutualAidApplyService.saveApply(apply, false)); + } + + /** + * 提交申请。 + * + * @param apply 申请表单 + * @return 提交后的申请数据 + */ + @At("/form/submitApply") + @ApiOperation("提交互助金申请") + @SaCheckPermission("medicalMutualAid.apply.form") + public Result submitApply(MutualApply apply) { + return Result.success(medicalMutualAidApplyService.saveApply(apply, true)); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidAuditController.java new file mode 100644 index 0000000..8011362 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidAuditController.java @@ -0,0 +1,127 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.MedicalMutualAidApplyService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * 互助会审核控制器,负责审核列表、审核详情页面入口以及审核相关接口。 + */ +@IocBean +@At("/platform/medicalMutualAid/apply") +@Api("互助会审核") +@Ok("json:full") +public class MedicalMutualAidAuditController { + + @Inject + private MedicalMutualAidApplyService medicalMutualAidApplyService; + + /** + * 打开互助会审核列表页面。 + */ + @At("/audit") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/index.html") + @SaCheckPermission("medicalMutualAid.apply.audit") + public void index() { + } + + /** + * 查询互助会审核列表。 + * + * @param pageForm 分页参数 + * @param keyword 申请人工号或申请人姓名 + * @param diseaseName 大病名称 + * @param status 审核状态 + * @return 审核分页数据 + */ + @At("/audit/page") + @ApiOperation("查询互助会审核列表") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result page(PageForm pageForm, String keyword, String diseaseName, Integer status) { + return Result.success(medicalMutualAidApplyService.auditPage(pageForm, keyword, diseaseName, status)); + } + + /** + * 打开互助会审核详情页面。 + */ + @At("/audit/review") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/review.html") + @SaCheckPermission("medicalMutualAid.apply.audit") + public void review() { + } + + /** + * 查询审核详情。 + * + * @param id 申请ID + * @return 审核详情和动态补助明细 + */ + @At("/audit/review/detail") + @ApiOperation("查询互助会审核详情") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result detail(Long id) { + return Result.success(medicalMutualAidApplyService.auditDetail(id)); + } + + /** + * 审核通过。 + * + * @param id 申请ID + * @param bonusRatio 补助系数 + * @param actualSubsidyAmount 实际补助金额 + * @param remark 审核备注 + * @return 审核后的详情数据 + */ + @At("/audit/review/approve") + @ApiOperation("互助会审核通过") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result approve(Long id, String bonusRatio, String actualSubsidyAmount, String remark) { + return Result.success(medicalMutualAidApplyService.approve(id, bonusRatio, actualSubsidyAmount, remark)); + } + + /** + * 弃审已审核申请,恢复为未审核状态并清理审核补助结果。 + * + * @param id 申请ID + * @return 弃审后的申请数据 + */ + @At("/audit/cancelAudit") + @ApiOperation("互助会弃审") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result cancelAudit(Long id) { + return Result.success(medicalMutualAidApplyService.cancelAudit(id)); + } + + /** + * 作废未审核申请,状态置为作废并记录审核人和审核时间。 + * + * @param id 申请ID + * @return 作废后的申请数据 + */ + @At("/audit/discard") + @ApiOperation("互助会作废") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result discard(Long id) { + return Result.success(medicalMutualAidApplyService.discard(id)); + } + + /** + * 取消作废申请,状态恢复为未审核并清空审核人和审核时间。 + * + * @param id 申请ID + * @return 取消作废后的申请数据 + */ + @At("/audit/cancelDiscard") + @ApiOperation("互助会取消作废") + @SaCheckPermission("medicalMutualAid.apply.audit") + public Result cancelDiscard(Long id) { + return Result.success(medicalMutualAidApplyService.cancelDiscard(id)); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidMineApplyController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidMineApplyController.java new file mode 100644 index 0000000..3878f52 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidMineApplyController.java @@ -0,0 +1,143 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model.MutualApply; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.MedicalMutualAidApplyService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.lang.util.NutMap; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; + +/** + * 我的申请页面控制器,负责个人申请列表页面入口和分页查询接口。 + */ +@IocBean +@At("/platform/medicalMutualAid/apply") +@Api("我的互助金申请") +@Ok("json:full") +public class MedicalMutualAidMineApplyController { + + @Inject + private MedicalMutualAidApplyService medicalMutualAidApplyService; + + /** + * 打开我的申请页面。 + */ + @At("/mine") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/index.html") + @SaCheckPermission("medicalMutualAid.apply.mine") + public void index() { + } + + /** + * 打开我的申请查看/编辑页面,页面入口独立于新增申请页,避免新增逻辑与个人记录维护逻辑互相影响。 + */ + @At("/mine/form") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/form.html") + @SaCheckPermission("medicalMutualAid.apply.mine") + public void form() { + } + + /** + * 查询我的申请维护页初始化数据,当前主要用于加载疾病类型下拉。 + * + * @return 页面初始化数据 + */ + @At("/mine/form/initApplyData") + @ApiOperation("查询我的互助金申请维护页初始化数据") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result initApplyData() { + return Result.success(medicalMutualAidApplyService.initApplyData()); + } + + /** + * 查询我的申请详情,供个人查看和编辑页面回显使用。 + * + * @param id 申请ID + * @return 申请详情 + */ + @At("/mine/form/detail") + @ApiOperation("查询我的互助金申请详情") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result detail(@Param("id") Long id) { + return Result.success(medicalMutualAidApplyService.applyDetail(id)); + } + + /** + * 保存我的申请草稿,复用申请服务保存逻辑但使用我的申请权限入口。 + * + * @param apply 申请表单 + * @return 保存后的申请数据 + */ + @At("/mine/form/saveDraft") + @ApiOperation("保存我的互助金申请草稿") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result saveDraft(MutualApply apply) { + return Result.success(medicalMutualAidApplyService.saveApply(apply, false)); + } + + /** + * 提交我的申请修改,提交后仍进入未审核状态等待审核。 + * + * @param apply 申请表单 + * @return 提交后的申请数据 + */ + @At("/mine/form/submitApply") + @ApiOperation("提交我的互助金申请") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result submitApply(MutualApply apply) { + return Result.success(medicalMutualAidApplyService.saveApply(apply, true)); + } + + /** + * 查询我的申请列表。 + * + * @param pageForm 分页参数 + * @param diseaseName 大病名称 + * @return 我的申请分页数据 + */ + @At("/mine/page") + @ApiOperation("查询我的互助金申请") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result page(PageForm pageForm, String diseaseName) { + return Result.success(medicalMutualAidApplyService.minePage(pageForm, diseaseName)); + } + + /** + * 查询我的申请列表,兼容平台通用 initTableMixins 的默认分页接口命名。 + * + * @param pageForm 分页与查询参数 + * @param diseaseName 大病名称 + * @return 我的申请分页数据 + */ + @At("/mine/pageData") + @ApiOperation("查询我的互助金申请") + @SaCheckPermission("medicalMutualAid.apply.mine") + public Result pageData(PageForm pageForm, String diseaseName) { + return Result.success(medicalMutualAidApplyService.minePage(pageForm, diseaseName)); + } + + /** + * 导出我的申请单,Word 模板来源于系统模板管理,模板编码为 medical_mutual_aid_apply_form。 + * + * @param id 申请ID + * @param response HTTP响应 + */ + @At("/mine/exportApplyForm") + @Ok("void") + @ApiOperation("导出我的大病医疗互助金申请单") + @SaCheckPermission("medicalMutualAid.apply.mine") + public void exportApplyForm(@Param("id") Long id, HttpServletResponse response) { + NutMap exportData = medicalMutualAidApplyService.exportMineApplyForm(id); + CommonDownloadUtil.download(exportData.getString("fileName"), (byte[]) exportData.get("bytes"), response); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidSummaryController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidSummaryController.java new file mode 100644 index 0000000..94c7e4a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/controller/MedicalMutualAidSummaryController.java @@ -0,0 +1,71 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.MedicalMutualAidApplyService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.servlet.http.HttpServletResponse; + +/** + * 医疗互助汇总控制器,负责汇总页面入口和审核通过数据的汇总查询接口。 + */ +@IocBean +@At("/platform/medicalMutualAid/apply") +@Api("医疗互助汇总") +@Ok("json:full") +public class MedicalMutualAidSummaryController { + + @Inject + private MedicalMutualAidApplyService medicalMutualAidApplyService; + + /** + * 打开医疗互助汇总页面。 + */ + @At("/summary") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/apply/summary/index.html") + @SaCheckPermission("medicalMutualAid.apply.summary") + public void index() { + } + + /** + * 查询医疗互助汇总列表。 + * + * @param pageForm 分页参数 + * @param deptName 所在单位 + * @param userName 姓名 + * @param joinYear 加入年份 + * @return 汇总分页数据 + */ + @At("/summary/page") + @ApiOperation("查询医疗互助汇总") + @SaCheckPermission("medicalMutualAid.apply.summary") + public Result page(PageForm pageForm, String deptName, String userName, Integer joinYear) { + return Result.success(medicalMutualAidApplyService.summaryPage(pageForm, deptName, userName, joinYear)); + } + + /** + * 导出医疗互助汇总,导出列与页面当前展示列保持一致。 + * + * @param deptName 所在单位 + * @param userName 姓名 + * @param joinYear 加入年份 + * @param response HTTP 响应 + */ + @At("/summary/exportExcel") + @Ok("void") + @ApiOperation("导出医疗互助汇总") + @SaCheckPermission("medicalMutualAid.apply.summary") + public void exportExcel(String deptName, String userName, Integer joinYear, HttpServletResponse response) { + Workbook workbook = medicalMutualAidApplyService.exportSummary(deptName, userName, joinYear); + CommonDownloadUtil.download("医疗互助汇总.xlsx", workbook, response); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApply.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApply.java new file mode 100644 index 0000000..d5b69ca --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApply.java @@ -0,0 +1,269 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Default; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.dao.interceptor.annotation.PrevUpdate; + +import java.util.Date; + +/** + * 互助金申请主表实体,承载申请人信息、疾病费用、审核状态和审核后的补助汇总结果。 + */ +@Data +@Table("tb_mutual_apply") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("互助金申请表") +public class MutualApply { + + /** 申请主键,数据库自增生成。 */ + @Id + @Comment("主键") + private Long id; + + /** 申请编号,用于后续查询、打印和业务留痕。 */ + @Column("apply_no") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("申请编号") + private String applyNo; + + /** 申请人用户 ID。 */ + @Column("user_id") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("申请人用户ID") + private String userId; + + /** 申请人工号或登录名。 */ + @Column("login_name") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("申请人工号/登录名") + private String loginName; + + /** 申请人姓名。 */ + @Column("user_name") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("申请人姓名") + private String userName; + + /** 性别。 */ + @Column("sex") + @ColDefine(type = ColType.VARCHAR, width = 20) + @Comment("性别") + private String sex; + + /** 出生年月。 */ + @Column("birthday") + @Comment("出生年月") + private Date birthday; + + /** 籍贯。 */ + @Column("native_place") + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("籍贯") + private String nativePlace; + + /** 学历。 */ + @Column("education") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("学历") + private String education; + + /** 职称。 */ + @Column("professional_title") + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("职称") + private String professionalTitle; + + /** 工作部门 ID。 */ + @Column("dept_id") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("工作部门ID") + private String deptId; + + /** 工作部门名称。 */ + @Column("dept_name") + @ColDefine(type = ColType.VARCHAR, width = 200) + @Comment("工作部门(系部)") + private String deptName; + + /** 身份证号码。 */ + @Column("id_card") + @ColDefine(type = ColType.VARCHAR, width = 30) + @Comment("身份证号码") + private String idCard; + + /** 联系电话。 */ + @Column("mobile") + @ColDefine(type = ColType.VARCHAR, width = 30) + @Comment("联系电话") + private String mobile; + + /** 工资银行卡号。 */ + @Column("bank_card_no") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("工资银行卡号") + private String bankCardNo; + + /** 开户行。 */ + @Column("bank_name") + @ColDefine(type = ColType.VARCHAR, width = 200) + @Comment("开户行") + private String bankName; + + /** 入会时间。 */ + @Column("join_date") + @Comment("入会时间") + private Date joinDate; + + /** 加入年份。 */ + @Column("join_year") + @Comment("加入年份") + private Integer joinYear; + + /** 大病类型 ID,来源于疾病类型档案。 */ + @Column("disease_type_id") + @Comment("大病类型ID") + private String diseaseTypeId; + + /** 大病名称,落表保存历史名称。 */ + @Column("disease_name") + @ColDefine(type = ColType.VARCHAR, width = 200) + @Comment("大病名称") + private String diseaseName; + + /** 何时何病住何医院。 */ + @Column("hospital_desc") + @ColDefine(type = ColType.TEXT) + @Comment("何时何病住何医院") + private String hospitalDesc; + + /** 全年医疗费用总金额。 */ + @Column("medical_total_amount") + @Default("0.00") + @Comment("全年医疗费用总金额") + private Double medicalTotalAmount; + + /** 自付金额。 */ + @Column("self_pay_amount") + @Default("0.00") + @Comment("自付金额") + private Double selfPayAmount; + + /** 申请人签名文件 ID。 */ + @Column("sign_file_id") + @ColDefine(type = ColType.VARCHAR, width = 64) + @Comment("申请人签名文件ID") + private String signFileId; + + /** 申请人签名时间。 */ + @Column("sign_time") + @Comment("申请人签名时间") + private Date signTime; + + /** 申请状态:0 未审核,1 已审核。 */ + @Column("status") + @Default("0") + @Comment("状态 0未审核 1已审核") + private Integer status; + + /** 提交时间。 */ + @Column("submit_time") + @Comment("提交时间") + private Date submitTime; + + /** 审核人。 */ + @Column("audit_by") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("审核人") + private String auditBy; + + /** 审核时间。 */ + @Column("audit_time") + @Comment("审核时间") + private Date auditTime; + + /** 审核意见。 */ + @Column("audit_opinion") + @ColDefine(type = ColType.VARCHAR, width = 500) + @Comment("审核意见") + private String auditOpinion; + + /** 审核使用的配置 ID。 */ + @Column("config_id") + @Comment("审核使用的互助金配置ID") + private Long configId; + + /** 审核使用的配置年度。 */ + @Column("config_year") + @Comment("审核使用的配置年度") + private Integer configYear; + + /** 区间补助小计。 */ + @Column("subsidy_total_amount") + @Comment("补助小计") + private Double subsidyTotalAmount; + + /** 奖励或补助系数。 */ + @Column("bonus_ratio") + @Comment("奖励/补助系数") + private Double bonusRatio; + + /** 实际补助金额。 */ + @Column("actual_subsidy_amount") + @Comment("实际补助金额") + private Double actualSubsidyAmount; + + /** 连续未申请年数。 */ + @Column("continuous_unapply_year") + @Comment("连续未申请年数") + private Integer continuousUnapplyYear; + + /** 本次适用最高补助限额。 */ + @Column("limit_amount") + @Comment("本次适用最高补助限额") + private Double limitAmount; + + /** 当前申报年度同申报人同病种已审核补助金额汇总,仅用于审核页提示展示。 */ + private Double yearUsedAmount; + + /** 当前申报年度同申报人同病种剩余可申报金额,仅用于审核页提示展示。 */ + private Double yearRemainAmount; + + /** 备注。 */ + @Column("remark") + @ColDefine(type = ColType.VARCHAR, width = 500) + @Comment("备注") + private String remark; + + /** 创建人。 */ + @Column("create_by") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("创建人") + private String createBy; + + /** 创建时间。 */ + @Column("create_time") + @PrevInsert(now = true) + @Comment("创建时间") + private Date createTime; + + /** 更新人。 */ + @Column("update_by") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("更新人") + private String updateBy; + + /** 更新时间。 */ + @Column("update_time") + @PrevInsert(now = true) + @PrevUpdate(now = true) + @Comment("更新时间") + private Date updateTime; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApplySubsidy.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApplySubsidy.java new file mode 100644 index 0000000..4ecdfe2 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/model/MutualApplySubsidy.java @@ -0,0 +1,86 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Default; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.Date; + +/** + * 互助金动态补贴金额明细实体,一条申请按配置区间拆分为多条补助计算记录。 + */ +@Data +@Table("tb_mutual_apply_subsidy") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("互助金补贴金额明细表") +public class MutualApplySubsidy { + + /** 补助明细主键。 */ + @Id + @Comment("主键") + private Long id; + + /** 所属申请 ID。 */ + @Column("apply_id") + @Comment("申请ID") + private Long applyId; + + /** 使用的补助比例配置 ID。 */ + @Column("ratio_id") + @Comment("使用的补助比例配置ID") + private Long ratioId; + + /** 页面展示用的区间名称。 */ + @Column("range_name") + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("区间名称") + private String rangeName; + + /** 区间开始金额。 */ + @Column("start_amount") + @Default("0.00") + @Comment("区间开始金额") + private Double startAmount; + + /** 区间结束金额,空表示不设上限。 */ + @Column("end_amount") + @Comment("区间结束金额(NULL表示无限)") + private Double endAmount; + + /** 该区间的补助比例。 */ + @Column("ratio") + @Default("0.00") + @Comment("补助比例(%)") + private Double ratio; + + /** 本区间参与补助计算的金额。 */ + @Column("base_amount") + @Default("0.00") + @Comment("本区间参与计算金额") + private Double baseAmount; + + /** 本区间计算出的补助金额。 */ + @Column("subsidy_amount") + @Default("0.00") + @Comment("本区间补助金额") + private Double subsidyAmount; + + /** 区间排序。 */ + @Column("sort") + @Default("1") + @Comment("排序") + private Integer sort; + + /** 创建时间。 */ + @Column("create_time") + @PrevInsert(now = true) + @Comment("创建时间") + private Date createTime; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/MedicalMutualAidApplyService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/MedicalMutualAidApplyService.java new file mode 100644 index 0000000..5659216 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/MedicalMutualAidApplyService.java @@ -0,0 +1,130 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model.MutualApply; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.lang.util.NutMap; + +/** + * 医疗互助申请服务,统一承载申请、我的申请、审核和汇总页面所需的公共业务方法。 + */ +public interface MedicalMutualAidApplyService extends BaseService { + + /** + * 构建申请页面初始化数据,包含当前用户占位信息和疾病类型下拉数据。 + * + * @return 页面初始化数据 + */ + NutMap initApplyData(); + + /** + * 保存互助金申请,草稿和提交都复用该方法并由 submit 参数控制状态。 + * + * @param apply 互助金申请表单 + * @param submit 是否提交审核 + * @return 保存后的申请数据 + */ + MutualApply saveApply(MutualApply apply, boolean submit); + + /** + * 查询申请表单详情,用于我的申请查看和编辑时回显原始申请数据。 + * + * @param applyId 申请ID + * @return 申请主表数据 + */ + MutualApply applyDetail(Long applyId); + + /** + * 查询我的申请列表。 + * + * @param pageForm 分页参数 + * @param diseaseName 大病名称 + * @return 我的申请分页列表 + */ + Pagination minePage(PageForm pageForm, String diseaseName); + + /** + * 导出我的申请单 Word 文件,模板来源于系统模板管理,参数在服务层统一组装。 + * + * @param applyId 申请ID + * @return 包含 fileName 和 bytes 的导出结果 + */ + NutMap exportMineApplyForm(Long applyId); + + /** + * 查询互助会审核列表。 + * + * @param pageForm 分页参数 + * @param keyword 申请人工号或申请人姓名 + * @param diseaseName 大病名称 + * @param status 审核状态 + * @return 审核分页列表 + */ + Pagination auditPage(PageForm pageForm, String keyword, String diseaseName, Integer status); + + /** + * 查询审核详情并携带动态补助明细。 + * + * @param applyId 申请ID + * @return 审核详情数据 + */ + NutMap auditDetail(Long applyId); + + /** + * 审核通过并保存补助计算结果。 + * + * @param applyId 申请ID + * @param bonusRatio 审核页面录入的补助系数 + * @param actualSubsidyAmount 实际补助金额 + * @param remark 审核备注 + * @return 审核后的详情数据 + */ + NutMap approve(Long applyId, String bonusRatio, String actualSubsidyAmount, String remark); + + /** + * 弃审已审核的互助金申请,将状态恢复为未审核并清理审核结果和补助明细。 + * + * @param applyId 申请ID + * @return 弃审后的申请数据 + */ + MutualApply cancelAudit(Long applyId); + + /** + * 作废未审核的互助金申请,记录作废操作人和操作时间。 + * + * @param applyId 申请ID + * @return 作废后的申请数据 + */ + MutualApply discard(Long applyId); + + /** + * 取消作废互助金申请,将状态恢复为未审核并清空审核人和审核时间。 + * + * @param applyId 申请ID + * @return 取消作废后的申请数据 + */ + MutualApply cancelDiscard(Long applyId); + + /** + * 查询医疗互助汇总列表。 + * + * @param pageForm 分页参数 + * @param deptName 所在单位 + * @param userName 姓名 + * @param joinYear 加入年份 + * @return 汇总分页列表 + */ + Pagination summaryPage(PageForm pageForm, String deptName, String userName, Integer joinYear); + + /** + * 导出医疗互助汇总,导出字段与汇总页面展示列保持一致,动态补助区间按当前查询结果生成。 + * + * @param deptName 所在单位 + * @param userName 姓名 + * @param joinYear 加入年份 + * @return Excel 工作簿 + */ + Workbook exportSummary(String deptName, String userName, Integer joinYear); +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/impl/MedicalMutualAidApplyServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/impl/MedicalMutualAidApplyServiceImpl.java new file mode 100644 index 0000000..7064e6f --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/apply/service/impl/MedicalMutualAidApplyServiceImpl.java @@ -0,0 +1,999 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.SysOfficeTemplateUtil; +import com.budwk.app.zhgh.dayofficework.fund.member.models.FundMemberChangeRecord; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model.MutualApply; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.model.MutualApplySubsidy; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.apply.service.MedicalMutualAidApplyService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualBonus; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualRatio; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddress; +import com.deepoove.poi.XWPFTemplate; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 医疗互助申请服务实现,先搭建申请、审核、计算和汇总的架构入口,细化公式后续可在本类集中调整。 + */ +@IocBean(args = {"refer:dao"}) +public class MedicalMutualAidApplyServiceImpl extends BaseServiceImpl + implements MedicalMutualAidApplyService { + + /** 我的申请单 Word 导出模板编码,对应系统模板管理中的模板代码。 */ + private static final String APPLY_FORM_TEMPLATE_CODE = "medical_mutual_aid_apply_form"; + + @Inject + private SysOfficeTemplateUtil sysOfficeTemplateUtil; + + /** + * 初始化申请服务的数据访问对象。 + * + * @param dao 数据访问对象 + */ + public MedicalMutualAidApplyServiceImpl(Dao dao) { + super(dao); + } + + /** + * 构建申请页面初始数据;当前用户信息先用登录 ID 占位,后续可替换为完整会员档案查询。 + */ + @Override + public NutMap initApplyData() { + List diseaseTypes = dao().query(MedicalDiseaseType.class, Cnd.NEW().asc("diseaseCode")); + return NutMap.NEW() + .addv("user", buildCurrentUserPlaceholder()) + .addv("diseaseTypes", diseaseTypes); + } + + /** + * 保存申请主表,提交时设置未审核状态和提交时间,草稿时仅保存表单内容。 + */ + @Override + public MutualApply saveApply(MutualApply apply, boolean submit) { + if (apply == null) { + throw new BaseException("申请信息不能为空"); + } + // 已有申请只允许未审核状态继续保存,防止已审核或已作废数据被个人端再次修改。 + if (apply.getId() != null) { + MutualApply oldApply = fetch(apply.getId()); + if (oldApply == null) { + throw new BaseException("申请记录不存在"); + } + if (oldApply.getStatus() == null || oldApply.getStatus() != 0) { + throw new BaseException("已审核或已作废的申请不能修改"); + } + } + fillApplyDefaults(apply, submit); + fillOperator(apply); + return insertOrUpdate(apply); + } + + /** + * 查询申请详情,供申请表单在查看和编辑模式下回显。 + */ + @Override + public MutualApply applyDetail(Long applyId) { + if (applyId == null) { + throw new BaseException("申请ID不能为空"); + } + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + return apply; + } + + /** + * 查询我的申请;架构阶段先按当前登录 ID 过滤,未登录时返回全部方便本地页面联调。 + */ + @Override + public Pagination minePage(PageForm pageForm, String diseaseName) { + Cnd cnd = Cnd.NEW(); + String loginId = getLoginId(); + if (StrUtil.isNotBlank(loginId)) { + cnd.and("createBy", "=", loginId); + } + appendDiseaseName(cnd, diseaseName); + return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd.desc("createTime")); + } + + /** + * 使用系统模板管理中的 Word 模板导出个人申请单,模板参数由 buildMineApplyFormDocData 统一维护。 + */ + @Override + public NutMap exportMineApplyForm(Long applyId) { + MutualApply apply = applyDetail(applyId); + assertMineApplyOwner(apply); + Map docData = buildMineApplyFormDocData(apply); + String fileName = StrUtil.blankToDefault(apply.getUserName(), "申请人") + "大病医疗互助金申请表.docx"; + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate(APPLY_FORM_TEMPLATE_CODE)) + .render(docData) + .writeAndClose(byteArrayOutputStream); + return NutMap.NEW() + .addv("fileName", fileName) + .addv("bytes", byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + throw new BaseException("导出大病医疗互助金申请表失败"); + } + } + + /** + * 查询审核列表;支持工号/姓名关键字、疾病类型和审核状态组合筛选。 + */ + @Override + public Pagination auditPage(PageForm pageForm, String keyword, String diseaseName, Integer status) { + Cnd cnd = Cnd.NEW(); + if (StrUtil.isNotBlank(keyword)) { + String keywordText = "%" + StrUtil.trim(keyword) + "%"; + cnd.and(Cnd.exps("loginName", "like", keywordText).or("userName", "like", keywordText)); + } + appendDiseaseName(cnd, diseaseName); + if (status != null) { + cnd.and("status", "=", status); + } + return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd.asc("status").desc("submitTime")); + } + + /** + * 查询审核详情,自动补齐基金会员入会信息,并按本年度启用配置生成补助预览明细。 + */ + @Override + public NutMap auditDetail(Long applyId) { + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + MutualConfig config = fetchEnabledConfig(getApplyYear(apply)); + enrichFundMemberJoinInfo(apply); + fillAuditCalcResult(apply, config); + List subsidies = dao().query(MutualApplySubsidy.class, Cnd.where("applyId", "=", applyId).asc("sort")); + if (subsidies.isEmpty()) { + subsidies = buildSubsidyPreview(apply, config); + } + return NutMap.NEW() + .addv("apply", apply) + .addv("subsidies", subsidies) + .addv("config", config) + .addv("yearUsedAmount", apply.getYearUsedAmount()) + .addv("yearRemainAmount", apply.getYearRemainAmount()) + .addv("yearLimitAmount", apply.getLimitAmount()); + } + + /** + * 审核通过时保存主表汇总结果,并重新落库按本年度启用配置计算出的动态区间补助明细。 + */ + @Override + public NutMap approve(Long applyId, String bonusRatio, String actualSubsidyAmount, String remark) { + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + if (apply.getStatus() == null || apply.getStatus() != 0) { + throw new BaseException("只有未审核申请才能审核"); + } + MutualConfig config = fetchEnabledConfig(getApplyYear(apply)); + enrichFundMemberJoinInfo(apply); + List subsidies = buildSubsidyPreview(apply, config); + BigDecimal total = subsidies.stream() + .map(subsidy -> toBigDecimal(subsidy.getSubsidyAmount())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + fillAuditCalcResult(apply, config, total); + apply.setStatus(1); + apply.setAuditBy(getLoginId()); + apply.setAuditTime(new Date()); + apply.setAuditOpinion(remark); + apply.setBonusRatio(parseMoney(bonusRatio, apply.getBonusRatio())); + apply.setActualSubsidyAmount(toDouble(toBigDecimal(parseMoney(actualSubsidyAmount, apply.getActualSubsidyAmount())) + .min(toBigDecimal(apply.getActualSubsidyAmount())).setScale(2, RoundingMode.DOWN))); + apply.setRemark(remark); + fillOperator(apply); + insertOrUpdate(apply); + dao().clear(MutualApplySubsidy.class, Cnd.where("applyId", "=", applyId)); + for (MutualApplySubsidy subsidy : subsidies) { + subsidy.setApplyId(applyId); + dao().insert(subsidy); + } + return auditDetail(applyId); + } + + /** + * 弃审已审核申请:恢复未审核状态,并删除已落库的动态补助明细,避免汇总页继续统计该申请。 + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public MutualApply cancelAudit(Long applyId) { + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + if (apply.getStatus() == null || apply.getStatus() != 1) { + throw new BaseException("只有已审核申请才能弃审"); + } + apply.setStatus(0); + apply.setAuditBy(null); + apply.setAuditTime(null); + apply.setAuditOpinion(null); + apply.setConfigId(null); + apply.setConfigYear(null); + apply.setSubsidyTotalAmount(null); + apply.setBonusRatio(null); + apply.setActualSubsidyAmount(null); + apply.setContinuousUnapplyYear(null); + apply.setLimitAmount(null); + apply.setRemark(null); + fillOperator(apply); + dao().update(MutualApply.class, Chain.make("status", 0) + .add("auditBy", null) + .add("auditTime", null) + .add("auditOpinion", null) + .add("configId", null) + .add("configYear", null) + .add("subsidyTotalAmount", null) + .add("bonusRatio", null) + .add("actualSubsidyAmount", null) + .add("continuousUnapplyYear", null) + .add("limitAmount", null) + .add("remark", null) + .add("updateBy", apply.getUpdateBy()) + .add("updateTime", new Date()), Cnd.where("id", "=", applyId)); + dao().clear(MutualApplySubsidy.class, Cnd.where("applyId", "=", applyId)); + return fetch(applyId); + } + + /** + * 作废未审核申请:状态置为作废,并把审核人和审核时间作为本次作废操作记录。 + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public MutualApply discard(Long applyId) { + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + if (apply.getStatus() == null || apply.getStatus() != 0) { + throw new BaseException("只有未审核申请才能作废"); + } + String loginId = getLoginId(); + Date now = new Date(); + dao().update(MutualApply.class, Chain.make("status", 2) + .add("auditBy", loginId) + .add("auditTime", now) + .add("updateBy", loginId) + .add("updateTime", now), Cnd.where("id", "=", applyId)); + return fetch(applyId); + } + + /** + * 取消作废申请:状态恢复为未审核,并清空作废时记录的审核人和审核时间。 + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public MutualApply cancelDiscard(Long applyId) { + MutualApply apply = fetch(applyId); + if (apply == null) { + throw new BaseException("申请记录不存在"); + } + if (apply.getStatus() == null || apply.getStatus() != 2) { + throw new BaseException("只有作废申请才能取消作废"); + } + String loginId = getLoginId(); + dao().update(MutualApply.class, Chain.make("status", 0) + .add("auditBy", null) + .add("auditTime", null) + .add("updateBy", loginId) + .add("updateTime", new Date()), Cnd.where("id", "=", applyId)); + return fetch(applyId); + } + + /** + * 汇总页先返回审核通过的申请数据,并携带动态补助明细列表,前端按明细动态展示列。 + */ + @Override + public Pagination summaryPage(PageForm pageForm, String deptName, String userName, Integer joinYear) { + Cnd cnd = buildSummaryCnd(deptName, userName, joinYear); + Pagination page = listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd.desc("auditTime")); + List rows = page.getList().stream() + .map(this::buildSummaryRow) + .toList(); + return new Pagination<>(page.getPageNo(), page.getPageSize(), page.getTotalCount(), rows); + } + + /** + * 按汇总页当前展示列导出 Excel,动态补助区间列由当前查询结果中的补助明细生成。 + */ + @Override + public Workbook exportSummary(String deptName, String userName, Integer joinYear) { + List applies = query(buildSummaryCnd(deptName, userName, joinYear).desc("auditTime")); + List rangeNames = collectSummaryRangeNames(applies); + List exportEntities = buildSummaryExportEntities(rangeNames); + List> exportRows = buildSummaryExportRows(applies, rangeNames); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + exportParams.setSheetName("医疗互助汇总"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, exportRows); + rebuildSummaryExportHeader(workbook, exportEntities.size(), rangeNames.size()); + return workbook; + } + + /** + * 按本年度启用配置生成动态区间预览明细,区间数完全来源于配置,不在代码中固定四段金额。 + */ + private List buildSubsidyPreview(MutualApply apply, MutualConfig config) { + if (config == null) { + return List.of(); + } + BigDecimal selfPayAmount = toBigDecimal(apply.getSelfPayAmount()); + List ratios = dao().query(MutualRatio.class, Cnd.where("configId", "=", config.getId()).asc("sort").asc("startAmount")); + return ratios.stream().map(ratio -> buildSubsidyRow(apply, ratio, selfPayAmount)).toList(); + } + + /** + * 按单个比例区间计算区间参与金额和区间补助金额,金额只取自费金额覆盖到该区间的有效部分。 + */ + private MutualApplySubsidy buildSubsidyRow(MutualApply apply, MutualRatio ratio, BigDecimal selfPayAmount) { + BigDecimal start = nvl(ratio.getStartAmount()); + BigDecimal end = ratio.getEndAmount(); + BigDecimal upper = end == null ? selfPayAmount : selfPayAmount.min(end); + BigDecimal baseAmount = upper.subtract(start).max(BigDecimal.ZERO); + BigDecimal subsidyAmount = baseAmount.multiply(nvl(ratio.getRatio())) + .divide(new BigDecimal("100"), 2, RoundingMode.DOWN); + MutualApplySubsidy row = new MutualApplySubsidy(); + row.setApplyId(apply.getId()); + row.setRatioId(ratio.getId()); + row.setRangeName(buildRangeName(ratio)); + row.setStartAmount(toDouble(start)); + row.setEndAmount(toDouble(end)); + row.setRatio(toDouble(ratio.getRatio())); + row.setBaseAmount(toDouble(baseAmount)); + row.setSubsidyAmount(toDouble(subsidyAmount)); + row.setSort(ratio.getSort()); + return row; + } + + /** + * 获取本年度启用互助金配置,审核计算必须使用启用配置,避免误用停用草稿配置。 + */ + private MutualConfig fetchEnabledConfig(Integer year) { + MutualConfig config = dao().fetch(MutualConfig.class, Cnd.where("year", "=", year).and("status", "=", 1)); + if (config == null) { + throw new BaseException(year + "年度未配置启用的医疗互助补助配置"); + } + return config; + } + + /** + * 审核计算按申请的申报年度取配置;没有提交时间时使用创建时间兜底。 + */ + private Integer getApplyYear(MutualApply apply) { + if (apply != null && apply.getSubmitTime() != null) { + return DateUtil.year(apply.getSubmitTime()); + } + if (apply != null && apply.getCreateTime() != null) { + return DateUtil.year(apply.getCreateTime()); + } + return DateUtil.thisYear(); + } + + /** + * 依据基金会员变更记录补齐入会日期和入会年度,来源与 /platform/fundMember/query 查询页保持一致。 + */ + private void enrichFundMemberJoinInfo(MutualApply apply) { + if (apply == null || StrUtil.isBlank(apply.getLoginName())) { + return; + } + FundMemberChangeRecord record = dao().fetch(FundMemberChangeRecord.class, + Cnd.where("loginName", "=", apply.getLoginName()).and("isJoin", "=", true).desc("changeTime")); + if (record != null && record.getChangeTime() != null) { + apply.setJoinDate(record.getChangeTime()); + apply.setJoinYear(DateUtil.year(record.getChangeTime())); + } + } + + /** + * 填充审核计算结果:补助小计、连续未申请年数、奖励系数和最终实际补助金额。 + */ + private void fillAuditCalcResult(MutualApply apply, MutualConfig config) { + List subsidies = buildSubsidyPreview(apply, config); + BigDecimal subtotal = subsidies.stream() + .map(subsidy -> toBigDecimal(subsidy.getSubsidyAmount())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + fillAuditCalcResult(apply, config, subtotal); + } + + /** + * 根据补助小计和连续未申请奖励比例计算最终补助金额,历史已有申请时连续未申请年数按 1 处理。 + */ + private void fillAuditCalcResult(MutualApply apply, MutualConfig config, BigDecimal subtotal) { + int continuousYear = calcContinuousUnapplyYear(apply); + BigDecimal increaseRatio = findIncreaseRatio(config, continuousYear); + BigDecimal bonusRatio = BigDecimal.ONE.add(increaseRatio.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP)); + BigDecimal actualAmount = nvl(subtotal).multiply(bonusRatio).setScale(2, RoundingMode.DOWN); + YearDiseaseLimitCalc limitCalc = calcYearDiseaseLimit(apply, config); + BigDecimal cappedActualAmount = actualAmount.min(limitCalc.remainAmount).max(BigDecimal.ZERO).setScale(2, RoundingMode.DOWN); + apply.setConfigId(config.getId()); + apply.setConfigYear(config.getYear()); + apply.setSubsidyTotalAmount(toDouble(nvl(subtotal).setScale(2, RoundingMode.DOWN))); + apply.setContinuousUnapplyYear(continuousYear); + apply.setBonusRatio(toDouble(bonusRatio)); + apply.setActualSubsidyAmount(toDouble(cappedActualAmount)); + apply.setLimitAmount(toDouble(limitCalc.limitAmount)); + apply.setYearUsedAmount(toDouble(limitCalc.usedAmount)); + apply.setYearRemainAmount(toDouble(limitCalc.remainAmount)); + } + + /** + * 计算同一申报人同一申报年度同一病种的年度剩余额度,实际补助金额不得超过该额度。 + */ + private YearDiseaseLimitCalc calcYearDiseaseLimit(MutualApply apply, MutualConfig config) { + BigDecimal limitAmount = isFirstApplyYear(apply) + ? nvl(config.getFirstYearMaxAmount()) + : nvl(config.getOtherYearMaxAmount()); + BigDecimal usedAmount = sumApprovedSameDiseaseAmount(apply); + BigDecimal remainAmount = limitAmount.subtract(usedAmount).max(BigDecimal.ZERO).setScale(2, RoundingMode.DOWN); + return new YearDiseaseLimitCalc(limitAmount.setScale(2, RoundingMode.DOWN), usedAmount.setScale(2, RoundingMode.DOWN), remainAmount); + } + + /** + * 判断当前申报年度是否为该申报人的第一申报年度,当前年度之前无已审核申请即视为第一年度。 + */ + private boolean isFirstApplyYear(MutualApply apply) { + if (apply == null || StrUtil.isBlank(apply.getLoginName())) { + return true; + } + Date applyYearStart = getApplyYearStart(apply); + Cnd cnd = Cnd.where("loginName", "=", apply.getLoginName()) + .and("status", "=", 1) + .and("submitTime", "<", applyYearStart); + if (apply.getId() != null) { + cnd.and("id", "!=", apply.getId()); + } + return dao().count(MutualApply.class, cnd) == 0; + } + + /** + * 汇总当前申报年度同申报人同病种已审核实际补助金额,排除当前正在审核的申请。 + */ + private BigDecimal sumApprovedSameDiseaseAmount(MutualApply apply) { + if (apply == null || StrUtil.isBlank(apply.getLoginName()) || StrUtil.isBlank(apply.getDiseaseName())) { + return BigDecimal.ZERO; + } + Date applyYearStart = getApplyYearStart(apply); + Date nextYearStart = DateUtil.offsetMonth(applyYearStart, 12); + Cnd cnd = Cnd.where("loginName", "=", apply.getLoginName()) + .and("diseaseName", "=", apply.getDiseaseName()) + .and("status", "=", 1) + .and("submitTime", ">=", applyYearStart) + .and("submitTime", "<", nextYearStart); + if (apply.getId() != null) { + cnd.and("id", "!=", apply.getId()); + } + return dao().query(MutualApply.class, cnd).stream() + .map(item -> toBigDecimal(item.getActualSubsidyAmount())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + /** + * 获取当前申请申报年度第一天,年度来源与审核配置年度一致。 + */ + private Date getApplyYearStart(MutualApply apply) { + return DateUtil.parseDate(getApplyYear(apply) + "-01-01"); + } + + /** + * 年度同病种限额计算结果,集中携带上限、已使用和剩余额度。 + */ + private static class YearDiseaseLimitCalc { + private final BigDecimal limitAmount; + private final BigDecimal usedAmount; + private final BigDecimal remainAmount; + + private YearDiseaseLimitCalc(BigDecimal limitAmount, BigDecimal usedAmount, BigDecimal remainAmount) { + this.limitAmount = limitAmount; + this.usedAmount = usedAmount; + this.remainAmount = remainAmount; + } + } + + /** + * 连续未申请年数从基金会员入会年度开始计算;只要存在历史申请记录,就按 1 年奖励口径处理。 + */ + private int calcContinuousUnapplyYear(MutualApply apply) { + if (apply == null || StrUtil.isBlank(apply.getLoginName())) { + return 1; + } + int historyCount = dao().count(MutualApply.class, + Cnd.where("loginName", "=", apply.getLoginName()).and("id", "!=", apply.getId())); + if (historyCount > 0) { + return 1; + } + Integer joinYear = apply.getJoinYear(); + if (joinYear == null) { + return 1; + } + return Math.max(getApplyYear(apply) - joinYear, 1); + } + + /** + * 奖励比例按“达到的连续未申请年数”匹配最高一档,未匹配时默认无奖励。 + */ + private BigDecimal findIncreaseRatio(MutualConfig config, int continuousYear) { + MutualBonus bonus = dao().fetch(MutualBonus.class, Cnd.where("configId", "=", config.getId()) + .and("continuousYear", "<=", continuousYear).desc("continuousYear")); + return bonus == null || bonus.getIncreaseRatio() == null ? BigDecimal.ZERO : bonus.getIncreaseRatio(); + } + + /** + * 构建汇总页单行数据,保留申请主信息并附带动态区间明细。 + */ + private NutMap buildSummaryRow(MutualApply apply) { + List subsidies = dao().query(MutualApplySubsidy.class, Cnd.where("applyId", "=", apply.getId()).asc("sort")); + return NutMap.NEW() + .addv("apply", apply) + .addv("subsidies", subsidies); + } + + /** + * 构建汇总查询条件,列表和导出共用该条件,保证页面展示与 Excel 导出数据范围一致。 + */ + private Cnd buildSummaryCnd(String deptName, String userName, Integer joinYear) { + Cnd cnd = Cnd.where("status", "=", 1); + if (StrUtil.isNotBlank(deptName)) { + cnd.and(Cnd.likeEX("deptName", StrUtil.trim(deptName))); + } + if (StrUtil.isNotBlank(userName)) { + cnd.and(Cnd.likeEX("userName", StrUtil.trim(userName))); + } + if (joinYear != null) { + cnd.and("joinYear", "=", joinYear); + } + return cnd; + } + + /** + * 收集导出数据中出现过的补助区间名称,顺序按明细排序和首次出现顺序保持稳定。 + */ + private List collectSummaryRangeNames(List applies) { + List rangeNames = new ArrayList<>(); + for (MutualApply apply : applies) { + List subsidies = dao().query(MutualApplySubsidy.class, Cnd.where("applyId", "=", apply.getId()).asc("sort")); + for (MutualApplySubsidy subsidy : subsidies) { + if (StrUtil.isNotBlank(subsidy.getRangeName()) && !rangeNames.contains(subsidy.getRangeName())) { + rangeNames.add(subsidy.getRangeName()); + } + } + } + return rangeNames; + } + + /** + * 构建汇总导出列,基础列和页面一致,补助计算方法下的区间列按查询结果动态生成。 + */ + private List buildSummaryExportEntities(List rangeNames) { + List exportEntities = new ArrayList<>(); + exportEntities.add(buildSummaryExportEntity("序号", "index", 10)); + exportEntities.add(buildSummaryExportEntity("所在单位", "deptName", 20)); + exportEntities.add(buildSummaryExportEntity("姓名", "userName", 14)); + exportEntities.add(buildSummaryExportEntity("加入\n时间\n(年)", "joinYear", 14)); + exportEntities.add(buildSummaryExportEntity("大病名称\n及病情", "diseaseText", 30)); + exportEntities.add(buildSummaryExportEntity("符合规定发\n票金额\n(元)", "medicalTotalAmount", 20)); + for (String rangeName : rangeNames) { + exportEntities.add(buildSummaryExportEntity(rangeName, rangeName, 18)); + } + exportEntities.add(buildSummaryExportEntity("补助小计", "subsidyTotalAmount", 16)); + exportEntities.add(buildSummaryExportEntity("补助\n比例", "bonusRatio", 12)); + exportEntities.add(buildSummaryExportEntity("实际补助金\n额(元)", "actualSubsidyAmount", 18)); + exportEntities.add(buildSummaryExportEntity("备注", "remark", 20)); + return exportEntities; + } + + /** + * 创建汇总导出列,统一开启换行以贴合纸质汇总表的多行表头样式。 + */ + private ExcelExportEntity buildSummaryExportEntity(String name, Object key, int width) { + ExcelExportEntity entity = new ExcelExportEntity(name, key, width); + entity.setWrap(true); + return entity; + } + + /** + * 重建医疗互助汇总导出表头:保留标题和两级表头,省略示例图中的第二行日期。 + */ + private void rebuildSummaryExportHeader(Workbook workbook, int totalColumnCount, int rangeColumnCount) { + if (workbook == null || totalColumnCount <= 0 || workbook.getNumberOfSheets() == 0) { + return; + } + Sheet sheet = workbook.getSheetAt(0); + int lastRowNum = sheet.getLastRowNum(); + if (lastRowNum >= 0) { + sheet.shiftRows(0, lastRowNum, 2, true, false); + } + Row titleRow = getOrCreateRow(sheet, 0); + Cell titleCell = getOrCreateCell(titleRow, 0); + titleCell.setCellValue(DateUtil.thisYear() + "年大病互助人员申请补助金情况汇总表"); + titleCell.setCellStyle(buildSummaryTitleStyle(workbook)); + mergeSummaryRegion(sheet, 0, 0, 0, totalColumnCount - 1); + + int groupStartColumn = 6; + int groupEndColumn = groupStartColumn + rangeColumnCount; + setMergedHeaderCell(sheet, 1, 2, 0, 0, "序号"); + setMergedHeaderCell(sheet, 1, 2, 1, 1, "所在单位"); + setMergedHeaderCell(sheet, 1, 2, 2, 2, "姓名"); + setMergedHeaderCell(sheet, 1, 2, 3, 3, "加入\n时间\n(年)"); + setMergedHeaderCell(sheet, 1, 2, 4, 4, "大病名称\n及病情"); + setMergedHeaderCell(sheet, 1, 2, 5, 5, "符合规定发\n票金额\n(元)"); + setSummaryGroupHeaderCell(sheet, workbook, groupStartColumn, groupEndColumn); + setMergedHeaderCell(sheet, 1, 2, groupEndColumn + 1, groupEndColumn + 1, "补助\n比例"); + setMergedHeaderCell(sheet, 1, 2, groupEndColumn + 2, groupEndColumn + 2, "实际补助金\n额(元)"); + setMergedHeaderCell(sheet, 1, 2, groupEndColumn + 3, groupEndColumn + 3, "备注"); + } + + /** + * 设置合并表头单元格;此处不设置 CellStyle,规避当前运行环境 POI 版本冲突导致的样式方法错误。 + */ + private void setMergedHeaderCell(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol, String value) { + Cell cell = getOrCreateCell(getOrCreateRow(sheet, firstRow), firstCol); + cell.setCellValue(value); + mergeSummaryRegion(sheet, firstRow, lastRow, firstCol, lastCol); + } + + /** + * 设置补助计算方法分组表头样式,仅放大字号并居中,不加粗也不设置填充色和边框。 + */ + private void setSummaryGroupHeaderCell(Sheet sheet, Workbook workbook, int firstCol, int lastCol) { + Cell cell = getOrCreateCell(getOrCreateRow(sheet, 1), firstCol); + cell.setCellValue("补助计算方法"); + cell.setCellStyle(buildSummaryGroupHeaderStyle(workbook)); + mergeSummaryRegion(sheet, 1, 1, firstCol, lastCol); + } + + /** + * 创建补助计算方法合并表头样式,按用户要求只做字号放大和居中,不设置加粗。 + */ + private CellStyle buildSummaryGroupHeaderStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font font = workbook.createFont(); + font.setFontHeightInPoints((short) 12); + style.setFont(font); + return style; + } + + /** + * 创建汇总导出第一行标题样式,仅设置字体和对齐,避免使用填充色等容易触发 POI 版本冲突的样式 API。 + */ + private CellStyle buildSummaryTitleStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font font = workbook.createFont(); + font.setBold(true); + font.setFontHeightInPoints((short) 18); + style.setFont(font); + return style; + } + + /** + * 合并区域只有跨度超过一个单元格时才执行,兼容没有动态区间时只剩补助小计列的场景。 + */ + private void mergeSummaryRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) { + if (firstRow == lastRow && firstCol == lastCol) { + return; + } + sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); + } + + /** + * 获取或创建指定行,避免 POI 移动行后出现空行导致空指针。 + */ + private Row getOrCreateRow(Sheet sheet, int rowIndex) { + Row row = sheet.getRow(rowIndex); + return row == null ? sheet.createRow(rowIndex) : row; + } + + /** + * 获取或创建指定单元格,表头重建时用于补齐合并区域内的样式。 + */ + private Cell getOrCreateCell(Row row, int columnIndex) { + Cell cell = row.getCell(columnIndex); + return cell == null ? row.createCell(columnIndex) : cell; + } + + /** + * 组装导出行数据,动态区间列使用区间名称作为 Map key,与动态表头一一对应。 + */ + private List> buildSummaryExportRows(List applies, List rangeNames) { + List> rows = new ArrayList<>(); + for (int i = 0; i < applies.size(); i++) { + MutualApply apply = applies.get(i); + Map row = new LinkedHashMap<>(); + row.put("index", i + 1); + row.put("deptName", apply.getDeptName()); + row.put("userName", apply.getUserName()); + row.put("joinYear", apply.getJoinYear()); + row.put("diseaseText", apply.getDiseaseName()); + row.put("medicalTotalAmount", formatExportMoney(apply.getMedicalTotalAmount())); + for (String rangeName : rangeNames) { + row.put(rangeName, ""); + } + List subsidies = dao().query(MutualApplySubsidy.class, Cnd.where("applyId", "=", apply.getId()).asc("sort")); + for (MutualApplySubsidy subsidy : subsidies) { + row.put(subsidy.getRangeName(), formatExportMoney(subsidy.getSubsidyAmount())); + } + row.put("subsidyTotalAmount", formatExportMoney(apply.getSubsidyTotalAmount())); + row.put("bonusRatio", apply.getBonusRatio()); + row.put("actualSubsidyAmount", formatExportMoney(apply.getActualSubsidyAmount())); + row.put("remark", apply.getRemark()); + rows.add(row); + } + return rows; + } + + /** + * 填充申请保存默认值,提交时状态仍为未审核。 + */ + /** + * 组装申请单 Word 模板参数,模板字段名和 /platform/sys/officeTemplate 中维护的 Word 占位符一一对应。 + */ + private Map buildMineApplyFormDocData(MutualApply apply) { + Date signDate = firstNotNullDate(apply.getSignTime(), apply.getSubmitTime(), apply.getCreateTime()); + Map docData = new LinkedHashMap<>(); + docData.put("applyNo", emptyToBlank(apply.getApplyNo())); + docData.put("userId", emptyToBlank(apply.getUserId())); + docData.put("loginName", emptyToBlank(apply.getLoginName())); + docData.put("userName", emptyToBlank(apply.getUserName())); + docData.put("sex", emptyToBlank(apply.getSex())); + docData.put("birthday", formatDate(apply.getBirthday(), "yyyy-MM-dd")); + docData.put("nativePlace", emptyToBlank(apply.getNativePlace())); + docData.put("deptName", emptyToBlank(apply.getDeptName())); + docData.put("education", emptyToBlank(apply.getEducation())); + docData.put("professionalTitle", emptyToBlank(apply.getProfessionalTitle())); + docData.put("idCard", emptyToBlank(apply.getIdCard())); + docData.put("mobile", emptyToBlank(apply.getMobile())); + docData.put("bankCardNo", emptyToBlank(apply.getBankCardNo())); + docData.put("bankName", emptyToBlank(apply.getBankName())); + docData.put("diseaseName", emptyToBlank(apply.getDiseaseName())); + docData.put("hospitalDesc", buildApplyHospitalText(apply)); + docData.put("medicalTotalAmount", formatExportMoney(apply.getMedicalTotalAmount())); + docData.put("selfPayAmount", formatExportMoney(apply.getSelfPayAmount())); + docData.put("submitTime", formatDate(apply.getSubmitTime(), "yyyy-MM-dd")); + docData.put("signDate", formatDate(signDate, "yyyy-MM-dd")); + docData.put("signYear", formatDate(signDate, "yyyy")); + docData.put("signMonth", formatDate(signDate, "MM")); + docData.put("signDay", formatDate(signDate, "dd")); + docData.put("remark", emptyToBlank(apply.getRemark())); + docData.put("statusText", buildStatusText(apply.getStatus())); + // 签字图片由 pc-signature 组件保存为文件下载地址,模板中使用 {{@sign}} 渲染图片。 + docData.put("sign", StrUtil.isBlank(apply.getSignFileId()) ? null + : sysOfficeTemplateUtil.createPictureRenderData(90, 35, apply.getSignFileId())); + return docData; + } + + /** + * 校验“我的申请”导出只能访问当前登录人的申请,避免通过 URL 参数导出他人申请。 + */ + private void assertMineApplyOwner(MutualApply apply) { + String loginId = getLoginId(); + if (StrUtil.isBlank(loginId) || apply == null) { + return; + } + boolean ownByCreate = StrUtil.equals(loginId, apply.getCreateBy()); + boolean ownByUserId = StrUtil.equals(loginId, apply.getUserId()); + boolean ownByLoginName = StrUtil.equals(loginId, apply.getLoginName()); + if (!ownByCreate && !ownByUserId && !ownByLoginName) { + throw new BaseException("只能导出本人申请单"); + } + } + + /** + * 将疾病名称和住院说明合并到模板“何时何病伤住何医院”栏,保留原 Word 模板结构。 + */ + private String buildApplyHospitalText(MutualApply apply) { + List texts = new ArrayList<>(); + if (StrUtil.isNotBlank(apply.getDiseaseName())) { + texts.add("大病名称:" + apply.getDiseaseName()); + } + if (StrUtil.isNotBlank(apply.getHospitalDesc())) { + texts.add(apply.getHospitalDesc()); + } + return String.join("\n", texts); + } + + /** + * 导出状态文案,模板如需展示状态时可直接使用 statusText 参数。 + */ + private String buildStatusText(Integer status) { + if (status == null || status == 0) { + return "未审核"; + } + if (status == 1) { + return "已审核"; + } + if (status == 2) { + return "已作废"; + } + return ""; + } + + private void fillApplyDefaults(MutualApply apply, boolean submit) { + if (StrUtil.isBlank(apply.getApplyNo())) { + apply.setApplyNo("HZ" + DateUtil.format(new Date(), "yyyyMMddHHmmss")); + } + if (apply.getStatus() == null) { + apply.setStatus(0); + } + if (submit && apply.getSubmitTime() == null) { + apply.setSubmitTime(new Date()); + apply.setStatus(0); + } + if (apply.getMedicalTotalAmount() == null) { + apply.setMedicalTotalAmount(0D); + } + if (apply.getSelfPayAmount() == null) { + apply.setSelfPayAmount(0D); + } + } + + /** + * 补充创建人与更新人,兼容未登录的本地调试场景。 + */ + private void fillOperator(MutualApply apply) { + String loginId = getLoginId(); + if (apply.getId() == null && StrUtil.isBlank(apply.getCreateBy())) { + apply.setCreateBy(loginId); + } + apply.setUpdateBy(loginId); + } + + /** + * 构建当前用户占位信息,真实会员字段映射后续在这里替换。 + */ + private NutMap buildCurrentUserPlaceholder() { + String loginId = getLoginId(); + return NutMap.NEW() + .addv("loginName", loginId) + .addv("userName", loginId); + } + + /** + * 追加大病名称模糊查询条件。 + */ + private void appendDiseaseName(Cnd cnd, String diseaseName) { + if (StrUtil.isNotBlank(diseaseName)) { + cnd.and(Cnd.likeEX("diseaseName", StrUtil.trim(diseaseName))); + } + } + + /** + * 构建动态区间展示名称。 + */ + private String buildRangeName(MutualRatio ratio) { + if (ratio.getEndAmount() == null) { + return formatWan(ratio.getStartAmount()) + "元以上补助" + ratio.getRatio() + "%"; + } + return formatWan(ratio.getStartAmount()) + "-" + formatWan(ratio.getEndAmount()) + "元之间补助" + ratio.getRatio() + "%"; + } + + /** + * 金额标题暂按万元展示,后续可按页面文案继续优化。 + */ + private String formatWan(BigDecimal amount) { + if (amount == null) { + return "0"; + } + return amount.divide(new BigDecimal("10000"), 0, RoundingMode.DOWN).toPlainString() + "万"; + } + + /** + * 导出金额与页面展示保持两位小数口径,按业务要求直接截断不四舍五入。 + */ + private String formatExportMoney(Double amount) { + return toBigDecimal(amount).setScale(2, RoundingMode.DOWN).toPlainString(); + } + + /** + * Word 模板日期统一格式化,空日期返回空字符串,避免模板中出现 null。 + */ + private String formatDate(Date date, String pattern) { + return date == null ? "" : DateUtil.format(date, pattern); + } + + /** + * Word 模板文本空值兜底,保证模板参数渲染为空白而不是 null。 + */ + private String emptyToBlank(String value) { + return StrUtil.blankToDefault(value, ""); + } + + /** + * 按优先级获取第一个非空日期,用于申请人签字日期兜底。 + */ + private Date firstNotNullDate(Date... dates) { + for (Date date : dates) { + if (date != null) { + return date; + } + } + return null; + } + + /** + * 获取当前登录 ID,未登录时返回空字符串。 + */ + private String getLoginId() { + try { + return StpUtil.getLoginIdAsString(); + } catch (Exception ignored) { + return ""; + } + } + + /** + * 空配置金额按 0 处理,配置实体仍保留 BigDecimal 以保证比例和区间计算精度。 + */ + private BigDecimal nvl(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + /** + * 将申请实体中的 Double 金额转换为 BigDecimal,避免直接使用浮点数参与补助公式计算。 + */ + private BigDecimal toBigDecimal(Double value) { + return value == null ? BigDecimal.ZERO : BigDecimal.valueOf(value); + } + + /** + * 将计算后的 BigDecimal 金额转回实体使用的 Double,页面 JSON 序列化时保持轻量数字类型。 + */ + private Double toDouble(BigDecimal value) { + return value == null ? null : value.doubleValue(); + } + + /** + * 字符串金额转换为实体使用的 Double,空值使用默认金额。 + */ + private Double parseMoney(String value, Double defaultValue) { + if (StrUtil.isBlank(value)) { + return defaultValue; + } + return new BigDecimal(value.replace(",", "")).doubleValue(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/controller/MedicalMutualAidConfigController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/controller/MedicalMutualAidConfigController.java new file mode 100644 index 0000000..d493bfc --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/controller/MedicalMutualAidConfigController.java @@ -0,0 +1,158 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualBonus; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualMemberConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualRatio; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.service.MedicalMutualAidConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * 医疗互助配置 PC 端控制器,负责页面入口与配置管理接口转发。 + */ +@IocBean +@At("/platform/medicalMutualAid/config") +@Api("医疗互助配置") +@Ok("json:full") +public class MedicalMutualAidConfigController { + + @Inject + private MedicalMutualAidConfigService medicalMutualAidConfigService; + + /** + * 打开医疗互助配置页面。 + */ + @At("") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/config/index.html") + @SaCheckPermission("medicalMutualAid.config") + public void index() { + } + + /** + * 查询互助金配置列表,供配置列表页按年度和配置名称筛选。 + * + * @param year 年度,为空时查询全部年度 + * @param configName 配置名称,为空时不限制名称 + * @return 互助金配置列表 + */ + @At + @ApiOperation("查询医疗互助配置列表") + @SaCheckPermission("medicalMutualAid.config") + public Result listConfigs(Integer year, String configName) { + return Result.success(medicalMutualAidConfigService.listConfigs(year, configName)); + } + + /** + * 查询指定年度的完整配置数据。 + * + * @param year 年度 + * @return 聚合配置数据 + */ + @At + @ApiOperation("查询医疗互助配置") + @SaCheckPermission("medicalMutualAid.config") + public Result configData(Integer year) { + return Result.success(medicalMutualAidConfigService.getConfigData(year)); + } + + /** + * 保存互助金基础配置。 + * + * @param config 基础配置表单 + * @return 保存后的基础配置 + */ + @At + @ApiOperation("保存互助金基础配置") + @SaCheckPermission("medicalMutualAid.config") + public Result saveConfig(MutualConfig config) { + return Result.success(medicalMutualAidConfigService.saveConfig(config)); + } + + /** + * 删除互助金基础配置及其关联配置。 + * + * @param id 基础配置 ID + * @return 删除结果 + */ + @At + @ApiOperation("删除互助金基础配置") + @SaCheckPermission("medicalMutualAid.config") + public Result deleteConfig(Long id) { + medicalMutualAidConfigService.deleteConfig(id); + return Result.success(); + } + + /** + * 保存补助比例配置。 + * + * @param ratio 补助比例表单 + * @return 保存后的补助比例 + */ + @At + @ApiOperation("保存补助比例配置") + @SaCheckPermission("medicalMutualAid.config") + public Result saveRatio(MutualRatio ratio) { + return Result.success(medicalMutualAidConfigService.saveRatio(ratio)); + } + + /** + * 删除补助比例配置。 + * + * @param id 补助比例 ID + * @return 删除结果 + */ + @At + @ApiOperation("删除补助比例配置") + @SaCheckPermission("medicalMutualAid.config") + public Result deleteRatio(Long id) { + medicalMutualAidConfigService.deleteRatio(id); + return Result.success(); + } + + /** + * 保存连续未申请奖励配置。 + * + * @param bonus 连续未申请奖励表单 + * @return 保存后的奖励配置 + */ + @At + @ApiOperation("保存连续未申请奖励配置") + @SaCheckPermission("medicalMutualAid.config") + public Result saveBonus(MutualBonus bonus) { + return Result.success(medicalMutualAidConfigService.saveBonus(bonus)); + } + + /** + * 删除连续未申请奖励配置。 + * + * @param id 奖励配置 ID + * @return 删除结果 + */ + @At + @ApiOperation("删除连续未申请奖励配置") + @SaCheckPermission("medicalMutualAid.config") + public Result deleteBonus(Long id) { + medicalMutualAidConfigService.deleteBonus(id); + return Result.success(); + } + + /** + * 保存会员缴费配置。 + * + * @param memberConfig 会员缴费配置表单 + * @return 保存后的会员缴费配置 + */ + @At + @ApiOperation("保存会员缴费配置") + @SaCheckPermission("medicalMutualAid.config") + public Result saveMemberConfig(MutualMemberConfig memberConfig) { + return Result.success(medicalMutualAidConfigService.saveMemberConfig(memberConfig)); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualBonus.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualBonus.java new file mode 100644 index 0000000..746c52a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualBonus.java @@ -0,0 +1,48 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; + +import java.math.BigDecimal; + +/** + * 连续未申请奖励配置实体,维护连续参保未申请后的补助提升比例。 + */ +@Data +@Table("tb_mutual_bonus") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("连续未申请奖励配置") +public class MutualBonus { + + /** 主键,数据库自增生成。 */ + @Id + @Comment("主键") + private Long id; + + /** 所属互助金基础配置 ID。 */ + @Column("config_id") + @Comment("配置ID") + private Long configId; + + /** 连续未申请年数。 */ + @Column("continuous_year") + @Comment("连续未申请年数") + private Integer continuousYear; + + /** 奖励增加比例,单位为百分比。 */ + @Column("increase_ratio") + @Comment("增加比例(%)") + private BigDecimal increaseRatio; + + /** 奖励说明。 */ + @Column("remark") + @ColDefine(type = ColType.VARCHAR, width = 200) + @Comment("备注") + private String remark; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualConfig.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualConfig.java new file mode 100644 index 0000000..7f96dd9 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualConfig.java @@ -0,0 +1,97 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Default; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.dao.interceptor.annotation.PrevUpdate; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 互助金补助基础配置实体,映射年度、起补金额、年度封顶金额等主配置。 + */ +@Data +@Table("tb_mutual_config") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("互助金配置") +public class MutualConfig { + + /** 主键,数据库自增生成。 */ + @Id + @Comment("主键") + private Long id; + + /** 配置所属年度,业务上同一年度只能存在一份配置。 */ + @Column("year") + @Comment("年度") + private Integer year; + + /** 配置名称,用于页面展示和后续业务识别。 */ + @Column("config_name") + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("配置名称") + private String configName; + + /** 起补金额,低于该金额的部分不参与补助计算。 */ + @Column("start_amount") + @Default("10000.00") + @Comment("起补金额") + private BigDecimal startAmount; + + /** 首年申请最高补助金额。 */ + @Column("first_year_max_amount") + @Default("100000.00") + @Comment("第一年最高补助") + private BigDecimal firstYearMaxAmount; + + /** 非首年申请最高补助金额。 */ + @Column("other_year_max_amount") + @Default("50000.00") + @Comment("其他年度最高补助") + private BigDecimal otherYearMaxAmount; + + /** 启停状态:1 启用,0 停用。 */ + @Column("status") + @Default("1") + @Comment("状态 1启用 0停用") + private Integer status; + + /** 配置备注,用于记录人工说明。 */ + @Column("remark") + @ColDefine(type = ColType.VARCHAR, width = 500) + @Comment("备注") + private String remark; + + /** 创建人。 */ + @Column("create_by") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("创建人") + private String createBy; + + /** 创建时间。 */ + @Column("create_time") + @PrevInsert(now = true) + @Comment("创建时间") + private Date createTime; + + /** 更新人。 */ + @Column("update_by") + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("更新人") + private String updateBy; + + /** 更新时间。 */ + @Column("update_time") + @PrevInsert(now = true) + @PrevUpdate(now = true) + @Comment("更新时间") + private Date updateTime; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualMemberConfig.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualMemberConfig.java new file mode 100644 index 0000000..db590e3 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualMemberConfig.java @@ -0,0 +1,35 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; + +import java.math.BigDecimal; + +/** + * 医疗互助会员缴费配置实体,维护每月缴费金额和连续缴费优惠年限。 + */ +@Data +@Table("tb_mutual_member_config") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("医疗互助会员缴费配置") +public class MutualMemberConfig { + + /** 主键,数据库自增生成。 */ + @Id + @Comment("主键") + private Long id; + + /** 每月缴纳互助金额。 */ + @Column("month_amount") + @Comment("每月缴纳互助金额(元)") + private BigDecimal monthAmount; + + /** 连续缴费满 N 年后,次年缴费减半。 */ + @Column("half_price_year") + @Comment("连续缴费满N年次年缴费减半") + private Integer halfPriceYear; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualRatio.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualRatio.java new file mode 100644 index 0000000..14aea2c --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/model/MutualRatio.java @@ -0,0 +1,58 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.TableMeta; + +import java.math.BigDecimal; + +/** + * 互助金补助比例配置实体,按金额区间维护阶梯补助比例。 + */ +@Data +@Table("tb_mutual_ratio") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("互助金补助比例配置") +public class MutualRatio { + + /** 主键,数据库自增生成。 */ + @Id + @Comment("主键") + private Long id; + + /** 所属互助金基础配置 ID。 */ + @Column("config_id") + @Comment("配置ID") + private Long configId; + + /** 当前补助区间开始金额。 */ + @Column("start_amount") + @Comment("开始金额") + private BigDecimal startAmount; + + /** 当前补助区间结束金额,空值表示不设上限。 */ + @Column("end_amount") + @Comment("结束金额(NULL表示无限)") + private BigDecimal endAmount; + + /** 当前区间补助比例,单位为百分比。 */ + @Column("ratio") + @Comment("补助比例(%)") + private BigDecimal ratio; + + /** 排序号,控制阶梯区间展示与计算顺序。 */ + @Column("sort") + @Comment("排序") + private Integer sort; + + /** 区间说明。 */ + @Column("remark") + @ColDefine(type = ColType.VARCHAR, width = 200) + @Comment("备注") + private String remark; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/MedicalMutualAidConfigService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/MedicalMutualAidConfigService.java new file mode 100644 index 0000000..d91a398 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/MedicalMutualAidConfigService.java @@ -0,0 +1,109 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.service; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualBonus; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualMemberConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualRatio; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** + * 医疗互助配置服务,统一处理基础配置、比例配置、奖励配置和会员缴费配置。 + */ +public interface MedicalMutualAidConfigService extends BaseService { + + /** + * 查询指定年度的完整配置数据。 + * + * @param year 年度,为空时使用当前年份 + * @return 包含基础配置、比例列表、奖励列表和会员缴费配置的聚合数据 + */ + NutMap getConfigData(Integer year); + + /** + * 查询互助金配置列表,用于配置列表页按年度和配置名称筛选历史配置。 + * + * @param year 年度,为空时不限制年度 + * @param configName 配置名称,为空时不限制名称 + * @return 互助金基础配置列表 + */ + List listConfigs(Integer year, String configName); + + /** + * 保存互助金基础配置。 + * + * @param config 互助金基础配置表单 + * @return 保存后的互助金基础配置 + */ + MutualConfig saveConfig(MutualConfig config); + + /** + * 删除互助金基础配置,并同步删除其下比例配置和奖励配置。 + * + * @param configId 基础配置 ID + */ + void deleteConfig(Long configId); + + /** + * 查询指定基础配置下的补助比例列表。 + * + * @param configId 基础配置 ID + * @return 补助比例列表 + */ + List listRatios(Long configId); + + /** + * 保存补助比例配置。 + * + * @param ratio 补助比例表单 + * @return 保存后的补助比例 + */ + MutualRatio saveRatio(MutualRatio ratio); + + /** + * 删除补助比例配置。 + * + * @param ratioId 补助比例 ID + */ + void deleteRatio(Long ratioId); + + /** + * 查询指定基础配置下的连续未申请奖励列表。 + * + * @param configId 基础配置 ID + * @return 连续未申请奖励列表 + */ + List listBonuses(Long configId); + + /** + * 保存连续未申请奖励配置。 + * + * @param bonus 连续未申请奖励表单 + * @return 保存后的连续未申请奖励配置 + */ + MutualBonus saveBonus(MutualBonus bonus); + + /** + * 删除连续未申请奖励配置。 + * + * @param bonusId 连续未申请奖励 ID + */ + void deleteBonus(Long bonusId); + + /** + * 查询会员缴费配置,未配置时返回页面默认值。 + * + * @return 会员缴费配置 + */ + MutualMemberConfig getMemberConfig(); + + /** + * 保存会员缴费配置。 + * + * @param memberConfig 会员缴费配置表单 + * @return 保存后的会员缴费配置 + */ + MutualMemberConfig saveMemberConfig(MutualMemberConfig memberConfig); +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/impl/MedicalMutualAidConfigServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/impl/MedicalMutualAidConfigServiceImpl.java new file mode 100644 index 0000000..44dff45 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/config/service/impl/MedicalMutualAidConfigServiceImpl.java @@ -0,0 +1,263 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.service.impl; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.date.DateUtil; +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.staffbenefit.medicalMutualAid.config.model.MutualBonus; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualMemberConfig; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.model.MutualRatio; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.config.service.MedicalMutualAidConfigService; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 医疗互助配置服务实现,集中放置配置保存、校验和关联数据维护逻辑。 + */ +@IocBean(args = {"refer:dao"}) +public class MedicalMutualAidConfigServiceImpl extends BaseServiceImpl + implements MedicalMutualAidConfigService { + + /** + * 初始化医疗互助配置服务的数据访问对象。 + * + * @param dao 数据访问对象 + */ + public MedicalMutualAidConfigServiceImpl(Dao dao) { + super(dao); + } + + /** + * 聚合返回页面初始化所需的全部配置数据,减少前端重复请求。 + */ + @Override + public NutMap getConfigData(Integer year) { + Integer configYear = year == null ? DateUtil.thisYear() : year; + MutualConfig config = fetch(Cnd.where("year", "=", configYear)); + if (config == null) { + config = buildDefaultConfig(configYear); + } + Long configId = config.getId(); + return NutMap.NEW() + .addv("config", config) + .addv("ratios", configId == null ? List.of() : listRatios(configId)) + .addv("bonuses", configId == null ? List.of() : listBonuses(configId)) + .addv("memberConfig", getMemberConfig()); + } + + /** + * 按列表页查询条件检索年度配置,年度和名称均为空时返回全部配置并按年度倒序展示。 + */ + @Override + public List listConfigs(Integer year, String configName) { + Cnd cnd = Cnd.NEW(); + if (year != null) { + cnd.and("year", "=", year); + } + if (StrUtil.isNotBlank(configName)) { + cnd.and("configName", "like", "%" + configName.trim() + "%"); + } + return query(cnd.desc("year")); + } + + /** + * 保存基础配置前补齐默认值,并处理同一年唯一配置的更新场景。 + */ + @Override + public MutualConfig saveConfig(MutualConfig config) { + if (config == null) { + throw new BaseException("配置不能为空"); + } + fillDefaultConfig(config); + MutualConfig oldYearConfig = fetch(Cnd.where("year", "=", config.getYear())); + if (oldYearConfig != null && (config.getId() == null || !oldYearConfig.getId().equals(config.getId()))) { + // 同一年只允许一条配置;新增时如果年度已存在,则复用原记录执行更新。 + config.setId(oldYearConfig.getId()); + config.setCreateBy(oldYearConfig.getCreateBy()); + config.setCreateTime(oldYearConfig.getCreateTime()); + } + fillOperator(config); + return insertOrUpdate(config); + } + + /** + * 删除主配置时同步清理从表,确保比例与奖励配置不会遗留无效 configId。 + */ + @Override + public void deleteConfig(Long configId) { + if (configId == null) { + return; + } + dao().clear(MutualRatio.class, Cnd.where("configId", "=", configId)); + dao().clear(MutualBonus.class, Cnd.where("configId", "=", configId)); + delete(configId); + } + + /** + * 按开始金额和排序号查询补助比例,保证页面阶梯区间顺序稳定。 + */ + @Override + public List listRatios(Long configId) { + if (configId == null) { + return List.of(); + } + return dao().query(MutualRatio.class, Cnd.where("configId", "=", configId).asc("sort").asc("startAmount")); + } + + /** + * 保存比例前校验所属基础配置存在,并补齐默认排序。 + */ + @Override + public MutualRatio saveRatio(MutualRatio ratio) { + if (ratio == null || ratio.getConfigId() == null) { + throw new BaseException("请先保存基础配置"); + } + ensureConfigExists(ratio.getConfigId()); + if (ratio.getSort() == null) { + ratio.setSort(listRatios(ratio.getConfigId()).size() + 1); + } + return dao().insertOrUpdate(ratio); + } + + /** + * 删除指定比例配置,空 ID 直接忽略。 + */ + @Override + public void deleteRatio(Long ratioId) { + if (ratioId != null) { + dao().delete(MutualRatio.class, ratioId); + } + } + + /** + * 按连续未申请年数查询奖励配置,保证页面展示顺序符合业务递增关系。 + */ + @Override + public List listBonuses(Long configId) { + if (configId == null) { + return List.of(); + } + return dao().query(MutualBonus.class, Cnd.where("configId", "=", configId).asc("continuousYear")); + } + + /** + * 保存奖励前校验所属基础配置存在,避免保存到无效主配置下。 + */ + @Override + public MutualBonus saveBonus(MutualBonus bonus) { + if (bonus == null || bonus.getConfigId() == null) { + throw new BaseException("请先保存基础配置"); + } + ensureConfigExists(bonus.getConfigId()); + return dao().insertOrUpdate(bonus); + } + + /** + * 删除指定奖励配置,空 ID 直接忽略。 + */ + @Override + public void deleteBonus(Long bonusId) { + if (bonusId != null) { + dao().delete(MutualBonus.class, bonusId); + } + } + + /** + * 查询会员缴费配置;未配置时返回默认表单,方便页面直接展示。 + */ + @Override + public MutualMemberConfig getMemberConfig() { + MutualMemberConfig memberConfig = dao().fetch(MutualMemberConfig.class, Cnd.NEW()); + if (memberConfig != null) { + return memberConfig; + } + MutualMemberConfig defaultConfig = new MutualMemberConfig(); + defaultConfig.setMonthAmount(new BigDecimal("0.00")); + defaultConfig.setHalfPriceYear(1); + return defaultConfig; + } + + /** + * 保存会员缴费配置时复用已有唯一记录,避免产生多条全局缴费配置。 + */ + @Override + public MutualMemberConfig saveMemberConfig(MutualMemberConfig memberConfig) { + if (memberConfig == null) { + throw new BaseException("会员缴费配置不能为空"); + } + MutualMemberConfig oldConfig = dao().fetch(MutualMemberConfig.class, Cnd.NEW()); + if (oldConfig != null && memberConfig.getId() == null) { + memberConfig.setId(oldConfig.getId()); + } + return dao().insertOrUpdate(memberConfig); + } + + /** + * 构造页面默认基础配置,数据库未保存时也能展示截图中的默认业务值。 + */ + private MutualConfig buildDefaultConfig(Integer year) { + MutualConfig config = new MutualConfig(); + config.setYear(year); + config.setConfigName(year + "年医疗互助补助配置"); + config.setStartAmount(new BigDecimal("10000.00")); + config.setFirstYearMaxAmount(new BigDecimal("100000.00")); + config.setOtherYearMaxAmount(new BigDecimal("50000.00")); + config.setStatus(1); + return config; + } + + /** + * 保存前补齐基础配置默认值,避免数据库非空字段因页面未传值保存失败。 + */ + private void fillDefaultConfig(MutualConfig config) { + if (config.getYear() == null) { + config.setYear(DateUtil.thisYear()); + } + if (StrUtil.isBlank(config.getConfigName())) { + config.setConfigName(config.getYear() + "年医疗互助补助配置"); + } + if (config.getStartAmount() == null) { + config.setStartAmount(new BigDecimal("10000.00")); + } + if (config.getFirstYearMaxAmount() == null) { + config.setFirstYearMaxAmount(new BigDecimal("100000.00")); + } + if (config.getOtherYearMaxAmount() == null) { + config.setOtherYearMaxAmount(new BigDecimal("50000.00")); + } + if (config.getStatus() == null) { + config.setStatus(1); + } + } + + /** + * 校验基础配置是否存在,比例与奖励保存必须依赖有效主配置。 + */ + private void ensureConfigExists(Long configId) { + if (fetch(configId) == null) { + throw new BaseException("基础配置不存在,请刷新后重试"); + } + } + + /** + * 记录当前登录人,兼容未登录或测试环境下获取不到登录 ID 的情况。 + */ + private void fillOperator(MutualConfig config) { + String loginId = ""; + try { + loginId = StpUtil.getLoginIdAsString(); + } catch (Exception ignored) { + } + if (config.getId() == null && StrUtil.isBlank(config.getCreateBy())) { + config.setCreateBy(loginId); + } + config.setUpdateBy(loginId); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDiseaseTypeController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDiseaseTypeController.java new file mode 100644 index 0000000..149469b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDiseaseTypeController.java @@ -0,0 +1,76 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalDiseaseTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * 医疗互助疾病类型 PC 端控制器。 + */ +@IocBean +@At("/platform/medicalMutualAid/medical/diseaseType") +@Api("医疗互助疾病类型") +@Ok("json:full") +public class MedicalDiseaseTypeController { + + @Inject + private MedicalDiseaseTypeService medicalDiseaseTypeService; + + /** + * 打开疾病类型 PC 管理页面。 + */ + @At("") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html") + @SaCheckPermission("medicalMutualAid.medical.diseaseType") + public void index() { + } + + /** + * 分页查询疾病类型。 + * + * @param pageForm 分页及查询参数 + * @return 分页结果 + */ + @At + @ApiOperation("分页查询疾病类型") + @SaCheckPermission("medicalMutualAid.medical.diseaseType") + public Result pageData(PageForm pageForm) { + return Result.success(medicalDiseaseTypeService.pageData(pageForm)); + } + + /** + * 保存或修改疾病类型。 + * + * @param medicalDiseaseType 疾病类型表单数据 + * @return 保存结果 + */ + @At + @ApiOperation("保存或修改疾病类型") + @SaCheckPermission("medicalMutualAid.medical.diseaseType") + public Result doSubmit(MedicalDiseaseType medicalDiseaseType) { + medicalDiseaseTypeService.saveDiseaseType(medicalDiseaseType); + return Result.success(); + } + + /** + * 删除指定疾病类型。 + * + * @param id 疾病类型主键 + * @return 删除结果 + */ + @At + @ApiOperation("删除疾病类型") + @SaCheckPermission("medicalMutualAid.medical.diseaseType") + public Result doDelete(String id) { + medicalDiseaseTypeService.deleteDiseaseType(id); + return Result.success(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/h5controller/H5MedicalDiseaseTypeController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/h5controller/H5MedicalDiseaseTypeController.java new file mode 100644 index 0000000..e25920a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/h5controller/H5MedicalDiseaseTypeController.java @@ -0,0 +1,76 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.h5controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalDiseaseTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * 医疗互助疾病类型移动端控制器。 + */ +@IocBean +@At("/platform/h5/medicalMutualAid/medical/diseaseType") +@Api("移动端医疗互助疾病类型") +@Ok("json:full") +public class H5MedicalDiseaseTypeController { + + @Inject + private MedicalDiseaseTypeService medicalDiseaseTypeService; + + /** + * 打开疾病类型移动端管理页面。 + */ + @At("") + @Ok("beetl:/platform/zhghh5/staffbenefit/medicalMutualAid/medical/diseaseType/index.html") + @SaCheckPermission("h5.medicalMutualAid.medical.diseaseType") + public void index() { + } + + /** + * 移动端分页查询疾病类型。 + * + * @param pageForm 分页及查询参数 + * @return 分页结果 + */ + @At + @ApiOperation("移动端分页查询疾病类型") + @SaCheckPermission("h5.medicalMutualAid.medical.diseaseType") + public Result pageData(PageForm pageForm) { + return Result.success(medicalDiseaseTypeService.pageData(pageForm)); + } + + /** + * 移动端保存或修改疾病类型。 + * + * @param medicalDiseaseType 疾病类型表单数据 + * @return 保存结果 + */ + @At + @ApiOperation("移动端保存或修改疾病类型") + @SaCheckPermission("h5.medicalMutualAid.medical.diseaseType") + public Result doSubmit(MedicalDiseaseType medicalDiseaseType) { + medicalDiseaseTypeService.saveDiseaseType(medicalDiseaseType); + return Result.success(); + } + + /** + * 移动端删除指定疾病类型。 + * + * @param id 疾病类型主键 + * @return 删除结果 + */ + @At + @ApiOperation("移动端删除疾病类型") + @SaCheckPermission("h5.medicalMutualAid.medical.diseaseType") + public Result doDelete(String id) { + medicalDiseaseTypeService.deleteDiseaseType(id); + return Result.success(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/model/MedicalDiseaseType.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/model/MedicalDiseaseType.java new file mode 100644 index 0000000..6a273e4 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/model/MedicalDiseaseType.java @@ -0,0 +1,52 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Default; +import org.nutz.dao.entity.annotation.Name; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +/** + * 医疗互助疾病类型实体,用于维护可申请的疾病基础数据。 + */ +@Data +@Comment("医疗互助疾病类型表") +@Accessors(chain = true) +@Table("medical_disease_type") +@EqualsAndHashCode(callSuper = true) +public class MedicalDiseaseType extends BaseModel { + + /** 疾病类型主键。 */ + @Column + @Name + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + /** 疾病名称。 */ + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("疾病名称") + private String diseaseName; + + /** 疾病编码,用于列表排序和业务引用。 */ + @Column + @Comment("疾病编码") + @ColDefine(type = ColType.VARCHAR, width = 20) + private String diseaseCode; + + /** 是否属于重大疾病,默认是。 */ + @Column + @Comment("是否重大疾病") + @Default("1") + @ColDefine(type = ColType.BOOLEAN) + private Boolean isMajorDiseases; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDiseaseTypeService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDiseaseTypeService.java new file mode 100644 index 0000000..9b78f4a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDiseaseTypeService.java @@ -0,0 +1,36 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType; + +/** + * 医疗互助疾病类型服务,统一承载 PC 端与移动端的公共业务逻辑。 + */ +public interface MedicalDiseaseTypeService extends BaseService { + + /** + * 按疾病名称分页查询疾病类型。 + * + * @param pageForm 分页及关键字参数 + * @return 疾病类型分页结果 + */ + Pagination pageData(PageForm pageForm); + + /** + * 新增或修改疾病类型。 + * + * @param medicalDiseaseType 疾病类型表单数据 + * @return 保存后的疾病类型 + */ + MedicalDiseaseType saveDiseaseType(MedicalDiseaseType medicalDiseaseType); + + /** + * 根据主键删除疾病类型。 + * + * @param id 疾病类型主键 + * @return 删除记录数 + */ + int deleteDiseaseType(String id); +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDiseaseTypeServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDiseaseTypeServiceImpl.java new file mode 100644 index 0000000..3ed8a1a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDiseaseTypeServiceImpl.java @@ -0,0 +1,67 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalDiseaseTypeService; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; + +/** + * 医疗互助疾病类型服务实现。 + */ +@IocBean(args = {"refer:dao"}) +public class MedicalDiseaseTypeServiceImpl extends BaseServiceImpl + implements MedicalDiseaseTypeService { + + /** + * 初始化疾病类型服务使用的数据访问对象。 + * + * @param dao 数据访问对象 + */ + public MedicalDiseaseTypeServiceImpl(Dao dao) { + super(dao); + } + + /** + * 构造统一查询条件,确保 PC 端与移动端使用相同的排序和过滤规则。 + */ + @Override + public Pagination pageData(PageForm pageForm) { + Cnd cnd = Cnd.NEW(); + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + // 关键字只匹配疾病名称,保持与源功能查询口径一致。 + cnd.and(Cnd.likeEX("diseaseName", StrUtil.trim(pageForm.getSearchKeyword()))); + } + cnd.asc("diseaseCode"); + return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); + } + + /** + * 保存前规范文本字段,并补全重大疾病默认值。 + */ + @Override + public MedicalDiseaseType saveDiseaseType(MedicalDiseaseType medicalDiseaseType) { + // 去除用户误输入的首尾空格,避免产生看似重复的数据。 + medicalDiseaseType.setDiseaseName(StrUtil.trim(medicalDiseaseType.getDiseaseName())); + medicalDiseaseType.setDiseaseCode(StrUtil.trim(medicalDiseaseType.getDiseaseCode())); + if (medicalDiseaseType.getIsMajorDiseases() == null) { + medicalDiseaseType.setIsMajorDiseases(Boolean.TRUE); + } + return insertOrUpdate(medicalDiseaseType); + } + + /** + * 校验主键后执行删除,避免空主键触发无意义数据库操作。 + */ + @Override + public int deleteDiseaseType(String id) { + if (StrUtil.isBlank(id)) { + return 0; + } + return delete(id); + } +} diff --git a/src/main/resources/db/medical_disease_type_create.sql b/src/main/resources/db/medical_disease_type_create.sql new file mode 100644 index 0000000..edc0d17 --- /dev/null +++ b/src/main/resources/db/medical_disease_type_create.sql @@ -0,0 +1,15 @@ +-- 医疗互助疾病类型基础表;脚本可重复执行。 +CREATE TABLE IF NOT EXISTS `medical_disease_type` ( + `id` varchar(32) NOT NULL COMMENT 'ID', + `diseaseName` varchar(50) NOT NULL COMMENT '疾病名称', + `diseaseCode` varchar(20) NOT NULL COMMENT '疾病编码', + `isMajorDiseases` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否重大疾病', + `createdBy` varchar(32) DEFAULT NULL COMMENT '创建人', + `createdAt` bigint DEFAULT NULL COMMENT '创建时间', + `updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人', + `updatedAt` bigint DEFAULT NULL COMMENT '修改时间', + `delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记', + PRIMARY KEY (`id`), + KEY `idx_medical_disease_type_code` (`diseaseCode`), + KEY `idx_medical_disease_type_name` (`diseaseName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='医疗互助疾病类型表'; diff --git a/src/main/resources/db/medical_mutual_apply_create.sql b/src/main/resources/db/medical_mutual_apply_create.sql new file mode 100644 index 0000000..f1dcb60 --- /dev/null +++ b/src/main/resources/db/medical_mutual_apply_create.sql @@ -0,0 +1,71 @@ +DROP TABLE IF EXISTS `tb_mutual_apply`; +CREATE TABLE `tb_mutual_apply` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `apply_no` varchar(50) DEFAULT NULL COMMENT '申请编号', + `user_id` varchar(50) DEFAULT NULL COMMENT '申请人用户ID', + `login_name` varchar(50) DEFAULT NULL COMMENT '申请人工号/登录名', + `user_name` varchar(50) NOT NULL COMMENT '申请人姓名', + `sex` varchar(20) DEFAULT NULL COMMENT '性别', + `birthday` date DEFAULT NULL COMMENT '出生年月', + `native_place` varchar(100) DEFAULT NULL COMMENT '籍贯', + `education` varchar(50) DEFAULT NULL COMMENT '学历', + `professional_title` varchar(100) DEFAULT NULL COMMENT '职称', + `dept_id` varchar(50) DEFAULT NULL COMMENT '工作部门ID', + `dept_name` varchar(200) DEFAULT NULL COMMENT '工作部门(系部)', + `id_card` varchar(30) DEFAULT NULL COMMENT '身份证号码', + `mobile` varchar(30) DEFAULT NULL COMMENT '联系电话', + `bank_card_no` varchar(50) DEFAULT NULL COMMENT '工资银行卡号', + `bank_name` varchar(200) DEFAULT NULL COMMENT '开户行', + `join_date` date DEFAULT NULL COMMENT '入会时间', + `join_year` int DEFAULT NULL COMMENT '加入年份', + `disease_type_id` varchar(32) DEFAULT NULL COMMENT '大病类型ID', + `disease_name` varchar(200) NOT NULL COMMENT '大病名称', + `hospital_desc` varchar(500) DEFAULT NULL COMMENT '何时何病住何医院', + `medical_total_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '全年医疗费用总金额', + `self_pay_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '自付金额', + `sign_file_id` varchar(50) DEFAULT NULL COMMENT '申请人签名文件ID', + `sign_time` datetime DEFAULT NULL COMMENT '申请人签名时间', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 0未审核 1已审核', + `submit_time` datetime DEFAULT NULL COMMENT '提交时间', + `audit_by` varchar(50) DEFAULT NULL COMMENT '审核人', + `audit_time` datetime DEFAULT NULL COMMENT '审核时间', + `audit_opinion` varchar(500) DEFAULT NULL COMMENT '审核意见', + `config_id` bigint DEFAULT NULL COMMENT '审核使用的互助金配置ID', + `config_year` int DEFAULT NULL COMMENT '审核使用的配置年度', + `subsidy_total_amount` decimal(12,2) DEFAULT NULL COMMENT '补助小计', + `bonus_ratio` decimal(5,2) DEFAULT NULL COMMENT '奖励/补助系数', + `actual_subsidy_amount` decimal(12,2) DEFAULT NULL COMMENT '实际补助金额', + `continuous_unapply_year` int DEFAULT NULL COMMENT '连续未申请年数', + `limit_amount` decimal(12,2) DEFAULT NULL COMMENT '本次适用最高补助限额', + `remark` varchar(500) DEFAULT NULL COMMENT '备注', + `create_by` varchar(50) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_by` varchar(50) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_login_name` (`login_name`), + KEY `idx_dept_id` (`dept_id`), + KEY `idx_status` (`status`), + KEY `idx_disease_type_id` (`disease_type_id`), + KEY `idx_join_year` (`join_year`), + KEY `idx_submit_time` (`submit_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='互助金申请表'; + +DROP TABLE IF EXISTS `tb_mutual_apply_subsidy`; +CREATE TABLE `tb_mutual_apply_subsidy` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `apply_id` bigint NOT NULL COMMENT '申请ID', + `ratio_id` bigint DEFAULT NULL COMMENT '使用的补助比例配置ID', + `range_name` varchar(100) DEFAULT NULL COMMENT '区间名称', + `start_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '区间开始金额', + `end_amount` decimal(12,2) DEFAULT NULL COMMENT '区间结束金额(NULL表示无限)', + `ratio` decimal(5,2) NOT NULL DEFAULT '0.00' COMMENT '补助比例(%)', + `base_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '本区间参与计算金额', + `subsidy_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '本区间补助金额', + `sort` int DEFAULT 1 COMMENT '排序', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_apply_id` (`apply_id`), + KEY `idx_ratio_id` (`ratio_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='互助金补贴金额明细表'; diff --git a/src/main/resources/db/menu/init_medical_disease_type_menu.sql b/src/main/resources/db/menu/init_medical_disease_type_menu.sql new file mode 100644 index 0000000..86f9bc5 --- /dev/null +++ b/src/main/resources/db/menu/init_medical_disease_type_menu.sql @@ -0,0 +1,51 @@ +-- 医疗互助疾病类型 PC 端与移动端菜单。 +-- 使用 permission 做幂等判断,重复执行不会插入重复菜单。 + +-- PC 端一级菜单。 +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService) +SELECT 'e5d7a110aa214cdf8505fd0000000001', '', LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'), '医疗互助', 'Medical Mutual Aid', 'menu', '', '', 'ti-heart', 1, 0, 'medicalMutualAid', NULL, 992, 1, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'y', 0, 0 +FROM sys_menu +WHERE platform = 'PC' AND (parentId = '' OR parentId IS NULL) AND CHAR_LENGTH(path) = 4 +HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'medicalMutualAid' AND platform = 'PC') t); + +-- PC 端医疗管理分组。 +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService) +SELECT 'e5d7a110aa214cdf8505fd0000000002', p.id, CONCAT(p.path, '0001'), '医疗管理', 'Medical Manage', 'menu', '', '', '', 1, 0, 'medicalMutualAid.medical', NULL, 1, 1, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'y', 0, 0 +FROM sys_menu p +WHERE p.permission = 'medicalMutualAid' AND p.platform = 'PC' + AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'medicalMutualAid.medical' AND platform = 'PC') t); + +-- PC 端疾病种类页面。 +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService) +SELECT 'e5d7a110aa214cdf8505fd0000000003', p.id, CONCAT(p.path, '0001'), '疾病种类', 'Disease Type', 'menu', '/platform/medicalMutualAid/medical/diseaseType', 'data-pjax', '', 1, 0, 'medicalMutualAid.medical.diseaseType', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'j', 0, 0 +FROM sys_menu p +WHERE p.permission = 'medicalMutualAid.medical' AND p.platform = 'PC' + AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'medicalMutualAid.medical.diseaseType' AND platform = 'PC') t); + +-- 移动端一级菜单。 +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService) +SELECT 'e5d7a110aa214cdf8505fd0000000004', '', LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'), '医疗互助', 'Medical Mutual Aid', 'menu', '', '', 'heart-o', 1, 0, 'h5.medicalMutualAid', NULL, 992, 1, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'H5', NULL, NULL, 'y', 0, 0 +FROM sys_menu +WHERE platform = 'H5' AND (parentId = '' OR parentId IS NULL) AND CHAR_LENGTH(path) = 4 +HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'h5.medicalMutualAid' AND platform = 'H5') t); + +-- 移动端疾病种类页面,权限严格使用 h5. 前缀。 +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService) +SELECT 'e5d7a110aa214cdf8505fd0000000005', p.id, CONCAT(p.path, '0001'), '疾病种类', 'Disease Type', 'menu', '/platform/h5/medicalMutualAid/medical/diseaseType', 'data-pjax', '', 1, 0, 'h5.medicalMutualAid.medical.diseaseType', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'H5', NULL, NULL, 'j', 0, 0 +FROM sys_menu p +WHERE p.permission = 'h5.medicalMutualAid' AND p.platform = 'H5' + AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'h5.medicalMutualAid.medical.diseaseType' AND platform = 'H5') t); + +-- 默认授予系统管理员,其他角色可在角色管理中按需分配。 +INSERT INTO sys_role_menu (roleId, menuId) +SELECT r.id, m.id +FROM sys_role r +JOIN sys_menu m ON m.permission IN ( + 'medicalMutualAid', + 'medicalMutualAid.medical', + 'medicalMutualAid.medical.diseaseType', + 'h5.medicalMutualAid', + 'h5.medicalMutualAid.medical.diseaseType' +) +LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id +WHERE r.code = 'SYSADMIN' AND rm.roleId IS NULL; diff --git a/src/main/resources/templates/medicalMutualAid/medical_mutual_aid_apply_form.docx b/src/main/resources/templates/medicalMutualAid/medical_mutual_aid_apply_form.docx new file mode 100644 index 0000000000000000000000000000000000000000..21780ae4fd2fe2e3e6230b77e857028c7d0cdc1f GIT binary patch literal 13492 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/templates/medicalMutualAid/~$dical_mutual_aid_apply_form.docx b/src/main/resources/templates/medicalMutualAid/~$dical_mutual_aid_apply_form.docx new file mode 100644 index 0000000000000000000000000000000000000000..8601cc0f2a6baf1d3f49350619de0d3771c31c91 GIT binary patch literal 162 dcmZR{O{~mgAQiAM + +
+
+ + + + + + + + + + + + + + + + 查询 + 重置 + + +
+
+
+
互助会审核
+
+ + + + + + + + + + + + + + + + + + + +
+ 共 {{ totalCount }} 条 + +
+
+
+ + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/review.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/review.html new file mode 100644 index 0000000..9f92da3 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/audit/review.html @@ -0,0 +1,275 @@ + + + +
+
+ 返回 +
+ +
申请信息
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
补助计算方法
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ 当前申报人本年度已申报:{{ formatMoney(yearLimit.yearUsedAmount) }},剩余可申报金额:{{ formatMoney(yearLimit.yearRemainAmount) }} +
+ + +
+
+ + + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/form/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/form/index.html new file mode 100644 index 0000000..78dfea6 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/form/index.html @@ -0,0 +1,258 @@ + + + +
+
+
申请信息
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 返回 + 暂存 + 提交申请 +
+
+
+ + + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/form.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/form.html new file mode 100644 index 0000000..d9e2dea --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/form.html @@ -0,0 +1,281 @@ + + + +
+
+ 返回 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+ +
+
+ + + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/index.html new file mode 100644 index 0000000..30a6de9 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/mine/index.html @@ -0,0 +1,213 @@ + + +
+
+ + + + + + + + 搜索 + 重置 + + +
+ +
+
+
我的申请
+ + + 互助金申请 + +
+ + + + + + + + + + + + + + + + + + +
+ 共 {{ totalCount }} 条 + +
+
+
+ + + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/summary/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/summary/index.html new file mode 100644 index 0000000..d84221f --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/apply/summary/index.html @@ -0,0 +1,200 @@ + + +
+
+ + + + + + + + + + + + 查询 + 重置 + 导出 + + +
+
+
+
医疗互助汇总
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ 共 {{ totalCount }} 条 + +
+
+
+ + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/config/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/config/index.html new file mode 100644 index 0000000..2bc4a69 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/config/index.html @@ -0,0 +1,689 @@ + + + +
+
+ + + + + + + + + + + 搜索 + 重置 + + +
+ +
+
+ 医疗互助配置 + 新增 +
+ + + + + + + + + + + + + + + + + + + + +
+ 共 {{ configList.length }} 条 + + +
+
+ + +
+ + +
+
基本信息
+ + + + + + + + + + + + + + + + + + + + + + + + + 启用 + 停用 + + + + + + + + + + + + + + + + + + + +
+ +
+
+
补助比例配置(超额累计计算)
+ 新增比例 +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
连续未申请奖励配置
+ 新增奖励 +
+ + + + + + + + + + + + + + + +
+
+ + +
+
会员缴费配置
+ + + + + + + 连续缴费满该年限后,次年缴费减半 + + +
+
+
+
+ + 取消 + 确认 + +
+ +
+ + + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html new file mode 100644 index 0000000..bd6f660 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html @@ -0,0 +1,131 @@ + +
+ + + + + + + + + + + + + 新增疾病种类 + + + + + + + + + + + + + + + + + + + + + + + + + + + 是 + 否 + + + + + 取消 + 确定 + + +
+ + + diff --git a/src/main/resources/views/platform/zhghh5/staffbenefit/medicalMutualAid/medical/diseaseType/index.html b/src/main/resources/views/platform/zhghh5/staffbenefit/medicalMutualAid/medical/diseaseType/index.html new file mode 100644 index 0000000..5ed5896 --- /dev/null +++ b/src/main/resources/views/platform/zhghh5/staffbenefit/medicalMutualAid/medical/diseaseType/index.html @@ -0,0 +1,210 @@ + + + +
+ + + +
+ + 新增 +
+
+ + + +
+
+ {{row.diseaseName}} + + {{row.isMajorDiseases ? "重大疾病" : "普通疾病"}} + +
+
编号:{{row.diseaseCode}}
+
+ 编辑 + 删除 +
+
+
+
+ + + + + + + + + + + + +
+ + +