医疗互助补助模块
This commit is contained in:
@@ -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
|
||||
|
||||
+86
@@ -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));
|
||||
}
|
||||
}
|
||||
+127
@@ -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));
|
||||
}
|
||||
}
|
||||
+143
@@ -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);
|
||||
}
|
||||
}
|
||||
+71
@@ -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);
|
||||
}
|
||||
}
|
||||
+269
@@ -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;
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
+130
@@ -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<MutualApply> {
|
||||
|
||||
/**
|
||||
* 构建申请页面初始化数据,包含当前用户占位信息和疾病类型下拉数据。
|
||||
*
|
||||
* @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<MutualApply> 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<MutualApply> 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<NutMap> 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);
|
||||
}
|
||||
+999
@@ -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<MutualApply>
|
||||
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<MedicalDiseaseType> 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<MutualApply> 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<String, Object> 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<MutualApply> 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<MutualApplySubsidy> 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<MutualApplySubsidy> 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<NutMap> summaryPage(PageForm pageForm, String deptName, String userName, Integer joinYear) {
|
||||
Cnd cnd = buildSummaryCnd(deptName, userName, joinYear);
|
||||
Pagination<MutualApply> page = listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd.desc("auditTime"));
|
||||
List<NutMap> 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<MutualApply> applies = query(buildSummaryCnd(deptName, userName, joinYear).desc("auditTime"));
|
||||
List<String> rangeNames = collectSummaryRangeNames(applies);
|
||||
List<ExcelExportEntity> exportEntities = buildSummaryExportEntities(rangeNames);
|
||||
List<Map<String, Object>> 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<MutualApplySubsidy> buildSubsidyPreview(MutualApply apply, MutualConfig config) {
|
||||
if (config == null) {
|
||||
return List.of();
|
||||
}
|
||||
BigDecimal selfPayAmount = toBigDecimal(apply.getSelfPayAmount());
|
||||
List<MutualRatio> 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<MutualApplySubsidy> 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<MutualApplySubsidy> 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<String> collectSummaryRangeNames(List<MutualApply> applies) {
|
||||
List<String> rangeNames = new ArrayList<>();
|
||||
for (MutualApply apply : applies) {
|
||||
List<MutualApplySubsidy> 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<ExcelExportEntity> buildSummaryExportEntities(List<String> rangeNames) {
|
||||
List<ExcelExportEntity> 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<Map<String, Object>> buildSummaryExportRows(List<MutualApply> applies, List<String> rangeNames) {
|
||||
List<Map<String, Object>> rows = new ArrayList<>();
|
||||
for (int i = 0; i < applies.size(); i++) {
|
||||
MutualApply apply = applies.get(i);
|
||||
Map<String, Object> 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<MutualApplySubsidy> 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<String, Object> buildMineApplyFormDocData(MutualApply apply) {
|
||||
Date signDate = firstNotNullDate(apply.getSignTime(), apply.getSubmitTime(), apply.getCreateTime());
|
||||
Map<String, Object> 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<String> 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();
|
||||
}
|
||||
}
|
||||
+158
@@ -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));
|
||||
}
|
||||
}
|
||||
+48
@@ -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;
|
||||
}
|
||||
+97
@@ -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;
|
||||
}
|
||||
+35
@@ -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;
|
||||
}
|
||||
+58
@@ -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;
|
||||
}
|
||||
+109
@@ -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<MutualConfig> {
|
||||
|
||||
/**
|
||||
* 查询指定年度的完整配置数据。
|
||||
*
|
||||
* @param year 年度,为空时使用当前年份
|
||||
* @return 包含基础配置、比例列表、奖励列表和会员缴费配置的聚合数据
|
||||
*/
|
||||
NutMap getConfigData(Integer year);
|
||||
|
||||
/**
|
||||
* 查询互助金配置列表,用于配置列表页按年度和配置名称筛选历史配置。
|
||||
*
|
||||
* @param year 年度,为空时不限制年度
|
||||
* @param configName 配置名称,为空时不限制名称
|
||||
* @return 互助金基础配置列表
|
||||
*/
|
||||
List<MutualConfig> listConfigs(Integer year, String configName);
|
||||
|
||||
/**
|
||||
* 保存互助金基础配置。
|
||||
*
|
||||
* @param config 互助金基础配置表单
|
||||
* @return 保存后的互助金基础配置
|
||||
*/
|
||||
MutualConfig saveConfig(MutualConfig config);
|
||||
|
||||
/**
|
||||
* 删除互助金基础配置,并同步删除其下比例配置和奖励配置。
|
||||
*
|
||||
* @param configId 基础配置 ID
|
||||
*/
|
||||
void deleteConfig(Long configId);
|
||||
|
||||
/**
|
||||
* 查询指定基础配置下的补助比例列表。
|
||||
*
|
||||
* @param configId 基础配置 ID
|
||||
* @return 补助比例列表
|
||||
*/
|
||||
List<MutualRatio> listRatios(Long configId);
|
||||
|
||||
/**
|
||||
* 保存补助比例配置。
|
||||
*
|
||||
* @param ratio 补助比例表单
|
||||
* @return 保存后的补助比例
|
||||
*/
|
||||
MutualRatio saveRatio(MutualRatio ratio);
|
||||
|
||||
/**
|
||||
* 删除补助比例配置。
|
||||
*
|
||||
* @param ratioId 补助比例 ID
|
||||
*/
|
||||
void deleteRatio(Long ratioId);
|
||||
|
||||
/**
|
||||
* 查询指定基础配置下的连续未申请奖励列表。
|
||||
*
|
||||
* @param configId 基础配置 ID
|
||||
* @return 连续未申请奖励列表
|
||||
*/
|
||||
List<MutualBonus> 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);
|
||||
}
|
||||
+263
@@ -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<MutualConfig>
|
||||
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<MutualConfig> 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<MutualRatio> 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<MutualBonus> 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);
|
||||
}
|
||||
}
|
||||
+76
@@ -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();
|
||||
}
|
||||
}
|
||||
+76
@@ -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();
|
||||
}
|
||||
}
|
||||
+52
@@ -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;
|
||||
}
|
||||
+36
@@ -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<MedicalDiseaseType> {
|
||||
|
||||
/**
|
||||
* 按疾病名称分页查询疾病类型。
|
||||
*
|
||||
* @param pageForm 分页及关键字参数
|
||||
* @return 疾病类型分页结果
|
||||
*/
|
||||
Pagination<MedicalDiseaseType> pageData(PageForm pageForm);
|
||||
|
||||
/**
|
||||
* 新增或修改疾病类型。
|
||||
*
|
||||
* @param medicalDiseaseType 疾病类型表单数据
|
||||
* @return 保存后的疾病类型
|
||||
*/
|
||||
MedicalDiseaseType saveDiseaseType(MedicalDiseaseType medicalDiseaseType);
|
||||
|
||||
/**
|
||||
* 根据主键删除疾病类型。
|
||||
*
|
||||
* @param id 疾病类型主键
|
||||
* @return 删除记录数
|
||||
*/
|
||||
int deleteDiseaseType(String id);
|
||||
}
|
||||
+67
@@ -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<MedicalDiseaseType>
|
||||
implements MedicalDiseaseTypeService {
|
||||
|
||||
/**
|
||||
* 初始化疾病类型服务使用的数据访问对象。
|
||||
*
|
||||
* @param dao 数据访问对象
|
||||
*/
|
||||
public MedicalDiseaseTypeServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造统一查询条件,确保 PC 端与移动端使用相同的排序和过滤规则。
|
||||
*/
|
||||
@Override
|
||||
public Pagination<MedicalDiseaseType> 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);
|
||||
}
|
||||
}
|
||||
@@ -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='医疗互助疾病类型表';
|
||||
@@ -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='互助金补贴金额明细表';
|
||||
@@ -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;
|
||||
Binary file not shown.
Binary file not shown.
+221
@@ -0,0 +1,221 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.mutual-list-page { padding: 16px 20px; background: #f3f6fa; height: calc(100vh - 88px); box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.search-panel { background: #fff; padding: 16px 42px; margin-bottom: 12px; box-sizing: border-box; flex-shrink: 0; }
|
||||
.search-panel .el-form-item { margin-bottom: 0; margin-right: 14px; }
|
||||
.content-panel { background: #fff; padding: 16px 20px 16px; box-sizing: border-box; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
||||
.panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
|
||||
.section-title { border-left: 4px solid #0079c2; padding-left: 10px; color: #0079c2; font-size: 16px; font-weight: 700; line-height: 22px; }
|
||||
.table-actions .el-button { min-width: 54px; padding: 7px 14px; border-radius: 2px; }
|
||||
.mutual-table.el-table th { background: #fafafa; color: #303133; font-weight: 700; }
|
||||
.mutual-table.el-table td, .mutual-table.el-table th { padding: 11px 0; }
|
||||
.pager { display: flex; justify-content: flex-start; align-items: center; padding-top: 12px; flex-shrink: 0; }
|
||||
.pager .total-text { margin-right: 18px; color: #303133; }
|
||||
</style>
|
||||
<div id="app" v-cloak class="mutual-list-page">
|
||||
<div class="search-panel">
|
||||
<el-form :inline="true" :model="searchForm">
|
||||
<el-form-item label="工号/姓名">
|
||||
<el-input v-model="searchForm.keyword" clearable placeholder="请输入工号或姓名" style="width: 220px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="大病名称">
|
||||
<el-select v-model="searchForm.diseaseName" clearable filterable placeholder="请选择大病名称" style="width: 220px">
|
||||
<el-option v-for="item in diseaseTypes" :key="item.id" :label="item.diseaseName" :value="item.diseaseName"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" clearable placeholder="请选择状态" style="width: 160px">
|
||||
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadPage">查询</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="content-panel" ref="contentPanel">
|
||||
<div class="panel-header" ref="panelHeader">
|
||||
<div class="section-title">互助会审核</div>
|
||||
</div>
|
||||
<el-table class="mutual-table" :data="tableData" border v-loading="loading" :height="tableHeight" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
|
||||
<el-table-column prop="loginName" label="申请人工号" width="130" align="center"></el-table-column>
|
||||
<el-table-column prop="userName" label="申请人姓名" width="130" align="center"></el-table-column>
|
||||
<el-table-column prop="joinDate" label="入会时间" width="130" align="center"></el-table-column>
|
||||
<el-table-column prop="diseaseName" label="大病名称" min-width="200" align="center"></el-table-column>
|
||||
<el-table-column label="全年医疗费用总金额(元)" width="190" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.medicalTotalAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自费金额(元)" width="150" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.selfPayAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag v-if="isAudited(row)" type="success" size="mini">已审核</el-tag>
|
||||
<el-tag v-else-if="isDiscarded(row)" type="danger" size="mini">已作废</el-tag>
|
||||
<el-tag v-else type="warning" size="mini">未审核</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="260" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<div class="table-actions">
|
||||
<el-button size="mini" @click="goView(row)">查看</el-button>
|
||||
<el-button v-if="isPending(row)" size="mini" type="primary" @click="goReview(row)">审核</el-button>
|
||||
<el-button v-if="isAudited(row)" size="mini" type="warning" @click="cancelAudit(row)">弃审</el-button>
|
||||
<el-button v-if="isPending(row)" size="mini" type="danger" @click="discard(row)">作废</el-button>
|
||||
<el-button v-if="isDiscarded(row)" size="mini" type="warning" @click="cancelDiscard(row)">取消作废</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager" ref="pager">
|
||||
<span class="total-text">共 {{ totalCount }} 条</span>
|
||||
<el-pagination background layout="sizes, prev, pager, next" :current-page.sync="pageForm.pageNumber" :page-size.sync="pageForm.pageSize" :total="totalCount" @current-change="loadPage" @size-change="loadPage"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tableData: [],
|
||||
diseaseTypes: [],
|
||||
statusOptions: [
|
||||
{ label: "未审核", value: 0 },
|
||||
{ label: "已审核", value: 1 },
|
||||
{ label: "作废", value: 2 }
|
||||
],
|
||||
totalCount: 0,
|
||||
tableHeight: 360,
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/audit",
|
||||
reviewPath: "${base!}/platform/medicalMutualAid/apply/audit/review",
|
||||
diseaseTypeApi: "${base!}/platform/medicalMutualAid/medical/diseaseType",
|
||||
searchForm: { keyword: "", diseaseName: "", status: "" },
|
||||
pageForm: { pageNumber: 1, pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载互助疾病类型下拉,查询条件与申请页面共用疾病基础数据。
|
||||
loadDiseaseTypes() {
|
||||
this.$axios.post(this.diseaseTypeApi + "/pageData", { pageNumber: 1, pageSize: 999 }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.diseaseTypes = resp.data.list || []
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查询互助金待审核/已审核申请列表。
|
||||
loadPage() {
|
||||
this.loading = true
|
||||
const params = Object.assign({}, this.pageForm, this.searchForm)
|
||||
if (params.status === "" || params.status === null || params.status === undefined) {
|
||||
delete params.status
|
||||
}
|
||||
this.$axios.post(this.apiBase + "/page", params).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list || []
|
||||
this.totalCount = resp.data.totalCount || 0
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.$nextTick(this.updateTableHeight)
|
||||
})
|
||||
},
|
||||
// 重置审核列表查询条件。
|
||||
resetSearch() {
|
||||
this.searchForm = { keyword: "", diseaseName: "", status: "" }
|
||||
this.pageForm.pageNumber = 1
|
||||
this.loadPage()
|
||||
},
|
||||
// 进入审核详情页,具体补助公式在详情页中展示。
|
||||
goReview(row) {
|
||||
commonUtil.pjaxPush(this.reviewPath + "?id=" + row.id)
|
||||
},
|
||||
// 查看复用审核详情页,通过 mode=view 控制页面只读并隐藏审核操作。
|
||||
goView(row) {
|
||||
commonUtil.pjaxPush(this.reviewPath + "?id=" + row.id + "&mode=view")
|
||||
},
|
||||
// 统一判断审核状态,兼容后端返回数字或字符串。
|
||||
isAudited(row) {
|
||||
return Number(row.status) === 1
|
||||
},
|
||||
// 未审核状态允许进入审核或作废。
|
||||
isPending(row) {
|
||||
return Number(row.status) === 0
|
||||
},
|
||||
// 作废状态只允许取消作废,不能继续审核或弃审。
|
||||
isDiscarded(row) {
|
||||
return Number(row.status) === 2
|
||||
},
|
||||
// 已审核申请支持弃审,恢复未审核状态并清理补助明细后刷新列表。
|
||||
cancelAudit(row) {
|
||||
this.$confirm("确定要弃审该互助金申请吗?", "提示", {
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post(this.apiBase + "/cancelAudit", { id: row.id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success("弃审成功")
|
||||
this.loadPage()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 作废未审核申请,后台会记录当前操作人为审核人并记录审核时间。
|
||||
discard(row) {
|
||||
this.$confirm("确定要作废该互助金申请吗?", "提示", {
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post(this.apiBase + "/discard", { id: row.id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success("作废成功")
|
||||
this.loadPage()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 取消作废后恢复未审核状态,并清空作废时写入的审核人和审核时间。
|
||||
cancelDiscard(row) {
|
||||
this.$confirm("确定要取消作废该互助金申请吗?", "提示", {
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post(this.apiBase + "/cancelDiscard", { id: row.id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success("取消作废成功")
|
||||
this.loadPage()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
formatMoney(value) {
|
||||
const num = Number(value || 0)
|
||||
return num.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
},
|
||||
// 根据内容面板剩余空间计算表格高度,避免列表高度受数据条数影响。
|
||||
updateTableHeight() {
|
||||
const panel = this.$refs.contentPanel
|
||||
if (!panel) {
|
||||
return
|
||||
}
|
||||
const headerHeight = this.$refs.panelHeader ? this.$refs.panelHeader.offsetHeight : 0
|
||||
const pagerHeight = this.$refs.pager ? this.$refs.pager.offsetHeight : 0
|
||||
this.tableHeight = Math.max(panel.clientHeight - headerHeight - pagerHeight - 32, 220)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadDiseaseTypes()
|
||||
this.loadPage()
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(this.updateTableHeight)
|
||||
window.addEventListener("resize", this.updateTableHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("resize", this.updateTableHeight)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#}#-->
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.audit-review-page { background: #f5f7fa; height: calc(100vh - 88px); display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box; }
|
||||
.back-bar { background: #fff; padding: 14px 24px; margin-bottom: 12px; border-bottom: 1px solid #ebeef5; flex-shrink: 0; }
|
||||
.back-bar .el-button { padding: 0; font-size: 15px; }
|
||||
.audit-review-card { flex: 1; min-height: 0; height: auto !important; overflow: hidden; }
|
||||
.audit-review-card .card-body { flex: 1; min-height: 0; overflow-y: auto; box-sizing: border-box; }
|
||||
.audit-review-card .el-card__footer { flex-shrink: 0; }
|
||||
.section-title { border-left: 4px solid #0079c2; padding-left: 10px; margin: 4px 0 14px; color: #0079c2; font-weight: 700; }
|
||||
.required-star { color: #f56c6c; padding-right: 4px; font-weight: 700; }
|
||||
.mutual-desc .el-descriptions-item__label { width: 150px; color: #303133; background: #fafafa; }
|
||||
.mutual-desc .el-descriptions-item__content { min-width: 220px; }
|
||||
.mutual-desc .el-form-item { margin-bottom: 0; }
|
||||
.mutual-desc .el-input-number { width: 100%; }
|
||||
.calc-block { margin-top: 16px; }
|
||||
.calc-table .cell { line-height: 22px; }
|
||||
.limit-tip { color: #f56c6c; font-size: 13px; line-height: 22px; margin: 12px 0 0; }
|
||||
.audit-actions { text-align: right; }
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak class="audit-review-page">
|
||||
<div class="back-bar">
|
||||
<el-button type="text" icon="el-icon-back" @click="goBack">返回</el-button>
|
||||
</div>
|
||||
<custom-card class="audit-review-card" v-loading="loading">
|
||||
<div class="section-title">申请信息</div>
|
||||
<el-form :model="apply" label-width="0">
|
||||
<el-descriptions class="mutual-desc" :column="3" border>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工号</template>
|
||||
<el-input v-model="apply.loginName" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>姓名</template>
|
||||
<el-input v-model="apply.userName" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">入会日期</template>
|
||||
<el-input :value="formatDate(apply.joinDate)" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">入会时间(年)</template>
|
||||
<el-input :value="calcJoinYears(apply.joinYear)" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">性别</template>
|
||||
<el-input v-model="apply.sex" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">出生年月</template>
|
||||
<el-input :value="formatDate(apply.birthday)" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">籍贯</template>
|
||||
<el-input v-model="apply.nativePlace" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">工作部门(系部)</template>
|
||||
<el-input v-model="apply.deptName" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">学历</template>
|
||||
<el-input v-model="apply.education" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">职称</template>
|
||||
<el-input v-model="apply.professionalTitle" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>身份证号码</template>
|
||||
<el-input v-model="apply.idCard" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>联系电话</template>
|
||||
<el-input v-model="apply.mobile" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工资银行卡号</template>
|
||||
<el-input v-model="apply.bankCardNo" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>开户行</template>
|
||||
<el-input v-model="apply.bankName" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item></el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>大病名称</template>
|
||||
<el-input v-model="apply.diseaseName" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>何时何病住何医院</template>
|
||||
<el-input type="textarea" :rows="5" v-model="apply.hospitalDesc" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>全年医疗费用总金额(元)</template>
|
||||
<el-input :value="formatMoney(apply.medicalTotalAmount)" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>自费金额(元)</template>
|
||||
<el-input :value="formatMoney(apply.selfPayAmount)" readonly></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-form>
|
||||
|
||||
<div class="calc-block">
|
||||
<div class="section-title">补助计算方法</div>
|
||||
<el-table class="calc-table" :data="calcRows" border style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
|
||||
<el-table-column label="补助计算方法" align="center">
|
||||
<el-table-column v-for="item in subsidies" :key="item.id || item.ratioId || item.sort" :label="item.rangeName" align="center" min-width="150">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.amounts[item.sort]) }}</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助小计" align="center" min-width="140">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.total) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助比例" align="center" min-width="120">
|
||||
<template slot-scope="{row}">{{ formatRatio(row.bonusRatio) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际补助金额(元)" align="center" min-width="160">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.actualSubsidyAmount) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-descriptions class="mutual-desc" :column="3" border style="margin-top: 12px">
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label">备注</template>
|
||||
<el-input type="textarea" :rows="3" maxlength="500" show-word-limit v-model="auditForm.remark" :readonly="isViewMode" placeholder="请输入备注(选填)"></el-input>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="limit-tip" v-if="showYearLimitTip">
|
||||
当前申报人本年度已申报:{{ formatMoney(yearLimit.yearUsedAmount) }},剩余可申报金额:{{ formatMoney(yearLimit.yearRemainAmount) }}
|
||||
</div>
|
||||
|
||||
<template slot="footer" v-if="!isViewMode">
|
||||
<div class="audit-actions">
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
<el-button type="primary" @click="approve">审核通过</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</custom-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
id: "",
|
||||
pageMode: "audit",
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/audit/review",
|
||||
auditPath: "${base!}/platform/medicalMutualAid/apply/audit",
|
||||
apply: {},
|
||||
subsidies: [],
|
||||
yearLimit: { yearUsedAmount: 0, yearRemainAmount: 0, yearLimitAmount: 0 },
|
||||
auditForm: { bonusRatio: "", actualSubsidyAmount: "", remark: "" }
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 查看模式由列表页传入,统一控制审核详情页隐藏操作按钮和锁定可编辑项。
|
||||
isViewMode() {
|
||||
return this.pageMode === "view"
|
||||
},
|
||||
// 年度同病种限额提示仅在审核计算结果返回后展示。
|
||||
showYearLimitTip() {
|
||||
return this.yearLimit.yearLimitAmount !== undefined && this.yearLimit.yearLimitAmount !== null
|
||||
},
|
||||
// 审核详情只展示一条申请的动态补助结果,表格列由后台配置区间决定。
|
||||
calcRows() {
|
||||
const amounts = {}
|
||||
let total = 0
|
||||
this.subsidies.forEach((item) => {
|
||||
amounts[item.sort] = item.subsidyAmount
|
||||
total += Number(item.subsidyAmount || 0)
|
||||
})
|
||||
return [{
|
||||
amounts: amounts,
|
||||
total: total,
|
||||
bonusRatio: this.apply.bonusRatio,
|
||||
actualSubsidyAmount: this.apply.actualSubsidyAmount
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 从 URL 中读取审核申请 ID,保持审核列表跳转参数简单明确。
|
||||
getQuery(name) {
|
||||
const query = window.location.search ? window.location.search.substring(1) : ""
|
||||
const parts = query.split("&")
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const pair = parts[i].split("=")
|
||||
if (decodeURIComponent(pair[0] || "") === name) {
|
||||
return decodeURIComponent(pair[1] || "")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
},
|
||||
// 加载审核详情,后台会同步返回基金会员入会信息和本年度启用配置计算结果。
|
||||
loadDetail() {
|
||||
this.loading = true
|
||||
this.$axios.post(this.apiBase + "/detail", { id: this.id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.apply = resp.data.apply || {}
|
||||
this.subsidies = resp.data.subsidies || []
|
||||
this.yearLimit = {
|
||||
yearUsedAmount: resp.data.yearUsedAmount || 0,
|
||||
yearRemainAmount: resp.data.yearRemainAmount || 0,
|
||||
yearLimitAmount: resp.data.yearLimitAmount || 0
|
||||
}
|
||||
this.auditForm.bonusRatio = this.formatRatio(this.apply.bonusRatio)
|
||||
this.auditForm.actualSubsidyAmount = this.formatMoney(this.apply.actualSubsidyAmount)
|
||||
this.auditForm.remark = this.apply.remark || ""
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 审核通过时提交后台重算后的补助比例、实际补助金额和审核备注。
|
||||
approve() {
|
||||
const params = {
|
||||
id: this.id,
|
||||
bonusRatio: this.apply.bonusRatio,
|
||||
actualSubsidyAmount: this.apply.actualSubsidyAmount,
|
||||
remark: this.auditForm.remark
|
||||
}
|
||||
this.$axios.post(this.apiBase + "/approve", params).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success("审核通过")
|
||||
this.goBack()
|
||||
}
|
||||
})
|
||||
},
|
||||
goBack() {
|
||||
commonUtil.pjaxPush(this.auditPath)
|
||||
},
|
||||
formatDate(value) {
|
||||
if (!value) {
|
||||
return ""
|
||||
}
|
||||
return this.$moment(value).format("YYYY-MM-DD")
|
||||
},
|
||||
formatRatio(value) {
|
||||
if (value === undefined || value === null || value === "") {
|
||||
return ""
|
||||
}
|
||||
return Number(value).toFixed(2)
|
||||
},
|
||||
// 入会时间(年)只表达基金会员入会年限,不参与表格展示列控制。
|
||||
calcJoinYears(joinYear) {
|
||||
if (!joinYear) {
|
||||
return ""
|
||||
}
|
||||
const currentYear = new Date().getFullYear()
|
||||
return Math.max(currentYear - Number(joinYear), 0)
|
||||
},
|
||||
formatMoney(value) {
|
||||
const num = Number(value || 0)
|
||||
const fixed = Math.floor(num * 100) / 100
|
||||
const parts = fixed.toFixed(2).split(".")
|
||||
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "." + parts[1]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.id = this.getQuery("id")
|
||||
this.pageMode = this.getQuery("mode") || "audit"
|
||||
this.loadDetail()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.mutual-apply-page { padding: 12px; background: #f5f7fa; min-height: calc(100vh - 24px); }
|
||||
.mutual-apply-card { background: #fff; border: 1px solid #e4e7ed; border-radius: 4px; padding: 16px; }
|
||||
.section-title { border-left: 4px solid #0079c2; padding-left: 10px; margin: 8px 0 14px; color: #0079c2; font-weight: 700; }
|
||||
.required-star { color: #f56c6c; padding-right: 4px; font-weight: 700; }
|
||||
.mutual-desc .el-descriptions-item__label { width: 150px; color: #303133; background: #fafafa; }
|
||||
.mutual-desc .el-descriptions-item__content { min-width: 220px; }
|
||||
.mutual-desc .el-form-item { margin-bottom: 0; }
|
||||
.mutual-desc .el-form-item__error { padding-top: 2px; }
|
||||
.mutual-desc .el-input-number { width: 100%; }
|
||||
.actions { text-align: right; padding-top: 18px; }
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak class="mutual-apply-page">
|
||||
<div class="mutual-apply-card">
|
||||
<div class="section-title">申请信息</div>
|
||||
<el-form :model="formData" ref="form" :rules="formRules" label-width="0" v-loading="loading">
|
||||
<el-descriptions class="mutual-desc" :column="3" border>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工号</template>
|
||||
<el-form-item prop="loginName">
|
||||
<el-input v-model="formData.loginName" readonly placeholder="请输入工号"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>姓名</template>
|
||||
<el-form-item prop="userName">
|
||||
<el-input v-model="formData.userName" readonly placeholder="请输入姓名"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">性别</template>
|
||||
<el-form-item prop="sex">
|
||||
<el-select v-model="formData.sex" disabled placeholder="请选择性别" style="width: 100%">
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">出生年月</template>
|
||||
<el-form-item prop="birthday">
|
||||
<el-date-picker v-model="formData.birthday" disabled value-format="yyyy-MM-dd" type="date" placeholder="请选择出生年月" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">籍贯</template>
|
||||
<el-form-item prop="nativePlace">
|
||||
<el-input v-model="formData.nativePlace" readonly placeholder="请输入籍贯"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">工作部门(系部)</template>
|
||||
<el-form-item prop="deptName">
|
||||
<el-input v-model="formData.deptName" readonly placeholder="请输入工作部门(系部)"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">学历</template>
|
||||
<el-form-item prop="education">
|
||||
<el-input v-model="formData.education" readonly placeholder="请输入学历"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">职称</template>
|
||||
<el-form-item prop="professionalTitle">
|
||||
<el-input v-model="formData.professionalTitle" readonly placeholder="请输入职称"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>身份证号码</template>
|
||||
<el-form-item prop="idCard">
|
||||
<el-input v-model="formData.idCard" placeholder="请输入身份证号码"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>联系电话</template>
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工资银行卡号</template>
|
||||
<el-form-item prop="bankCardNo">
|
||||
<el-input v-model="formData.bankCardNo" placeholder="请输入工资银行卡号"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>开户行</template>
|
||||
<el-form-item prop="bankName">
|
||||
<el-input v-model="formData.bankName" placeholder="请输入开户行"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>大病名称</template>
|
||||
<el-form-item prop="diseaseTypeId">
|
||||
<el-select v-model="formData.diseaseTypeId" filterable placeholder="请选择大病名称" style="width: 100%" @change="handleDiseaseChange">
|
||||
<el-option v-for="item in diseaseTypes" :key="item.id" :label="item.diseaseName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>何时何病住何医院</template>
|
||||
<el-form-item prop="hospitalDesc">
|
||||
<el-input type="textarea" :rows="7" show-word-limit v-model="formData.hospitalDesc" placeholder="请详细说明何时何病住何医院"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>全年医疗费用总金额(元)</template>
|
||||
<el-form-item prop="medicalTotalAmount">
|
||||
<el-input-number v-model="formData.medicalTotalAmount" :min="0" :precision="2" :step="100" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>自付金额(元)</template>
|
||||
<el-form-item prop="selfPayAmount">
|
||||
<el-input-number v-model="formData.selfPayAmount" :min="0" :precision="2" :step="100" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item></el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>申请人签字</template>
|
||||
<el-form-item prop="signFileId">
|
||||
<pc-signature v-model="formData.signFileId"></pc-signature>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-form>
|
||||
<div class="actions">
|
||||
<el-button @click="goMine">返回</el-button>
|
||||
<el-button @click="saveDraft">暂存</el-button>
|
||||
<el-button type="primary" @click="submitApply">提交申请</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
diseaseTypes: [],
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/form",
|
||||
minePath: "${base!}/platform/medicalMutualAid/apply/mine",
|
||||
formRules: {
|
||||
loginName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
userName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
idCard: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
mobile: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
bankCardNo: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
bankName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
diseaseTypeId: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
hospitalDesc: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
medicalTotalAmount: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
selfPayAmount: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
signFileId: [{required: true, message: "请签字", trigger: ["change", "blur"]}]
|
||||
},
|
||||
formData: {
|
||||
status: 0,
|
||||
medicalTotalAmount: 0,
|
||||
selfPayAmount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化新增申请页面:疾病类型由后端提供,当前登录用户信息从 Vuex store 回填。
|
||||
initPage() {
|
||||
this.fillCurrentUser()
|
||||
this.loading = true
|
||||
this.$axios.post(this.apiBase + "/initApplyData").then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.diseaseTypes = resp.data.diseaseTypes || []
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 使用平台全局 store 中的当前登录用户信息回填申请人基础字段。
|
||||
fillCurrentUser() {
|
||||
const user = this.$store.state.user || {}
|
||||
const unit = user.unit || {}
|
||||
const joinDate = user.memberJoinTime || user.joinDate || user.joinTime || ""
|
||||
this.formData = Object.assign({}, this.formData, {
|
||||
userId: user.id,
|
||||
loginName: user.loginname,
|
||||
userName: user.username,
|
||||
sex: user.sex,
|
||||
birthday: user.birthday,
|
||||
nativePlace: user.nativePlace || user.nativeplace || "",
|
||||
deptId: unit.id,
|
||||
deptName: unit.name,
|
||||
joinDate: joinDate,
|
||||
joinYear: this.getYear(joinDate),
|
||||
education: user.education || user.educationName || "",
|
||||
professionalTitle: user.professionalTitle || user.title || user.positionTitle || "",
|
||||
idCard: user.idCard || user.idcard || "",
|
||||
mobile: user.mobile
|
||||
})
|
||||
},
|
||||
// 从入会时间中提取年份,字段不展示但随 formData 一起提交给后台保存。
|
||||
getYear(value) {
|
||||
if (!value) {
|
||||
return null
|
||||
}
|
||||
const text = String(value)
|
||||
const year = Number(text.substring(0, 4))
|
||||
return isNaN(year) ? null : year
|
||||
},
|
||||
// 选择疾病类型时同步疾病名称,避免后续档案改名影响历史申请展示。
|
||||
handleDiseaseChange(value) {
|
||||
const item = this.diseaseTypes.find((disease) => disease.id === value)
|
||||
this.formData.diseaseName = item ? item.diseaseName : ""
|
||||
},
|
||||
// 暂存申请,不改变审核状态。
|
||||
saveDraft() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$axios.post(this.apiBase + "/saveDraft", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 提交申请,状态仍为未审核,等待互助会审核。
|
||||
submitApply() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$axios.post(this.apiBase + "/submitApply", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.$message.success(resp.msg)
|
||||
window.location.href = this.minePath
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 返回我的申请列表,查看模式和编辑完成后共用该入口。
|
||||
goMine() {
|
||||
window.location.href = this.minePath
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.mine-form-page { background: #f5f7fa; height: calc(100vh - 88px); display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box; }
|
||||
.back-bar { background: #fff; padding: 14px 24px; margin-bottom: 12px; border-bottom: 1px solid #ebeef5; flex-shrink: 0; }
|
||||
.back-bar .el-button { padding: 0; font-size: 15px; }
|
||||
.mine-form-card { flex: 1; min-height: 0; height: auto !important; overflow: hidden; }
|
||||
.mine-form-card .card-body { flex: 1; min-height: 0; overflow-y: auto; box-sizing: border-box; }
|
||||
.mine-form-card .el-card__footer { flex-shrink: 0; }
|
||||
.required-star { color: #f56c6c; padding-right: 4px; font-weight: 700; }
|
||||
.mutual-desc .el-descriptions-item__label { width: 150px; color: #303133; background: #fafafa; }
|
||||
.mutual-desc .el-descriptions-item__content { min-width: 220px; }
|
||||
.mutual-desc .el-form-item { margin-bottom: 0; }
|
||||
.mutual-desc .el-form-item__error { padding-top: 2px; }
|
||||
.mutual-desc .el-input-number { width: 100%; }
|
||||
.signature-readonly { pointer-events: none; }
|
||||
.actions { text-align: right; padding-top: 18px; }
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak class="mine-form-page">
|
||||
<div class="back-bar">
|
||||
<el-button type="text" icon="el-icon-back" @click="goMine">返回</el-button>
|
||||
</div>
|
||||
<custom-card class="mine-form-card">
|
||||
<el-form :model="formData" ref="form" :rules="formRules" label-width="0" v-loading="loading">
|
||||
<el-descriptions class="mutual-desc" :column="3" border>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工号</template>
|
||||
<el-form-item prop="loginName">
|
||||
<el-input v-model="formData.loginName" readonly placeholder="请输入工号"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>姓名</template>
|
||||
<el-form-item prop="userName">
|
||||
<el-input v-model="formData.userName" readonly placeholder="请输入姓名"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">性别</template>
|
||||
<el-form-item prop="sex">
|
||||
<el-select v-model="formData.sex" disabled placeholder="请选择性别" style="width: 100%">
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">出生年月</template>
|
||||
<el-form-item prop="birthday">
|
||||
<el-date-picker v-model="formData.birthday" disabled value-format="yyyy-MM-dd" type="date" placeholder="请选择出生年月" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">籍贯</template>
|
||||
<el-form-item prop="nativePlace">
|
||||
<el-input v-model="formData.nativePlace" readonly placeholder="请输入籍贯"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">工作部门(系部)</template>
|
||||
<el-form-item prop="deptName">
|
||||
<el-input v-model="formData.deptName" readonly placeholder="请输入工作部门(系部)"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">学历</template>
|
||||
<el-form-item prop="education">
|
||||
<el-input v-model="formData.education" readonly placeholder="请输入学历"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">职称</template>
|
||||
<el-form-item prop="professionalTitle">
|
||||
<el-input v-model="formData.professionalTitle" readonly placeholder="请输入职称"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>身份证号码</template>
|
||||
<el-form-item prop="idCard">
|
||||
<el-input v-model="formData.idCard" :readonly="readonlyMode" placeholder="请输入身份证号码"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>联系电话</template>
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="formData.mobile" :readonly="readonlyMode" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>工资银行卡号</template>
|
||||
<el-form-item prop="bankCardNo">
|
||||
<el-input v-model="formData.bankCardNo" :readonly="readonlyMode" placeholder="请输入工资银行卡号"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>开户行</template>
|
||||
<el-form-item prop="bankName">
|
||||
<el-input v-model="formData.bankName" :readonly="readonlyMode" placeholder="请输入开户行"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>大病名称</template>
|
||||
<el-form-item prop="diseaseTypeId">
|
||||
<el-select v-model="formData.diseaseTypeId" filterable :disabled="readonlyMode" placeholder="请选择大病名称" style="width: 100%" @change="handleDiseaseChange">
|
||||
<el-option v-for="item in diseaseTypes" :key="item.id" :label="item.diseaseName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>何时何病住何医院</template>
|
||||
<el-form-item prop="hospitalDesc">
|
||||
<el-input type="textarea" :rows="7" show-word-limit v-model="formData.hospitalDesc" :readonly="readonlyMode" placeholder="请详细说明何时何病住何医院"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>全年医疗费用总金额(元)</template>
|
||||
<el-form-item prop="medicalTotalAmount">
|
||||
<el-input-number v-model="formData.medicalTotalAmount" :disabled="readonlyMode" :min="0" :precision="2" :step="100" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label"><span class="required-star">*</span>自付金额(元)</template>
|
||||
<el-form-item prop="selfPayAmount">
|
||||
<el-input-number v-model="formData.selfPayAmount" :disabled="readonlyMode" :min="0" :precision="2" :step="100" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item></el-descriptions-item>
|
||||
<el-descriptions-item :span="3">
|
||||
<template slot="label"><span class="required-star">*</span>申请人签字</template>
|
||||
<el-form-item prop="signFileId">
|
||||
<div :class="{'signature-readonly': readonlyMode}">
|
||||
<pc-signature v-model="formData.signFileId"></pc-signature>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-form>
|
||||
<template slot="footer" v-if="!readonlyMode">
|
||||
<el-button @click="saveDraft">暂存</el-button>
|
||||
<el-button type="primary" @click="submitApply">提交申请</el-button>
|
||||
</template>
|
||||
</custom-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
diseaseTypes: [],
|
||||
applyId: "",
|
||||
pageMode: "add",
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/mine/form",
|
||||
minePath: "${base!}/platform/medicalMutualAid/apply/mine",
|
||||
formRules: {
|
||||
loginName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
userName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
idCard: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
mobile: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
bankCardNo: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
bankName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
diseaseTypeId: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
hospitalDesc: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
medicalTotalAmount: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
selfPayAmount: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
signFileId: [{required: true, message: "请签字", trigger: ["change", "blur"]}]
|
||||
},
|
||||
formData: {
|
||||
status: 0,
|
||||
medicalTotalAmount: 0,
|
||||
selfPayAmount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 查看模式下页面只负责展示历史申请,所有表单控件统一禁止操作。
|
||||
readonlyMode() {
|
||||
return this.pageMode === "view"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化我的申请维护页面:必须携带申请ID,按模式控制查看或编辑。
|
||||
initPage() {
|
||||
this.applyId = this.getQueryValue("id")
|
||||
this.pageMode = this.getQueryValue("mode") || "add"
|
||||
if (!this.applyId) {
|
||||
this.$message.error("申请ID不能为空")
|
||||
this.goMine()
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
this.$axios.post(this.apiBase + "/initApplyData").then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.diseaseTypes = resp.data.diseaseTypes || []
|
||||
if (this.applyId) {
|
||||
return this.loadApplyDetail()
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
if (!this.applyId) {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 读取 URL 查询参数,避免引入额外公共依赖。
|
||||
getQueryValue(name) {
|
||||
const query = window.location.search ? window.location.search.substring(1) : ""
|
||||
const parts = query.split("&")
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const item = parts[i].split("=")
|
||||
if (decodeURIComponent(item[0] || "") === name) {
|
||||
return decodeURIComponent(item[1] || "")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
},
|
||||
// 根据申请ID加载历史申请,供我的申请查看和编辑复用当前页面。
|
||||
loadApplyDetail() {
|
||||
return this.$axios.post(this.apiBase + "/detail", {id: this.applyId}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data || {}
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 选择疾病类型时同步疾病名称,避免后续档案改名影响历史申请展示。
|
||||
handleDiseaseChange(value) {
|
||||
const item = this.diseaseTypes.find((disease) => disease.id === value)
|
||||
this.formData.diseaseName = item ? item.diseaseName : ""
|
||||
},
|
||||
// 暂存申请,不改变审核状态。
|
||||
saveDraft() {
|
||||
if (this.readonlyMode) {
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$axios.post(this.apiBase + "/saveDraft", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 提交申请,状态仍为未审核,等待互助会审核。
|
||||
submitApply() {
|
||||
if (this.readonlyMode) {
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$axios.post(this.apiBase + "/submitApply", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.$message.success(resp.msg)
|
||||
commonUtil.pjaxPush(this.minePath)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 返回我的申请列表,查看模式和编辑完成后共用该入口。
|
||||
goMine() {
|
||||
commonUtil.pjaxPush(this.minePath)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
#sub-app-container-main-content { overflow: hidden; }
|
||||
#sub-app-container-main-content-body { height: 100%; overflow: hidden; }
|
||||
.mine-list-page { padding: 16px 20px; background: #f3f6fa; height: 100%; box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.mine-search-panel { background: #fff; padding: 16px 42px; margin-bottom: 12px; box-sizing: border-box; flex-shrink: 0; }
|
||||
.mine-search-panel .el-form-item { margin-bottom: 0; margin-right: 28px; }
|
||||
.mine-content-panel { background: #fff; padding: 16px 20px; box-sizing: border-box; flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.mine-panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; flex-shrink: 0; }
|
||||
.mine-section-title { border-left: 4px solid #0079c2; padding-left: 10px; color: #0079c2; font-size: 16px; font-weight: 700; line-height: 22px; }
|
||||
.mine-table.el-table th { background: #fafafa; color: #303133; font-weight: 700; }
|
||||
.mine-table.el-table td, .mine-table.el-table th { padding: 11px 0; }
|
||||
.mine-actions { display: flex; align-items: center; justify-content: center; gap: 8px; }
|
||||
.mine-actions .el-button { min-width: 54px; padding: 7px 14px; border-radius: 2px; margin-left: 0; }
|
||||
.mine-pager { display: flex; justify-content: flex-start; align-items: center; padding-top: 12px; flex-shrink: 0; }
|
||||
.mine-pager .total-text { margin-right: 18px; color: #303133; }
|
||||
</style>
|
||||
<div id="app" v-cloak class="mine-list-page">
|
||||
<div class="mine-search-panel">
|
||||
<el-form :inline="true" :model="searchForm">
|
||||
<el-form-item label="大病名称">
|
||||
<el-select v-model="searchForm.diseaseName" clearable filterable placeholder="请选择大病名称" style="width: 260px">
|
||||
<el-option v-for="item in diseaseTypes" :key="item.id" :label="item.diseaseName" :value="item.diseaseName"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="mine-content-panel" ref="contentPanel">
|
||||
<div class="mine-panel-header" ref="panelHeader">
|
||||
<div class="mine-section-title">我的申请</div>
|
||||
<el-button type="primary" size="small" @click="onAdd">
|
||||
<i class="ti-plus"></i>
|
||||
互助金申请
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table ref="mineTable" class="mine-table" :data="tableData" border v-loading="loading" :height="tableHeight" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
|
||||
<el-table-column prop="loginName" label="工号" width="130" align="center"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名" width="120" align="center"></el-table-column>
|
||||
<el-table-column prop="diseaseName" label="大病名称" min-width="300" align="center" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="全年医疗费用总金额(元)" width="190" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.medicalTotalAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自费金额(元)" width="160" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.selfPayAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag v-if="isAudited(row)" type="success" size="mini">已审核</el-tag>
|
||||
<el-tag v-else-if="isDiscarded(row)" type="danger" size="mini">已作废</el-tag>
|
||||
<el-tag v-else type="warning" size="mini">未审核</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template slot-scope="{row}">
|
||||
<div class="mine-actions">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button @click="onExportApplyForm(row)" size="mini" type="primary">导出申请单</el-button>
|
||||
<el-button v-if="isPending(row)" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button v-if="isPending(row)" @click="onDeleteTip" size="mini" type="danger">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mine-pager" ref="pager">
|
||||
<span class="total-text">共 {{ totalCount }} 条</span>
|
||||
<el-pagination background layout="sizes, prev, pager, next" :current-page.sync="pageForm.pageNumber" :page-size.sync="pageForm.pageSize" :page-sizes="[5, 10, 20, 30, 50]" :total="totalCount" @current-change="loadPage" @size-change="loadPage"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tableData: [],
|
||||
diseaseTypes: [],
|
||||
totalCount: 0,
|
||||
tableHeight: 360,
|
||||
layoutTimer: null,
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/mine",
|
||||
diseaseTypeApi: "${base!}/platform/medicalMutualAid/medical/diseaseType",
|
||||
searchForm: { diseaseName: "" },
|
||||
pageForm: { pageNumber: 1, pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载互助疾病类型下拉,和互助金申请页面保持同一疾病基础数据来源。
|
||||
loadDiseaseTypes() {
|
||||
this.$axios.post(this.diseaseTypeApi + "/pageData", { pageNumber: 1, pageSize: 999 }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.diseaseTypes = resp.data.list || []
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查询我的申请列表,使用独立分页结构保证列表高度不受通用组件影响。
|
||||
loadPage() {
|
||||
this.loading = true
|
||||
const params = Object.assign({}, this.pageForm, this.searchForm)
|
||||
this.$axios.post(this.apiBase + "/page", params).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list || []
|
||||
this.totalCount = resp.data.totalCount || 0
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.scheduleTableLayout()
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.loadPage()
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchForm = { diseaseName: "" }
|
||||
this.pageForm.pageNumber = 1
|
||||
this.loadPage()
|
||||
},
|
||||
// 新增申请按平台通用页面跳转方式进入申请页。
|
||||
onAdd() {
|
||||
commonUtil.pjaxPush("${base!}/platform/medicalMutualAid/apply/form")
|
||||
},
|
||||
// 查看申请进入我的申请独立维护页,查看模式由 mode 参数控制。
|
||||
onView(row) {
|
||||
commonUtil.pjaxPush("${base!}/platform/medicalMutualAid/apply/mine/form?id=" + row.id + "&mode=view")
|
||||
},
|
||||
// 编辑申请进入我的申请独立维护页,编辑模式由 mode 参数控制。
|
||||
onEdit(row) {
|
||||
commonUtil.pjaxPush("${base!}/platform/medicalMutualAid/apply/mine/form?id=" + row.id + "&mode=edit")
|
||||
},
|
||||
// 按当前行申请ID导出申请单,后端通过系统模板管理中的 Word 模板完成参数渲染。
|
||||
onExportApplyForm(row) {
|
||||
window.open(this.apiBase + "/exportApplyForm?id=" + row.id)
|
||||
},
|
||||
onDeleteTip() {
|
||||
this.$message.info("删除逻辑后续接入")
|
||||
},
|
||||
// 未审核申请允许个人继续编辑和删除。
|
||||
isPending(row) {
|
||||
return Number(row.status) === 0
|
||||
},
|
||||
// 已审核申请只允许查看,不能再编辑或删除。
|
||||
isAudited(row) {
|
||||
return Number(row.status) === 1
|
||||
},
|
||||
// 已作废申请只允许查看,不能再编辑或删除。
|
||||
isDiscarded(row) {
|
||||
return Number(row.status) === 2
|
||||
},
|
||||
formatMoney(value) {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
return ""
|
||||
}
|
||||
return Number(value).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
},
|
||||
// 根据内容面板剩余空间计算表格高度,保证列表铺满且页面不出现纵向滚动条。
|
||||
updateTableHeight() {
|
||||
const panel = this.$refs.contentPanel
|
||||
if (!panel) {
|
||||
return
|
||||
}
|
||||
const headerHeight = this.$refs.panelHeader ? this.$refs.panelHeader.offsetHeight : 0
|
||||
const pagerHeight = this.$refs.pager ? this.$refs.pager.offsetHeight : 0
|
||||
this.tableHeight = Math.max(panel.clientHeight - headerHeight - pagerHeight - 32, 260)
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.mineTable) {
|
||||
this.$refs.mineTable.doLayout()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 数据加载和窗口变化后延迟重算,避开菜单/顶部栏刷新时机导致的首屏高度误差。
|
||||
scheduleTableLayout() {
|
||||
if (this.layoutTimer) {
|
||||
clearTimeout(this.layoutTimer)
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.updateTableHeight()
|
||||
const vm = this
|
||||
this.layoutTimer = setTimeout(function () {
|
||||
vm.updateTableHeight()
|
||||
}, 80)
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadDiseaseTypes()
|
||||
this.loadPage()
|
||||
},
|
||||
mounted() {
|
||||
this.scheduleTableLayout()
|
||||
window.addEventListener("resize", this.scheduleTableLayout)
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.layoutTimer) {
|
||||
clearTimeout(this.layoutTimer)
|
||||
}
|
||||
window.removeEventListener("resize", this.scheduleTableLayout)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.mutual-list-page { padding: 16px 20px; background: #f3f6fa; height: calc(100vh - 88px); box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.search-panel { background: #fff; padding: 16px 42px; margin-bottom: 12px; box-sizing: border-box; flex-shrink: 0; }
|
||||
.search-panel .el-form-item { margin-bottom: 0; margin-right: 14px; }
|
||||
.content-panel { background: #fff; padding: 16px 20px 16px; box-sizing: border-box; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
||||
.panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
|
||||
.section-title { border-left: 4px solid #0079c2; padding-left: 10px; color: #0079c2; font-size: 16px; font-weight: 700; line-height: 22px; }
|
||||
.mutual-table.el-table th { background: #fafafa; color: #303133; font-weight: 700; }
|
||||
.mutual-table.el-table td, .mutual-table.el-table th { padding: 11px 0; }
|
||||
.pager { display: flex; justify-content: flex-start; align-items: center; padding-top: 12px; flex-shrink: 0; }
|
||||
.pager .total-text { margin-right: 18px; color: #303133; }
|
||||
</style>
|
||||
<div id="app" v-cloak class="mutual-list-page">
|
||||
<div class="search-panel">
|
||||
<el-form :inline="true" :model="searchForm">
|
||||
<el-form-item label="所在单位">
|
||||
<el-input v-model="searchForm.deptName" placeholder="请输入所在单位" style="width: 240px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="searchForm.userName" placeholder="请输入姓名" style="width: 220px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="加入年份">
|
||||
<el-date-picker v-model="searchForm.joinYear" type="year" value-format="yyyy" placeholder="请选择加入年份" style="width: 220px"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadPage">查询</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
<el-button icon="el-icon-upload2" @click="exportTip">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="content-panel" ref="contentPanel">
|
||||
<div class="panel-header" ref="panelHeader">
|
||||
<div class="section-title">医疗互助汇总</div>
|
||||
</div>
|
||||
<el-table ref="summaryTable" class="mutual-table" :data="tableData" border v-loading="loading" :height="tableHeight" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
|
||||
<el-table-column prop="deptName" label="所在单位" min-width="140" align="center"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名" width="110" align="center"></el-table-column>
|
||||
<el-table-column prop="joinYear" label="加入时间(年)" width="120" align="center"></el-table-column>
|
||||
<el-table-column prop="diseaseText" label="大病名称及病情" min-width="190" align="center"></el-table-column>
|
||||
<el-table-column label="符合规定发票金额(元)" width="160" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.medicalTotalAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助计算方法" align="center">
|
||||
<el-table-column v-for="item in subsidyRanges" :key="item" :label="item" min-width="130" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.subsidyMap[item]) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助小计" width="120" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.subsidyTotalAmount) }}</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助比例" width="100" align="center">
|
||||
<template slot-scope="{row}">{{ row.bonusRatio || "" }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际补助金额(元)" width="150" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.actualSubsidyAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="120" align="center"></el-table-column>
|
||||
</el-table>
|
||||
<div class="pager" ref="pager">
|
||||
<span class="total-text">共 {{ totalCount }} 条</span>
|
||||
<el-pagination background layout="sizes, prev, pager, next" :current-page.sync="pageForm.pageNumber" :page-size.sync="pageForm.pageSize" :total="totalCount" @current-change="loadPage" @size-change="loadPage"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tableData: [],
|
||||
subsidyRanges: [],
|
||||
totalCount: 0,
|
||||
tableHeight: 360,
|
||||
apiBase: "${base!}/platform/medicalMutualAid/apply/summary",
|
||||
searchForm: { deptName: "", userName: "", joinYear: "" },
|
||||
pageForm: { pageNumber: 1, pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查询审核通过的互助金申请,并把补助明细转换成动态列数据。
|
||||
loadPage() {
|
||||
this.loading = true
|
||||
const params = Object.assign({}, this.pageForm, this.searchForm)
|
||||
this.$axios.post(this.apiBase + "/page", params).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
const rows = resp.data.list || []
|
||||
this.tableData = rows.map((item) => this.buildRow(item))
|
||||
this.totalCount = resp.data.totalCount || 0
|
||||
this.refreshRanges()
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.scheduleTableLayout()
|
||||
})
|
||||
},
|
||||
// 将后端主表与补助明细组合为列表展示行。
|
||||
buildRow(item) {
|
||||
const apply = item.apply || {}
|
||||
const subsidies = item.subsidies || []
|
||||
const subsidyMap = {}
|
||||
subsidies.forEach((subsidy) => {
|
||||
subsidyMap[subsidy.rangeName] = subsidy.subsidyAmount
|
||||
})
|
||||
return {
|
||||
deptName: apply.deptName,
|
||||
userName: apply.userName,
|
||||
joinYear: apply.joinYear,
|
||||
diseaseText: apply.diseaseName,
|
||||
medicalTotalAmount: apply.medicalTotalAmount,
|
||||
subsidyTotalAmount: apply.subsidyTotalAmount,
|
||||
bonusRatio: apply.bonusRatio,
|
||||
actualSubsidyAmount: apply.actualSubsidyAmount,
|
||||
remark: apply.remark,
|
||||
subsidies: subsidies,
|
||||
subsidyMap: subsidyMap
|
||||
}
|
||||
},
|
||||
// 根据当前页明细刷新动态补助区间表头。
|
||||
refreshRanges() {
|
||||
const names = []
|
||||
this.tableData.forEach((row) => {
|
||||
row.subsidies.forEach((item) => {
|
||||
if (names.indexOf(item.rangeName) === -1) {
|
||||
names.push(item.rangeName)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.subsidyRanges = names
|
||||
this.scheduleTableLayout()
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchForm = { deptName: "", userName: "", joinYear: "" }
|
||||
this.pageForm.pageNumber = 1
|
||||
this.loadPage()
|
||||
},
|
||||
exportTip() {
|
||||
const params = []
|
||||
if (this.searchForm.deptName) {
|
||||
params.push("deptName=" + encodeURIComponent(this.searchForm.deptName))
|
||||
}
|
||||
if (this.searchForm.userName) {
|
||||
params.push("userName=" + encodeURIComponent(this.searchForm.userName))
|
||||
}
|
||||
if (this.searchForm.joinYear) {
|
||||
params.push("joinYear=" + encodeURIComponent(this.searchForm.joinYear))
|
||||
}
|
||||
window.open(this.apiBase + "/exportExcel" + (params.length ? "?" + params.join("&") : ""))
|
||||
},
|
||||
formatMoney(value) {
|
||||
if (value === undefined || value === null || value === "") {
|
||||
return ""
|
||||
}
|
||||
const num = Number(value || 0)
|
||||
return num.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
},
|
||||
// 根据内容面板剩余空间计算表格高度,汇总动态列只影响横向滚动,不影响页面纵向高度。
|
||||
updateTableHeight() {
|
||||
const panel = this.$refs.contentPanel
|
||||
if (!panel) {
|
||||
return
|
||||
}
|
||||
const headerHeight = this.$refs.panelHeader ? this.$refs.panelHeader.offsetHeight : 0
|
||||
const pagerHeight = this.$refs.pager ? this.$refs.pager.offsetHeight : 0
|
||||
this.tableHeight = Math.max(panel.clientHeight - headerHeight - pagerHeight - 32, 220)
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.summaryTable) {
|
||||
this.$refs.summaryTable.doLayout()
|
||||
}
|
||||
})
|
||||
},
|
||||
// F5 刷新时动态二级表头渲染和外层布局完成顺序不稳定,延迟触发表格重排保证列宽不乱。
|
||||
scheduleTableLayout() {
|
||||
this.$nextTick(() => {
|
||||
this.updateTableHeight()
|
||||
const vm = this
|
||||
setTimeout(function () {
|
||||
vm.updateTableHeight()
|
||||
}, 80)
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadPage()
|
||||
},
|
||||
mounted() {
|
||||
this.scheduleTableLayout()
|
||||
window.addEventListener("resize", this.scheduleTableLayout)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("resize", this.scheduleTableLayout)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#}#-->
|
||||
+689
@@ -0,0 +1,689 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.mutual-config-page {
|
||||
padding: 16px 20px;
|
||||
background: #f5f7fa;
|
||||
height: calc(100vh - 88px);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mutual-config-page .search-panel,
|
||||
.mutual-config-page .list-panel {
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 16px 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mutual-config-page .search-panel {
|
||||
margin-bottom: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .list-panel {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mutual-config-page .list-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .list-title-text {
|
||||
border-left: 4px solid #0079c2;
|
||||
padding-left: 10px;
|
||||
color: #0079c2;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.mutual-config-page .pager-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.el-dialog.mutual-edit-dialog {
|
||||
margin-top: 3vh !important;
|
||||
}
|
||||
|
||||
.mutual-edit-dialog .el-dialog__body {
|
||||
height: 700px;
|
||||
overflow: hidden;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-tabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-tabs__header {
|
||||
flex: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-tabs__content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-tab-pane {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding-right: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mutual-config-page .dialog-section {
|
||||
border-top: 1px dashed #dcdfe6;
|
||||
padding-top: 18px;
|
||||
margin-top: 18px;
|
||||
max-width: 100%;
|
||||
overflow-x: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mutual-config-page .dialog-section:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .dialog-section-title {
|
||||
border-left: 4px solid #0079c2;
|
||||
padding-left: 10px;
|
||||
margin-bottom: 16px;
|
||||
color: #0079c2;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.mutual-config-page .section-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-form-item__label {
|
||||
white-space: normal;
|
||||
line-height: 20px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .aid-limit-label.is-required .el-form-item__label:before {
|
||||
content: "";
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .aid-limit-label-text {
|
||||
display: inline-block;
|
||||
line-height: 20px;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .aid-limit-label-star {
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-table {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mutual-config-page .config-dialog-body .el-table__body-wrapper {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.mutual-config-page .dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak class="mutual-config-page">
|
||||
<div class="search-panel">
|
||||
<el-form :inline="true" :model="searchForm" label-width="70px">
|
||||
<el-form-item label="年度">
|
||||
<el-select v-model="searchForm.year" clearable placeholder="请选择年度" style="width: 220px">
|
||||
<el-option v-for="year in yearOptions" :key="year" :label="year" :value="year"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置名称">
|
||||
<el-input v-model="searchForm.configName" clearable placeholder="请输入配置名称" style="width: 260px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="loadConfigList">搜索</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="list-panel" ref="listPanel" v-loading="loading">
|
||||
<div class="list-title" ref="listTitle">
|
||||
<span class="list-title-text">医疗互助配置</span>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="openConfigDialog()">新增</el-button>
|
||||
</div>
|
||||
<el-table :data="pageList" border :height="tableHeight" style="width: 100%">
|
||||
<el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
|
||||
<el-table-column prop="year" label="年度" width="110" align="center"></el-table-column>
|
||||
<el-table-column prop="configName" label="配置名称" min-width="260" align="center"></el-table-column>
|
||||
<el-table-column label="起补金额(元)" width="150" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.startAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="第一年最高补助(元)" width="170" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.firstYearMaxAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="其他年度最高补助(元)" width="190" align="center">
|
||||
<template slot-scope="{row}">{{ formatMoney(row.otherYearMaxAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否启用" width="110" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag v-if="row.status === 1" type="success" size="mini">启用</el-tag>
|
||||
<el-tag v-else type="info" size="mini">停用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="170" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-button type="primary" size="mini" @click="openConfigDialog(row)">编辑</el-button>
|
||||
<el-button type="danger" size="mini" @click="deleteConfig(row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager-bar" ref="pagerBar">
|
||||
<span style="margin-right: 14px">共 {{ configList.length }} 条</span>
|
||||
<el-pagination
|
||||
background
|
||||
layout="sizes, prev, pager, next"
|
||||
:current-page.sync="pageNumber"
|
||||
:page-size.sync="pageSize"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="configList.length">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="configDialogTitle" :visible.sync="configDialogVisible" width="1320px" custom-class="mutual-edit-dialog" :close-on-click-modal="false">
|
||||
<div class="config-dialog-body" v-loading="dialogLoading">
|
||||
<el-tabs v-model="activeTab" type="card">
|
||||
<el-tab-pane label="互助金补助配置" name="subsidy">
|
||||
<div class="dialog-section">
|
||||
<div class="dialog-section-title">基本信息</div>
|
||||
<el-form :model="configForm" :rules="configRules" ref="configFormRef" label-width="160px">
|
||||
<el-row :gutter="28">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="年度" prop="year">
|
||||
<el-select v-model="configForm.year" style="width: 100%" placeholder="请选择年度">
|
||||
<el-option v-for="year in yearOptions" :key="year" :label="year" :value="year"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="配置名称" prop="configName">
|
||||
<el-input v-model="configForm.configName" maxlength="100" placeholder="请输入配置名称"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="28">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="起补金额(元)" prop="startAmount">
|
||||
<el-input-number v-model="configForm.startAmount" :min="0" :precision="2" :step="1000" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否启用" prop="status">
|
||||
<el-radio-group v-model="configForm.status">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="28">
|
||||
<el-col :span="12">
|
||||
<el-form-item class="aid-limit-label" prop="firstYearMaxAmount">
|
||||
<template slot="label">
|
||||
<span class="aid-limit-label-text"><span class="aid-limit-label-star">*</span>第一年最高补助<br>(元)</span>
|
||||
</template>
|
||||
<el-input-number v-model="configForm.firstYearMaxAmount" :min="0" :precision="2" :step="1000" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item class="aid-limit-label" prop="otherYearMaxAmount">
|
||||
<template slot="label">
|
||||
<span class="aid-limit-label-text"><span class="aid-limit-label-star">*</span>其他年度最高补助<br>(元)</span>
|
||||
</template>
|
||||
<el-input-number v-model="configForm.otherYearMaxAmount" :min="0" :precision="2" :step="1000" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="dialog-section">
|
||||
<div class="section-toolbar">
|
||||
<div class="dialog-section-title" style="margin-bottom: 0">补助比例配置(超额累计计算)</div>
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" @click="addRatioRow">新增比例</el-button>
|
||||
</div>
|
||||
<el-table :data="ratioList" border style="width: 100%">
|
||||
<el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
|
||||
<el-table-column label="开始金额(元)" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.startAmount" :min="0" :precision="2" :step="1000" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束金额(元)" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.endAmount" :min="0" :precision="2" :step="1000" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="补助比例(%)" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.ratio" :min="0" :max="100" :precision="2" :step="1" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="说明" min-width="220" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.remark" maxlength="200" placeholder="请输入说明"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" width="120" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.sort" :min="1" :step="1" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="removeRatio(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="dialog-section">
|
||||
<div class="section-toolbar">
|
||||
<div class="dialog-section-title" style="margin-bottom: 0">连续未申请奖励配置</div>
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" @click="addBonusRow">新增奖励</el-button>
|
||||
</div>
|
||||
<el-table :data="bonusList" border style="width: 100%">
|
||||
<el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
|
||||
<el-table-column prop="continuousYear" label="连续未申请年数(年)" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.continuousYear" :min="1" :step="1" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="增加比例(%)" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input-number v-model="row.increaseRatio" :min="0" :max="100" :precision="2" :step="1" controls-position="right" style="width: 100%"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="说明" min-width="260" align="center">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.remark" maxlength="200" placeholder="请输入说明"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="removeBonus(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="会员缴费配置" name="member">
|
||||
<div class="dialog-section">
|
||||
<div class="dialog-section-title">会员缴费配置</div>
|
||||
<el-form :model="memberForm" :rules="memberRules" ref="memberFormRef" label-width="190px" style="max-width: 760px">
|
||||
<el-form-item label="每月缴纳互助金额(元)" prop="monthAmount">
|
||||
<el-input-number v-model="memberForm.monthAmount" :min="0" :precision="2" :step="1" controls-position="right" style="width: 320px"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="缴费减半年限" prop="halfPriceYear">
|
||||
<el-input-number v-model="memberForm.halfPriceYear" :min="1" :step="1" controls-position="right" style="width: 320px"></el-input-number>
|
||||
<span style="margin-left: 10px; color: #909399">连续缴费满该年限后,次年缴费减半</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="configDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="dialogSaving" @click="confirmConfigDialog">确认</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
dialogLoading: false,
|
||||
dialogSaving: false,
|
||||
yearOptions: [],
|
||||
searchForm: {
|
||||
year: null,
|
||||
configName: ""
|
||||
},
|
||||
configList: [],
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
tableHeight: 360,
|
||||
configDialogVisible: false,
|
||||
configDialogTitle: "新增医疗互助配置",
|
||||
activeTab: "subsidy",
|
||||
configForm: {},
|
||||
memberForm: {},
|
||||
ratioList: [],
|
||||
bonusList: [],
|
||||
deletedRatioIds: [],
|
||||
deletedBonusIds: [],
|
||||
configRules: {
|
||||
year: [{ required: true, message: "请选择年度", trigger: "change" }],
|
||||
configName: [{ required: true, message: "请输入配置名称", trigger: "blur" }],
|
||||
startAmount: [{ required: true, message: "请输入起补金额", trigger: "change" }],
|
||||
firstYearMaxAmount: [{ required: true, message: "请输入第一年最高补助", trigger: "change" }],
|
||||
otherYearMaxAmount: [{ required: true, message: "请输入其他年度最高补助", trigger: "change" }],
|
||||
status: [{ required: true, message: "请选择状态", trigger: "change" }]
|
||||
},
|
||||
memberRules: {
|
||||
monthAmount: [{ required: true, message: "请输入每月缴纳互助金额", trigger: "change" }],
|
||||
halfPriceYear: [{ required: true, message: "请输入缴费减半年限", trigger: "change" }]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageList() {
|
||||
const start = (this.pageNumber - 1) * this.pageSize
|
||||
return this.configList.slice(start, start + this.pageSize)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化年度选项,列表查询和弹窗年度录入共用同一组选项。
|
||||
initYearOptions() {
|
||||
const currentYear = new Date().getFullYear()
|
||||
const years = []
|
||||
for (let year = currentYear - 5; year <= currentYear + 2; year++) {
|
||||
years.push(year)
|
||||
}
|
||||
this.yearOptions = years.reverse()
|
||||
},
|
||||
// 查询年度配置列表,每年一条配置,供页面主列表展示和检索。
|
||||
loadConfigList() {
|
||||
this.loading = true
|
||||
this.$axios.post(loc() + "/listConfigs", this.searchForm).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.configList = resp.data || []
|
||||
this.pageNumber = 1
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.$nextTick(this.updateTableHeight)
|
||||
})
|
||||
},
|
||||
// 重置列表查询条件,并重新加载全部年度配置。
|
||||
resetSearch() {
|
||||
this.searchForm = {
|
||||
year: null,
|
||||
configName: ""
|
||||
}
|
||||
this.loadConfigList()
|
||||
},
|
||||
// 打开新增或编辑弹窗,编辑时加载该年度完整配置,新增时使用当前年度默认值。
|
||||
openConfigDialog(row) {
|
||||
this.configDialogTitle = row ? "编辑医疗互助配置" : "新增医疗互助配置"
|
||||
this.activeTab = "subsidy"
|
||||
this.deletedRatioIds = []
|
||||
this.deletedBonusIds = []
|
||||
this.configDialogVisible = true
|
||||
if (!row) {
|
||||
this.resetDialogForm()
|
||||
return
|
||||
}
|
||||
this.dialogLoading = true
|
||||
const year = row ? row.year : new Date().getFullYear()
|
||||
this.$axios.post(loc() + "/configData", { year: year }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.configForm = resp.data.config || this.defaultConfig(year)
|
||||
this.memberForm = resp.data.memberConfig || this.defaultMemberConfig()
|
||||
this.ratioList = resp.data.ratios || []
|
||||
this.bonusList = resp.data.bonuses || []
|
||||
}
|
||||
}).finally(() => {
|
||||
this.dialogLoading = false
|
||||
this.$nextTick(() => {
|
||||
this.$refs.configFormRef && this.$refs.configFormRef.clearValidate()
|
||||
this.$refs.memberFormRef && this.$refs.memberFormRef.clearValidate()
|
||||
})
|
||||
})
|
||||
},
|
||||
// 新增弹窗初始化,仅保留年度、配置名称、启用状态和会员缴费配置默认值。
|
||||
resetDialogForm() {
|
||||
const year = new Date().getFullYear()
|
||||
this.dialogLoading = false
|
||||
this.configForm = this.defaultConfig(year)
|
||||
this.memberForm = this.defaultMemberConfig()
|
||||
this.ratioList = []
|
||||
this.bonusList = []
|
||||
this.$nextTick(() => {
|
||||
this.$refs.configFormRef && this.$refs.configFormRef.clearValidate()
|
||||
this.$refs.memberFormRef && this.$refs.memberFormRef.clearValidate()
|
||||
})
|
||||
},
|
||||
// 删除年度主配置会同步删除后端已关联的比例和奖励配置。
|
||||
deleteConfig(id) {
|
||||
this.$confirm("确定删除此年度医疗互助配置吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post(loc() + "/deleteConfig", { id: id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.loadConfigList()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 弹窗确认时统一保存两个页签数据,避免每个页签出现独立保存按钮。
|
||||
confirmConfigDialog() {
|
||||
this.$refs.configFormRef.validate((configValid) => {
|
||||
if (!configValid) {
|
||||
this.activeTab = "subsidy"
|
||||
return
|
||||
}
|
||||
this.$refs.memberFormRef.validate((memberValid) => {
|
||||
if (!memberValid) {
|
||||
this.activeTab = "member"
|
||||
return
|
||||
}
|
||||
if (!this.validateDetailRows()) {
|
||||
this.activeTab = "subsidy"
|
||||
return
|
||||
}
|
||||
this.saveDialogData()
|
||||
})
|
||||
})
|
||||
},
|
||||
// 先保存基础配置拿到主键,再保存会员缴费、比例和奖励明细。
|
||||
saveDialogData() {
|
||||
this.dialogSaving = true
|
||||
this.$axios.post(loc() + "/saveConfig", this.configForm).then((resp) => {
|
||||
if (resp.code !== 0) {
|
||||
return Promise.reject(resp)
|
||||
}
|
||||
const savedConfig = resp.data
|
||||
const tasks = [this.$axios.post(loc() + "/saveMemberConfig", this.memberForm)]
|
||||
this.deletedRatioIds.forEach((id) => {
|
||||
tasks.push(this.$axios.post(loc() + "/deleteRatio", { id: id }))
|
||||
})
|
||||
this.deletedBonusIds.forEach((id) => {
|
||||
tasks.push(this.$axios.post(loc() + "/deleteBonus", { id: id }))
|
||||
})
|
||||
this.ratioList.forEach((row) => {
|
||||
const payload = this.cleanPayload(row)
|
||||
payload.configId = savedConfig.id
|
||||
tasks.push(this.$axios.post(loc() + "/saveRatio", payload))
|
||||
})
|
||||
this.bonusList.forEach((row) => {
|
||||
const payload = this.cleanPayload(row)
|
||||
payload.configId = savedConfig.id
|
||||
tasks.push(this.$axios.post(loc() + "/saveBonus", payload))
|
||||
})
|
||||
return Promise.all(tasks).then((results) => {
|
||||
for (let index = 0; index < results.length; index++) {
|
||||
if (results[index].code !== 0) {
|
||||
return Promise.reject(results[index])
|
||||
}
|
||||
}
|
||||
return results
|
||||
})
|
||||
}).then(() => {
|
||||
this.$message.success("保存成功")
|
||||
this.configDialogVisible = false
|
||||
this.loadConfigList()
|
||||
}).catch((resp) => {
|
||||
if (resp && resp.msg) {
|
||||
this.$message.error(resp.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.dialogSaving = false
|
||||
})
|
||||
},
|
||||
// 新增比例时直接追加可编辑行,主弹窗确认前仅保存在前端列表中。
|
||||
addRatioRow() {
|
||||
this.ratioList.push({
|
||||
startAmount: null,
|
||||
endAmount: null,
|
||||
ratio: null,
|
||||
sort: null,
|
||||
remark: ""
|
||||
})
|
||||
},
|
||||
// 从弹窗内存列表移除比例,已有主键的记录延迟到主弹窗确认时删除。
|
||||
removeRatio(row, index) {
|
||||
if (row.id) {
|
||||
this.deletedRatioIds.push(row.id)
|
||||
}
|
||||
this.ratioList.splice(index, 1)
|
||||
},
|
||||
// 新增奖励时直接追加可编辑行,主弹窗确认前仅保存在前端列表中。
|
||||
addBonusRow() {
|
||||
this.bonusList.push({
|
||||
continuousYear: null,
|
||||
increaseRatio: null,
|
||||
remark: ""
|
||||
})
|
||||
},
|
||||
// 从弹窗内存列表移除奖励,已有主键的记录延迟到主弹窗确认时删除。
|
||||
removeBonus(row, index) {
|
||||
if (row.id) {
|
||||
this.deletedBonusIds.push(row.id)
|
||||
}
|
||||
this.bonusList.splice(index, 1)
|
||||
},
|
||||
// 统一保存前校验行内明细,避免新增空行或缺少关键字段的数据提交到后台。
|
||||
validateDetailRows() {
|
||||
for (let index = 0; index < this.ratioList.length; index++) {
|
||||
const row = this.ratioList[index]
|
||||
if (row.startAmount === null || row.startAmount === undefined || row.ratio === null || row.ratio === undefined || row.sort === null || row.sort === undefined) {
|
||||
this.$message.error("请完善第 " + (index + 1) + " 行补助比例配置")
|
||||
return false
|
||||
}
|
||||
}
|
||||
for (let index = 0; index < this.bonusList.length; index++) {
|
||||
const row = this.bonusList[index]
|
||||
if (row.continuousYear === null || row.continuousYear === undefined || row.increaseRatio === null || row.increaseRatio === undefined) {
|
||||
this.$message.error("请完善第 " + (index + 1) + " 行奖励配置")
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
// 新增弹窗默认基础配置,仅设置用户要求保留默认值的基础字段。
|
||||
defaultConfig(year) {
|
||||
return {
|
||||
year: year,
|
||||
configName: year + "年医疗互助补助配置",
|
||||
status: 1
|
||||
}
|
||||
},
|
||||
// 会员缴费配置为全局单条配置,未配置时给出可编辑默认值。
|
||||
defaultMemberConfig() {
|
||||
return {
|
||||
monthAmount: 0,
|
||||
halfPriceYear: 1
|
||||
}
|
||||
},
|
||||
// 清理前端临时字段,避免弹窗编辑辅助字段传到后端实体。
|
||||
cleanPayload(row) {
|
||||
const payload = this.copy(row)
|
||||
delete payload._editIndex
|
||||
return payload
|
||||
},
|
||||
// 金额展示统一保留两位小数,并添加千分位分隔。
|
||||
formatMoney(value) {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
return ""
|
||||
}
|
||||
return Number(value).toLocaleString("zh-CN", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
})
|
||||
},
|
||||
// 复制行数据,避免弹窗编辑时直接污染列表原数据。
|
||||
copy(row) {
|
||||
return JSON.parse(JSON.stringify(row))
|
||||
},
|
||||
// 根据列表面板剩余空间计算主表格高度,避免页面外层出现滚动条。
|
||||
updateTableHeight() {
|
||||
const panel = this.$refs.listPanel
|
||||
if (!panel) {
|
||||
return
|
||||
}
|
||||
const titleHeight = this.$refs.listTitle ? this.$refs.listTitle.offsetHeight : 0
|
||||
const pagerHeight = this.$refs.pagerBar ? this.$refs.pagerBar.offsetHeight : 0
|
||||
this.tableHeight = Math.max(panel.clientHeight - titleHeight - pagerHeight - 32, 220)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initYearOptions()
|
||||
this.loadConfigList()
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(this.updateTableHeight)
|
||||
window.addEventListener("resize", this.updateTableHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("resize", this.updateTableHeight)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="疾病种类">
|
||||
<el-input placeholder="请输入疾病种类" clearable v-model="pageForm.searchKeyword"
|
||||
@keyup.enter.native="doSearch"></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<table-tool label="疾病种类">
|
||||
<el-button @click="openAdd" icon="el-icon-plus" size="small" type="primary">
|
||||
新增疾病种类
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
ref="table" row-key="id" style="width: 100%" v-loading="tableLoading">
|
||||
<el-table-column label="编号" prop="diseaseCode"></el-table-column>
|
||||
<el-table-column label="疾病种类" prop="diseaseName"></el-table-column>
|
||||
<el-table-column label="是否重大疾病" prop="isMajorDiseases">
|
||||
<template v-slot="{row}">
|
||||
<el-tag v-if="row.isMajorDiseases" type="danger">是</el-tag>
|
||||
<el-tag v-else>否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" width="180px">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button @click="doDelete(row.id)" size="mini" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</guava>
|
||||
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%">
|
||||
<el-form :model="formData" :rules="rules" label-width="120px" ref="form">
|
||||
<el-form-item label="疾病名称" prop="diseaseName">
|
||||
<el-input maxlength="50" show-word-limit v-model="formData.diseaseName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="编号" prop="diseaseCode">
|
||||
<el-input maxlength="20" v-model="formData.diseaseCode"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否重大疾病" prop="isMajorDiseases">
|
||||
<el-radio-group v-model="formData.isMajorDiseases" size="small">
|
||||
<el-radio :label="true" border>是</el-radio>
|
||||
<el-radio :label="false" border>否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row justify="end" type="flex">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button @click="doSubmit" class="ml10" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
dialogTitle: "新增疾病种类",
|
||||
formData: {
|
||||
isMajorDiseases: true
|
||||
},
|
||||
rules: {
|
||||
diseaseName: [{ required: true, message: "请输入疾病名称", trigger: ["change", "blur"] }],
|
||||
diseaseCode: [{ required: true, message: "请输入疾病编号", trigger: ["change", "blur"] }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 删除前要求用户二次确认,避免误删疾病基础数据。
|
||||
doDelete(id) {
|
||||
this.$confirm("您确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post(loc() + "/doDelete", { id: id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 打开编辑弹窗时复制行数据,防止未保存操作直接修改列表。
|
||||
openEdit(row) {
|
||||
this.formData = clone(row)
|
||||
this.dialogTitle = "编辑疾病种类"
|
||||
this.dialogVisible = true
|
||||
},
|
||||
// 表单校验通过后提交,成功时关闭弹窗并刷新列表。
|
||||
doSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$axios.post(loc() + "/doSubmit", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.dialogVisible = false
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 新增时重置默认值,确保重大疾病选项默认选中“是”。
|
||||
openAdd() {
|
||||
this.formData = { isMajorDiseases: true }
|
||||
this.dialogTitle = "新增疾病种类"
|
||||
this.dialogVisible = true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
<style scoped>
|
||||
.disease-type-page {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
.search-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background: #fff;
|
||||
}
|
||||
.search-toolbar .van-search {
|
||||
flex: 1;
|
||||
padding: 0 8px 0 0;
|
||||
}
|
||||
.disease-card {
|
||||
margin: 10px 12px;
|
||||
padding: 14px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.disease-card__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.disease-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #323233;
|
||||
}
|
||||
.disease-card__code {
|
||||
margin-bottom: 12px;
|
||||
color: #969799;
|
||||
}
|
||||
.disease-card__actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
.popup-title {
|
||||
padding: 18px 16px 8px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
.popup-actions {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="disease-type-page" id="app">
|
||||
<van-nav-bar title="疾病种类" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<div class="search-toolbar">
|
||||
<van-search v-model="pageForm.searchKeyword" placeholder="请输入疾病种类"
|
||||
@clear="doSearch" @search="doSearch"></van-search>
|
||||
<van-button size="small" type="info" icon="plus" @click="openAdd">新增</van-button>
|
||||
</div>
|
||||
</van-sticky>
|
||||
|
||||
<van-pull-refresh v-model="refreshing" @refresh="doSearch">
|
||||
<van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="loadData">
|
||||
<div class="disease-card" v-for="row in list" :key="row.id">
|
||||
<div class="disease-card__header">
|
||||
<span class="disease-card__name">{{row.diseaseName}}</span>
|
||||
<van-tag :type="row.isMajorDiseases ? 'danger' : 'primary'">
|
||||
{{row.isMajorDiseases ? "重大疾病" : "普通疾病"}}
|
||||
</van-tag>
|
||||
</div>
|
||||
<div class="disease-card__code">编号:{{row.diseaseCode}}</div>
|
||||
<div class="disease-card__actions">
|
||||
<van-button plain size="small" type="info" @click="openEdit(row)">编辑</van-button>
|
||||
<van-button plain size="small" type="danger" @click="doDelete(row.id)">删除</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
|
||||
<van-popup v-model="dialogVisible" position="bottom" round :style="{ height: '68%' }">
|
||||
<div class="popup-title">{{dialogTitle}}</div>
|
||||
<van-form ref="form" @submit="doSubmit">
|
||||
<van-field v-model="formData.diseaseName" name="diseaseName" label="疾病名称"
|
||||
maxlength="50" placeholder="请输入疾病名称"
|
||||
:rules="[{ required: true, message: '请输入疾病名称' }]"></van-field>
|
||||
<van-field v-model="formData.diseaseCode" name="diseaseCode" label="编号"
|
||||
maxlength="20" placeholder="请输入疾病编号"
|
||||
:rules="[{ required: true, message: '请输入疾病编号' }]"></van-field>
|
||||
<van-field name="isMajorDiseases" label="重大疾病">
|
||||
<template #input>
|
||||
<van-switch v-model="formData.isMajorDiseases" size="22"></van-switch>
|
||||
</template>
|
||||
</van-field>
|
||||
<div class="popup-actions">
|
||||
<van-button block round type="info" native-type="submit">确定</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
apiPath: "/platform/h5/medicalMutualAid/medical/diseaseType",
|
||||
list: [],
|
||||
loading: false,
|
||||
refreshing: false,
|
||||
finished: false,
|
||||
dialogVisible: false,
|
||||
dialogTitle: "新增疾病种类",
|
||||
formData: {
|
||||
isMajorDiseases: true
|
||||
},
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 分页加载疾病类型,刷新时替换列表,翻页时追加列表。
|
||||
loadData() {
|
||||
this.$axios.post(this.apiPath + "/pageData", this.pageForm).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
const rows = resp.data && resp.data.list ? resp.data.list : []
|
||||
if (this.pageForm.pageNumber === 1) {
|
||||
this.list = rows
|
||||
} else {
|
||||
this.list = this.list.concat(rows)
|
||||
}
|
||||
this.pageForm.totalCount = resp.data ? resp.data.totalCount : 0
|
||||
if (this.list.length >= this.pageForm.totalCount || rows.length === 0) {
|
||||
this.finished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber += 1
|
||||
}
|
||||
} else {
|
||||
this.$toast.fail(resp.msg)
|
||||
this.finished = true
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
})
|
||||
},
|
||||
// 重置分页状态并按当前关键字重新查询。
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.finished = false
|
||||
this.list = []
|
||||
this.loading = true
|
||||
this.loadData()
|
||||
},
|
||||
// 新增时初始化默认表单。
|
||||
openAdd() {
|
||||
this.formData = { isMajorDiseases: true }
|
||||
this.dialogTitle = "新增疾病种类"
|
||||
this.dialogVisible = true
|
||||
},
|
||||
// 编辑时复制列表数据,避免关闭弹窗前污染原列表。
|
||||
openEdit(row) {
|
||||
this.formData = Object.assign({}, row)
|
||||
this.dialogTitle = "编辑疾病种类"
|
||||
this.dialogVisible = true
|
||||
},
|
||||
// Vant 表单校验成功后保存疾病类型。
|
||||
doSubmit() {
|
||||
this.$axios.post(this.apiPath + "/doSubmit", this.formData).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$toast.success(resp.msg)
|
||||
this.dialogVisible = false
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(resp.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 删除前二次确认,成功后从第一页重新加载。
|
||||
doDelete(id) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要删除吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post(this.apiPath + "/doDelete", { id: id }).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$toast.success(resp.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(resp.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user