Merge remote-tracking branch 'origin/main'

This commit is contained in:
@jyuhsin
2026-01-24 17:38:23 +08:00
53 changed files with 7329 additions and 509 deletions
+6
View File
@@ -89,6 +89,12 @@
<artifactId>aviator</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<!-- minio文件sdk -->
<dependency>
<groupId>io.minio</groupId>
@@ -0,0 +1,165 @@
package com.budwk.app.base.utils;
import java.math.BigDecimal;
/**
* @author : hongqiwei
* @description :
* @createDate : 2026/1/20 15:41
*/
public class MoneyUtil {
public MoneyUtil() {
}
public static String toRMBUpper(String money) throws Exception {
boolean lessZero = false;
if (money.contains("E")) {
BigDecimal bg = new BigDecimal(Double.valueOf(money));
money = bg.toPlainString();
}
if (money.startsWith("-")) {
money = money.substring(1);
lessZero = true;
}
if (!money.matches("^[0-9]*$|^0+\\.[0-9]+$|^[1-9]+[0-9]*$|^[1-9]+[0-9]*.[0-9]+$")) {
throw new Exception("钱数格式错误!");
} else {
String[] part = money.split("\\.");
String integerData = part[0];
String decimalData = part.length > 1 ? part[1] : "";
if (integerData.matches("^0+$")) {
integerData = "0";
} else if (integerData.matches("^0+(\\d+)$")) {
integerData = integerData.replaceAll("^0+(\\d+)$", "$1");
}
StringBuffer integer = new StringBuffer();
for(int i = 0; i < integerData.length(); ++i) {
char perchar = integerData.charAt(i);
integer.append(upperNumber(perchar));
integer.append(upperNumber(integerData.length() - i - 1));
}
StringBuffer decimal = new StringBuffer();
if (part.length > 1 && !"00".equals(decimalData)) {
int length = decimalData.length() >= 2 ? 2 : decimalData.length();
for(int i = 0; i < length; ++i) {
char perchar = decimalData.charAt(i);
decimal.append(upperNumber(perchar));
if (i == 0) {
decimal.append('角');
}
if (i == 1) {
decimal.append('分');
}
}
}
String var10000 = integer.toString();
String result = var10000 + decimal.toString();
result = dispose(result);
if (lessZero && !"零圆整".equals(result)) {
result = "" + result;
}
return result;
}
}
private static char upperNumber(char number) {
switch (number) {
case '0' -> {
return '零';
}
case '1' -> {
return '壹';
}
case '2' -> {
return '贰';
}
case '3' -> {
return '叁';
}
case '4' -> {
return '肆';
}
case '5' -> {
return '伍';
}
case '6' -> {
return '陆';
}
case '7' -> {
return '柒';
}
case '8' -> {
return '捌';
}
case '9' -> {
return '玖';
}
default -> {
return '0';
}
}
}
private static char upperNumber(int index) {
int realIndex = index % 9;
if (index > 8) {
realIndex = (index - 9) % 8;
++realIndex;
}
switch (realIndex) {
case 0 -> {
return '圆';
}
case 1 -> {
return '拾';
}
case 2 -> {
return '佰';
}
case 3 -> {
return '仟';
}
case 4 -> {
return '万';
}
case 5 -> {
return '拾';
}
case 6 -> {
return '佰';
}
case 7 -> {
return '仟';
}
case 8 -> {
return '亿';
}
default -> {
return '0';
}
}
}
private static String dispose(String result) {
result = result.replaceAll("0", "");
result = result.replaceAll("零仟零佰零拾|零仟零佰|零佰零拾|零仟|零佰|零拾", "");
result = result.replaceAll("零+", "").replace("零亿", "亿");
result = result.matches("^.*亿零万[^零]仟.*$") ? result.replace("零万", "") : result.replace("零万", "");
result = result.replace("亿万", "亿");
result = result.replace("零角", "").replace("零分", "");
result = result.replaceAll("(^[零圆]*)(.+$)", "$2");
result = result.replaceAll("(^.*)([零]+圆)(.+$)", "$1圆零$3");
result = result.replaceAll("圆零角零分|圆零角$|圆$|^零$|圆零$|圆零零$|零圆$", "圆整");
result = result.replaceAll("^圆整$", "零圆整");
return result;
}
}
@@ -16,6 +16,7 @@ import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -84,7 +85,17 @@ public class UnionReimburseApplyController {
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
@SLog(type = "unionReimburse", tag = "工会报销-报销申请", msg = "保存报销申请")
public Result save(@Param("data") UnionReimburse unionReimburse) {
if (StrUtil.isBlank(unionReimburse.getId())) unionReimburse.setCreateTime(new Date());
if (StrUtil.isBlank(unionReimburse.getId())) {
unionReimburse.setCreateTime(new Date());
String documentNo = generateDocumentNo();
unionReimburse.setDocumentNo(documentNo);
}
unionReimburse.setStateId(1);//待提交
if (("UNION_REIMBURSE_PROJECT_1").equals(unionReimburse.getReimburseProject())){
unionReimburse.setRealMoney(unionReimburse.getCondolenceMoney());
}else {
unionReimburse.setRealMoney(unionReimburse.getMoney());
}
dao.insertOrUpdate(unionReimburse);
return Result.success();
}
@@ -94,52 +105,56 @@ public class UnionReimburseApplyController {
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
public Result submit(@Param("data") UnionReimburse unionReimburse) {
if (StrUtil.isBlank(unionReimburse.getId())) unionReimburse.setCreateTime(new Date());
dao.insertOrUpdate(unionReimburse);
// 开启流程实例
Dict args = Dict.create();
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, unionReimburse);
args.set("userId", unionReimburse.getCertifierUserId());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("GHBX", unionReimburse.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
if (StrUtil.isBlank(unionReimburse.getId())) {
unionReimburse.setCreateTime(new Date());
String documentNo = generateDocumentNo();
unionReimburse.setDocumentNo(documentNo);
}
unionReimburse.setStateId(2);//待审核
if (("UNION_REIMBURSE_PROJECT_1").equals(unionReimburse.getReimburseProject())){
unionReimburse.setRealMoney(unionReimburse.getCondolenceMoney());
}else {
unionReimburse.setRealMoney(unionReimburse.getMoney());
}
return Result.success();
}
@At
@ApiOperation("重新提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
public Result submitAgain(@Param("data") UnionReimburse unionReimburse, @Param("taskId") Long taskId) {
if (StrUtil.isBlank(unionReimburse.getId())) unionReimburse.setCreateTime(new Date());
dao.insertOrUpdate(unionReimburse);
Dict dict = Dict.create();
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
dict.set("userId", unionReimburse.getCertifierUserId());
flowCommonService.executeTask(dict);
// // 开启流程实例
// Dict args = Dict.create();
// args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
// args.set(FlowConst.FORM_DATA, unionReimburse);
// args.set("userId", unionReimburse.getCondolenceUserId());
// ProcessInstance instance = flowEngine.startProcessInstanceByKey("GHBX", unionReimburse.getId(), SecurityUtil.getUserId(), args);
//
// // 自动完成第一个申请任务
// List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
// for (ProcessTask task : doingTaskList) {
// flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
// }
return Result.success();
}
// @At
// @ApiOperation("重新提交申请")
// @Aop(TransAop.READ_COMMITTED)
// @SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
// public Result submitAgain(@Param("data") UnionReimburse unionReimburse, @Param("taskId") Long taskId) {
// if (StrUtil.isBlank(unionReimburse.getId())) unionReimburse.setCreateTime(new Date());
//
// dao.insertOrUpdate(unionReimburse);
//
// Dict dict = Dict.create();
// dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
// dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
// dict.set("userId", unionReimburse.getCondolenceUserId());
// flowCommonService.executeTask(dict);
// return Result.success();
// }
@At
@SaCheckLogin
@ApiOperation("获取当前登录人的申请信息")
public Result info(@Param("id") String id) {
UnionReimburse unionReimburse = dao.fetch(UnionReimburse.class, id);
CondolenceType type = unionReimburseService.dao().fetch(CondolenceType.class,
Cnd.where(CondolenceType::getId, "=", unionReimburse.getCondolenceType()));
NutMap nutMap = Lang.obj2nutmap(unionReimburse);
// 使用三元运算符处理 null 情况
nutMap.put("typeName", type != null ? type.getName() : "");
return Result.success(nutMap);
return Result.success(unionReimburse);
}
@@ -159,7 +174,10 @@ public class UnionReimburseApplyController {
IFNULL(unitname, '暂无') as unitName,
unitid as unitId,
unionid as unionId,
unionname as unionName
unionname as unionName,
DATE(birthday) AS birthday,
idCard,
unionCode
from
vw_user
$condition
@@ -189,10 +207,29 @@ public class UnionReimburseApplyController {
@ApiOperation("查询职工慰问类型")
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
public Result queryCondolenceType() {
List<CondolenceType> list = typeService.query(Cnd.NEW().desc(CondolenceType::getCode));
List<CondolenceType> list = typeService.query(Cnd.NEW().asc(CondolenceType::getCode));
return Result.success(list);
}
@At
@ApiOperation("查询厉害账号信息")
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
public Result findUserBankHistory(String payer) {
Sql sql = Sqls.create("""
SELECT DISTINCT
bankCardNumber,
bankOfDeposit
FROM union_reimburse
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("payer", "=", payer);
sql.setCondition(cnd);
List<NutMap> result = unionReimburseService.listMap(sql);
return Result.success(result);
}
@At
@ApiOperation("查询校工会经费余额")
@SaCheckPermission(value = {"unionReimburse.apply", "h5.unionReimburse.apply"}, mode = SaMode.OR)
@@ -244,6 +281,39 @@ public class UnionReimburseApplyController {
// 如果没有找到该社团的经费记录,返回0
return Result.success(0.0);
}
@At
@ApiOperation("生成文件编号")
private String generateDocumentNo() {
int currentYear = DateUtil.thisYear();
String yearPrefix = String.valueOf(currentYear);
org.nutz.dao.Cnd cnd = org.nutz.dao.Cnd.where("documentNo", "LIKE", yearPrefix + "%");
cnd.desc("documentNo");
cnd.limit(1);
List<UnionReimburse> list = dao.query(UnionReimburse.class, cnd);
int nextSeq = 1; // 默认从01开始
if (!list.isEmpty()) {
String maxNo = list.get(0).getDocumentNo();
if (maxNo != null && maxNo.startsWith(yearPrefix)) {
// 提取序号部分(去掉年份前缀)
String seqPart = maxNo.substring(yearPrefix.length());
try {
int currentMaxSeq = Integer.parseInt(seqPart);
nextSeq = currentMaxSeq + 1;
} catch (NumberFormatException e) {
// 如果解析失败,使用默认值1
nextSeq = 1;
}
}
}
// 格式化序号为两位数
String seqStr = String.format("%02d", nextSeq);
return yearPrefix + seqStr;
}
}
@@ -3,10 +3,12 @@ package com.budwk.app.zhgh.dayofficework.unionReimburse.controller;
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.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
@@ -14,12 +16,16 @@ import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService;
import com.budwk.app.zhgh.dayofficework.unionReimburse.vo.UnionReimburseCollectExcelVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
@@ -33,6 +39,7 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@IocBean
@@ -74,28 +81,9 @@ public class UnionReimburseCollectController {
@Param(value = "reimburseProject") String reimburseProject) {
Sql sql = Sqls.create("""
SELECT
info.*,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
info.*
FROM
union_reimburse info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
@@ -116,8 +104,7 @@ public class UnionReimburseCollectController {
cnd.and(seg);
}
// 只查询流程实例状态为20的数据(已完成状态)
cnd.and("ins.state", "=", 20);
cnd.and("info.stateId", "in", List.of(3, 2));
cnd.desc("info.createTime");
sql.setCondition(cnd);
@@ -125,6 +112,68 @@ public class UnionReimburseCollectController {
return Result.success(pagination);
}
@At
@SaCheckPermission(value = {"unionReimburse.collect", "h5.unionReimburse.collect"}, mode = SaMode.OR)
public Result updateActuallyAmount(String id,Double realMoney) {
UnionReimburse unionReimburse = unionReimburseService.fetch(id);
unionReimburse.setRealMoney(realMoney);
unionReimburseService.updateIgnoreNull(unionReimburse);
return Result.success();
}
@At
@Ok("void")
@SaCheckPermission(value = {"unionReimburse.collect", "h5.unionReimburse.collect"}, mode = SaMode.OR)
public void exportSkr(Integer year, String unionId, String unitId, String reimburseProject,HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
CONCAT(u.username,'(',u.loginname,')') as skrxx,
rei.bankCardNumber,
rei.bankOfDeposit,
CASE
WHEN rei.reimburseProject = 'UNION_REIMBURSE_PROJECT_1' THEN '慰问'
WHEN rei.reimburseProject = 'UNION_REIMBURSE_PROJECT_2' THEN '文体活动'
WHEN rei.reimburseProject = 'UNION_REIMBURSE_PROJECT_3' THEN '日常活动'
WHEN rei.reimburseProject = 'UNION_REIMBURSE_PROJECT_4' THEN '专项活动'
ELSE rei.reimburseProject
END as reimbursementItemName,
u.mobile
FROM
`union_reimburse` rei
LEFT JOIN `vw_user` u ON u.id = rei.payer
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("rei.paymentWay","=","UNION_REIMBURSE_PAYMENT_WAY_2");
cnd.andEX("rei.reimburseProject", "=", reimburseProject);
cnd.andEX("YEAR(rei.createTime)", "=", year);
cnd.andEX("u.unitid", "=", unitId);
cnd.andEX("u.unionid", "=", unionId);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("u.unionid", "=", SecurityUtil.getUnionId());
}
cnd.desc("rei.createTime");
sql.setCondition(cnd);
List<NutMap> list = unionReimburseService.listMap(sql);
List<ExcelExportEntity> excelExportEntities = new ArrayList<>();
excelExportEntities.add(new ExcelExportEntity("收款人信息","skrxx",20));
excelExportEntities.add(new ExcelExportEntity("收款人账号","bankCardNumber",20));
excelExportEntities.add(new ExcelExportEntity("地区","area",20));
excelExportEntities.add(new ExcelExportEntity("开户行信息","bankOfDeposit",20));
excelExportEntities.add(new ExcelExportEntity("手机号码","mobile",20));
excelExportEntities.add(new ExcelExportEntity("报销项目","reimbursementItemName",20));
try{
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + new String(("收款人名册.xls").getBytes("utf-8"), "ISO8859-1"));
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), excelExportEntities, list);
workbook.write(response.getOutputStream());
}catch (Exception e){
e.printStackTrace();
}
}
@At
@Ok("void")
@SaCheckPermission(value = {"unionReimburse.collect", "h5.unionReimburse.collect"}, mode = SaMode.OR)
@@ -0,0 +1,93 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburseDesc;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseDescService;
import com.budwk.app.zhgh.staffbenefit.condolence.model.CondolenceType;
import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceTypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
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 java.util.List;
/**
* @author : hongqiwei
* @description :
* @createDate : 2026/1/20 11:32
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "职工慰问类型")
@At("/platform/unionReimburse/desc")
public class UnionReimburseDescController {
@Inject
private Dao dao;
@Inject
private UnionReimburseDescService unionReimburseDesc;
@At("")
@SaCheckPermission("unionReimburse.desc")
@Ok("beetl:/platform/zhgh/dayofficework/unionReimburse/desc/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("unionReimburse.desc")
public Result pageData(PageForm pageForm) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or(UnionReimburseDesc::getName, "like", "%" + pageForm.getSearchKeyword() + "%");
seg.or(UnionReimburseDesc::getCode, "like", "%" + pageForm.getSearchKeyword() + "%");
cnd.and(seg);
}
cnd.asc("code");
Pagination pagination = unionReimburseDesc.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@ApiOperation("新增/修改职工慰问类型")
@SaCheckPermission("unionReimburse.desc")
@SLog(tag = "职工慰问系统-慰问类型", msg = "新增/修改职工慰问类型")
public Object onSubmit(UnionReimburseDesc desc) {
unionReimburseDesc.insertOrUpdate(desc);
return Result.success();
}
@At
@ApiOperation("删除职工慰问类型")
@SaCheckPermission("unionReimburse.desc")
@SLog(tag = "职工慰问系统-慰问类型", msg = "删除职工慰问类型")
public Object onDelete(String id) {
unionReimburseDesc.delete(id);
return Result.success();
}
@At
@ApiOperation("查询附件说明")
@SaCheckPermission(value = {"unionReimburse.desc", "h5.unionReimburse.desc"}, mode = SaMode.OR)
public Result queryFileDesc() {
List<UnionReimburseDesc> list = unionReimburseDesc.query(Cnd.NEW().desc(UnionReimburseDesc::getCode));
return Result.success(list);
}
}
@@ -3,30 +3,58 @@ package com.budwk.app.zhgh.dayofficework.unionReimburse.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.page.Pagination;
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.base.utils.MoneyUtil;
import com.budwk.app.base.utils.OfficePlusUtil;
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
/**
* @ClassName UnionReimburseMineController
* @Author hongqiwei
@@ -41,10 +69,15 @@ import org.nutz.mvc.annotation.Param;
@Slf4j
public class UnionReimburseMineController {
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@Inject
private UnionReimburseService unionReimburseService;
@Inject
private FlowEngine flowEngine;
@Inject
private Dao dao;
@At("/index")
@@ -124,7 +157,274 @@ public class UnionReimburseMineController {
@SLog( tag = "删除工会报销", msg = "删除工会报销")
public Result delete(@Param("id") String id) {
unionReimburseService.delete(id);
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
}
@At
@ApiOperation("撤回")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"unionReimburse.mine", "h5.unionReimburse.mine"}, mode = SaMode.OR)
@SLog( tag = "撤回工会报销", msg = "撤回工会报销")
public Result revokeTask(@Param("id") String id) {
UnionReimburse unionReimburse = unionReimburseService.fetch(id);
unionReimburse.setStateId(1);//待审核
dao.insertOrUpdate(unionReimburse);
return Result.success();
}
@At
@Ok("void")
public void ActExport(String id, HttpServletResponse response, boolean Print) throws Exception {
UnionReimburse unionReimburse = unionReimburseService.fetch(id);
if (unionReimburse == null) {
throw new RuntimeException("报销记录不存在");
}
HashMap<String, Object> docData = new HashMap<>();
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(unionReimburse.getDocumentNo(), BarcodeFormat.QR_CODE, 80, 80);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
File tempFile = File.createTempFile("qrcode_", ".png");
javax.imageio.ImageIO.write(bufferedImage, "PNG", tempFile);
PictureRenderData pictureRenderData = com.deepoove.poi.data.Pictures.of(tempFile.getAbsolutePath())
.size(80, 80)
.create();
docData.put("qrcode", pictureRenderData);
tempFile.deleteOnExit();
docData.put("createTime", DateUtil.format(unionReimburse.getCreateTime(), "yyyy-MM-dd"));
docData.put("unitName", unionReimburse.getUnitName());
docData.put("userName", unionReimburse.getUserName());
docData.put("loginName", unionReimburse.getLoginName());
docData.put("mobile", unionReimburse.getMobile());
docData.put("paymentNotes", unionReimburse.getPaymentNotes());
docData.put("invoiceNumber", unionReimburse.getInvoiceNumber());
docData.put("notes", unionReimburse.getNotes());
docData.put("realMoney", unionReimburse.getRealMoney());
docData.put("reimburseProject", unionReimburse.getReimburseProject());
docData.put("paymentWay", unionReimburse.getPaymentWay());
//对私支付,付款人信息
docData.put("payerLoginname", unionReimburse.getPayerLoginname());
docData.put("payerName", unionReimburse.getPayerName());
docData.put("bankOfDeposit", unionReimburse.getBankOfDeposit());
docData.put("bankCardNumber", unionReimburse.getBankCardNumber());
// 金额转大写
if (unionReimburse.getRealMoney() != null) {
docData.put("money_big", MoneyUtil.toRMBUpper(String.valueOf(unionReimburse.getRealMoney())));
} else {
docData.put("money_big", "");
}
// 设置报销项目类型标记
String wtAct = "□文体活动 □慰问 □日常活动 □专项活动";
if ("UNION_REIMBURSE_PROJECT_2".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□文体活动", "√文体活动");
} else if ("UNION_REIMBURSE_PROJECT_3".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□日常活动", "√日常活动");
} else if ("UNION_REIMBURSE_PROJECT_4".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□专项活动", "√专项活动");
} else if ("UNION_REIMBURSE_PROJECT_1".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□慰问", "√慰问");
}
docData.put("bxxm", wtAct);
String templateName;
Double realMoney = unionReimburse.getRealMoney() != null ? unionReimburse.getRealMoney() : 0.0;
String paymentWay = unionReimburse.getPaymentWay();
if (("UNION_REIMBURSE_PAYMENT_WAY_2").equals(paymentWay)) { // 对私支付
docData.put("paymentWay", "对私支付");
if (realMoney < 5000) {
templateName = "unionReimburse_act_private_small";
} else {
templateName = "unionReimburse_act_private_big";
}
} else { // 对公支付
docData.put("paymentWay", "对公支付");
if (realMoney < 5000) {
templateName = "unionReimburse_act_public_small";
} else {
templateName = "unionReimburse_act_public_big";
}
}
if (Print) {
exportAsPDF(templateName, docData, unionReimburse, response);
} else {
exportAsWord(templateName, docData, unionReimburse, response);
}
}
@At
@Ok("void")
public void ConExport(String id, HttpServletResponse response, boolean Print) throws Exception {
UnionReimburse unionReimburse = unionReimburseService.fetch(id);
if (unionReimburse == null) {
throw new RuntimeException("报销记录不存在");
}
HashMap<String, Object> docData = new HashMap<>();
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(unionReimburse.getDocumentNo(), BarcodeFormat.QR_CODE, 80, 80);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
File tempFile = File.createTempFile("qrcode_", ".png");
javax.imageio.ImageIO.write(bufferedImage, "PNG", tempFile);
PictureRenderData pictureRenderData = com.deepoove.poi.data.Pictures.of(tempFile.getAbsolutePath())
.size(80, 80)
.create();
docData.put("qrcode", pictureRenderData);
docData.put("createTime", DateUtil.format(unionReimburse.getCreateTime(), "yyyy-MM-dd"));
docData.put("unitName", unionReimburse.getUnitName());
docData.put("userName", unionReimburse.getUserName());
docData.put("loginName", unionReimburse.getLoginName());
docData.put("mobile", unionReimburse.getMobile());
docData.put("paymentNotes", unionReimburse.getPaymentNotes());
docData.put("invoiceNumber", unionReimburse.getInvoiceNumber());
docData.put("notes", unionReimburse.getNotes());
docData.put("realMoney", unionReimburse.getRealMoney());
docData.put("reimburseProject", unionReimburse.getReimburseProject());
docData.put("paymentWay", unionReimburse.getPaymentWay());
//对私支付,付款人信息
docData.put("payerLoginname", unionReimburse.getPayerLoginname());
docData.put("payerName", unionReimburse.getPayerName());
docData.put("bankOfDeposit", unionReimburse.getBankOfDeposit());
docData.put("bankCardNumber", unionReimburse.getBankCardNumber());
//慰问
docData.put("condolenceUserName", unionReimburse.getCondolenceUserName());
docData.put("condolenceLoginName", unionReimburse.getCondolenceLoginName());
docData.put("typeName", unionReimburse.getTypeName());
docData.put("way", unionReimburse.getWay());
docData.put("condolenceTime", DateUtil.format(unionReimburse.getCondolenceTime(), "yyyy-MM-dd"));
docData.put("participants", unionReimburse.getParticipants());
//结婚
docData.put("marryTime", DateUtil.format(unionReimburse.getMarryTime(), "yyyy-MM-dd"));
//生育
docData.put("fertilityTime", DateUtil.format(unionReimburse.getFertilityTime(), "yyyy-MM-dd"));
//生病住院
docData.put("hospitalCausation", unionReimburse.getHospitalCausation());
docData.put("hospital", unionReimburse.getHospital());
docData.put("hospitalCount", unionReimburse.getHospitalCount());
String hospitalTime = DateUtil.format(unionReimburse.getHospitalizationStartTime(), "yyyy-MM-dd") +
"" +
DateUtil.format(unionReimburse.getHospitalizationEndTime(), "yyyy-MM-dd");
docData.put("hospitalTime", hospitalTime);
//去世
docData.put("deathTime", DateUtil.format(unionReimburse.getDeathTime(), "yyyy-MM-dd"));
docData.put("condolenceRelationship", unionReimburse.getCondolenceRelationship());
// 金额转大写
if (unionReimburse.getRealMoney() != null) {
docData.put("money_big", MoneyUtil.toRMBUpper(String.valueOf(unionReimburse.getRealMoney())));
} else {
docData.put("money_big", "");
}
// 设置报销项目类型标记
String wtAct = "□文体活动 □慰问 □日常活动 □专项活动";
if ("UNION_REIMBURSE_PROJECT_2".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□文体活动", "√文体活动");
} else if ("UNION_REIMBURSE_PROJECT_3".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□日常活动", "√日常活动");
} else if ("UNION_REIMBURSE_PROJECT_4".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□专项活动", "√专项活动");
} else if ("UNION_REIMBURSE_PROJECT_1".equals(unionReimburse.getReimburseProject())) {
wtAct = wtAct.replace("□慰问", "√慰问");
}
docData.put("bxxm", wtAct);
String templateName;
Double realMoney = unionReimburse.getRealMoney() != null ? unionReimburse.getRealMoney() : 0.0;
String paymentWay = unionReimburse.getPaymentWay();
if (("UNION_REIMBURSE_PAYMENT_WAY_2").equals(paymentWay)) { // 对私支付
docData.put("paymentWay", "对私支付");
if (("生病住院").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_private_hospital";
} else if (("结婚").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_private_mary";
} else if (("生育").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_private_birth";
} else if (("会员去世").equals(unionReimburse.getTypeName()) || ("直系亲属去世").equals(unionReimburse.getTypeName())) {
if (realMoney < 5000) {
templateName = "unionReimburse_con_private_dead_small";
} else {
templateName = "unionReimburse_con_private_dead_big";
}
} else {//其他
templateName = "unionReimburse_con_private_other";
}
} else { // 对公支付
docData.put("paymentWay", "对公支付");
if (("生病住院").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_public_hospital";
} else if (("结婚").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_public_mary";
} else if (("生育").equals(unionReimburse.getTypeName())) {
templateName = "unionReimburse_con_public_birth";
} else if (("会员去世").equals(unionReimburse.getTypeName()) || ("直系亲属去世").equals(unionReimburse.getTypeName())) {
if (realMoney < 5000) {
templateName = "unionReimburse_con_public_dead_small";
} else {
templateName = "unionReimburse_con_public_dead_big";
}
} else {//其他
templateName = "unionReimburse_con_public_other";
}
}
if (Print) {
exportAsPDF(templateName, docData, unionReimburse, response);
} else {
exportAsWord(templateName, docData, unionReimburse, response);
}
}
// 导出PDF
@At
private void exportAsPDF(String templateName, HashMap<String, Object> docData,
UnionReimburse unionReimburse, HttpServletResponse response) throws Exception {
String fileName = "中国地质大学(武汉)工会经费日常报销_" + unionReimburse.getUserName() + "_" +
DateUtil.format(unionReimburse.getCreateTime(), "yyyyMMdd") + ".pdf";
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate(templateName))
.render(docData)
.writeAndClose(byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
File sourceFile = File.createTempFile("file_convert_origin", ".docx");
Files.write(sourceFile.toPath(), bytes, StandardOpenOption.WRITE);
File pdfFile = File.createTempFile("file_convert", ".pdf");
OfficePlusUtil.convert(sourceFile.getPath(), pdfFile.getPath());
CommonDownloadUtil.download(fileName, IoUtil.readBytes(FileUtil.getInputStream(pdfFile)), response);
// 删除临时文件
FileUtil.del(sourceFile);
FileUtil.del(pdfFile.toPath());
} catch (IOException e) {
log.error("工会报销单据导出PDF失败,id:{},错误信息:{}", unionReimburse.getId(), e.getMessage());
}
}
// 导出Word
@At
private void exportAsWord(String templateName, HashMap<String, Object> docData,
UnionReimburse unionReimburse, HttpServletResponse response) throws Exception {
String fileName = "中国地质大学(武汉)工会经费日常报销_" + unionReimburse.getUserName() + "_" +
DateUtil.format(unionReimburse.getCreateTime(), "yyyyMMdd") + ".docx";
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate(templateName))
.render(docData)
.writeAndClose(byteArrayOutputStream);
CommonDownloadUtil.download(fileName, byteArrayOutputStream.toByteArray(), response);
} catch (IOException e) {
log.error("工会报销单据导出Word失败,id:{},错误信息:{}", unionReimburse.getId(), e.getMessage());
}
}
}
@@ -5,28 +5,38 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
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.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
import java.util.List;
import static org.openjdk.nashorn.internal.runtime.regexp.joni.Config.log;
@IocBean
@At("/platform/unionReimburse/review")
@Ok("json:full")
@@ -34,6 +44,8 @@ import java.util.List;
@Slf4j
public class UnionReimburseReviewController {
@Inject
private Dao dao;
@Inject
private UnionReimburseService unionReimburseService;
@@ -59,41 +71,20 @@ public class UnionReimburseReviewController {
String unitId,
String reimburseProject) {
Sql sql = Sqls.create("""
SELECT
info.*,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN union_reimburse info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
SELECT
info.*
FROM
union_reimburse info
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "019925d2-6f33-449a-9fb0-34c470222e99");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
// 已审核:查询 stateId 为 3(报销成功)、4(拒绝)、5(退回)的记录
cnd.and("info.stateId", "in", List.of(3, 4, 5));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
// 未审核:只查询 stateId 为 2(待审核确认)的记录
cnd.and("info.stateId", "=", 2);
}
// 年度查询条件
cnd.andEX("year(info.createTime)", "=", year);
@@ -118,10 +109,55 @@ public class UnionReimburseReviewController {
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
cnd.desc("t.createdAt");
cnd.desc("info.createdAt");
sql.setCondition(cnd);
Pagination<NutMap> pagination = unionReimburseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("审核")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"unionReimburse.review", "h5.unionReimburse.review"}, mode = SaMode.OR)
@SLog( tag = "审核工会报销", msg = "审核工会报销")
public Result reviewTask(@Param("data") UnionReimburse unionReimburse,String submitType) {
if (submitType == null || !List.of("3", "4", "5").contains(submitType)) {
return Result.error("无效的审核操作类型");
}
UnionReimburse dbRecord = dao.fetch(UnionReimburse.class, unionReimburse.getId());
if (dbRecord == null) {
return Result.error("记录不存在");
}
dbRecord.setReviewTime(new Date());
dbRecord.setStateId(Integer.parseInt(submitType));
dbRecord.setReviewOpinion(unionReimburse.getReviewOpinion());
dao.update(dbRecord);
return Result.success();
}
@At
@ApiOperation("一键审核")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"unionReimburse.review", "h5.unionReimburse.review"}, mode = SaMode.OR)
@SLog( tag = "一键审核", msg = "一键审核")
public Result allReview() {
try {
List<UnionReimburse> reimbursements = unionReimburseService.query(Cnd.where("stateId", "=", 2));
for (UnionReimburse reimbursement : reimbursements) {
reimbursement.setStateId(3);
reimbursement.setReviewTime(new Date());
reimbursement.setReviewOpinion("通过");
dao.update(reimbursement);
}
return Result.success("一键审核完成,共处理 " + reimbursements.size() + " 条记录");
} catch (Exception e) {
log.error("一键审核失败");
return Result.error("一键审核失败: " + e.getMessage());
}
}
}
@@ -0,0 +1,153 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.controller;
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.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.zhgh.dayofficework.unionReimburse.param.UnionReimbursePageForm;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@IocBean
@At("/platform/unionReimburse/statistics")
@Ok("json:full")
@Api("慰问统计")
@Slf4j
public class UnionReimburseStatisticsController {
@Inject
private Dao dao;
@Inject
private FlowEngine flowEngine;
@Inject
private SysDictService sysDictService;
@Inject
private UnionReimburseService unionReimburseService;
@At("")
@Ok("beetl:/platform/zhgh/dayofficework/unionReimburse/statistics/index.html")
@SaCheckPermission("unionReimburse.statistics")
public void index() {
}
@At("/h5")
@Ok("beetl:/platform/zhghh5/dayofficework/unionReimburse/statistics/index.html")
@SaCheckPermission("h5.unionReimburse.statistics")
public void h5Index() {
}
@At
@ApiOperation("慰问类型统计图表数据")
@SaCheckPermission(value = {"unionReimburse.statistics", "h5.unionReimburse.statistics"}, mode = SaMode.OR)
public Result condolencesType(String year, String unionId, String condolenceTypeId, String way) {
Sql sql = Sqls.create("""
SELECT
type.`name`,
type.`code`,
(
SELECT
COUNT(*)
FROM
union_reimburse con
LEFT JOIN `vw_user` us ON us.id = con.condolenceUserId
WHERE
type.name = con.typeName
$yearCnd
$unionIdCnd
$typeCnd
$wayCnd
$stateId
AND con.stateId IN (2, 3)
) `value`
FROM
condolence_type type $condition
""");
if (Strings.isNotBlank(year)) {
sql.setVar("yearCnd", String.format("AND YEAR ( con.createTime )= %s ", year));
}
if (Strings.isNotBlank(unionId)) {
sql.setVar("unionIdCnd", String.format("AND us.unionId = '%s' ", unionId));
}
if (Strings.isNotBlank(condolenceTypeId)) {
sql.setVar("typeCnd", String.format("AND con.condolenceTypeId = '%s' ", condolenceTypeId));
}
if (Strings.isNotBlank(way)) {
sql.setVar("wayCnd", String.format("AND con.way = '%s' ", way));
}
Cnd cnd = Cnd.NEW();
cnd.asc("type.location");
sql.setCondition(cnd);
List<NutMap> result = unionReimburseService.listMap(sql);
return Result.success(result);
}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"unionReimburse.statistics", "h5.unionReimburse.statistics"}, mode = SaMode.OR)
public Result pageData(UnionReimbursePageForm pageForm) {
Sql sql = unionReimburseService.getSql(pageForm);
Pagination pagination = unionReimburseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@Ok("void")
@ApiOperation("导出慰问信息列表")
@SaCheckPermission(value = {"unionReimburse.statistics", "h5.unionReimburse.statistics"}, mode = SaMode.OR)
public void doExport(UnionReimbursePageForm pageForm,
HttpServletResponse response){
Sql sql = unionReimburseService.getSql(pageForm);
List<NutMap> list = unionReimburseService.listMap(sql);
List<ExcelExportEntity> excelExportEntities = new ArrayList<>();
excelExportEntities.add(new ExcelExportEntity("工号","condolenceLoginName",20));
excelExportEntities.add(new ExcelExportEntity("姓名","condolenceUserName",20));
excelExportEntities.add(new ExcelExportEntity("分工会代码","condolenceUnionCode",20));
excelExportEntities.add(new ExcelExportEntity("分工会名称","condolenceUnionName",20));
excelExportEntities.add(new ExcelExportEntity("慰问类型","typeName",20));
excelExportEntities.add(new ExcelExportEntity("慰问方式","way",20));
excelExportEntities.add(new ExcelExportEntity("慰问金额","realMoney",20));
excelExportEntities.add(new ExcelExportEntity("慰问时间","newCreateTime",20));
excelExportEntities.add(new ExcelExportEntity("录入时间","newCondolenceTime",20));
try {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
CommonDownloadUtil.download("慰问信息列表.xlsx", workbook, response);
} catch (Exception e) {
log.error("导出慰问信息列表失败", e);
}
}
}
@@ -0,0 +1,91 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.condolence.model.CondolenceType;
import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceTypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
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 java.util.List;
/**
* @ClassName UnionReimburseTypeController
* @Author =
* @Date 2025/7/29 10:00
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean
@Ok("json:full")
@Api(tags = "职工慰问类型")
@At("/platform/unionReimburse/type")
public class UnionReimburseTypeController {
@Inject
private Dao dao;
@Inject
private CondolenceTypeService typeService;
@At("")
@SaCheckPermission("unionReimburse.type")
@Ok("beetl:/platform/zhgh/staffbenefit/condolence/type/index.html")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("unionReimburse.type")
public Result pageData(PageForm pageForm) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or(CondolenceType::getName, "like", "%" + pageForm.getSearchKeyword() + "%");
seg.or(CondolenceType::getCode, "like", "%" + pageForm.getSearchKeyword() + "%");
cnd.and(seg);
}
cnd.asc("code");
Pagination pagination = typeService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@ApiOperation("新增/修改职工慰问类型")
@SaCheckPermission("unionReimburse.type")
@SLog(tag = "职工慰问系统-慰问类型", msg = "新增/修改职工慰问类型")
public Object onSubmit(CondolenceType type) {
typeService.insertOrUpdate(type);
return Result.success();
}
@At
@ApiOperation("删除职工慰问类型")
@SaCheckPermission("unionReimburse.type")
@SLog(tag = "职工慰问系统-慰问类型", msg = "删除职工慰问类型")
public Object onDelete(String id) {
typeService.delete(id);
return Result.success();
}
@At
@ApiOperation("查询职工慰问类型")
@SaCheckLogin
public Result queryCondolenceType() {
List<CondolenceType> list = typeService.query(Cnd.where(CondolenceType::getEnable, "=", true).asc(CondolenceType::getCode));
return Result.success(list);
}
}
@@ -1,5 +1,6 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.model;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.hutool.db.DaoTemplate;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
@@ -70,41 +71,6 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionName;
@Column
@Comment("证明人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String certifierUserId;
@Column
@Comment("证明人姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String certifierUserName;
@Column
@Comment("证明人工号")
@ColDefine(type = ColType.VARCHAR, width = 120)
private String certifierLoginName;
@Column
@Comment("证明人分工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String certifierUnionId;
@Column
@Comment("证明人分工会")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String certifierUnionName;
@Column
@Comment("证明人单位ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String certifierUnitId;
@Column
@Comment("证明人单位")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String certifierUnitName;
@Column
@Comment("报销类别")
@@ -117,6 +83,11 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 30)
private String reimburseProject;
@Column
@Comment("文件编号")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String documentNo;
@Column
@Comment("支付方式")
@@ -139,6 +110,56 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 100)
private Double fundBalance;
@Column
@Comment("发票张数")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String invoiceNumber;
@Column
@Comment("发票号码")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String invoice;
@Column
@Comment("报销事由")
@ColDefine(type = ColType.VARCHAR)
private String paymentNotes;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR)
private String notes;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Comment("签字")
@ColDefine(type = ColType.VARCHAR, width = 255)
@Column(hump = true)
private String userSign;
/**
* 对私支付
*/
@Column
@Comment("付款人")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String payer;
@Column
@Comment("付款人工号")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String payerLoginname;
@Column
@Comment("付款人姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String payerName;
@Column
@Comment("户名")
@ColDefine(type = ColType.VARCHAR, width = 100)
@@ -154,32 +175,6 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 100)
private String bankOfDeposit;
@Column
@Comment("发票张数")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String invoiceNumber;
@Column
@Comment("发票号码")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String invoice;
@Column
@Comment("支付内容")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String paymentNotes;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Comment("签字")
@ColDefine(type = ColType.VARCHAR, width = 255)
@Column(hump = true)
private String userSign;
/**
* 慰问
*/
@@ -189,6 +184,66 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceId;
@Column
@Comment("慰问人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceUserId;
@Column
@Comment("慰问人姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceUserName;
@Column
@Comment("慰问人工号")
@ColDefine(type = ColType.VARCHAR, width = 120)
private String condolenceLoginName;
@Column
@Comment("慰问人性别")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String condolenceSex;
@Column
@Comment("慰问人生日")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceBirthday;
@Column
@Comment("慰问人身份证")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceIdCard;
@Column
@Comment("证明人分工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String certifierUnionId;
@Column
@Comment("慰问人分工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceUnionId;
@Column
@Comment("慰问人分工会code")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceUnionCode;
@Column
@Comment("慰问人分工会")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceUnionName;
@Column
@Comment("慰问人单位ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceUnitId;
@Column
@Comment("慰问人单位")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceUnitName;
@Column
@Comment("慰问对象名称")
@ColDefine(type = ColType.VARCHAR, width = 32)
@@ -205,9 +260,34 @@ public class UnionReimburse extends BaseModel {
private String condolenceType;
@Column
@Comment("慰问金额/报销金额")
@Comment("慰问类型名称")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String typeName;
@Column
@Comment("慰问上传附件说明")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String condolenceFilesNotes;
@Column
@Comment("慰问类型id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String condolenceTypeId;
@Column
@Comment("慰问类型方式")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String way;
@Column
@Comment("慰问金额")
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
private Double money;
private Double condolenceMoney;
@Column
@Comment("实际金额")
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
private Double realMoney;
@Column
@@ -215,9 +295,59 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.DATETIME)
private Date condolenceTime;
@Column
@Comment("结婚时间")
@ColDefine(type = ColType.DATETIME)
private Date marryTime;
@Column
@Comment("生育时间")
@ColDefine(type = ColType.DATETIME)
private Date fertilityTime;
@Column
@Comment("住院开始时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private Date hospitalizationStartTime;
@Column
@Comment("住院结束时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private Date hospitalizationEndTime;
@Column
@Comment("入住医院")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String hospital;
@Column
@Comment("住院病由")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String hospitalCausation;
@Column
@Comment("当年次数")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String hospitalCount;
@Column
@Comment("去逝时间")
@ColDefine(type = ColType.DATETIME)
private Date deathTime;
@Column
@Comment("与被慰问人关系")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String condolenceRelationship;
@Column
@Comment("参与随行人员")
@ColDefine(type = ColType.VARCHAR)
private String participants;
/**
* 活动/建家/日常
* 活动
*/
@Column
@@ -246,6 +376,11 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 50)
private String activityPlace;
@Column
@Comment("报销金额")
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
private Double money;
/*
* 所属社团
*/
@@ -265,4 +400,19 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.DATETIME)
private Date createTime;
@Column
@Comment("状态(1.待提交,2.待审核确认,3.报销成功,4.拒绝,5.退回)")
@ColDefine(type = ColType.VARCHAR, width = 32)
private int stateId;
@Column
@Comment("审核意见")
@ColDefine(type = ColType.VARCHAR)
private String reviewOpinion;
@Column
@Comment("审核时间")
@ColDefine(type = ColType.DATETIME)
private Date reviewTime;
}
@@ -0,0 +1,61 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.DB;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @author : hongqiwei
* @description :
* @createDate : 2026/1/20 11:22
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("union_reimburse_desc")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("工会报销-附件说明")
public class UnionReimburseDesc extends BaseModel {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String code;
@Column
@Comment("报销项目Id(1.慰问,2.文体活动,3.日常活动,4.专项活动)")
@ColDefine(type = ColType.INT, width = 2)
private String reimburseProject;
@Column
@Comment("报销项目名称")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String name;
@Column
@Comment("附件说明")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String fileDesc;
@Column
@Comment("排序字段")
@Prev({
@SQL(db = DB.MYSQL, value = "SELECT IFNULL(MAX(location),0)+1 FROM Condolence_Type"),
@SQL(db = DB.ORACLE, value = "SELECT COALESCE(MAX(location),0)+1 FROM Condolence_Type")
})
private Integer location;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
private int sortNum;
}
@@ -0,0 +1,24 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.param;
import com.budwk.app.base.param.PageForm;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @author : hongqiwei
* @description :
* @createDate : 2026/1/22 15:15
*/
@Data
public class UnionReimbursePageForm extends PageForm {
private Integer year;
private String unionId;
private String condolenceTypeId;
private String way;
private String reimburseProject;
private String unitId;
}
@@ -0,0 +1,7 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburseDesc;
public interface UnionReimburseDescService extends BaseService<UnionReimburseDesc> {
}
@@ -2,6 +2,10 @@ package com.budwk.app.zhgh.dayofficework.unionReimburse.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.param.UnionReimbursePageForm;
import org.nutz.dao.sql.Sql;
public interface UnionReimburseService extends BaseService<UnionReimburse> {
Sql getSql(UnionReimbursePageForm pageForm);
}
@@ -0,0 +1,17 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburseDesc;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseDescService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
@Slf4j
@IocBean(args = {"refer:dao"})
public class UnionReimburseDescServiceImpl extends BaseServiceImpl<UnionReimburseDesc> implements UnionReimburseDescService {
public UnionReimburseDescServiceImpl(Dao dao) {
super(dao);
}
}
@@ -1,17 +1,64 @@
package com.budwk.app.zhgh.dayofficework.unionReimburse.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.dayofficework.unionReimburse.model.UnionReimburse;
import com.budwk.app.zhgh.dayofficework.unionReimburse.param.UnionReimbursePageForm;
import com.budwk.app.zhgh.dayofficework.unionReimburse.service.UnionReimburseService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.List;
@Slf4j
@IocBean(args = {"refer:dao"})
public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> implements UnionReimburseService {
public UnionReimburseServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getSql(UnionReimbursePageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
LEFT(info.createTime,10) newCreateTime,
LEFT(info.condolenceTime,10) newCondolenceTime
FROM
union_reimburse info
$condition
""");
Cnd cnd = Cnd.NEW();
// 年度查询条件
cnd.andEX("year(info.createTime)", "=", pageForm.getYear());
// 工会、单位名称查询条件
cnd.andEX("info.condolenceUnionId", "=", pageForm.getUnionId());
cnd.andEX("info.unitId", "=", pageForm.getUnitId());
cnd.andEX("info.condolenceTypeId", "=", pageForm.getCondolenceTypeId());
cnd.andEX("info.way", "=", pageForm.getWay());
// 报销项目查询条件
cnd.andEX("info.reimburseProject", "=", pageForm.getReimburseProject());
// 姓名和工号查询条件
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("info.condolenceUserName",pageForm.getSearchKeyword());
seg.orLike("info.condolenceLoginName",pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.and("info.stateId", "in", List.of(3, 2));
cnd.desc("info.createTime");
sql.setCondition(cnd);
return sql;
}
}
@@ -137,7 +137,6 @@ public class CondolenceMineController {
CondolenceType type = condolenceService.dao().fetch(CondolenceType.class, Cnd.where(CondolenceType::getId, "=", condolence.getType()));
NutMap nutMap = Lang.obj2nutmap(condolence);
nutMap.put("typeName", type.getName());
//smsService.send("20182040", "这是一条由智慧工会系统发出的测试消息。");
return Result.success(nutMap);
}
@Inject
@@ -0,0 +1,255 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApplyCost;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zhf
* @date 2026/1/22 11:24
* @description
*/
@IocBean
@At("/platform/medicalMutualAid/medical/apply")
@Api("医疗互助申请")
@Ok("json:full")
@Slf4j
public class MedicalApplyController {
@Inject
private MedicalApplyService medicalApplyService;
@Inject
private FlowEngine flowEngine;
@Inject
private FlowCommonService flowCommonService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/apply/index.html")
@SaCheckPermission("medicalMutualAid.medical.apply")
public void index() {
}
@At
@ApiOperation("获取疾病列表")
@SaCheckLogin
public Result getDiseaseList() {
List<MedicalDiseaseType> typeList = medicalApplyService.dao().query(MedicalDiseaseType.class, Cnd.NEW().asc(MedicalDiseaseType::getDiseaseCode));
return Result.success(typeList);
}
@At
@ApiOperation("获取可以申请补助的人")
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result getSubsidyUser(String id, Integer year, String keyword) {
Sql sql = Sqls.create("""
SELECT
us.id,
us.sex,
us.birthday,
us.loginname,
us.username,
us.unitName,
us.homeAddress,
us.idCard,
TIMESTAMPDIFF(YEAR, us.birthday, CURDATE()) AS age
FROM
vw_user us
LEFT JOIN aid_fund_member_pay pay ON pay.userId = us.id
$condition
""");
Cnd cnd = Cnd.NEW();
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("us.username", keyword);
group.orLike("us.loginname", keyword);
group.orLike("us.oldLoginName", keyword);
group.or("us.id", "=", keyword);
cnd.and(group);
cnd.and("pay.isPayed", "=", 1);
Integer applyYear = DateUtil.thisYear();
if (StrUtil.isNotBlank(id)) {
//如果不等于空的话,则是编辑查询申请年的人员
MedicalApply medicalApply = medicalApplyService.dao().fetch(MedicalApply.class, id);
applyYear = DateUtil.year(DateUtil.parse(medicalApply.getApplyTime()));
} else {
//如果等于空,就代表不是编辑
if (year != null) {
applyYear = year;
}
}
cnd.and("pay.`year`", "=", applyYear);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
group1.and("us.unionId", "=", SecurityUtil.getUnionId());
}
if (AuthUtil.hasRoleOr(RoleConstant.RETIREMENT_WORKPLACE.name())) {
group1.and("us.aidFundMemberUserType", "=", "离退休人员");
}
cnd.and(group1);
}
sql.setCondition(cnd);
Pagination pagination = medicalApplyService.listPageMap(1, 10, sql);
List<NutMap> list = pagination.getList();
list.forEach(map -> {
String loginname = map.getString("loginname");
Sys_user user = medicalApplyService.dao().fetch(Sys_user.class, Cnd.where("oldLoginName", "=", loginname));
if (Lang.isNotEmpty(user)) {
//说明变更过工号 那页面上需要显示变更过的工号
map.setv("loginname", user.getLoginname());
map.setv("id", user.getId());
}
});
return Result.success(list);
}
@At
@ApiOperation("获取累计补助金额")
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result getMedicalSubsidyMoney(String userId) {
if (StrUtil.isBlank(userId)) {
return Result.error("参数错误");
}
NutMap medicalSubsidyMoney = medicalApplyService.getMedicalSubsidyMoney(userId);
return Result.success(medicalSubsidyMoney);
}
@At
@ApiOperation("获取补助申请次数")
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result getMedicalApplyNum(String userId) {
if (StrUtil.isBlank(userId)) {
return Result.error("参数错误");
}
Integer medicalApplyNum = medicalApplyService.getMedicalApplyNum(userId);
return Result.success(medicalApplyNum);
}
@At
@ApiOperation("保存")
@SLog(tag = "医疗互助申请", msg = "保存申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result save(@Param("data") MedicalApply medicalApply) {
if (StrUtil.isNotBlank(medicalApply.getId())) {
medicalApplyService.dao().clear(MedicalApplyCost.class, Cnd.where(MedicalApplyCost::getApplyId, "=", medicalApply.getId()));
medicalApplyService.delete(medicalApply.getId());
}
medicalApply.setApplyTime(DateUtil.now());
medicalApplyService.insertWith(medicalApply, "costList");
return Result.success();
}
@At
@ApiOperation("提交")
@SLog(tag = "医疗互助申请", msg = "提交申请")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result submit(@Param("data") MedicalApply medicalApply) {
if (StrUtil.isNotBlank(medicalApply.getId())) {
medicalApplyService.dao().clear(MedicalApplyCost.class, Cnd.where(MedicalApplyCost::getApplyId, "=", medicalApply.getId()));
medicalApplyService.delete(medicalApply.getId());
}
medicalApply.setApplyTime(DateUtil.now());
medicalApplyService.insertWith(medicalApply, "costList");
Sys_user user = medicalApplyService.dao().fetch(Sys_user.class, medicalApply.getUserId());
// 开启流程实例
Dict args = Dict.create();
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, medicalApply);
args.set("aidFundMemberUserType", user.getAidFundMemberUserType());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("YLBB", medicalApply.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}
@At
@ApiOperation("重新提交")
@SLog(tag = "医疗互助申请", msg = "重新提交")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result submitAgain(@Param("data") MedicalApply medicalApply, @Param("taskId") Long taskId) {
medicalApplyService.update(medicalApply);
medicalApplyService.dao().clear(MedicalApplyCost.class, Cnd.where(MedicalApplyCost::getApplyId, "=", medicalApply.getId()));
medicalApplyService.insert(medicalApply.getCostList());
Dict dict = Dict.create();
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
flowCommonService.executeTask(dict);
return Result.success();
}
@At
@ApiOperation("查询是否有进行中的申请")
@SaCheckPermission("medicalMutualAid.medical.apply")
public Result getIsAfootMedicalApply(String userId, String id) {
Boolean isAfootMedicalApply = medicalApplyService.getIsAfootMedicalApply(userId, id);
if (isAfootMedicalApply) {
Sys_user user = medicalApplyService.dao().fetch(Sys_user.class, userId);
return Result.error("【%s】有一条进行中的申请,请到“我的补助”菜单中查看。".formatted(user.getUsername()));
}
return Result.success();
}
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalSetting;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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;
/**
* @author zhf
* @date 2026/1/22 08:58
* @description 补助参数配置
*/
@IocBean
@At("/platform/medicalMutualAid/medical/basicSetting")
@Api("医疗互助补助参数配置")
@Ok("json:full")
@Slf4j
public class MedicalBasicSettingController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/basicSetting/index.html")
@SaCheckPermission("medicalMutualAid.medical.basicSetting")
public void index() {
}
@At
@SaCheckLogin
public Result getSetting() {
return Result.success(baseService.dao().fetch(MedicalSetting.class, Cnd.NEW()));
}
@At
@ApiOperation("保存/修改参数配置")
@SaCheckPermission("medicalMutualAid.medical.basicSetting")
public Result doSubmit(MedicalSetting medicalSetting) {
baseService.insertOrUpdate(medicalSetting);
return Result.success();
}
}
@@ -0,0 +1,76 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
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;
/**
* @author zhf
* @date 2026/1/21 10:52
* @description 医疗互助疾病类型表
*/
@IocBean
@At("/platform/medicalMutualAid/medical/diseaseType")
@Api("医疗互助疾病类型")
@Ok("json:full")
@Slf4j
public class MedicalDiseaseTypeController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/diseaseType/index.html")
@SaCheckPermission("medicalMutualAid.medical.diseaseType")
public void index() {
}
@At
@SaCheckPermission("medicalMutualAid.medical.diseaseType")
public Result pageData(PageForm pageForm) {
Sql sql = Sqls.create("SELECT * FROM medical_disease_type $condition");
Cnd cnd = Cnd.NEW();
if (ObjectUtil.isNotEmpty(pageForm.getSearchKeyword())) {
cnd.and(Cnd.likeEX("diseaseName", pageForm.getSearchKeyword()));
}
cnd.asc("diseaseCode");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("保存/修改疾病类型")
@SaCheckPermission("medicalMutualAid.medical.diseaseType")
public Result doSubmit(MedicalDiseaseType medicalDiseaseType) {
baseService.insertOrUpdate(medicalDiseaseType);
return Result.success();
}
@At
@ApiOperation("删除疾病类型")
@SaCheckPermission("medicalMutualAid.medical.diseaseType")
public Object doDelete(String id) {
baseService.dao().clear(MedicalDiseaseType.class, Cnd.where(MedicalDiseaseType::getId, "=", id));
return Result.success();
}
}
@@ -0,0 +1,174 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApplyCost;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param.MedicalPageForm;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zhf
* @date 2026/1/23 17:09
* @description 互管会审核
*/
@IocBean
@At("/platform/medicalMutualAid/medical/foundationAudit")
@Api("医疗互助校互管会审核")
@Ok("json:full")
@Slf4j
public class MedicalFoundationAuditController {
@Inject
private MedicalApplyService medicalApplyService;
@Inject
private FlowCommonService flowCommonService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/foundationAudit/index.html")
@SaCheckPermission("medicalMutualAid.medical.foundationAudit")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.foundationAudit")
public Result pageData(MedicalPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unionName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN medical_apply info ON info.id = ins.businessNo
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.andEX("us.unionid", "=", pageForm.getUnionId());
cnd.andEX("us.unitid", "=", pageForm.getUnitId());
cnd.and("t.taskName", "=", "cd560356-cc70-48b5-8d99-ff9bd3505869");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageForm.getApproval()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> costList = medicalApplyService.getCostList(pageVO.getList());
pageVO.setList(costList);
return Result.success(pageVO);
}
@At
@SLog(tag = "医院补助-互管会审核", msg = "修改了一条住院记录")
@SaCheckPermission("medicalMutualAid.medical.foundationAudit")
public Result updateCost(String data) {
List<MedicalApplyCost> applyCosts = Json.fromJsonAsList(MedicalApplyCost.class, data);
medicalApplyService.updateIgnoreNull(applyCosts);
return Result.success();
}
@At
@SLog(tag = "医院补助-互管会审核", msg = "互管会审核了一条记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.foundationAudit")
public Result executeTask(@Param("data") String param) {
if (StrUtil.isBlank(param)) {
return Result.error("参数错误");
}
Dict args = Json.fromJson(Dict.class, param);
String loveSubsidyMoney = args.getStr("tf_loveSubsidyMoney");
String forecastSubsidyMoney = args.getStr("tf_forecastSubsidyMoney");
if (args.getInt("submitType") == 1) {
medicalApplyService.update(Chain.make("loveSubsidyMoney", loveSubsidyMoney)
.add("forecastSubsidyMoney", forecastSubsidyMoney),
Cnd.where("id", "=", args.getStr("id")));
}
flowCommonService.executeTask(args);
return Result.success();
}
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("预测补助金额")
@SaCheckPermission("medicalMutualAid.medical.foundationAudit")
public Result calcMedicalMoney(String id, String diseaseId) {
NutMap nutMap = medicalApplyService.calcMedicalMoney(id, diseaseId);
return Result.success(nutMap);
}
}
@@ -0,0 +1,161 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApplyCost;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param.MedicalPageForm;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zhf
* @date 2026/1/23 09:17
* @description 我的申请
*/
@IocBean
@At("/platform/medicalMutualAid/medical/mine")
@Api("医疗互助我的申请")
@Ok("json:full")
@Slf4j
public class MedicalMineController {
@Inject
private MedicalApplyService medicalApplyService;
@Inject
private FlowEngine flowEngine;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/mine/index.html")
@SaCheckPermission("medicalMutualAid.medical.mine")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.mine")
public Result pageData(MedicalPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unionName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(SELECT MAX(id) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'startTask') AS startTaskId
FROM
medical_apply info
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id
AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.and("info.userId", "=", SecurityUtil.getUserId());
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.desc("info.applyTime");
}
sql.setCondition(cnd);
Pagination<NutMap> pagination = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> costList = medicalApplyService.getCostList(pagination.getList());
pagination.setList(costList);
return Result.success(pagination);
}
@At
@ApiOperation("删除")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.mine")
@SLog(tag = "医疗补助系统-我的补助", msg = "删除我的补助申请")
public Result delete(@Param("id") String id) {
medicalApplyService.delete(id);
medicalApplyService.dao().clear(MedicalApplyCost.class, Cnd.where(MedicalApplyCost::getApplyId, "=", id));
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
}
@At
@SaCheckPermission("medicalMutualAid.medical")
public Result info(String id) {
MedicalApply medicalApply = medicalApplyService.fetch(id);
MedicalDiseaseType diseaseType = medicalApplyService.dao().fetch(MedicalDiseaseType.class, medicalApply.getDiseaseId());
MedicalApply fetchLinks = medicalApplyService.fetchLinks(medicalApply, "costList",Cnd.NEW().asc("visitStartTime"));
View_user user = medicalApplyService.dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", medicalApply.getUserId()));
NutMap nutMap = Lang.obj2nutmap(fetchLinks);
nutMap.put("sex", user.getSex());
nutMap.put("loginName", user.getLoginname());
nutMap.put("userName", user.getUsername());
nutMap.put("unitName", user.getUnitName());
nutMap.put("unionName", user.getUnionName());
nutMap.put("aidFundDeductTime", user.getAidFundDeductTime());
nutMap.put("diseaseName", diseaseType.getDiseaseName());
nutMap.put("isMajorDiseases", diseaseType.getIsMajorDiseases());
return Result.success(nutMap);
}
}
@@ -0,0 +1,150 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param.MedicalPageForm;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zhf
* @date 2026/1/23 16:14
* @description 校医院审核
*/
@IocBean
@At("/platform/medicalMutualAid/medical/schoolHospitalAudit")
@Api("医疗互助校医院审核")
@Ok("json:full")
@Slf4j
public class MedicalSchoolHospitalAuditController {
@Inject
private MedicalApplyService medicalApplyService;
@Inject
private FlowCommonService flowCommonService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/schoolHospitalAudit/index.html")
@SaCheckPermission("medicalMutualAid.medical.schoolHospitalAudit")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.schoolHospitalAudit")
public Result pageData(MedicalPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unionName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN medical_apply info ON info.id = ins.businessNo
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.andEX("us.unionid", "=", pageForm.getUnionId());
cnd.andEX("us.unitid", "=", pageForm.getUnitId());
cnd.and("t.taskName", "=", "39916c1e-857d-407d-86c1-678ccf3011bc");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageForm.getApproval()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> costList = medicalApplyService.getCostList(pageVO.getList());
pageVO.setList(costList);
return Result.success(pageVO);
}
@At
@SLog(tag = "医院补助-校医院审核", msg = "校医院审核了一条记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("medicalMutualAid.medical.schoolHospitalAudit")
public Result executeTask(@Param("data") String param, String id){
Dict args = Json.fromJson(Dict.class, param);
if (args.getInt("submitType") == 1) {
String tfDiseaseId = args.getStr("tf_diseaseId");
medicalApplyService.update(Chain.make("diseaseId", tfDiseaseId), Cnd.where("id", "=", id));
}
flowCommonService.executeTask(args);
return Result.success();
}
}
@@ -0,0 +1,241 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
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.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param.MedicalPageForm;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author : hongqiwei
* @description :医疗互助汇总
* @createDate : 2026/1/24 10:20
*/
@IocBean
@At("/platform/medicalMutualAid/medical/statistics")
@Api("医疗互助汇总")
@Ok("json:full")
@Slf4j
public class MedicalStatisticsController {
@Inject
private MedicalApplyService medicalApplyService;
@Inject
private FlowEngine flowEngine;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/statistics/index.html")
@SaCheckPermission("medicalMutualAid.medical.statistics")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.statistics")
public Result pageData(MedicalPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unionName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(SELECT MAX(id) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'startTask') AS startTaskId
FROM
medical_apply info
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN aid_fund_member_pay member ON member.userId = info.userId
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id
AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.andEX("us.unionId", "=", pageForm.getUnionId());
cnd.andEX("us.unitId", "=", pageForm.getUnitId());
cnd.andEX("member.aidFundMemberUserType", "=", pageForm.getAidFundMemberUserType());
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.desc("info.applyTime");
}
cnd.and("ins.state", "=", 20);
cnd.groupBy("info.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> costList = medicalApplyService.getCostList(pagination.getList());
pagination.setList(costList);
return Result.success(pagination);
}
@At
@Ok("void")
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.statistics")
public void doExport(MedicalPageForm pageForm, Boolean isMajorDiseases, HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.diseaseCode,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unitCode,
us.unionName,
us.unionCode,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(SELECT MAX(id) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'startTask') AS startTaskId
FROM
medical_apply info
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN aid_fund_member_pay member ON member.userId = info.userId
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id
AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.andEX("us.unionId", "=", pageForm.getUnionId());
cnd.andEX("us.unitId", "=", pageForm.getUnitId());
cnd.andEX("member.aidFundMemberUserType", "=", pageForm.getAidFundMemberUserType());
cnd.andEX("type.isMajorDiseases", "=", isMajorDiseases);
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.desc("info.applyTime");
}
cnd.and("ins.state", "=", 20);
cnd.groupBy("info.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = medicalApplyService.getCostList(pagination.getList());
for (NutMap map : list) {
boolean isMajor = map.getBoolean("isMajorDiseases");
map.put("isMajorDiseasesDisplay", isMajor ? "" : "");
}
List<ExcelExportEntity> excelExportEntities = new ArrayList<>();
excelExportEntities.add(new ExcelExportEntity("姓名","username",20));
excelExportEntities.add(new ExcelExportEntity("工号","loginname",20));
excelExportEntities.add(new ExcelExportEntity("单位","unitName",20));
excelExportEntities.add(new ExcelExportEntity("单位编码","unitCode",20));
excelExportEntities.add(new ExcelExportEntity("工会","unionName",20));
excelExportEntities.add(new ExcelExportEntity("工会编码","unionCode",20));
excelExportEntities.add(new ExcelExportEntity("疾病名称","diseaseName",20));
excelExportEntities.add(new ExcelExportEntity("疾病编码","diseaseCode",20));
excelExportEntities.add(new ExcelExportEntity("是否重疾","isMajorDiseasesDisplay",20));
excelExportEntities.add(new ExcelExportEntity("申请时间","applyTime",20));
excelExportEntities.add(new ExcelExportEntity("申请次数","applyNum",20));
excelExportEntities.add(new ExcelExportEntity("住院医疗费总额(不含门诊)","hospitalSumMoney$",20));
excelExportEntities.add(new ExcelExportEntity("实际报销总额","reimbursementMoney$",20));
excelExportEntities.add(new ExcelExportEntity("(住院医疗)允许报销范围内个人承担部分金额","singleBearMoney$",20));
excelExportEntities.add(new ExcelExportEntity("(住院医疗)自费部分金额","personExpenseMoney$",20));
excelExportEntities.add(new ExcelExportEntity("重病门诊自费金额","outpatientServiceMoney$",20));
excelExportEntities.add(new ExcelExportEntity("非住院肾衰竭治疗、靶向药金额","bxyMoney$",20));
excelExportEntities.add(new ExcelExportEntity("合计","totalMoney",20));
excelExportEntities.add(new ExcelExportEntity("预测补助金额","forecastSubsidyMoney",20));
excelExportEntities.add(new ExcelExportEntity("补助金额","subsidyMoney",20));
excelExportEntities.add(new ExcelExportEntity("爱心基金","loveSubsidyMoney",20));
String exportYear = String.valueOf(pageForm.getYear());
if (StrUtil.isBlank(exportYear)) {
exportYear = String.valueOf(java.time.Year.now().getValue());
}
String fileName = exportYear + "年补助人员列表.xlsx";
try {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
CommonDownloadUtil.download(fileName, workbook, response);
} catch (Exception e) {
log.error("导出补助人员列表失败", e);
}
}
}
@@ -0,0 +1,120 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param.MedicalPageForm;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @author zhf
* @date 2026/1/23 15:19
* @description 分工会审核
*/
@IocBean
@At("/platform/medicalMutualAid/medical/unionAudit")
@Api("医疗互助分工会审核")
@Ok("json:full")
@Slf4j
public class MedicalUnionAuditController {
@Inject
private MedicalApplyService medicalApplyService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/unionAudit/index.html")
@SaCheckPermission("medicalMutualAid.medical.unionAudit")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("medicalMutualAid.medical.unionAudit")
public Result pageData(MedicalPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.diseaseName,
type.isMajorDiseases,
us.username,
us.loginname,
us.unitName,
us.unionName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN medical_apply info ON info.id = ins.businessNo
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN vw_user us ON us.id = info.userId
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("us.loginname", pageForm.getSearchKeyword());
seg.orLike("us.username", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId());
cnd.and("t.taskName", "=", "a9bbf69c-5edf-4161-a364-47996d212472");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (pageForm.getApproval()) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.applyTime");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = medicalApplyService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> costList = medicalApplyService.getCostList(pageVO.getList());
pageVO.setList(costList);
return Result.success(pageVO);
}
}
@@ -0,0 +1,135 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.math.BigDecimal;
import java.util.List;
/**
* @author zhf
* @date 2026/1/22 09:58
* @description 医疗互助申请表
*/
@Data
@Comment("医疗互助申请表")
@Accessors(chain = true)
@Table("medical_apply")
@EqualsAndHashCode(callSuper = true)
public class MedicalApply extends BaseModel {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("申请时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String applyTime;
@Column
@Comment("家庭住址")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String homeAddress;
@Column
@Comment("联系电话")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String mobile;
@Column
@Comment("身份证号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String idCard;
@Column
@Comment("年龄")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String age;
@Column
@Comment("申请次数")
@ColDefine(type = ColType.INT)
private Integer applyNum;
@Column
@Comment("累计补助金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal medicalSubsidyMoney;
@Column
@Comment("报销类型")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String subsidyType;
@Column
@Comment("补助金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal subsidyMoney;
@Column
@Comment("预测补助金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal forecastSubsidyMoney;
@Column
@Comment("爱心补助金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal loveSubsidyMoney;
@Column
@Comment("家庭年度总收入")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal familyIncome;
@Column
@Comment("疾病种类id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String diseaseId;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 300)
private String note;
@Column
@Comment("填写人工号")
@PrevInsert(els = @EL("$me.operatorLoginName()"))
@ColDefine(type = ColType.VARCHAR, width = 32)
private String applyLoginName;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Many(field = "applyId")
private List<MedicalApplyCost> costList;
public String operatorLoginName() {
return SecurityUtil.getUserLoginname();
}
}
@@ -0,0 +1,83 @@
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.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2026/1/22 11:10
* @description 申请住院记录
*/
@Data
@Comment("医疗互助申请表")
@Accessors(chain = true)
@Table("medical_apply_cost")
@EqualsAndHashCode(callSuper = true)
public class MedicalApplyCost extends BaseModel {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("主键Id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String applyId;
@Column
@Comment("就诊开始时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String visitStartTime;
@Column
@Comment("就诊结束时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String visitEndTime;
@Column
@Comment("就诊医院")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String visitHospital;
@Column
@Comment("住院医疗总额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal hospitalSumMoney;
@Column
@Comment("实际报销金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal reimbursementMoney;
@Column
@Comment("个人承担部分金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal singleBearMoney;
@Column
@Comment("自费部分金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal personExpenseMoney;
@Column
@Comment("门诊费")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal outpatientServiceMoney;
@Column
@Comment("靶向药")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal bxyMoney;
}
@@ -0,0 +1,46 @@
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.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @author zhf
* @date 2026/1/21 10:45
* @description 疾病类型
*/
@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;
}
@@ -0,0 +1,88 @@
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.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2026/1/21 10:45
* @description 疾病类型
*/
@Data
@Comment("医疗互助补助参数配置")
@Accessors(chain = true)
@Table("medical_setting")
@EqualsAndHashCode(callSuper = true)
public class MedicalSetting extends BaseModel {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("公费医疗患大病年度累计补助标准")
private BigDecimal publicYearInDiseaseMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("社保患大病年度累计补助标准")
private BigDecimal socialYearInDiseaseMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("患普通疾病单次补助标准")
private BigDecimal ordinaryOnceNotInDiseaseMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("爱心互助基金标准")
private BigDecimal loveMoney;
@Column
@ColDefine(type = ColType.INT)
@Comment("补助比例")
private Integer subsidyRatio;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("患大病补助最高限额")
private BigDecimal maxYearInDiseaseMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("患普通疾病补助最高限额")
private BigDecimal maxYearNotInDiseaseMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("历年总额度最高限额")
private BigDecimal previousYearMaxMoney;
@Column
@ColDefine(customType = "decimal(10,2)")
@Comment("超过最大限额后每年补助最大金额")
private BigDecimal beyondMaxQuotaMoney;
@Column
@ColDefine(type = ColType.INT)
@Comment("十年未补助首次申请增加比例")
private Integer tenYearNeverAddSubsidyRatio;
@Column
@ColDefine(type = ColType.INT)
@Comment("十五年未补助首次申请增加比例")
private Integer fifteenYearNeverAddSubsidyRatio;
}
@@ -0,0 +1,27 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.param;
import com.budwk.app.base.param.PageForm;
import lombok.Data;
/**
* @author zhf
* @date 2026/1/23 09:46
* @description
*/
@Data
public class MedicalPageForm extends PageForm {
/**
* 疾病id
*/
private String diseaseId;
private Integer year;
private Boolean approval;
private String unionId;
private String unitId;
private String aidFundMemberUserType;
}
@@ -0,0 +1,48 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply;
import org.nutz.lang.util.NutMap;
import java.util.List;
public interface MedicalApplyService extends BaseService<MedicalApply> {
/**
* 获取累计补助金额
*
* @param userId
* @return
*/
NutMap getMedicalSubsidyMoney(String userId);
Integer getMedicalApplyNum(String userId);
/**
* 根据每一条的申请记录获取填写的住院金额
*
* @param list 申请记录
* @return
*/
List<NutMap> getCostList(List<NutMap> list);
/**
* 查询是否有进行中的申请
*
* @param userId
* @param id
* @return
*/
Boolean getIsAfootMedicalApply(String userId, String id);
/**
* 计算补助金额
* @param applyId
* @param diseaseId
* @return
*/
NutMap calcMedicalMoney(String applyId, String diseaseId);
}
@@ -0,0 +1,398 @@
package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApplyCost;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalDiseaseType;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalSetting;
import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalApplyService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2026/1/22 18:10
* @description
*/
@IocBean(args = {"refer:dao"})
public class MedicalApplyServiceImpl extends BaseServiceImpl<MedicalApply> implements MedicalApplyService {
public MedicalApplyServiceImpl(Dao dao) {
super(dao);
}
@Override
public NutMap getMedicalSubsidyMoney(String userId) {
Sql sql = Sqls.create("""
SELECT SUM(subsidyMoney) medicalSubsidyMoney FROM medical_apply WHERE userId=@userId
""").setParam("userId", userId);
sql.setCallback(Sqls.callback.map());
dao().execute(sql);
NutMap info = (NutMap) sql.getResult();
return info;
}
@Override
public Integer getMedicalApplyNum(String userId) {
return 0 + 1;
}
@Override
public List<NutMap> getCostList(List<NutMap> list) {
for (NutMap map : list) {
List<MedicalApplyCost> costList = dao().query(MedicalApplyCost.class,
Cnd.where(MedicalApplyCost::getApplyId, "=", map.getString("id")));
BigDecimal hospitalSumMoney$ = costList.stream()
.map(MedicalApplyCost::getHospitalSumMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("hospitalSumMoney$", hospitalSumMoney$);
BigDecimal reimbursementMoney$ = costList.stream()
.map(MedicalApplyCost::getReimbursementMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("reimbursementMoney$", reimbursementMoney$);
BigDecimal singleBearMoney$ = costList.stream()
.map(MedicalApplyCost::getSingleBearMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("singleBearMoney$", singleBearMoney$);
BigDecimal personExpenseMoney$ = costList.stream()
.map(MedicalApplyCost::getPersonExpenseMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("personExpenseMoney$", personExpenseMoney$);
BigDecimal outpatientServiceMoney$ = costList.stream()
.map(MedicalApplyCost::getOutpatientServiceMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("outpatientServiceMoney$", outpatientServiceMoney$);
BigDecimal bxyMoney$ = costList.stream()
.map(MedicalApplyCost::getBxyMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put("bxyMoney$", bxyMoney$);
map.put("totalMoney", hospitalSumMoney$
.add(reimbursementMoney$)
.add(singleBearMoney$)
.add(personExpenseMoney$)
.add(outpatientServiceMoney$)
.add(bxyMoney$));
map.put("costList", costList);
}
return list;
}
@Override
public Boolean getIsAfootMedicalApply(String userId, String id) {
Sql sql = Sqls.create("""
SELECT
COUNT(*)
FROM
medical_apply info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id
AND t.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
SqlExpressionGroup group = new SqlExpressionGroup();
group.or("t.taskName", "is", null);
group.or("ins.state", "=", ProcessInstanceStateEnum.DOING.getCode());
cnd.and(group);
cnd.and("info.userId", "=", userId);
cnd.andEX("info.id", "!=", id);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.integer());
dao().execute(sql);
return sql.getInt() > 0;
}
@Override
public NutMap calcMedicalMoney(String applyId, String diseaseId) {
MedicalSetting medicalSetting = dao().fetch(MedicalSetting.class);
//获取申请信息
NutMap applyInfo = this.getApplyInfo(applyId);
//获取申请疾病类型
MedicalDiseaseType applyDiseaseType = dao().fetch(MedicalDiseaseType.class, Cnd.where(MedicalDiseaseType::getId, "=", applyInfo.getString("diseaseId")));
//获取申请住院信息
List<MedicalApplyCost> costs = dao().query(MedicalApplyCost.class, Cnd.where("applyId", "=", applyId));
//个人承担费用
BigDecimal singleBearMoney = costs.stream()
.map(MedicalApplyCost::getSingleBearMoney)
.filter(Objects::nonNull) // 防御性编程,避免 NPE
.reduce(BigDecimal.ZERO, BigDecimal::add);
//自费
BigDecimal personExpenseMoney = costs.stream()
.map(MedicalApplyCost::getPersonExpenseMoney)
.filter(Objects::nonNull) // 防御性编程,避免 NPE
.reduce(BigDecimal.ZERO, BigDecimal::add);
//门诊费用
BigDecimal outpatientServiceMoney = costs.stream()
.map(MedicalApplyCost::getOutpatientServiceMoney)
.filter(Objects::nonNull) // 防御性编程,避免 NPE
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 靶向药
BigDecimal bxyMoney = costs.stream()
.map(MedicalApplyCost::getBxyMoney)
.filter(Objects::nonNull) // 防御性编程,避免 NPE
.reduce(BigDecimal.ZERO, BigDecimal::add);
//可能此次申请人退休变号了,所以也要把旧号的申请记录一起查出来
Sys_user currentUser = dao().fetch(Sys_user.class, applyInfo.getString("userId"));
List<String> allUserIds = Lang.list(currentUser.getId());
if (StrUtil.isNotBlank(currentUser.getOldLoginName())) {
Sys_user oldUser = dao().fetch(Sys_user.class, Cnd.where("loginname", "=", currentUser.getOldLoginName()));
allUserIds.add(oldUser.getId());
}
// 查询申请成功的记录
List<NutMap> applyRecords = getApplyRecord(allUserIds);
//是否首次申请 爱心互助基金 重大疾病
boolean isFirstApply = applyRecords.stream().filter(v -> v.getBoolean("isMajorDiseases")).toList().isEmpty();
List<NutMap> applyRecordList = applyRecords.stream().filter(applyRecord -> {
int applyYear = DateUtil.year(DateUtil.parse(applyRecord.getString("applyTime")));
if (!applyRecord.getString("id").equals(applyId) && applyYear == DateUtil.thisYear()) {
return true;
}
return false;
}).toList();
//今年获得的补助(重疾)
BigDecimal subsidMoneyCurrentYear999 = applyRecordList.stream()
.filter(s -> s.getBoolean("isMajorDiseases"))
.map(a -> a.getString("loveSubsidyMoney") + a.getString("subsidyMoney"))
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//今年获得的补助(普疾)
BigDecimal subsidMoneyCurrentYear000 = applyRecordList.stream()
.filter(s -> !s.getBoolean("isMajorDiseases"))
.map(a -> a.getString("loveSubsidyMoney") + a.getString("subsidyMoney"))
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//历年来所获全部补助
BigDecimal allMoney = applyRecords.stream()
.map(a -> a.getString("loveSubsidyMoney") + a.getString("subsidyMoney"))
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//是否超过历年所获补助限额
Boolean isBeyondAllMoney = allMoney.compareTo(medicalSetting.getPreviousYearMaxMoney()) > 0;
Sys_user user = dao().fetch(Sys_user.class, SecurityUtil.getUserId());
boolean fullTenYears = DateUtil.thisYear() - Integer.parseInt(user.getAidFundDeductTime()) >= 10;
boolean fullFifYears = DateUtil.thisYear() - Integer.parseInt(user.getAidFundDeductTime()) >= 15;
//补助比例
double ratio = medicalSetting.getSubsidyRatio();
// 连续缴满15年 或者是 连续缴满10年
if (fullFifYears) {
ratio += medicalSetting.getFifteenYearNeverAddSubsidyRatio();
} else if (fullTenYears) {
ratio += medicalSetting.getTenYearNeverAddSubsidyRatio();
}
//是否重疾
Boolean isMajorDiseases = applyDiseaseType.getIsMajorDiseases();
if (StrUtil.isNotBlank(diseaseId)) {
MedicalDiseaseType diseaseType = dao().fetch(MedicalDiseaseType.class, Cnd.where(MedicalDiseaseType::getId, "=", diseaseId));
isMajorDiseases = diseaseType.getIsMajorDiseases();
}
//普通疾病不包含门诊费用 重大疾病包含门诊费
//门诊费用 + 自费 + 个人承担
BigDecimal allMedicalMoney;
if (isMajorDiseases) {
//如果是重大疾病
allMedicalMoney = personExpenseMoney.add(singleBearMoney).add(outpatientServiceMoney).add(bxyMoney);
} else {
//个人承担费用
singleBearMoney = costs.stream()
.map(MedicalApplyCost::getSingleBearMoney)
.filter(amount -> amount.compareTo(BigDecimal.valueOf(10000)) >= 0) // >= 10000
.reduce(BigDecimal.ZERO, BigDecimal::add);
//自费
personExpenseMoney = costs.stream()
.map(MedicalApplyCost::getPersonExpenseMoney)
.filter(amount -> amount.compareTo(BigDecimal.valueOf(10000)) >= 0) // >= 10000
.reduce(BigDecimal.ZERO, BigDecimal::add);
allMedicalMoney = personExpenseMoney.add(singleBearMoney).add(outpatientServiceMoney).add(bxyMoney);
}
allMedicalMoney = allMedicalMoney
.multiply(BigDecimal.valueOf(ratio))
.divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_UP);
//每年最多补多少钱
if (isMajorDiseases) {
BigDecimal maxYearInDiseaseMoney = medicalSetting.getMaxYearInDiseaseMoney();
//最大补助金额减去今年已获得
BigDecimal availableLimit = maxYearInDiseaseMoney.subtract(subsidMoneyCurrentYear999);
if (allMedicalMoney.compareTo(availableLimit) > 0) {
allMedicalMoney = availableLimit;
}
} else {
BigDecimal maxYearNotInDiseaseMoney = medicalSetting.getMaxYearNotInDiseaseMoney();
//最大补助金额减去今年已获得
BigDecimal availableLimit = maxYearNotInDiseaseMoney.subtract(subsidMoneyCurrentYear000);
if (allMedicalMoney.compareTo(availableLimit) > 0) {
allMedicalMoney = availableLimit;
}
}
// 根据是否为重大疾病,确定对应的年度补助上限
BigDecimal maxYearMedicalMoney = isMajorDiseases
? medicalSetting.getMaxYearInDiseaseMoney() // 重大疾病年度最高补助金额
: medicalSetting.getMaxYearNotInDiseaseMoney(); // 非重大疾病年度最高补助金额
// 判断是否满足“从未申请 + 补助金额恰好等于年度上限”的上浮条件
boolean isEligibleForBonus = applyRecords.isEmpty()
&& allMedicalMoney.compareTo(maxYearMedicalMoney) == 0;
// 若满足条件,根据连续缴费年限应用对应上浮比例
if (isEligibleForBonus) {
if (fullFifYears) {
// 连续缴满15年且从未申请:应用15年专属上浮比例(如10%)
double ratioPercent = medicalSetting.getFifteenYearNeverAddSubsidyRatio(); // 例如返回 10.0 表示 10%
BigDecimal ratioFactor = BigDecimal.valueOf(ratioPercent).divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_UP);
allMedicalMoney = allMedicalMoney.multiply(BigDecimal.ONE.add(ratioFactor)).setScale(2, RoundingMode.HALF_UP);
} else if (fullTenYears) {
// 连续缴满10年且从未申请:应用10年专属上浮比例(如5%)
double ratioPercent = medicalSetting.getTenYearNeverAddSubsidyRatio(); // 例如返回 5.0 表示 5%
BigDecimal ratioFactor = BigDecimal.valueOf(ratioPercent).divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_UP);
allMedicalMoney = allMedicalMoney.multiply(BigDecimal.ONE.add(ratioFactor)).setScale(2, RoundingMode.HALF_UP);
}
// 注意:15年条件优先于10年,若同时满足,仅执行15年分支
}
if (isBeyondAllMoney) {
allMedicalMoney = new BigDecimal("10000");
}
if (allMedicalMoney.compareTo(BigDecimal.ZERO) < 0) {
allMedicalMoney = BigDecimal.ZERO;
}
// 规则1:首次申请的重大疾病患者,若个人自付不足5000元,不给予常规补助(由爱心基金覆盖)
if (applyInfo.getInt("applyNum") == 1
&& applyDiseaseType.getIsMajorDiseases()
&& singleBearMoney != null
&& singleBearMoney.compareTo(new BigDecimal("5000")) < 0) {
allMedicalMoney = BigDecimal.ZERO;
}
// 规则2:普通疾病患者,只有当至少有一次住院自付 ≥ 10000元时才给予补助;否则补助为0
if (!applyDiseaseType.getIsMajorDiseases()
&& costs.stream().noneMatch(c -> {
BigDecimal bear = c.getSingleBearMoney();
return bear != null && bear.compareTo(new BigDecimal("10000")) >= 0;
})) {
allMedicalMoney = BigDecimal.ZERO;
}
NutMap nutMap = new NutMap();
if (Objects.equals(applyInfo.getString("state"), ProcessInstanceStateEnum.FINISHED.getCode())) {
nutMap.put("loveSubsidyMoney", applyInfo.getString("loveSubsidyMoney"));
} else {
nutMap.put("loveSubsidyMoney", (isFirstApply && isMajorDiseases ? medicalSetting.getLoveMoney() : 0));
}
nutMap.put("forecastSubsidyMoney", allMedicalMoney.setScale(2, RoundingMode.HALF_UP));
return nutMap;
}
/**
* 获取申请成功的记录
*
* @param userIds
* @return
*/
public List<NutMap> getApplyRecord(List<String> userIds) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.isMajorDiseases
FROM
medical_apply info
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("info.userId", "in", userIds);
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
sql.setCondition(cnd);
List<NutMap> listMap = listMap(sql);
return listMap;
}
/**
* 获取申请信息
*
* @param id
* @return
*/
public NutMap getApplyInfo(String id) {
Sql sql = Sqls.create("""
SELECT
info.*,
ins.state,
type.isMajorDiseases
FROM
medical_apply info
LEFT JOIN medical_disease_type type ON info.diseaseId = type.id
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("info.id", "=", id);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.map());
dao().execute(sql);
return (NutMap) sql.getResult();
}
}
@@ -4,16 +4,30 @@ layout("/layouts/platform.html"){
<div id="app" v-cloak>
<el-card shadow="never">
<snaker-start slot="header" label="工会报销" define_key="GHBX"></snaker-start>
<template #header>
<h3 style="color: rgb(24, 103, 176);" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问申请</h3>
<h3 style="color: rgb(24, 103, 176);" v-else-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动申请</h3>
<h3 style="color: rgb(24, 103, 176);" v-else-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动申请</h3>
<h3 style="color: rgb(24, 103, 176);" v-else-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动申请</h3>
</template>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="经办人">{{formData.userName}}</el-descriptions-item>
<el-descriptions-item label="工号">{{formData.loginName}}</el-descriptions-item>
<el-descriptions-item label="报销类别">
<el-form-item label="报销类别" prop="reimburseType">
<el-radio-group v-model="formData.reimburseType" size="medium">
<el-radio :label="item.code" border v-for="item in dict.type.UNION_REIMBURSE_TYPE">
<!-- <el-descriptions-item label="报销类别">-->
<!-- <el-form-item label="报销类别" prop="reimburseType">-->
<!-- <el-radio-group v-model="formData.reimburseType" size="medium">-->
<!-- <el-radio :label="item.code" border v-for="item in dict.type.UNION_REIMBURSE_TYPE">-->
<!-- {{item.name}}-->
<!-- </el-radio>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
<el-descriptions-item label="报销项目" span="2">
<el-form-item label="报销项目" prop="reimburseProject">
<el-radio-group v-model="formData.reimburseProject" size="medium">
<el-radio :label="item.code" border v-for="item in reimburseProjectList">
{{item.name}}
</el-radio>
</el-radio-group>
@@ -30,16 +44,6 @@ layout("/layouts/platform.html"){
</el-descriptions-item>
<el-descriptions-item label="报销项目" span="2">
<el-form-item label="报销项目" prop="reimburseProject">
<el-radio-group v-model="formData.reimburseProject" size="medium">
<el-radio :label="item.code" border v-for="item in reimburseProjectList">
{{item.name}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="报销经费来源" span="2">
<el-form-item label="报销经费来源" prop="reimburseFundSource">
<el-radio-group v-model="formData.reimburseFundSource" size="medium" @change="reimburseFundSourceChange">
@@ -56,98 +60,351 @@ layout("/layouts/platform.html"){
placeholder="请输入联系方式"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="证明人">
<el-form-item label="证明人" prop="certifierUserId">
<el-select
style="width: 100%"
v-model="formData.certifierUserId"
filterable
clearable
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethod(userOptions)"
@change="userChange">
<el-descriptions-item label="付款人" v-if="formData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<el-form-item prop="payer" label="付款人">
<el-select style="width: 100%"
v-model="formData.payer"
@change="payerUserChange"
filterable
clearable
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethodForPayer">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.userName+''+item.loginName+''+''+item.unitName+''"
:value="item.id">
v-for="item in payerOptions"
:key="item.id"
:label="item.userName+''+item.loginName+''+''+item.unitName+''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="户名">
<el-form-item prop="bankUserName" label="户名">
<el-input v-model="formData.bankUserName" show-word-limit
placeholder="请输入户名"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="银行账号">
<el-form-item prop="bankCardNumber" label="银行账号">
<el-input v-model="formData.bankCardNumber" show-word-limit
placeholder="请输入银行账号"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="开户行">
<el-form-item prop="bankOfDeposit" label="开户行">
<el-input v-model="formData.bankOfDeposit" show-word-limit
placeholder="请输入开户行"></el-input>
<el-descriptions-item label="开户行" v-if="formData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<el-form-item label="开户行" prop="bankOfDeposit">
<el-select
v-model="formData.bankOfDeposit"
@change="getUserBankHistory"
clearable
filterable
allow-create
default-first-option
placeholder="请输入开户行名称"
style="width: 100%">
<el-option
v-for="(item, index) in historyData"
:key="index"
:label="item.bankOfDeposit"
:value="item.bankOfDeposit">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动名称">
<el-descriptions-item label="银行卡号" v-if="formData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<el-form-item label="银行卡号" prop="bankCardNumber" >
<el-select
v-model="formData.bankCardNumber"
@change="getUserBankHistory"
clearable
filterable
allow-create
default-first-option
placeholder="请输入银行卡号"
style="width: 100%">
<el-option
v-for="(item, index) in historyData"
:key="index"
:label="item.bankCardNumber"
:value="item.bankCardNumber">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问对象" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="慰问对象" prop="condolenceUserId">
<el-select
style="width: 100%"
v-model="formData.condolenceUserId"
filterable
clearable
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethod(userOptions)"
@change="userChange">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.userName+''+item.loginName+''+''+item.unitName+''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="性别" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="condolenceSex" label="性别">
<el-input v-model="formData.condolenceSex" show-word-limit
placeholder="请输入性别" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="生日" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="condolenceBirthday" label="生日">
<el-input :value="formData.condolenceBirthday && $moment(formData.condolenceBirthday).isValid() ?$moment(formData.condolenceBirthday).format('YYYY-MM-DD') : ''"
show-word-limit placeholder="请输入生日" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="身份证号" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="condolenceIdCard" label="身份证号">
<el-input v-model="formData.condolenceIdCard" show-word-limit
placeholder="请输入身份证号" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="联系方式" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="condolenceMobile" label="联系方式">
<el-input v-model="formData.condolenceMobile" show-word-limit
placeholder="请输入联系方式" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问类型" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="慰问类型" prop="condolenceTypeId">
<el-select style="width: 100%"
v-model="formData.condolenceTypeId"
filterable
clearable
placeholder="请选择慰问类型"
@change="typeChange">
<el-option
v-for="item in typeOptions"
:key="item.id"
:label="item.name+''+item.code+''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问方式" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="way" label="慰问方式">
<el-select style="width: 100%" v-model="formData.way" placeholder="请选择慰问方式">
<el-option
v-for="option in condolenceWays"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问金额" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="condolenceMoney" label="慰问金额">
<el-input
v-model="formData.condolenceMoney"
show-word-limit
placeholder="请输入慰问金额"
type="number"
:precision="2"
step="0.01">
</el-input>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="户名">-->
<!-- <el-form-item prop="bankUserName" label="户名">-->
<!-- <el-input v-model="formData.bankUserName" show-word-limit-->
<!-- placeholder="请输入户名"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="银行账号">-->
<!-- <el-form-item prop="bankCardNumber" label="银行账号">-->
<!-- <el-input v-model="formData.bankCardNumber" show-word-limit-->
<!-- placeholder="请输入银行账号"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="开户行">-->
<!-- <el-form-item prop="bankOfDeposit" label="开户行">-->
<!-- <el-input v-model="formData.bankOfDeposit" show-word-limit-->
<!-- placeholder="请输入开户行"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
<el-descriptions-item label="活动名称" v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="活动名称" prop="activityName">
<el-input type="text" v-model="formData.activityName" placeholder="请输入活动名称"
maxlength="60"></el-input>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="活动类型" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">
<el-form-item label="活动类型" prop="activityType">
<el-select v-model="formData.activityType" placeholder="请选择活动类型" style="width: 100%">
<el-option label="分工会活动" value="分工会活动"></el-option>
<el-option label="校工会活动" value="校工会活动"></el-option>
<el-option label="协会(社团)活动" value="协会(社团)活动"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>-->
<el-descriptions-item label="活动类型" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">
<el-form-item label="活动类型" prop="activityType">
<el-select v-model="formData.activityType" placeholder="请选择活动类型" style="width: 100%">
<el-option label="分工会活动" value="分工会活动"></el-option>
<el-option label="校工会活动" value="校工会活动"></el-option>
<el-option label="协会(社团)活动" value="协会(社团)活动"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动人数" v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="活动人数" prop="activityNumber">
<el-input v-model="formData.activityNumber" placeholder="请输入活动人数" type="text"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动地点">
<el-descriptions-item label="活动地点" v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="活动地点" prop="activityPlace">
<el-input v-model="formData.activityPlace" placeholder="请输入活动地点" type="text"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="报销金额">
<el-descriptions-item label="报销金额" v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="报销金额" prop="money">
<el-input v-model="formData.money" placeholder="输入报销金额"
type="number"></el-input>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="活动时间" >
<el-form-item label="活动时间" prop="activityTime">
<el-date-picker v-model="formData.activityTime"
placeholder="活动时间"
style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>-->
<!-- <el-descriptions-item label="发票张数">-->
<!-- <el-form-item label="发票张数" prop="invoiceNumber">-->
<!-- <el-input-number v-model="formData.invoiceNumber"-->
<!-- :max="1000" :min="0" controls-position="right"-->
<!-- placeholder="请填写发票张数"-->
<!-- style="width: 100%"></el-input-number>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item ></el-descriptions-item>-->
<el-descriptions-item label="活动时间" v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="活动时间" prop="activityTime">
<el-date-picker v-model="formData.activityTime"
placeholder="活动时间" style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="支付内容" :span="2">
<el-form-item prop="paymentNotes" label="支付内容">
<el-input maxlength="500" v-model="formData.paymentNotes" placeholder="请填写支付内容"
<el-descriptions-item label="发票张数">
<el-form-item label="发票张数" prop="invoiceNumber">
<el-input-number v-model="formData.invoiceNumber"
:max="1000" :min="0" controls-position="right"
placeholder="请填写发票张数"
style="width: 100%"></el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问时间" v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item label="慰问时间" prop="condolenceTime">
<el-date-picker v-model="formData.condolenceTime"
placeholder="慰问时间"
style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="结婚时间"
v-if="formData.condolenceTypeId === 'cf4ce7af322d464f8f86d818fcc00203'">
<el-form-item label="结婚时间" prop="marryTime">
<el-date-picker v-model="formData.marryTime"
placeholder="结婚时间"
style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="生育时间"
v-if="formData.condolenceTypeId === 'c90cb10dce6542e99ae271bee6fe8cc0'">
<el-form-item label="生育时间" prop="fertilityTime">
<el-date-picker v-model="formData.fertilityTime"
placeholder="生育时间"
style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="住院病由"
v-if="formData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<el-form-item label="住院病由" prop="hospitalCausation">
<el-input v-model="formData.hospitalCausation" placeholder="请输入住院病由"
type="text"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="住院时间"
v-if="formData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<el-form-item label="住院时间" prop="hospitalizationTimeRange">
<el-date-picker
v-model="formData.hospitalizationTimeRange"
type="daterange"
range-separator="-"
start-placeholder="住院开始时间"
end-placeholder="住院结束时间"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd" style="width: 100%">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="入住医院"
v-if="formData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<el-form-item label="入住医院" prop="hospital">
<el-input v-model="formData.hospital" placeholder="请输入入住医院" type="text"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="当年次数"
v-if="formData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<el-form-item label="当年次数" prop="hospitalCount">
<el-input-number v-model="formData.hospitalCount"
:max="1000" :min="0" controls-position="right"
placeholder="请填写当年次数"
style="width: 100%"></el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="去逝时间"
v-if="formData.condolenceTypeId === '60f03a87b62b4823855814afdbf5672a'">
<el-form-item label="去逝时间" prop="deathTime">
<el-date-picker v-model="formData.deathTime"
placeholder="去逝时间"
style="width: 100%" type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="与被慰问人关系"
v-if="formData.condolenceTypeId === '60f03a87b62b4823855814afdbf5672a'">
<el-form-item prop="condolenceRelationship" label="与被慰问人关系">
<el-select style="width: 100%" v-model="formData.condolenceRelationship" placeholder="请选择">
<el-option
v-for="option in relationships"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="参加随行人员" :span="2"
v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="participants" label="参加随行人员">
<el-input maxlength="500" v-model="formData.participants" placeholder="请填写参加随行人员"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="报销事由" :span="2">
<el-form-item prop="paymentNotes" label="报销事由">
<el-input maxlength="500" v-model="formData.paymentNotes" placeholder="请填写报销事由"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">
<el-form-item prop="notes" label="备注">
<el-input maxlength="500" v-model="formData.notes" placeholder="需要填写:发票编号、开具方、金额"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
</el-form-item>
</el-descriptions-item>
@@ -157,19 +414,28 @@ layout("/layouts/platform.html"){
</template>
<el-form-item prop="files" label="附件">
<file-upload
:value.sync="formData.files"
:upload_number="10"
upload_result_category="array"
complete_result
upload_mode="drag"
:value.sync="formData.files"
:upload_number="10"
upload_result_category="array"
complete_result
upload_mode="drag"
></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-form-item label="签字" prop="userSign">
<pc-signature v-model="formData.userSign"></pc-signature>
<el-form-item v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'" class="mt10">
<div style="color: red;">
{{ formData.condolenceFilesNotes || getFileDescByProject(formData.reimburseProject) || '需要提供购买的慰问品发票,慰问照片' }} </div>
</el-form-item>
<el-form-item v-else class="mt10">
<div style="color: red;">
{{ getFileDescByProject(formData.reimburseProject) || '请上传活动照片、参加人员名单、付款凭证等相关材料' }}
</div>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="签字" :span="2">-->
<!-- <el-form-item label="签字" prop="userSign">-->
<!-- <pc-signature v-model="formData.userSign"></pc-signature>-->
<!-- </el-form-item>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</el-form>
<el-row type="flex" justify="end" class="mt20">
@@ -191,52 +457,76 @@ layout("/layouts/platform.html"){
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {
reimburseType: ""
reimburseType: "",
hospitalizationTimeRange: [],
reimburseProject:''
},
historyData: [],
condolenceWays: [
{label: "慰问金(A", value: "慰问金(A"},
{label: "提货券(B", value: "提货券(B"},
{label: "慰问品(C", value: "慰问品(C"}
],
relationships: [
{label: "配偶", value: "配偶"},
{label: "父亲", value: "父亲"},
{label: "母亲", value: "母亲"},
{label: "子女", value: "子女"},
],
formRules: {
reimburseType: [{ required: true, message: "请选择报销类别", trigger: ["change", "blur"] }],
paymentWay: [{ required: true, message: "请选择支付方式", trigger: ["change", "blur"] }],
reimburseProject: [{ required: true, message: "请选择报销项目", trigger: ["change", "blur"] }],
reimburseFundSource: [{ required: true, message: "请选择经费来源", trigger: ["change", "blur"] }],
bankUserName: [{ required: true, message: "请填写户名", trigger: ["change", "blur"] }],
// reimburseType: [{ required: true, message: "请选择报销类别", trigger: ["change", "blur"] }],
paymentWay: [{required: true, message: "请选择支付方式", trigger: ["change", "blur"]}],
reimburseProject: [{required: true, message: "请选择报销项目", trigger: ["change", "blur"]}],
reimburseFundSource: [{required: true, message: "请选择经费来源", trigger: ["change", "blur"]}],
bankUserName: [{required: true, message: "请填写户名", trigger: ["change", "blur"]}],
bankCardNumber: [{
required: true,
message: "请填写银行账号",
trigger: ["change", "blur"]
}, { pattern: /^([1-9]{1})(\d{15}|\d{18})$/, message: "请输入正确的银行卡号", trigger: "blur" }],
bankOfDeposit: [{ required: true, message: "请填写开户行", trigger: ["change", "blur"] }],
condolenceMobile: [{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }],
condolenceTime: [{ required: true, message: "请选择慰问时间", trigger: ["change", "blur"] }],
invoiceNumber: [{ required: true, message: "请填写发票张数", trigger: ["change", "blur"] }],
invoice: [{ required: true, message: "请填写发票号码", trigger: ["change", "blur"] }],
paymentNotes: [{ required: true, message: "请填写支付内容", trigger: ["change", "blur"] }],
activityName: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
money: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
mobile: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
files: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
userSign: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
certifierUserId: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}, {pattern: /^([1-9]{1})(\d{15}|\d{18})$/, message: "请输入正确的银行卡号", trigger: "blur"}],
bankOfDeposit: [{required: true, message: "请填写开户行", trigger: ["change", "blur"]}],
condolenceMobile: [{pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur"}],
condolenceTime: [{required: true, message: "请选择慰问时间", trigger: ["change", "blur"]}],
// invoiceNumber: [{required: true, message: "请填写发票张数", trigger: ["change", "blur"]}],
// invoice: [{required: true, message: "请填写发票号码", trigger: ["change", "blur"]}],
paymentNotes: [{required: true, message: "请填写支付内容", trigger: ["change", "blur"]}],
activityName: [{required: true, message: "请填写活动名称", trigger: ["change", "blur"]}],
money: [{required: true, message: "请填写报销金额", trigger: ["change", "blur"]}],
mobile: [{required: true, message: "请填写联系方式", trigger: ["change", "blur"]}],
files: [{required: true, message: "请上传附件", trigger: ["change", "blur"]}],
userSign: [{required: true, message: "请签名", trigger: ["change", "blur"]}],
// certifierUserId: [{required: true, message: "请填写认证人", trigger: ["change", "blur"]}],
condolenceUserId: [{required: true, message: "请选择慰问对象", trigger: ["change", "blur"]}],
condolenceTypeId: [{required: true, message: "请选择慰问类型", trigger: ["change", "blur"]}],
way: [{required: true, message: "请选择慰问方式", trigger: ["change", "blur"]}],
condolenceMoney: [{required: true, message: "请输入慰问金额", trigger: ["change", "blur"]}],
participants: [{required: true, message: "请填写参与随行人员", trigger: ["change", "blur"]}],
payer: [{required: true, message: "请选择付款人", trigger: ["change", "blur"]}],
activityType: [{required: true, message: "请选择活动类型", trigger: ["change", "blur"]}],
activityPlace: [{required: true, message: "请输入活动地点", trigger: ["change", "blur"]}],
activityTime: [{required: true, message: "请选择活动时间", trigger: ["change", "blur"]}],
activityNumber: [{required: true, message: "请输入活动人数", trigger: ["change", "blur"]}]
},
chooseType: {},
userOptions: [],
typeOptions: [],
descOptions: [],
reimburseProjectList: [],
reimburseProjects: [],
clubOptions: [],
budgetTypeOption: []
budgetTypeOption: [],
payerOptions: []
}
},
// 监听报销类别发生变化,报销项目联动改变
watch: {
"formData.reimburseType"(newVal) {
if (newVal === "UNION_REIMBURSE_TYPE_1") {
this.reimburseProjects = this.reimburseProjectList.filter((o) => {
return ["1", "UNION_REIMBURSE_TYPE_1"].includes(o.remark)
})
"formData.hospitalizationTimeRange"(newVal) {
if (newVal && newVal.length === 2) {
this.$set(this.formData, "hospitalizationStartTime", newVal[0]);
this.$set(this.formData, "hospitalizationEndTime", newVal[1]);
} else {
this.reimburseProjects = this.reimburseProjectList.filter((o) => {
return ["1", "UNION_REIMBURSE_TYPE_2"].includes(o.remark)
})
this.$set(this.formData, "hospitalizationStartTime", null);
this.$set(this.formData, "hospitalizationEndTime", null);
}
},
// 添加对社团选择的监听
@@ -253,6 +543,17 @@ layout("/layouts/platform.html"){
}
},
methods: {
createRemoteMethodForPayer(keyword) {
this.selectQueryUserForPayer(keyword, this.payerOptions)
},
selectQueryUserForPayer(keyword, options) {
options.length = 0
this.$axios.post("/platform/UnionReimburse/apply/listUser", {keyword: keyword}).then((res) => {
if (res.code === 0) {
options.push(...res.data)
}
})
},
createRemoteMethod(options) {
return (keyword) => {
this.selectQueryUser(keyword, options)
@@ -260,32 +561,90 @@ layout("/layouts/platform.html"){
},
selectQueryUser(keyword, options) {
options.length = 0
this.$axios.post("/platform/UnionReimburse/apply/listUser", { keyword: keyword }).then((res) => {
this.$axios.post("/platform/unionReimburse/apply/listUser", {keyword: keyword}).then((res) => {
if (res.code === 0) {
options.push(...res.data)
}
})
},
userChange(val) {
// 获取用户历史银行卡信息
getUserBankHistory() {
if (!this.formData.payer) {
this.historyData = [];
return;
}
this.$axios.get("/platform/unionReimburse/apply/findUserBankHistory", {
params: { payer: this.formData.payer }
}).then((res) => {
if (res.code === 0) {
this.historyData = Array.isArray(res.data) ? res.data : [];
} else {
console.warn("获取历史银行卡信息失败:", res);
this.historyData = [];
}
})
},
async payerUserChange(){
if (this.formData.payer) {
await this.getUserBankHistory();
}
const user = this.payerOptions.find(o => o.id === this.formData.payer)
if (user) {
const {userName, loginName,} = user
this.$set(this.formData, "payerName", userName);
this.$set(this.formData, "payerLoginname", loginName);
}
},
async userChange(val) {
const user = this.userOptions.find(o => o.id === val)
if (user) {
const { userName, loginName, unitId, unitName, unionId, unionName } = user
this.$set(this.formData, "certifierUserName", userName)
this.$set(this.formData, "certifierLoginName", loginName)
this.$set(this.formData, "certifierUnitId", unitId)
this.$set(this.formData, "certifierUnitName", unitName)
this.$set(this.formData, "certifierUnionId", unionId)
this.$set(this.formData, "certifierUnionName", unionName)
const {
userName,
loginName,
unitId,
unitName,
unionId,
unionName,
unionCode,
sex,
birthday,
idCard,
mobile
} = user
this.$set(this.formData, "condolenceUserName", userName)
this.$set(this.formData, "condolenceLoginName", loginName)
this.$set(this.formData, "condolenceUnitId", unitId)
this.$set(this.formData, "condolenceUnitName", unitName)
this.$set(this.formData, "condolenceUnionId", unionId)
this.$set(this.formData, "condolenceUnionName", unionName)
this.$set(this.formData, "condolenceUnionCode", unionCode)
this.$set(this.formData, "condolenceSex", sex)
this.$set(this.formData, "condolenceBirthday", birthday)
this.$set(this.formData, "condolenceIdCard", idCard)
this.$set(this.formData, "condolenceMobile", mobile)
}
},
typeChange(val) {
const type = this.typeOptions.find(o => o.id === val)
if (type) {
const {id, way, money, uploadFileDesc,name} = type
this.$set(this.formData, "condolenceTypeId", id)
this.$set(this.formData, "way", way)
this.$set(this.formData, "condolenceMoney", parseFloat(money).toFixed(2))
this.$set(this.formData, "condolenceFilesNotes", uploadFileDesc)
this.$set(this.formData, "typeName", name)
}
},
//
typeChange(id) {
this.chooseType = this.typeOptions.find(o => o.id === id)
if (this.chooseType) {
this.$set(this.formData, "money", this.chooseType.money)
this.$set(this.formData, "way", this.chooseType.way)
}
},
// typeChange(id) {
// this.chooseType = this.typeOptions.find(o => o.id === id)
// if (this.chooseType) {
// this.$set(this.formData, "money", this.chooseType.money)
// this.$set(this.formData, "way", this.chooseType.way)
// }
// },
// 保存
onSave() {
this.$confirm("您确定保存吗?", "提示", {
@@ -293,7 +652,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/unionReimburse/apply/save", { data: JSON.stringify(this.formData) }).then(res => {
this.$axios.post("/platform/unionReimburse/apply/save", {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
commonUtil.pjaxPush("/platform/unionReimburse/mine/index")
@@ -308,7 +667,7 @@ layout("/layouts/platform.html"){
if (valid) {
resolve(true)
} else {
this.$message.error("请完善必填信息")
this.$message.warning("请完善必填信息")
resolve(false)
}
})
@@ -316,7 +675,6 @@ layout("/layouts/platform.html"){
},
// 提交
async onSubmit() {
// 表单验证
const isValid = await this.validateBeforeSubmit()
if (!isValid) return
@@ -337,7 +695,6 @@ layout("/layouts/platform.html"){
},
// 再次提交
async onFinishTask() {
// 表单验证
const isValid = await this.validateBeforeSubmit()
if (!isValid) return
@@ -364,6 +721,21 @@ layout("/layouts/platform.html"){
this.typeOptions = resp.data
})
},
queryFileDesc() {
this.$axios.post("/platform/unionReimburse/desc/queryFileDesc")
.then((resp) => {
this.descOptions = resp.data
console.log(this.descOptions)
})
},
// 根据报销项目获取对应的附件说明
getFileDescByProject(projectCode) {
if (!this.descOptions || !Array.isArray(this.descOptions)) {
return '';
}
const project = this.descOptions.find(item => item.reimburseProject === projectCode);
return project ? project.fileDesc : '';
},
//经费来源查询
reimburseFundSourceChange() {
// 检查是否有选择经费来源
@@ -437,6 +809,12 @@ layout("/layouts/platform.html"){
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
} else {
if (this.formData.hospitalizationStartTime && this.formData.hospitalizationEndTime) {
this.$set(this.formData, "hospitalizationTimeRange", [
this.formData.hospitalizationStartTime,
this.formData.hospitalizationEndTime
]);
}
if (this.$auth.hasRoleOr(["SCHOOL_OUTLAY_ADMIN", "SCHOOL_UNION_ADMIN"])) {
this.budgetTypeOption.map(v => {
if (["UNION_REIMBURSE_FUND_SOURCE_1"].includes(v.code)) {
@@ -462,7 +840,7 @@ layout("/layouts/platform.html"){
}
this.reimburseProjectList = await this.$businessTool.getDictOptions("UNION_REIMBURSE_PROJECT")
if (this.bizId) {
this.$axios.post("/platform/unionReimburse/apply/info", { id: this.bizId }).then(async (res) => {
this.$axios.post("/platform/unionReimburse/apply/info", {id: this.bizId}).then(async (res) => {
if (res.code === 0) {
this.formData = res.data
await this.selectQueryUser(this.formData.certifierLoginName, this.userOptions)
@@ -470,7 +848,7 @@ layout("/layouts/platform.html"){
}
})
} else {
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
const {username, loginname, id, unit, union, mobile} = this.$store.state.user
this.formData = {
userName: username,
loginName: loginname,
@@ -478,17 +856,21 @@ layout("/layouts/platform.html"){
unitName: unit?.name,
unionId: union?.id,
unionName: union?.name,
reimburseType: "UNION_REIMBURSE_TYPE_1",
// reimburseType: "UNION_REIMBURSE_TYPE_1",
reimburseProject: 'UNION_REIMBURSE_PROJECT_1',
paymentWay: 'UNION_REIMBURSE_PAYMENT_WAY_2',
mobile: mobile,
userId: id
userId: id,
}
}
}
},
created() {
this.init()
this.queryFileDesc()
this.queryCondolenceType()
//社团查询
this.$businessTool.listClubByRole().then((res) => (this.clubOptions = res))
this.$businessTool.listCLubByRole().then((res) => (this.clubOptions = res))
}
})
</script>
@@ -46,7 +46,8 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>
<el-button type="primary" size="small" @click="exportSkr">导出收款人名册</el-button>
<!-- <el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>-->
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
@@ -54,37 +55,38 @@ layout("/layouts/platform.html"){
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="unionName" label="所属工会"></el-table-column>
<el-table-column prop="unitName" label="所属单位"></el-table-column>
<el-table-column prop="certifierUserName" label="证明人">
<template slot-scope="{row}">
{{row.certifierUserName}}({{row.certifierLoginName}})
</template>
</el-table-column>
<el-table-column prop="reimburseType" label="报销类别">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
:value="row.reimburseType">
</dict-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="reimburseProject" label="报销项目">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
:value="row.reimburseProject">
</dict-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动</span>
<span v-else>{{ row.reimburseProject }}</span>
</template>
</el-table-column>
<el-table-column prop="money" label="金额"></el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="taskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column label="备注">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
被慰问人:{{ row.condolenceUserName }}</span>
<span v-else>活动名称:{{ row.activityName }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<el-table-column label="申请状态">
<template slot-scope="{row}">
<span v-if="row.stateId == 1" style="color: #409eff;">待提交</span>
<span v-else-if="row.stateId == 2" style="color: #409eff;">待审核确认</span>
<span v-else-if="row.stateId == 3" style="color: #67c23a;">报销成功</span>
<span v-else-if="row.stateId == 4" style="color: #f56c6c;">拒绝</span>
<span v-else-if="row.stateId == 5" style="color: #409eff;">退回</span>
<span v-else style="color: #409eff;">{{ row.stateId }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="350px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="openEdit(row)" size="mini" type="primary">实际金额</el-button>
<el-button v-if="row.stateId == 3" @click="doPrint(row)" size="mini" type="primary">打印</el-button>
<el-button v-if="$auth.hasRole('SYSADMIN')" @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
@@ -96,6 +98,17 @@ layout("/layouts/platform.html"){
<union-reimburse-info ref="unionReimburseInfoRef">
</union-reimburse-info>
</template>
<el-dialog :visible.sync="editDialogVisible" title="编辑实际报销金额" width="400px" @close="handleDialogClose">
<el-form :model="editFormData" :rules="editFormRules" ref="editForm" label-width="120px">
<el-form-item label="实际报销金额" prop="realMoney">
<el-input v-model="editFormData.realMoney" placeholder="请输入实际报销金额"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="saveFinallyMoney">确 定</el-button>
</div>
</el-dialog>
</guava>
</div>
@@ -117,6 +130,17 @@ layout("/layouts/platform.html"){
pageDataUrl: "/platform/unionReimburse/collect/pageData",
unionOptions: [],
unitOptions: [],
editDialogVisible: false,
editFormData: {
realMoney: '',
id: '' // 报销记录ID
},
editFormRules: {
realMoney: [
{ required: true, message: '请输入实际报销金额', trigger: 'blur' },
{ pattern: /^([0-9]+)(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式', trigger: 'blur' }
]
}
}
}
,
@@ -141,6 +165,47 @@ layout("/layouts/platform.html"){
})
})
},
openEdit(row) {
// 初始化编辑表单数据
this.editFormData.id = row.id;
this.editFormData.realMoney = row.realMoney || '';
this.editDialogVisible = true;
},
// 弹窗关闭时的处理
handleDialogClose() {
this.$refs.editForm.resetFields();
},
// 保存实际报销金额
saveFinallyMoney() {
this.$refs.editForm.validate(async (valid) => {
if (valid) {
const resp = await this.$axios.post("/platform/unionReimburse/collect/updateActuallyAmount", {
id: this.editFormData.id,
realMoney: this.editFormData.realMoney
}).then((res) => {
if (res.code === 0) {
this.$message.success('保存成功');
this.editDialogVisible = false;
this.$refs.editForm.resetFields();
this.pageData();
}
})
}
});
},
exportSkr() {
const {year = '', unionId = '', unitId = '', reimburseProject = ''} = this.pageForm
window.open('/platform/unionReimburse/collect/exportSkr?year=' + year + "&unionId=" + unionId + '&unitId=' + unitId + "&reiItemId=" + reimburseProject)
},
doPrint(row) {
if (row.reimburseProject != "UNION_REIMBURSE_PROJECT_1") {
window.location.href = "/platform/unionReimburse/mine/ActExport?id=" + (row.id || '') + "&Print=true"
} else {
window.location.href = "/platform/unionReimburse/mine/ConExport?id=" + (row.id || '') + "&Print=true"
}
},
onExport() {
this.$downLoad('/platform/unionReimburse/collect/onExport', this.pageForm)
},
@@ -0,0 +1,67 @@
const basicForm = {
template: /*language=HTML*/ `
<div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="110px" label-position="left">
<el-form-item label="项目编码" prop="code">
<el-input type="text" v-model="formData.code" maxlength="50"
placeholder="请填写项目编码"></el-input>
</el-form-item>
<el-form-item label="项目名称" prop="name">
<el-input type="text" v-model="formData.name" maxlength="50"
placeholder="请填写项目名称"></el-input>
</el-form-item>
<el-form-item label="附件说明" prop="fileDesc">
<el-input type="text" v-model="formData.fileDesc" maxlength="50"
placeholder="请填写附件说明"></el-input>
</el-form-item>
</el-form-item>
</el-form>
<el-row class="mt10" justify="end" type="flex">
<el-button @click="$emit('refresh')">取消</el-button>
<el-button @click="onSubmit" type="primary">提交</el-button>
</el-row>
</div>
`,
data() {
return {
formData: {},
formRules: {
code: [{required: true, message: '必填', trigger: ['blur', 'change']}],
name: [{required: true, message: '必填', trigger: ['blur', 'change']}],
fileDesc: [{required: true, message: '必填', trigger: ['blur', 'change']}],
},
}
},
methods: {
onOpen(row) {
if(row && row.id) {
this.formData = clone(row)
}
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
const resp = await this.$axios.post("/platform/unionReimburse/desc/onSubmit", this.formData)
if (resp.code === 0) {
this.$message.success(resp.msg)
this.$emit('refresh')
} else {
this.$message.warning(resp.msg)
}
})
}
})
},
},
style: /*language=CSS*/ `
.el-input-number .el-input__inner {
text-align: left;
}
`
}
@@ -0,0 +1,146 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<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" class="mt20">
<table-tool label="类型列表">
<el-button type="primary" size="small" @click="onAdd">
<i class="ti-plus"></i>
新增类型
</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize">
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'isUploadFile'">
<span v-if="row.isUploadFile" class="text-success"></span>
<span v-else class="text-danger"></span>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'enable'">
<el-switch
@change="switchChange(row)"
v-model="row.enable"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="230">
<template v-slot="{ row }">
<el-button @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #edit>
<basic-form ref="basicFormRef" @refresh="refresh"></basic-form>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('basicForm.js'){}#-->
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"basic-form": basicForm,
},
data() {
return {
tableColumns: [
{prop: 'code', label: '项目编码'},
{prop: 'name', label: '项目名称'},
{prop: 'fileDesc', label: '附件说明'},
// {prop: 'isUploadFile', label: '是否上传附件'},
],
}
},
methods: {
refresh() {
this.doSearch()
this.$refs.guava.index()
},
onAdd() {
this.$refs.guava.edit(() => {
this.$refs.basicFormRef.onOpen()
})
},
onEdit(row) {
this.$refs.guava.edit(() => {
this.$refs.basicFormRef.onOpen(row)
})
},
onDelete(row) {
this.$confirm("您确定要删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios.post("/platform/unionReimburse/desc/onDelete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
.catch(() => {})
},
switchChange(row) {
this.$axios.post("/platform/unionReimburse/desc/onSubmit", row).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
},
pageData() {
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
},
async created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -10,37 +10,157 @@ const unionReimburseInfo = {
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
<el-descriptions-item label="工会">{{viewData.unionName}}</el-descriptions-item>
<el-descriptions-item label="报销类别">
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
:value="viewData.reimburseType">
</dict-tag>
<el-descriptions-item label="报销项目">
<span v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问</span>
<span v-else-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动</span>
<span v-else-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动</span>
<span v-else-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动</span>
<span v-else>{{ viewData.reimburseProject }}</span>
</el-descriptions-item>
<el-descriptions-item label="支付方式">
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
:value="viewData.paymentWay">
</dict-tag>
</el-descriptions-item>
<el-descriptions-item label="报销项目">
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
:value="viewData.reimburseProject">
</dict-tag>
</el-descriptions-item>
<el-descriptions-item label="联系方式">{{viewData.mobile}}</el-descriptions-item>
<el-descriptions-item label="证明人">{{viewData.certifierUserName}}{{viewData.certifierLoginName}}
<el-descriptions-item label="付款人" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.payerName }}</span>
</el-descriptions-item>
<el-descriptions-item label="户名">{{viewData.bankUserName}}</el-descriptions-item>
<el-descriptions-item label="银行账号">{{viewData.bankCardNumber}}</el-descriptions-item>
<el-descriptions-item label="开户行">{{viewData.bankOfDeposit}}</el-descriptions-item>
<el-descriptions-item label="活动名称">{{viewData.activityName}}</el-descriptions-item>
<el-descriptions-item label="活动地点">{{viewData.activityPlace||'暂无'}}</el-descriptions-item>
<el-descriptions-item label="报销金额">{{viewData.money}}</el-descriptions-item>
<!-- <el-descriptions-item label="发票张数">{{viewData.invoiceNumber}}</el-descriptions-item>-->
<el-descriptions-item label="支付内容" :span="2">{{viewData.paymentNotes}}</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-image :src="viewData.userSign" fit="cover" style="height: 60px"
v-if="viewData.userSign"></el-image>
<span v-else>暂无附件</span>
<el-descriptions-item label="开户行" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.bankOfDeposit }}</span>
</el-descriptions-item>
<el-descriptions-item label="银行卡号" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.bankCardNumber }}</span>
</el-descriptions-item>
<!-- 慰问相关字段 -->
<el-descriptions-item label="慰问对象" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceUserName }}{{ viewData.condolenceLoginName }})({{ viewData.condolenceUnitName }}</span>
</el-descriptions-item>
<el-descriptions-item label="性别" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceSex }}</span>
</el-descriptions-item>
<el-descriptions-item label="生日" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceBirthday && $moment(viewData.condolenceBirthday).isValid() ? $moment(viewData.condolenceBirthday).format('YYYY-MM-DD') : '' }}</span>
</el-descriptions-item>
<el-descriptions-item label="身份证号" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceIdCard }}</span>
</el-descriptions-item>
<el-descriptions-item label="联系方式" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceMobile }}</span>
</el-descriptions-item>
<el-descriptions-item label="慰问类型" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.typeName }}</span>
</el-descriptions-item>
<el-descriptions-item label="慰问方式" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.way }}</span>
</el-descriptions-item>
<el-descriptions-item label="慰问金额" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceMoney }}</span>
</el-descriptions-item>
<el-descriptions-item label="实际报销金额" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.realMoney }}</span>
</el-descriptions-item>
<!-- 活动相关字段 -->
<el-descriptions-item label="活动名称" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.activityName }}</span>
</el-descriptions-item>
<el-descriptions-item label="活动类型" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">
<span>{{ viewData.activityType }}</span>
</el-descriptions-item>
<el-descriptions-item label="活动人数" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.activityNumber }}</span>
</el-descriptions-item>
<el-descriptions-item label="活动地点" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.activityPlace }}</span>
</el-descriptions-item>
<el-descriptions-item label="报销金额" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.money }}</span>
</el-descriptions-item>
<el-descriptions-item label="实际报销金额" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.realMoney }}</span>
</el-descriptions-item>
<el-descriptions-item label="活动时间" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.activityTime | dateFormat }}</span>
</el-descriptions-item>
<el-descriptions-item label="发票张数">
<span>{{ viewData.invoiceNumber }}</span>
</el-descriptions-item>
<el-descriptions-item label="慰问时间" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.condolenceTime | dateFormat }}</span>
</el-descriptions-item>
<el-descriptions-item label="结婚时间" v-if="viewData.condolenceTypeId === 'cf4ce7af322d464f8f86d818fcc00203'">
<span>{{ viewData.marryTime | dateFormat }}</span>
</el-descriptions-item>
<el-descriptions-item label="生育时间" v-if="viewData.condolenceTypeId === 'c90cb10dce6542e99ae271bee6fe8cc0'">
<span>{{ viewData.fertilityTime | dateFormat }}</span>
</el-descriptions-item>
<el-descriptions-item label="住院病由" v-if="viewData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<span>{{ viewData.hospitalCausation }}</span>
</el-descriptions-item>
<el-descriptions-item label="住院时间" v-if="viewData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<span v-if="viewData.hospitalizationStartTime && viewData.hospitalizationEndTime">
{{ $moment(viewData.hospitalizationStartTime).format('YYYY-MM-DD') }} 至 {{ $moment(viewData.hospitalizationEndTime).format('YYYY-MM-DD') }}
</span>
<span v-else>暂无住院时间</span>
</el-descriptions-item>
<el-descriptions-item label="入住医院" v-if="viewData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<span>{{ viewData.hospital }}</span>
</el-descriptions-item>
<el-descriptions-item label="当年次数" v-if="viewData.condolenceTypeId === '4e316737e71047e0b01aea78524c1416'">
<span>{{ viewData.hospitalCount }}</span>
</el-descriptions-item>
<el-descriptions-item label="去逝时间" v-if="viewData.condolenceTypeId === '60f03a87b62b4823855814afdbf5672a'">
<span>{{ viewData.deathTime | dateFormat }}</span>
</el-descriptions-item>
<el-descriptions-item label="与被慰问人关系" v-if="viewData.condolenceTypeId === '60f03a87b62b4823855814afdbf5672a'">
<span>{{ viewData.condolenceRelationship }}</span>
</el-descriptions-item>
<el-descriptions-item label="参加随行人员" :span="2"
v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.participants }}</span>
</el-descriptions-item>
<el-descriptions-item label="报销事由" :span="2">
<span>{{ viewData.paymentNotes }}</span>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">
<span>{{ viewData.notes }}</span>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files"
complete_result></file-preview>
@@ -48,39 +168,21 @@ const unionReimburseInfo = {
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<template>
<div class="mt10" v-if="viewData.reviewTime">
<div class="process-title">校工会审核</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode" :span="3">{{
task.taskFormData.opinion }}
</el-descriptions-item>
<el-descriptions-item label="签字" :span="3">
<el-image v-if="task.ext.tf_userSign"
:src="task.ext.tf_userSign"
class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions border class="flow-task-form" :column="2">
<el-descriptions-item label="审核时间">{{ viewData.reviewTime }}</el-descriptions-item>
<el-descriptions-item label="审核状态">
<span v-if="viewData.stateId == 1" style="color: #409eff;">待提交</span>
<span v-else-if="viewData.stateId == 2" style="color: #409eff;">待审核确认</span>
<span v-else-if="viewData.stateId == 3" style="color: #67c23a;">报销成功</span>
<span v-else-if="viewData.stateId == 4" style="color: #f56c6c;">拒绝</span>
<span v-else-if="viewData.stateId == 5" style="color: #409eff;">退回</span>
<span v-else style="color: #409eff;">{{ viewData.stateId }}</span>
</el-descriptions-item>
<el-descriptions-item label="审核意见">{{ viewData.reviewOpinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
@@ -90,12 +192,18 @@ const unionReimburseInfo = {
</div>
`,
store,
dicts: ["UNION_REIMBURSE_TYPE", "UNION_REIMBURSE_PAYMENT_WAY", "UNION_REIMBURSE_FUND_SOURCE","UNION_REIMBURSE_PROJECT","PROCESS_TASK_SUBMIT_TYPE"],
dicts: ["UNION_REIMBURSE_TYPE", "UNION_REIMBURSE_PAYMENT_WAY", "UNION_REIMBURSE_FUND_SOURCE", "UNION_REIMBURSE_PROJECT", "PROCESS_TASK_SUBMIT_TYPE"],
filters: {
dateFormat(date) {
if (!date) return '';
return moment(date).format('YYYY-MM-DD');
}
},
data() {
return {
visible: false,
viewData: {},
doneTasks: [],
typeName: '',
row: null
}
},
@@ -105,32 +213,30 @@ const unionReimburseInfo = {
this.row = row
this.visible = true
this.getInfo()
this.getDoneTasks()
},
// 获取申请信息
getInfo() {
this.$axios.post('/platform/unionReimburse/apply/info', {id: this.row.id}).then((res) => {
if (res.code === 0) {
this.viewData = res.data
this.typeName = res.data.typeName || ''
}
})
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
// 查看流程图
openChart(){
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId,this.row.instanceId)
}
// // 获取已办任务审批记录
// getDoneTasks() {
// this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
// if (res.code === 0) {
// this.doneTasks = res.data
// }
// })
// },
//
// // 查看流程图
// openChart(){
// this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId,this.row.instanceId)
// }
}
}
@@ -13,24 +13,24 @@ layout("/layouts/platform.html"){
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" @change="doSearch" style="width: 100%"
placeholder="请选择所属工会" clearable>
<el-option v-for="item in unionOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
<el-select v-model="pageForm.unionId" @change="doSearch" style="width: 100%"
placeholder="请选择所属工会" clearable>
<el-option v-for="item in unionOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="pageForm.unitId" @change="doSearch" style="width: 100%"
placeholder="请选择所属单位" clearable>
<el-option v-for="item in unitOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
<el-select v-model="pageForm.unitId" @change="doSearch" style="width: 100%"
placeholder="请选择所属单位" clearable>
<el-option v-for="item in unitOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
<search-item label="报销项目">
<el-select v-model="pageForm.reimburseProject" @change="doSearch" style="width: 100%"
@@ -52,41 +52,41 @@ layout("/layouts/platform.html"){
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="unionName" label="所属工会"></el-table-column>
<el-table-column prop="unitName" label="所属单位"></el-table-column>
<el-table-column prop="certifierUserName" label="证明人">
<template slot-scope="{row}">
{{row.certifierUserName}}({{row.certifierLoginName}})
</template>
</el-table-column>
<el-table-column prop="reimburseType" label="报销类别">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
:value="row.reimburseType">
</dict-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="reimburseProject" label="报销项目">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
:value="row.reimburseProject">
</dict-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动</span>
<span v-else>{{ row.reimburseProject }}</span>
</template>
</el-table-column>
<el-table-column prop="money" label="金额"></el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="taskName" label="当前节点"></el-table-column>·
<el-table-column prop="instanceState" label="流程状态">
<el-table-column label="备注">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
被慰问人:{{ row.condolenceUserName }}</span>
<span v-else>活动名称:{{ row.activityName }}</span>
</template>
</el-table-column>
<el-table-column label="申请状态">
<template slot-scope="{row}">
<span v-if="row.stateId == 1" style="color: #409eff;">待提交</span>
<span v-else-if="row.stateId == 2" style="color: #409eff;">待审核确认</span>
<span v-else-if="row.stateId == 3" style="color: #67c23a;">报销成功</span>
<span v-else-if="row.stateId == 4" style="color: #f56c6c;">拒绝</span>
<span v-else-if="row.stateId == 5" style="color: #409eff;">退回</span>
<span v-else style="color: #409eff;">{{ row.stateId }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
<el-button v-if="row.stateId == 1 || row.stateId == 5" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button v-if="row.stateId == 2" @click="onRevoke(row.id)" size="mini" type="danger">撤回</el-button>
<el-button v-if="row.stateId == 3" @click="doExport(row)" size="mini" type="primary">导出报销表</el-button>
<el-button v-if="row.stateId == 3" @click="doPrint(row)" size="mini" type="primary">打印</el-button>
<el-button v-if="row.stateId == 1" @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -100,13 +100,12 @@ layout("/layouts/platform.html"){
</div>
<script nonce="${cspNonce!}">
<!--#include('../info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["UNION_REIMBURSE_TYPE","UNION_REIMBURSE_PROJECT"],
dicts: ["UNION_REIMBURSE_TYPE", "UNION_REIMBURSE_PROJECT"],
//分页数据
mixins: [initTableMixins],
components: {
@@ -122,20 +121,20 @@ layout("/layouts/platform.html"){
,
methods: {
onView(row) {
this.$refs.guava.view(()=>{
this.$refs.guava.view(() => {
this.$refs.unionReimburseInfoRef.onOpen(row)
})
},
onEdit(row) {
commonUtil.pjaxPush('/platform/unionReimburse/apply/index?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
},
onRevoke(row) {
onRevoke(id) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((res) => {
this.$axios.post("/platform/unionReimburse/mine/revokeTask", {id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
@@ -157,6 +156,22 @@ layout("/layouts/platform.html"){
}
})
})
},
doExport(row) {
if (row.reimburseProject != "UNION_REIMBURSE_PROJECT_1") {
window.location.href = "/platform/unionReimburse/mine/ActExport?id=" + (row.id || '')
} else {
window.location.href = "/platform/unionReimburse/mine/ConExport?id=" + (row.id || '')
}
},
doPrint(row) {
if (row.reimburseProject != "UNION_REIMBURSE_PROJECT_1") {
window.location.href = "/platform/unionReimburse/mine/ActExport?id=" + (row.id || '') + "&Print=true"
} else {
window.location.href = "/platform/unionReimburse/mine/ConExport?id=" + (row.id || '') + "&Print=true"
}
}
},
@@ -46,6 +46,7 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<table-tool>
<el-button @click="AllReview" size="medium" type="primary">一键审核</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -57,40 +58,37 @@ layout("/layouts/platform.html"){
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="unionName" label="所属工会"></el-table-column>
<el-table-column prop="unitName" label="所属单位"></el-table-column>
<el-table-column prop="certifierUserName" label="证明人">
<template slot-scope="{row}">
{{row.certifierUserName}}({{row.certifierLoginName}})
</template>
</el-table-column>
<el-table-column prop="reimburseType" label="报销类别">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
:value="row.reimburseType">
</dict-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="reimburseProject" label="报销项目">
<template slot-scope="{row}">
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
:value="row.reimburseProject">
</dict-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动</span>
<span v-else>{{ row.reimburseProject }}</span>
</template>
</el-table-column>
<el-table-column prop="money" label="金额"></el-table-column>
<el-table-column prop="createTime" label="申请时间"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column label="备注">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
被慰问人:{{ row.condolenceUserName }}</span>
<span v-else>活动名称:{{ row.activityName }}</span>
</template>
</el-table-column>
<el-table-column label="申请状态">
<template slot-scope="{row}">
<span v-if="row.stateId == 1" style="color: #409eff;">待提交</span>
<span v-else-if="row.stateId == 2" style="color: #409eff;">待审核确认</span>
<span v-else-if="row.stateId == 3" style="color: #67c23a;">报销成功</span>
<span v-else-if="row.stateId == 4" style="color: #f56c6c;">拒绝</span>
<span v-else-if="row.stateId == 5" style="color: #409eff;">退回</span>
<span v-else style="color: #409eff;">{{ row.stateId }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
<el-button v-if="row.stateId == 2" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
</template>
</el-table-column>
@@ -102,24 +100,24 @@ layout("/layouts/platform.html"){
<union-reimburse-info ref="unionReimburseInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
校工会审核
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
<el-form-item label="审批意见" prop="reviewOpinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="签字" prop="tf_userSign"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<pc-signature v-model="formData.tf_userSign"></pc-signature>
<user-opinion-textarea v-model="formData.reviewOpinion"></user-opinion-textarea>
</el-form-item>
<!-- <el-form-item label="签字" prop="tf_userSign"-->
<!-- :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.tf_userSign"></pc-signature>-->
<!-- </el-form-item>-->
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
<el-button @click="handleTaskAction(5)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(4)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(3)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</union-reimburse-info>
@@ -160,12 +158,31 @@ layout("/layouts/platform.html"){
})
},
AllReview() {
this.$confirm('确定所有申请都通过线下审核了吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const resp = await $.post("/platform/unionReimburse/review/allReview");
if (resp && resp.code === 0) {
this.pageForm.approval = true
this.pageData();
this.$message.success(resp.msg || '一键审核成功');
} else {
this.$message.error(resp.msg || '一键审核失败');
}
}).catch(() => {
// 用户取消操作
});
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
id: row.id,
reviewOpinion: '通过'
}
this.$refs.unionReimburseInfoRef.onOpen(row)
})
@@ -179,11 +196,9 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
this.$axios.post("/platform/unionReimburse/review/reviewTask", {
data: JSON.stringify({...this.formData}),
submitType: val
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
@@ -196,21 +211,6 @@ layout("/layouts/platform.html"){
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.taskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
}
},
created() {
@@ -0,0 +1,312 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度"
style="width: 100%"></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入慰问对象姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" @change="doSearch" style="width: 100%"
placeholder="请选择所属工会" clearable>
<el-option v-for="item in unionOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
<search-item label="慰问类型">
<el-select v-model="pageForm.condolenceTypeId" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name+''+item.code+''"
></el-option>
</el-select>
</search-item>
<search-item label="慰问方式">
<el-select v-model="pageForm.way" @change="doSearch" style="width: 100%"
placeholder="请选择慰问方式" clearable>
<el-option v-for="option in wayOptions"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
</search-item>
<!-- <search-item label="所属单位">-->
<!-- <el-select v-model="pageForm.unitId" @change="doSearch" style="width: 100%"-->
<!-- placeholder="请选择所属单位" clearable>-->
<!-- <el-option v-for="item in unitOptions"-->
<!-- :value="item.id"-->
<!-- :key="item.id"-->
<!-- :label="item.name"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </search-item>-->
<!-- <search-item label="报销项目">-->
<!-- <el-select v-model="pageForm.reimburseProject" @change="doSearch" style="width: 100%"-->
<!-- placeholder="请选择报销项目" clearable>-->
<!-- <el-option v-for="item in dict.type.UNION_REIMBURSE_PROJECT"-->
<!-- :value="item.code"-->
<!-- :key="item.code"-->
<!-- :label="item.name"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </search-item>-->
</search>
</el-card>
<div id="condolencesTypeId"
style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
v-loading="loading.condolencesType"></div>
<el-card class="mt10" shadow="never">
<table-tool label="申请列表">
<el-button @click="allView" icon="el-icon-refresh" type="primary" size="small">查看全部</el-button>
<el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" row-key="id" style="width: 100%"
v-loading="tabLoading">
<el-table-column align="center" header-align="center" label="序号" width="120px">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column prop="condolenceLoginName" label="被慰问人工号"></el-table-column>
<el-table-column prop="condolenceUserName" label="姓名"></el-table-column>
<el-table-column prop="condolenceUnionCode" label="分工会代码"></el-table-column>
<el-table-column prop="condolenceUnionName" label="分工会名称"></el-table-column>
<el-table-column prop="typeName" label="慰问类型"></el-table-column>
<el-table-column prop="way" label="慰问方式"></el-table-column>
<el-table-column prop="condolenceMoney" label="慰问金额"></el-table-column>
<el-table-column prop="newCreateTime" label="慰问时间"></el-table-column>
<el-table-column prop="newCondolenceTime" label="录入时间"></el-table-column>
<el-table-column label="申请状态">
<template slot-scope="{row}">
<span v-if="row.stateId == 1" style="color: #409eff;">待提交</span>
<span v-else-if="row.stateId == 2" style="color: #409eff;">待审核确认</span>
<span v-else-if="row.stateId == 3" style="color: #67c23a;">报销成功</span>
<span v-else-if="row.stateId == 4" style="color: #f56c6c;">拒绝</span>
<span v-else-if="row.stateId == 5" style="color: #409eff;">退回</span>
<span v-else style="color: #409eff;">{{ row.stateId }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<union-reimburse-info ref="unionReimburseInfoRef">
</union-reimburse-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../info.js'){}#-->
const chart = {
condolencesTypeId: undefined
}
new Vue({
el: "#app",
store,
dicts: ["UNION_REIMBURSE_TYPE","UNION_REIMBURSE_PROJECT"],
//分页数据
mixins: [initTableMixins],
components: {
"union-reimburse-info": unionReimburseInfo
},
data() {
return {
pageDataUrl: "/platform/unionReimburse/statistics/pageData",
unionOptions: [],
unitOptions: [],
typeOptions: [],
wayOptions: [
{label: "慰问金 (A)", value: "慰问金 (A)"},
{label: "提货券 (B)", value: "提货券 (B)"},
{label: "慰问品 (C)", value: "慰问品 (C)"}
],
condolence: {
way: {
'慰问金 (A)': '慰问金 (A)',
'提货券 (B)': '提货券 (B)',
'慰问品 (C)': '慰问品 (C)'
},
},
tabLoading: false,
loading: {
condolencesType: false,
},
editDialogVisible: false,
editFormData: {
realMoney: '',
id: '' // 报销记录ID
},
pageForm:{
reimburseProject:"UNION_REIMBURSE_PROJECT_1",
},
editFormRules: {
realMoney: [
{ required: true, message: '请输入实际报销金额', trigger: 'blur' },
{ pattern: /^([0-9]+)(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式', trigger: 'blur' }
]
}
}
}
,
methods: {
onView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.unionReimburseInfoRef.onOpen(row)
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/unionReimburse/mine/delete", {id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
openEdit(row) {
// 初始化编辑表单数据
this.editFormData.id = row.id;
this.editFormData.realMoney = row.realMoney || '';
this.editDialogVisible = true;
},
queryCondolenceType() {
this.$axios.post("/platform/unionReimburse/apply/queryCondolenceType")
.then((resp) => {
this.typeOptions = resp.data
})
},
allView() {
this.$set(this.pageForm, 'condolenceTypeId', null);
this.$set(this.pageForm, 'way', '');
this.doSearch();
},
getCondolencesType() {
this.$nextTick(async v => {
this.loading.condolencesType = true
const queryParams = {
year: this.pageForm.year || '',
unionId: this.pageForm.unionId || '',
condolenceTypeId: this.pageForm.condolenceTypeId ? this.pageForm.condolenceTypeId : null,
way: this.pageForm.way || ''
}
const resp = await this.$axios.get('/platform/unionReimburse/statistics/condolencesType', {
params: queryParams
})
if (resp.code === 0) {
this.loading.condolencesType = false
const chartContainer = document.getElementById('condolencesTypeId');
if (!chartContainer) {
console.error('Chart container not found');
return;
}
if (chart.condolencesTypeId) {
chart.condolencesTypeId.changeData(resp.data)
return
}
chart.condolencesTypeId = new G2Plot.Column('condolencesTypeId', {
data: resp.data,
autoFit: true,
xField: 'name',
yField: 'value',
label: {
position: 'middle',
style: {
fill: '#FFFFFF',
opacity: 0.6,
},
},
xAxis: {
label: {
autoHide: true,
autoRotate: false,
},
},
meta: {
label: {
alias: '类型',
},
value: {
alias: '慰问数',
},
}
});
chart.condolencesTypeId.render();
chart.condolencesTypeId.on('element:click', (v) => {
const clickedName = v.data?.data?.name;
if (clickedName) {
const selectedType = this.typeOptions.find(type => type.name === clickedName);
if (selectedType) {
this.$set(this.pageForm, 'condolenceTypeId', selectedType.id);
this.doSearch();
}
}
});
}
})
},
doSearch() {
this.pageForm.pageNumber = 1
this.pageData()
this.$nextTick(() => {
this.getCondolencesType()
})
},
handleDialogClose() {
this.$refs.editForm.resetFields();
},
onExport() {
this.$downLoad("/platform/unionReimburse/statistics/doExport", this.pageForm)
}
},
created() {
this.pageData()
this.queryCondolenceType()
//工会查询
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
//单位查询
this.$businessTool.listUnit().then((res) => (this.unitOptions = res))
this.$nextTick(() => {
setTimeout(() => {
this.getCondolencesType()
}, 200)
})
}
})
</script>
<!--#
}
#-->
@@ -37,12 +37,12 @@ const basicForm = {
<el-radio-button :label="false">不上传</el-radio-button>
</el-radio-group>
</el-form-item>-->
<el-form-item label="是否上传附件" prop="isUploadFile">
<el-radio-group v-model="formData.isUploadFile">
<el-radio-button :label="true">是</el-radio-button>
<el-radio-button :label="false">否</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="是否上传附件" prop="isUploadFile">-->
<!-- <el-radio-group v-model="formData.isUploadFile">-->
<!-- <el-radio-button :label="true">是</el-radio-button>-->
<!-- <el-radio-button :label="false">否</el-radio-button>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<el-form-item label="上传附件说明" prop="uploadFileDesc" v-if="formData.isUploadFile">
<el-input v-model="formData.uploadFileDesc" maxlength="50" clearable placeholder="请填写上传附件说明"></el-input>
</el-form-item>
@@ -85,7 +85,7 @@ layout("/layouts/platform.html"){
{prop: 'name', label: '类型名称'},
{prop: 'money', label: '金额'},
{prop: 'way', label: '慰问方式'},
{prop: 'isUploadFile', label: '是否上传附件'},
// {prop: 'isUploadFile', label: '是否上传附件'},
{prop: 'enable', label: '是否启用'},
],
}
@@ -95,15 +95,13 @@ layout("/layouts/platform.html"){
<script nonce="${cspNonce!}">
<!--#include("../common/payRecord.js"){}#-->
const vue = new Vue({
new Vue({
el: '#app',
store,
dicts: ["AIDFUND_MEMBER_USER_TYPE"],
mixins: [initTableMixins],
data() {
return {
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formRules: {
mobile: [{required: true, message: "必填", trigger: ["blur", "change"]}],
idCard: [{required: true, message: "必填", trigger: ["blur", "change"]}],
@@ -0,0 +1,579 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.cost .el-form-item {
margin-bottom: 0 !important;
}
</style>
<div id="app" v-cloak>
<custom-card>
<snaker-start slot="header" label="医疗补助申请" define_key="YLBB">
<template slot="header-right-label">
<el-link type="primary" @click="tipsDialog=true" class="mr10">查看补助标准</el-link>
</template>
</snaker-start>
<el-form :model="formData" :rules="formRules" label-suffix=""
ref="formRef" class="flow-task-form">
<table-tool label="申请基础信息"></table-tool>
<el-descriptions :column="3" border>
<template>
<el-descriptions-item label="申请人姓名"
v-if="$auth.hasRole('SYSADMIN') || $auth.hasRole('SCHOOL_UNION_ADMIN')|| $auth.hasRole('RETIREMENT_WORKPLACE')">
<el-form-item prop="userId" label="申请人姓名">
<el-select
style="width: 100%"
v-model="formData.userId"
filterable
:clearable="false"
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethod"
@change="userChange">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.username+''+item.loginname+''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="申请人姓名" v-else>{{formData.userName}}</el-descriptions-item>
</template>
<el-descriptions-item label="性别">
<el-form-item label="性别">
<el-input readonly v-model="formData.sex"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="年龄">
<el-form-item label="年龄">
<el-input readonly v-model="formData.age"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所在单位">
<el-form-item label="所在单位">
<el-input readonly v-model="formData.unitName"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="身份证号">
<el-form-item label="身份证号" prop="idCard">
<el-input clearable v-model="formData.idCard" placeholder="请输入身份证号"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="累计补助金额">
<el-form-item label="累计补助金额" prop="medicalSubsidyMoney">
<el-input readonly v-model="formData.medicalSubsidyMoney"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="申请次数">
<el-form-item label="申请次数">
<el-input readonly v-model="formData.applyNum"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="家庭住址" :span="2">
<el-form-item label="家庭住址" prop="homeAddress">
<el-input placeholder="请填写家庭住址" v-model="formData.homeAddress"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="联系电话">
<el-form-item label="联系电话" prop="mobile">
<el-input placeholder="请填写联系电话" v-model="formData.mobile"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="上年总收入">
<el-form-item label="上年总收入" prop="familyIncome">
<el-input-number :min="0" placeholder="请填写上年总收入"
v-model="formData.familyIncome"></el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="报销类型">
<el-form-item label="报销类型" prop="subsidyType">
<el-radio-group v-model="formData.subsidyType">
<el-radio-button :label="i" v-for="i in subsidyTypeList" :key="i">
{{i}}
</el-radio-button>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="疾病种类" :span="3">
<el-form-item label="疾病种类" prop="diseaseId">
<el-select clearable placeholder="请选择疾病种类"
v-model="formData.diseaseId" filterable @change="diseaseIdChange">
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="3">
<el-form-item label="备注" prop="note">
<el-input clearable maxlength="100" placeholder="请输入具体病情说明,不要超过100字"
rows="3" type="textarea" v-model="formData.note">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="3">
<el-form-item label="附件" prop="files">
<file-upload :value.sync="formData.files"
upload_mode="drag"
:upload_number="50"
:upload_size="1024 * 1024 * 20"
upload_result_category="array"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
<table-tool label="住院记录"></table-tool>
<el-table :data="formData.costList" border show-summary class="cost">
<el-table-column label="序号" type="index" width="50px" fixed></el-table-column>
<el-table-column label="住院时间段" width="300">
<template v-slot="{row,$index}">
<el-form-item label-width="0"
label="住院时间段"
:prop="'costList.'+$index+'.visitTime'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-date-picker
style="width: 100%"
format="yyyy-MM-dd"
placeholder="选择住院时间段"
type="daterange"
v-model="row.visitTime"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="住院医院" width="200">
<template v-slot="{row,$index}">
<el-form-item label-width="0"
label="住院医院"
:prop="'costList.'+$index+'.visitHospital'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input placeholder="住院医院" v-model="row.visitHospital"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="住院医疗费总额(不含门诊)" width="180" prop="hospitalSumMoney">
<template v-slot="{row}">
<el-input-number placeholder="住院医疗费总额(不含门诊)"
:min="0"
controls-position="right" style="width: 100%"
v-model="row.hospitalSumMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="实际报销金额" width="180" prop="reimbursementMoney">
<template v-slot="{row}">
<el-input-number placeholder="实际报销金额"
:min="0"
controls-position="right" style="width: 100%"
v-model="row.reimbursementMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)允许报销范围内个人承担部分金额"
width="180" prop="singleBearMoney">
<template v-slot="{row}">
<el-input-number :min="0" placeholder="个人承担部分金额"
controls-position="right" style="width: 100%"
v-model="row.singleBearMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)自费部分金额" width="180" prop="personExpenseMoney">
<template v-slot="{row}">
<el-input-number placeholder="自费部分金额"
:min="0"
controls-position="right"
disabled style="width: 100%"
v-model="row.personExpenseMoney = calcPersonExpenseMoney(row)"></el-input-number>
</template>
</el-table-column>
<el-table-column label="重病门诊自费金额" width="180" prop="outpatientServiceMoney">
<template v-slot="{row}">
<el-input-number placeholder="门诊费"
:min="0"
:disabled="!formData.isMajorDiseases"
controls-position="right" style="width: 100%"
v-model="row.outpatientServiceMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="非住院肾衰竭治疗、靶向药" width="180" prop="bxyMoney">
<template v-slot="{row}">
<el-input-number placeholder="靶向药"
:min="0"
:disabled="!formData.isMajorDiseases"
controls-position="right" style="width: 100%"
v-model="row.bxyMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="操作" width="100px" fixed="right">
<template slot="header" slot-scope="scope">
<el-button type="primary" @click="formData.costList.push({
hospitalSumMoney:0,
reimbursementMoney:0,
singleBearMoney:0,
outpatientServiceMoney:0,
bxyMoney:0,
})" size="mini">增加
</el-button>
</template>
<template v-slot="scope">
<el-button @click="formData.costList.splice(scope.$index,1)" icon="el-icon-delete" size="mini"
type="danger">
</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<template slot="footer">
<el-button type="primary" plain @click="onSave" :loading="formLoading">保存</el-button>
<el-button type="primary" @click="onSubmit" v-if="!taskId" :loading="formLoading">提交</el-button>
<el-button type="primary" @click="onFinishTask" v-else :loading="formLoading">提交</el-button>
</template>
</custom-card>
<el-dialog :visible.sync="tipsDialog" title="申请补助须知" top="50px" width="60%">
<p>
1.享受公费医疗的互助基金会员患本办法所列疾病,住院治疗期间发生的医疗费经校医院审核并报销后,个人承担费用(不含国家规定应该由个人支付的费用)年度累计超过
5000 元者,可申请并获得补助。
</p>
<p>
2.参加社会医疗保险的互助基金会员患本办法所列疾病,住院治疗期间发生的医疗费经社会医疗保险机构报销后,并经校医院审核,个人承担费用(不含国家规定应该由个人支付的费用)年度累计超过
5000 元者,可申请并获得补助。
</p>
<p>
3.互助基金会员患不属于本办法所列重大疾病目录中费用支出较大的疾病,经住院治疗、且经公费医疗或社会医疗保险报销后,单次住院个人承担费用(不含国家规定应该由个人支付的费用)超过
10000
元(年度不累计)者,也可申请并获得补助。
</p>
<ul class="list-group" style="max-height: 450px;overflow-y: scroll">
<li class="list-group-item" v-for="i in diseaseList">{{i.diseaseName}}</li>
</ul>
<el-row class="mt25" justify="center" type="flex">
<el-button @click="tipsDialog=false" type="primary">我已知晓</el-button>
</el-row>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: '#app',
store,
mixins: [initTableMixins],
data() {
return {
tipsDialog: false,
diseaseList: [],
userOptions: [],
subsidyTypeList: ['公费医疗', '社会保险'],
formRules: {
userId: [{required: true, message: '请选择用户', trigger: 'blur'}],
homeAddress: [{required: true, message: '请填写家庭住址', trigger: 'blur'}],
familyIncome: [{required: true, message: '请填写上年总收入', trigger: 'blur'}],
subsidyType: [{required: true, message: '请选择报销类型', trigger: 'blur'}],
diseaseId: [{required: true, message: '请选择疾病种类', trigger: 'blur'}],
mobile: [{required: true, message: '请输入联系电话', trigger: 'blur'}],
files: [{required: true, message: '请上传附件', trigger: 'blur'}],
},
formData: {
costList: []
},
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
medicalSetting: {}
}
},
methods: {
getMedicalSetting() {
this.$axios.post("/platform/medicalMutualAid/medical/basicSetting/getSetting").then(res => {
if (res.code === 0) {
this.medicalSetting = res.data
}
})
},
// 获取累计补助金额
getMedicalSubsidyMoney(userId) {
this.$axios.post(loc() + "/getMedicalSubsidyMoney", {userId}).then(res => {
if (res.code === 0) {
if (res.data.medicalSubsidyMoney !== null) {
this.$set(this.formData, 'medicalSubsidyMoney', res.data.medicalSubsidyMoney + this.medicalSetting.loveMoney)
} else {
this.$set(this.formData, 'medicalSubsidyMoney', 0)
}
}
})
},
// 获取补助申请次数
getMedicalApplyNum(userId) {
this.$axios.post(loc() + "/getMedicalApplyNum", {userId}).then(res => {
if (res.code === 0) {
this.$set(this.formData, 'applyNum', res.data)
}
})
},
diseaseIdChange(val) {
const disease = this.diseaseList.find(i => i.id === val)
if (disease) {
this.$set(this.formData, 'isMajorDiseases', disease.isMajorDiseases)
} else {
this.$set(this.formData, 'isMajorDiseases', false)
}
},
// 计算每个表格中的自费部分金额
calcPersonExpenseMoney(row) {
// fix 2025-11-16 个人自费金额 计算需要减去靶向药
// const mz = isNaN(row.outpatientServiceMoney) ? 0 : row.outpatientServiceMoney
// const personExpenseMoney = (this.formData.majorDisease ? (mz + row.hospitalSumMoney) : row.hospitalSumMoney) - row.reimbursementMoney - row.singleBearMoney - row.bxyMoney
//自费部分金额=住院医疗费总额(不含门诊)-实际报销金额-个人承担部分金额 zhf 2025-11-17
const personExpenseMoney = row.hospitalSumMoney - row.reimbursementMoney - row.singleBearMoney
return isNaN(personExpenseMoney) ? 0 : personExpenseMoney < 0 ? 0 : personExpenseMoney.toFixed(2)
},
async userChange(val) {
const user = this.userOptions.find(u => u.id === val)
this.$set(this.formData, 'sex', user.sex)
if (user.birthday) {
this.$set(this.formData, 'age', this.$moment().diff(user.birthday, 'years'))
}
this.$set(this.formData, 'unitName', user.unitName)
this.$set(this.formData, 'idCard', user.idCard)
this.$set(this.formData, 'homeAddress', user.homeAddress)
this.$set(this.formData, 'mobile', user.mobile)
this.$set(this.formData, 'userId', user.id)
this.getMedicalSubsidyMoney(this.formData.userId)
this.getMedicalApplyNum(this.formData.userId)
this.getIsAfootMedicalApply(this.formData.userId, null)
},
onSave() {
this.$confirm("保存后可在我的补助申请页面继续填写然后提交,是否保存?", '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.formLoading = true
//判断每个住院记录中是否有开始时间和结束时间
this.formData.costList.forEach(cost => {
if (cost.visitTime && cost.visitTime.length > 0) {
cost.visitStartTime = cost.visitTime[0]
cost.visitEndTime = cost.visitTime[1]
}
})
this.$axios.post("/platform/medicalMutualAid/medical/apply/save", {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
commonUtil.pjaxPush("/platform/medicalMutualAid/medical/mine")
}
}).finally(() => {
this.formLoading = false
})
})
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
if (this.formData.costList.length === 0) {
this.$message.error("请添加住院记录!")
return
}
if (!this.validateIsMajorDiseases()){
this.$alert('您的个人承担部分金额达不到补助标准,无法申请!', '提示', {
confirmButtonText: '确定',
callback: action => {
}
});
return;
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/apply/submit", {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
commonUtil.pjaxPush("/platform/medicalMutualAid/medical/mine")
}
})
})
}
})
},
onFinishTask() {
this.$refs.formRef.validate((valid) => {
if (valid) {
if (this.formData.costList.length === 0) {
this.$message.error("请添加住院记录!")
return
}
if (!this.validateIsMajorDiseases()){
this.$alert('您的个人承担部分金额达不到补助标准,无法申请!', '提示', {
confirmButtonText: '确定',
callback: action => {
}
});
return;
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/apply/submitAgain", {
data: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
commonUtil.pjaxPush("/platform/medicalMutualAid/medical/mine")
}
})
})
}
})
},
// 判断个人承担部分金额有没有达到标准,true不能申请,false可以申请
validateIsMajorDiseases() {
let flag = true
if (this.formData.isMajorDiseases) {
const singleBearMoneyList = this.formData.costList.map(cost => cost.singleBearMoney)
const allSingleBearMoney = singleBearMoneyList.reduce((a, b) => {
return parseFloat(a) + parseFloat(b)
})
if (this.formData.subsidyType === '公费医疗' && allSingleBearMoney < this.medicalSetting.publicYearInDiseaseMoney) {
flag = false
} else if (this.formData.subsidyType === '社会保险' && allSingleBearMoney < this.medicalSetting.socialYearInDiseaseMoney) {
flag = false
}
if (this.formData.applyNum === 1) {
flag = true
}
} else {
if (this.formData.costList.some(v => v.singleBearMoney < this.medicalSetting.ordinaryOnceNotInDiseaseMoney)) {
flag = false
}
}
return flag
},
async createRemoteMethod(keyword) {
const resp = await this.$axios.post(loc() + "/getSubsidyUser", {keyword})
if (resp.code === 0) {
this.userOptions = resp.data;
}
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
async init() {
this.getMedicalSetting()
if (this.bizId) {
this.getIsAfootMedicalApply(this.$store.state.user.id, this.bizId)
this.$axios.post("/platform/medicalMutualAid/medical/mine/info", {id: this.bizId}).then((res) => {
if (res.code === 0) {
res.data.costList.forEach(cost => {
if (cost.visitStartTime) {
cost.visitTime = [cost.visitStartTime, cost.visitEndTime]
}
})
this.createRemoteMethod(res.data.userId)
this.formData = res.data
this.diseaseIdChange(res.data.diseaseId)
}
})
} else {
await this.createRemoteMethod(this.$store.state.user.id)
this.$set(this.formData, 'sex', this.$store.state.user.sex)
if (this.$store.state.user.birthday) {
this.$set(this.formData, 'age', this.$moment().diff(this.$store.state.user.birthday, 'years'))
}
this.$set(this.formData, 'unitName', this.$store.state.user.unit.name)
this.$set(this.formData, 'idCard', this.$store.state.user.idCard)
this.$set(this.formData, 'homeAddress', this.$store.state.user.homeAddress)
this.$set(this.formData, 'mobile', this.$store.state.user.mobile)
this.$set(this.formData, 'userId', this.$store.state.user.id)
this.getMedicalSubsidyMoney(this.formData.userId)
this.getMedicalApplyNum(this.formData.userId)
this.getIsAfootMedicalApply(this.$store.state.user.id, null)
}
},
// 查询是否有进行中的申请
getIsAfootMedicalApply(userId, id) {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getIsAfootMedicalApply", {
userId,
id
}).then(res => {
if (res.code === 0) {
}
}).catch(e => {
this.$alert(e.msg, '温馨提示', {
confirmButtonText: '确定',
callback: action => {
commonUtil.pjaxPush("/platform/medicalMutualAid/medical/mine")
}
});
})
}
},
created() {
this.getDiseaseList()
this.init()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,134 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<div style="max-width: 900px; margin: 0 auto;">
<custom-card>
<el-form :model="formData" label-suffix="" ref="formRef" label-width="250px">
<el-form-item label="公费医疗年度补助标准(重疾)" prop="publicYearInDiseaseMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.publicYearInDiseaseMoney"></el-input-number>
</el-form-item>
<el-form-item label="社保年度补助标准(重疾)" prop="socialYearInDiseaseMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.socialYearInDiseaseMoney"></el-input-number>
</el-form-item>
<el-form-item label="单次补助标准(普疾)" prop="ordinaryOnceNotInDiseaseMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.ordinaryOnceNotInDiseaseMoney"></el-input-number>
</el-form-item>
<el-form-item label="爱心互助基金补助标准" prop="loveMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.loveMoney"></el-input-number>
</el-form-item>
<el-form-item label="补助比例" prop="subsidyRatio">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.subsidyRatio"></el-input-number>
</el-form-item>
<el-form-item label="每年补助限额(重疾)" prop="maxYearInDiseaseMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.maxYearInDiseaseMoney"></el-input-number>
</el-form-item>
<el-form-item label="每年补助限额(普疾)" prop="maxYearNotInDiseaseMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.maxYearNotInDiseaseMoney"></el-input-number>
</el-form-item>
<el-form-item label="共计补助限额" prop="previousYearMaxMoney">
<el-input-number :max="500000" :min="0" style="width: 100%"
v-model="formData.previousYearMaxMoney"></el-input-number>
</el-form-item>
<el-form-item label="超过共计补助限额后每年限额" prop="beyondMaxQuotaMoney">
<el-input-number :max="100000" :min="0" style="width: 100%"
v-model="formData.beyondMaxQuotaMoney"></el-input-number>
</el-form-item>
<el-form-item label="十年未申请首次补助比例增加" prop="tenYearNeverAddSubsidyRatio">
<el-input-number :max="100" :min="0" style="width: 100%"
v-model="formData.tenYearNeverAddSubsidyRatio"></el-input-number>
</el-form-item>
<el-form-item label="十五年未补助首次申请比例增加" prop="fifteenYearNeverAddSubsidyRatio">
<el-input-number :max="100" :min="0" style="width: 100%"
v-model="formData.fifteenYearNeverAddSubsidyRatio"></el-input-number>
</el-form-item>
</el-form>
<template slot="footer">
<el-button type="primary" @click="doSubmit">确定</el-button>
</template>
</custom-card>
</div>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {}
},
methods: {
doSubmit() {
this.$refs.formRef.validate(valid => {
if (valid) {
this.$axios.post(loc() + "/doSubmit", this.formData).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
this.initData()
}
})
}
})
},
initData() {
this.$axios.post(loc() + "/getSetting").then(res => {
if (res.code === 0) {
if (res.data == null) {
this.formData = {
publicYearInDiseaseMoney: 0,
socialYearInDiseaseMoney: 0,
ordinaryOnceNotInDiseaseMoney: 0,
loveMoney: 0,
subsidyRatio: 0,
maxYearInDiseaseMoney: 0,
maxYearNotInDiseaseMoney: 0,
previousYearMaxMoney: 0,
}
} else {
this.formData = res.data
}
}
})
}
},
created() {
this.initData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,141 @@
const MEDICAL_INFO = {
template: /*language=HTML*/
`
<div>
<div class="process-title">
申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-descriptions :column="3" border>
<el-descriptions-item label="申请人姓名">{{ viewData.userName }}{{viewData.loginName}}
</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="年龄">{{ viewData.age }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="累计补助金额">{{ viewData.medicalSubsidyMoney }}</el-descriptions-item>
<el-descriptions-item label="起扣时间">{{ viewData.aidFundDeductTime }}</el-descriptions-item>
<el-descriptions-item label="所在单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所在工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="疾病种类">{{ viewData.diseaseName }}</el-descriptions-item>
<el-descriptions-item label="重大疾病(次数)">
<span :class="[viewData.isMajorDiseases?'text-danger':'text-info']">
<i class="fa fa-circle ml5"></i>
{{viewData.isMajorDiseases?'是':'否'}}{{viewData.applyNum}}
</span>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="备注" :span="3">
<div style="white-space: pre-line">{{viewData.note}}</div>
</el-descriptions-item>
<el-descriptions-item label="住院记录" :span="3">
<el-table :data="viewData.costList" border show-summary>
<el-table-column label="序号" type="index" width="50px" fixed></el-table-column>
<el-table-column label="住院时间段" width="200">
<template v-slot="{row}">
{{row.visitStartTime}}至{{row.visitEndTime}}
</template>
</el-table-column>
<el-table-column label="住院医院" prop="visitHospital" width="250"></el-table-column>
<el-table-column label="住院医疗费总额(不含门诊)" prop="hospitalSumMoney"></el-table-column>
<el-table-column label="实际报销金额" prop="reimbursementMoney"></el-table-column>
<el-table-column label="(住院医疗)允许报销范围内个人承担部分金额"
prop="singleBearMoney"></el-table-column>
<el-table-column label="(住院医疗)自费部分金额" prop="personExpenseMoney"></el-table-column>
<el-table-column label="重病门诊自费金额" prop="outpatientServiceMoney"></el-table-column>
<el-table-column label="非住院肾衰竭治疗、靶向药" prop="bxyMoney"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="3">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="详细疾病名称"
v-if="task.taskName==='39916c1e-857d-407d-86c1-678ccf3011bc'"
:span="3">{{
task.taskFormData.diseaseDetailName }}
</el-descriptions-item>
<template v-if="task.taskName==='cd560356-cc70-48b5-8d99-ff9bd3505869'">
<el-descriptions-item label="预测补助金额" :span="3">
{{
task.taskFormData.tf_forecastSubsidyMoney }}
</el-descriptions-item>
<el-descriptions-item label="爱心基金(元)" :span="3">
{{
task.taskFormData.tf_loveSubsidyMoney }}
</el-descriptions-item>
</template>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode" :span="3">{{
task.taskFormData.opinion }}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
`,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
visible: false,
viewData: {},
doneTasks: [],
row: null
}
},
methods: {
onOpen(row) {
this.row = row
this.visible = true
this.getInfo()
this.getDoneTasks()
},
getInfo() {
this.$axios.post('/platform/medicalMutualAid/medical/mine/info', {id: this.row.id}).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
// 查看流程图
openChart() {
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
}
}
}
@@ -0,0 +1,111 @@
const MEDICAL_TABLE = {
template: /*language=HTML*/
`
<div>
<el-table :data="localTableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%"
:summary-method="getSummaries" :show-summary="showSummary">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"
fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:fixed="column.fixed"
:sortable="column.sortable"
show-overflow-tooltip
sortable
v-for="column in tableColumns"
>
<template v-if="column.prop==='isMajorDiseases'" v-slot="{row}">
<span :class="[row.isMajorDiseases?'text-danger':'text-info']">
<i class="fa fa-circle ml5"></i>
{{row.isMajorDiseases?'是':'否'}}{{row.applyNum}}
</span>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'curTaskName'">
{{row.curTaskName?row.curTaskName:row.taskName}}
</template>
</el-table-column>
<slot name="operation"></slot>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
props: {
localTableData: {
type: Array,
default: []
},
showSummary: {
type: Boolean,
default: false
},
localPageForm:{
type: Object,
default: () => {
return {}
}
}
},
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{prop: 'loginname', label: '工号', fixed: "left"},
{prop: 'username', label: '姓名', fixed: "left"},
{prop: 'unionName', label: '所属工会', width: "180"},
{prop: 'unitName', label: '所属单位', width: "180"},
{prop: 'diseaseName', label: '疾病种类', width: "180"},
{prop: 'isMajorDiseases', label: '重大疾病(次数)', width: "100"},
{prop: 'applyNum', label: '申请总次数'},
{prop: 'applyTime', label: '申请时间', width: "180"},
{prop: 'hospitalSumMoney$', label: '住院医疗总额(不含门诊)', width: "120"},
{prop: 'reimbursementMoney$', label: '实际报销总额', width: "120"},
{prop: 'singleBearMoney$', label: '(住院医疗)允许报销范围内个人承担部分总额', width: "120"},
{prop: 'personExpenseMoney$', label: '(住院医疗)自费部分总额', width: "120"},
{prop: 'outpatientServiceMoney$', label: '重病门诊自费金额', width: "120"},
{prop: 'bxyMoney$', label: '非住院肾衰竭治疗、靶向药金额', width: "120"},
{prop: 'totalMoney', label: '合计金额', width: "120"},
{prop: 'curTaskName', label: '当前节点', width: "120"},
{prop: 'instanceState', label: '流程状态'},
],
}
},
methods: {
getSummaries(param) {
const {columns, data} = param
const sums = []
columns.forEach((column, index) => {
const sumColumn = ['hospitalSumMoney$', 'reimbursementMoney$', 'singleBearMoney$', 'personExpenseMoney$', 'subsidyMoney', 'loveSubsidyMoney', 'outpatientServiceMoney$', 'totalMoney']
if (sumColumn.includes(column.property)) {
const values = data.map(i => Number(i[column.property]))
if (values && values.length > 0) {
const everyColumnSum = values.reduce((a, b) => a + b)
sums[index] = isNaN(everyColumnSum) ? 0 : everyColumnSum.toFixed(2)
}
}
})
sums[0] = '合计'
return sums
},
},
created() {
this.$emit('ready')
},
watch: {
"localPageForm": {
handler(val) {
this.pageForm = {...this.pageForm, ...val}
},
deep: true
},
}
}
@@ -0,0 +1,121 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<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" 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 label="操作">
<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 :visible.sync="dialogVisible" title="新增" width="50%">
<el-form :model="formData" :rules="rules" label-width="120px" ref="form">
<el-form-item label="疾病名称" prop="diseaseName">
<el-input maxlength="50" v-model="formData.diseaseName"></el-input>
</el-form-item>
<el-form-item label="编号" prop="diseaseCode">
<el-input max="128" v-model.number="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,
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.pageData()
}
})
})
},
openEdit(row) {
this.formData = clone(row)
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.dialogVisible = false
this.pageData()
}
})
}
})
},
openAdd() {
this.formData = {isMajorDiseases: true}
this.dialogVisible = true
}
},
async created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,350 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="疾病种类">
<el-select clearable placeholder="请选择疾病种类"
v-model="pageForm.diseaseId" filterable>
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择院级工会"
@change="getUnitList()">
<el-option v-for="item in unionList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="pageForm.unitId" clearable filterable placeholder="请选择单位">
<el-option v-for="item in unitList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<medical-table ref="table" :local-table-data="tableData" v-loading="tableLoading"
:local-page-form="pageForm" @ready="doSearch">
<template slot="operation">
<el-table-column label="操作" fixed="right" width="200">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke||row.curTaskName==='结束'" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</template>
</medical-table>
</el-card>
<template #edit>
<medical-info ref="medicalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px" label-suffix=""
>
<el-table :data="costList" border show-summary class="cost">
<el-table-column label="序号" type="index" width="50px" fixed></el-table-column>
<el-table-column label="住院时间段" width="200">
<template v-slot="{row}">
{{row.visitStartTime}}至{{row.visitEndTime}}
</template>
</el-table-column>
<el-table-column label="住院医院" prop="visitHospital" width="250"></el-table-column>
<el-table-column label="住院医疗费总额(不含门诊)" width="180" prop="hospitalSumMoney">
<template v-slot="{row}">
<el-input-number placeholder="住院医疗费总额(不含门诊)"
:min="0"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.hospitalSumMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="实际报销金额" width="180" prop="reimbursementMoney">
<template v-slot="{row}">
<el-input-number placeholder="实际报销金额"
:min="0"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.reimbursementMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)允许报销范围内个人承担部分金额"
width="180" prop="singleBearMoney">
<template v-slot="{row}">
<el-input-number :min="0" placeholder="个人承担部分金额"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.singleBearMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)自费部分金额" width="180"
prop="personExpenseMoney"></el-table-column>
<el-table-column label="重病门诊自费金额" width="180" prop="outpatientServiceMoney">
<template v-slot="{row}">
<el-input-number placeholder="门诊费"
:min="0"
:disabled="!formData.tf_isMajorDiseases"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.outpatientServiceMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="非住院肾衰竭治疗、靶向药" width="180" prop="bxyMoney">
<template v-slot="{row}">
<el-input-number placeholder="靶向药"
:min="0"
:disabled="!formData.tf_isMajorDiseases"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.bxyMoney"></el-input-number>
</template>
</el-table-column>
</el-table>
<div class="mt10">
<el-form-item label="疾病种类" prop="tf_diseaseId"
:rules="[{required:true,message:'请选择疾病种类',trigger:['change','blur']}]">
<el-select placeholder="请选择疾病种类" style="width: 50%"
v-model="formData.tf_diseaseId" filterable @change="diseaseIdChange">
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预测补助金额(元)" prop="tf_forecastSubsidyMoney">
<span slot="label">
预测补助金额(元)
<el-tooltip class="item" effect="dark"
content="计算公式:((住院医疗)允许报销范围内个人承担部分金额+(住院医疗)自费部分金额+重病门诊自费金额+非住院肾衰竭治疗、靶向药金额)* 补助比例"
placement="top-start">
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-input-number v-model="formData.tf_forecastSubsidyMoney"
style="width: 50%"></el-input-number>
<el-button @click="calcMedicalMoney(formData.id,formData.tf_diseaseId)" type="primary">
重新计算金额
</el-button>
</el-form-item>
<el-form-item label="爱心基金(元)" prop="tf_loveSubsidyMoney">
<el-input-number :max="medicalSetting.loveMoney" :min="0" style="width: 50%"
v-model="formData.tf_loveSubsidyMoney"></el-input-number>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</div>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</medical-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/medicalTable.js'){}#-->
<!--#include('../common/medicalInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
costList: [],
unionList: [],
unitList: [],
diseaseList: [],
showApprovalForm: false,
pageForm: {
approval: false,
year: new Date().getFullYear() + "",
},
medicalSetting: {}
}
},
components: {
"medical-table": MEDICAL_TABLE,
"medical-info": MEDICAL_INFO
},
methods: {
// 修改表格里面的金额并修改数据库里的数据
tableChangeMoney() {
this.costList.forEach(cost => {
const personExpenseMoney = cost.hospitalSumMoney - cost.reimbursementMoney - cost.singleBearMoney
cost.personExpenseMoney = isNaN(personExpenseMoney) ? 0 : personExpenseMoney < 0 ? 0 : personExpenseMoney.toFixed(2)
})
this.$axios.post("/platform/medicalMutualAid/medical/foundationAudit/updateCost", {
data: JSON.stringify(this.costList)
}).then(res => {
if (res.code === 0) {
}
})
},
// 重新计算预测补助金额
calcMedicalMoney(id, diseaseId) {
this.$axios.post("/platform/medicalMutualAid/medical/foundationAudit/calcMedicalMoney", {
id, diseaseId
}).then(res => {
if (res.code === 0) {
this.$set(this.formData, 'tf_loveSubsidyMoney', res.data.loveSubsidyMoney)
this.$set(this.formData, 'tf_forecastSubsidyMoney', res.data.forecastSubsidyMoney)
}
})
},
diseaseIdChange(val) {
const disease = this.diseaseList.find(i => i.id === val)
this.$set(this.formData, "tf_diseaseName", disease.diseaseName)
this.$set(this.formData, "tf_isMajorDiseases", disease.isMajorDiseases)
},
onView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.medicalInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
const disease = this.diseaseList.find(i => i.id === row.diseaseId)
this.formData = {
id: row.id,
tf_diseaseId: row.diseaseId,
tf_oldDiseaseId: row.diseaseId,
tf_oldDiseaseName: disease.diseaseName,
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.diseaseIdChange(row.diseaseId)
this.calcMedicalMoney(row.id, row.diseaseId)
this.$refs.medicalInfoRef.onOpen(row)
})
setTimeout(() => {
this.costList = this.$refs.medicalInfoRef.viewData.costList
}, 500)
},
handleTaskAction(val) {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/foundationAudit/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
}
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
async getUnitList() {
this.unitList = await this.$businessTool.listUnit(this.pageForm.unionId)
},
getMedicalSetting() {
this.$axios.post("/platform/medicalMutualAid/medical/basicSetting/getSetting").then(res => {
if (res.code === 0) {
this.medicalSetting = res.data
}
})
},
},
async created() {
this.getMedicalSetting()
this.getDiseaseList()
this.unionList = await this.$businessTool.listUnion()
this.unitList = await this.$businessTool.listUnit()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,139 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="疾病种类">
<el-select clearable placeholder="请选择疾病种类"
v-model="pageForm.diseaseId" filterable>
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="我的申请">
</table-tool>
<medical-table ref="table" :local-table-data="tableData"
:show-summary='true' v-loading="tableLoading"
:local-page-form="pageForm" @ready="doSearch">
<template slot="operation">
<el-table-column label="操作" fixed="right" width="300">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)"
size="mini" type="primary">编辑
</el-button>
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="onRevoke(row)">撤回
</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)"
size="mini" type="danger">
删除
</el-button>
</template>
</el-table-column>
</template>
</medical-table>
</el-card>
<template #view>
<medical-info ref="medicalInfoRef"></medical-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/medicalTable.js'){}#-->
<!--#include('../common/medicalInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
diseaseList: []
}
},
components: {
"medical-table": MEDICAL_TABLE,
"medical-info": MEDICAL_INFO
},
methods: {
onView(row) {
this.$refs.guava.view(()=>{
this.$refs.medicalInfoRef.onOpen(row)
})
},
onEdit(row) {
commonUtil.pjaxPush('/platform/medicalMutualAid/medical/apply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/mine/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
},
created() {
this.getDiseaseList()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,231 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="疾病种类">
<el-select clearable placeholder="请选择疾病种类"
v-model="pageForm.diseaseId" filterable>
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择院级工会"
@change="getUnitList()">
<el-option v-for="item in unionList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="pageForm.unitId" clearable filterable placeholder="请选择单位">
<el-option v-for="item in unitList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<medical-table ref="table" :local-table-data="tableData" v-loading="tableLoading"
:local-page-form="pageForm" @ready="doSearch">
<template slot="operation">
<el-table-column label="操作" fixed="right" width="200">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</template>
</medical-table>
</el-card>
<template #edit>
<medical-info ref="medicalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="疾病种类" prop="tf_diseaseId"
:rules="[{required:true,message:'请选择疾病种类',trigger:['change','blur']}]">
疾病种类:
<el-select placeholder="请选择疾病种类"
v-model="formData.tf_diseaseId" filterable @change="diseaseIdChange">
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="详细疾病名称" prop="tf_diseaseDetailName"
:rules="[{required:true,message:'请填写详细疾病名称',trigger:['change','blur']}]">
详细疾病名称:
<el-input maxlength="100" v-model="formData.tf_diseaseDetailName"
placeholder="请填写详细疾病名称"></el-input>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</medical-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/medicalTable.js'){}#-->
<!--#include('../common/medicalInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
unionList: [],
unitList: [],
diseaseList: [],
showApprovalForm: false,
pageForm: {
approval: false,
year: new Date().getFullYear() + "",
},
}
},
components: {
"medical-table": MEDICAL_TABLE,
"medical-info": MEDICAL_INFO
},
methods: {
diseaseIdChange(val){
const disease= this.diseaseList.find(i => i.id === val)
this.$set(this.formData, "tf_diseaseName", disease.diseaseName)
},
onView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.medicalInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
const disease= this.diseaseList.find(i => i.id === row.diseaseId)
this.formData = {
id: row.id,
tf_diseaseId: row.diseaseId,
tf_oldDiseaseId: row.diseaseId,
tf_oldDiseaseName: disease.diseaseName,
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.diseaseIdChange(row.diseaseId)
this.$refs.medicalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/schoolHospitalAudit/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
}
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
async getUnitList() {
this.unitList = await this.$businessTool.listUnit(this.pageForm.unionId)
}
},
async created() {
this.getDiseaseList()
this.unionList = await this.$businessTool.listUnion()
this.unitList = await this.$businessTool.listUnit()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,411 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="疾病种类">
<el-select clearable placeholder="请选择疾病种类"
v-model="pageForm.diseaseId" filterable>
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</search-item>
<search-item label="会员类型">
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
style="width: 100%"></dict-select>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择院级工会"
@change="getUnitList()">
<el-option v-for="item in unionList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="pageForm.unitId" clearable filterable placeholder="请选择单位">
<el-option v-for="item in unitList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-dropdown @command="doExport">
<el-button type="primary" size="small">导出 <i class="el-icon-arrow-down el-icon--right"></i></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{val:true}" key="major">重疾</el-dropdown-item>
<el-dropdown-item :command="{val:false}" key="normal">普通</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%"
:summary-method="getSummaries" :show-summary="showSummary">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"
fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:fixed="column.fixed"
:sortable="column.sortable"
show-overflow-tooltip
sortable
v-for="column in tableColumns"
>
<template v-if="column.prop==='isMajorDiseases'" v-slot="{row}">
<span :class="[row.isMajorDiseases?'text-danger':'text-info']">
<i class="fa fa-circle ml5"></i>
{{row.isMajorDiseases?'是':'否'}}{{row.applyNum}}
</span>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'curTaskName'">
{{row.curTaskName?row.curTaskName:row.taskName}}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="100">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)"
size="mini" type="danger">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<template #edit>
<medical-info ref="medicalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px" label-suffix=""
>
<el-table :data="costList" border show-summary class="cost">
<el-table-column label="序号" type="index" width="50px" fixed></el-table-column>
<el-table-column label="住院时间段" width="200">
<template v-slot="{row}">
{{row.visitStartTime}}至{{row.visitEndTime}}
</template>
</el-table-column>
<el-table-column label="住院医院" prop="visitHospital" width="250"></el-table-column>
<el-table-column label="住院医疗费总额(不含门诊)" width="180" prop="hospitalSumMoney">
<template v-slot="{row}">
<el-input-number placeholder="住院医疗费总额(不含门诊)"
:min="0"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.hospitalSumMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="实际报销金额" width="180" prop="reimbursementMoney">
<template v-slot="{row}">
<el-input-number placeholder="实际报销金额"
:min="0"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.reimbursementMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)允许报销范围内个人承担部分金额"
width="180" prop="singleBearMoney">
<template v-slot="{row}">
<el-input-number :min="0" placeholder="个人承担部分金额"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.singleBearMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="(住院医疗)自费部分金额" width="180"
prop="personExpenseMoney"></el-table-column>
<el-table-column label="重病门诊自费金额" width="180" prop="outpatientServiceMoney">
<template v-slot="{row}">
<el-input-number placeholder="门诊费"
:min="0"
:disabled="!formData.tf_isMajorDiseases"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.outpatientServiceMoney"></el-input-number>
</template>
</el-table-column>
<el-table-column label="非住院肾衰竭治疗、靶向药" width="180" prop="bxyMoney">
<template v-slot="{row}">
<el-input-number placeholder="靶向药"
:min="0"
:disabled="!formData.tf_isMajorDiseases"
controls-position="right" style="width: 100%"
@change="tableChangeMoney"
v-model="row.bxyMoney"></el-input-number>
</template>
</el-table-column>
</el-table>
<div class="mt10">
<el-form-item label="疾病种类" prop="tf_diseaseId"
:rules="[{required:true,message:'请选择疾病种类',trigger:['change','blur']}]">
<el-select placeholder="请选择疾病种类" style="width: 50%"
v-model="formData.tf_diseaseId" filterable @change="diseaseIdChange">
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预测补助金额(元)" prop="tf_forecastSubsidyMoney">
<span slot="label">
预测补助金额(元)
<el-tooltip class="item" effect="dark"
content="计算公式:((住院医疗)允许报销范围内个人承担部分金额+(住院医疗)自费部分金额+重病门诊自费金额+非住院肾衰竭治疗、靶向药金额)* 补助比例"
placement="top-start">
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-input-number v-model="formData.tf_forecastSubsidyMoney"
style="width: 50%"></el-input-number>
<el-button @click="calcMoney(formData.id)" type="primary">重新计算金额</el-button>
</el-form-item>
<el-form-item label="爱心基金(元)" prop="tf_loveSubsidyMoney">
<el-input-number :max="medicalSetting.loveMoney" :min="0" style="width: 50%"
v-model="formData.tf_loveSubsidyMoney"></el-input-number>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</div>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</medical-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/medicalInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
props: {
showSummary: {
type: Boolean,
default: true
},
localPageForm: {
type: Object,
default: () => ({})
}
},
data() {
return {
tableData: [],
tableColumns: [
{prop: 'loginname', label: '工号', fixed: "left"},
{prop: 'username', label: '姓名', fixed: "left"},
{prop: 'unionName', label: '所属工会', width: "180"},
{prop: 'unitName', label: '所属单位', width: "180"},
{prop: 'diseaseName', label: '疾病种类', width: "180"},
{prop: 'isMajorDiseases', label: '重大疾病(次数)', width: "100"},
{prop: 'applyNum', label: '申请总次数'},
{prop: 'applyTime', label: '申请时间', width: "180"},
{prop: 'hospitalSumMoney$', label: '住院医疗总额(不含门诊)', width: "120"},
{prop: 'reimbursementMoney$', label: '实际报销总额', width: "120"},
{prop: 'singleBearMoney$', label: '(住院医疗)允许报销范围内个人承担部分总额', width: "120"},
{prop: 'personExpenseMoney$', label: '(住院医疗)自费部分总额', width: "120"},
{prop: 'outpatientServiceMoney$', label: '重病门诊自费金额', width: "120"},
{prop: 'bxyMoney$', label: '非住院肾衰竭治疗、靶向药金额', width: "120"},
{prop: 'totalMoney', label: '合计金额', width: "120"},
{prop: 'instanceState', label: '流程状态'},
{prop: 'subsidyMoney', label: '补助金额'},
{prop: 'loveSubsidyMoney', label: '爱心补助金额'},
],
costList: [],
unionList: [],
unitList: [],
diseaseList: [],
showApprovalForm: false,
pageForm: {
approval: false,
year: new Date().getFullYear() + "",
pageSize: 9999,
isMajorDiseases: null
},
medicalSetting: {}
}
},
components: {
"medical-info": MEDICAL_INFO
},
watch: {
"localPageForm": {
handler(val) {
this.pageForm = {...this.pageForm, ...val}
},
deep: true
},
},
methods: {
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/medicalMutualAid/medical/mine/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
getSummaries(param) {
const {columns, data} = param
const sums = []
columns.forEach((column, index) => {
const sumColumn = ['hospitalSumMoney$', 'reimbursementMoney$', 'singleBearMoney$', 'personExpenseMoney$', 'subsidyMoney', 'loveSubsidyMoney', 'outpatientServiceMoney$', 'totalMoney']
if (sumColumn.includes(column.property)) {
const values = data.map(i => Number(i[column.property]))
if (values && values.length > 0) {
const everyColumnSum = values.reduce((a, b) => a + b)
sums[index] = isNaN(everyColumnSum) ? 0 : everyColumnSum.toFixed(2)
}
}
})
sums[0] = '合计'
return sums
},
// 修改表格里面的金额并修改数据库里的数据
tableChangeMoney() {
this.costList.forEach(cost => {
const personExpenseMoney = cost.hospitalSumMoney - cost.reimbursementMoney - cost.singleBearMoney
cost.personExpenseMoney = isNaN(personExpenseMoney) ? 0 : personExpenseMoney < 0 ? 0 : personExpenseMoney.toFixed(2)
})
console.log(this.costList)
this.$axios.post("/platform/medicalMutualAid/medical/foundationAudit/updateCost", {
data: JSON.stringify(this.costList)
}).then(res => {
if (res.code === 0) {
}
})
},
// 重新计算预测补助金额
calcMoney() {
},
diseaseIdChange(val) {
const disease = this.diseaseList.find(i => i.id === val)
this.$set(this.formData, "tf_diseaseName", disease.diseaseName)
this.$set(this.formData, "tf_isMajorDiseases", disease.isMajorDiseases)
},
onView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.medicalInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
const disease = this.diseaseList.find(i => i.id === row.diseaseId)
this.formData = {
id: row.id,
tf_diseaseId: row.diseaseId,
tf_oldDiseaseId: row.diseaseId,
tf_oldDiseaseName: disease.diseaseName,
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.diseaseIdChange(row.diseaseId)
this.$refs.medicalInfoRef.onOpen(row)
})
setTimeout(() => {
this.costList = this.$refs.medicalInfoRef.viewData.costList
}, 500)
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
async getUnitList() {
this.unitList = await this.$businessTool.listUnit(this.pageForm.unionId)
},
getMedicalSetting() {
this.$axios.post("/platform/medicalMutualAid/medical/basicSetting/getSetting").then(res => {
if (res.code === 0) {
this.medicalSetting = res.data
}
})
},
doExport(command) {
const params = {
...this.pageForm,
isMajorDiseases: command.val
};
this.$downLoad('/platform/medicalMutualAid/medical/statistics/doExport', params);
},
},
async created() {
this.pageData()
this.$emit('ready')
this.getMedicalSetting()
this.getDiseaseList()
this.unionList = await this.$businessTool.listUnion()
this.unitList = await this.$businessTool.listUnit()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,182 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="疾病种类">
<el-select clearable placeholder="请选择疾病种类"
v-model="pageForm.diseaseId" filterable>
<el-option
:key="i.id"
:label="i.diseaseName"
:value="i.id"
v-for="i in diseaseList">
</el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<medical-table ref="table" :local-table-data="tableData" v-loading="tableLoading"
:local-page-form="pageForm" @ready="doSearch">
<template slot="operation">
<el-table-column label="操作" fixed="right" width="200">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</template>
</medical-table>
</el-card>
<template #edit>
<medical-info ref="medicalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</medical-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/medicalTable.js'){}#-->
<!--#include('../common/medicalInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
diseaseList: [],
showApprovalForm: false,
pageForm: {
approval: false,
year: new Date().getFullYear() + "",
},
}
},
components: {
"medical-table": MEDICAL_TABLE,
"medical-info": MEDICAL_INFO
},
methods: {
onView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.medicalInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.medicalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
}
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
getDiseaseList() {
this.$axios.post("/platform/medicalMutualAid/medical/apply/getDiseaseList").then(res => {
if (res.code === 0) {
this.diseaseList = res.data;
}
})
},
},
created() {
this.getDiseaseList()
}
})
</script>
<!--#
}
#-->