diff --git a/src/main/java/com/saye/hospitalgd/commons/excel/RefundStatisticsExportXLSX.java b/src/main/java/com/saye/hospitalgd/commons/excel/RefundStatisticsExportXLSX.java new file mode 100644 index 0000000..208bc71 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/commons/excel/RefundStatisticsExportXLSX.java @@ -0,0 +1,219 @@ +package com.saye.hospitalgd.commons.excel; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 退款统计报表Excel导出工具类 + * @date 2024/12/19 10:00 + */ +public class RefundStatisticsExportXLSX { + + /** + * 导出退款统计报表 + * @param dataList 统计数据列表 + * @param summaryData 汇总数据 + * @param filePath 文件路径 + * @throws IOException + */ + public void exportRefundStatistics(List> dataList, + HashMap summaryData, + String filePath) throws IOException { + + Workbook workbook = new XSSFWorkbook(); + + // 创建样式 + CellStyle titleStyle = createTitleStyle(workbook); + CellStyle headerStyle = createHeaderStyle(workbook); + CellStyle dataStyle = createDataStyle(workbook); + CellStyle summaryStyle = createSummaryStyle(workbook); + + // 创建汇总数据表 + createSummarySheet(workbook, summaryData, titleStyle, summaryStyle); + + // 创建详细数据表 + createDataSheet(workbook, dataList, titleStyle, headerStyle, dataStyle); + + // 写入文件 + try (FileOutputStream fileOut = new FileOutputStream(filePath)) { + workbook.write(fileOut); + } + + workbook.close(); + } + + /** + * 创建汇总数据表 + */ + private void createSummarySheet(Workbook workbook, HashMap summaryData, + CellStyle titleStyle, CellStyle summaryStyle) { + Sheet sheet = workbook.createSheet("汇总统计"); + + // 标题 + Row titleRow = sheet.createRow(0); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellValue("退款数据统计汇总"); + titleCell.setCellStyle(titleStyle); + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7)); + + // 汇总数据 + int rowIndex = 2; + String[] labels = {"退款总笔数", "退款总金额(元)", "平均退款金额(元)", "最大退款金额(元)", + "最小退款金额(元)", "涉及患者数", "操作员数", "支付方式数"}; + String[] keys = {"total_refund_count", "total_refund_amount", "avg_refund_amount", + "max_refund_amount", "min_refund_amount", "unique_patients", + "unique_operators", "pay_type_count"}; + + for (int i = 0; i < labels.length; i++) { + Row row = sheet.createRow(rowIndex++); + + Cell labelCell = row.createCell(0); + labelCell.setCellValue(labels[i]); + labelCell.setCellStyle(summaryStyle); + + Cell valueCell = row.createCell(1); + Object value = summaryData.get(keys[i]); + if (value != null) { + if (keys[i].contains("amount")) { + valueCell.setCellValue(Double.parseDouble(value.toString())); + } else { + valueCell.setCellValue(value.toString()); + } + } else { + valueCell.setCellValue(0); + } + valueCell.setCellStyle(summaryStyle); + } + + // 设置列宽 + sheet.setColumnWidth(0, 3000); + sheet.setColumnWidth(1, 3000); + } + + /** + * 创建详细数据表 + */ + private void createDataSheet(Workbook workbook, List> dataList, + CellStyle titleStyle, CellStyle headerStyle, CellStyle dataStyle) { + Sheet sheet = workbook.createSheet("详细统计"); + + // 标题 + Row titleRow = sheet.createRow(0); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellValue("退款数据详细统计"); + titleCell.setCellStyle(titleStyle); + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8)); + + // 表头 + Row headerRow = sheet.createRow(2); + String[] headers = {"统计维度", "维度值", "退款笔数", "退款总金额(元)", "平均退款金额(元)", + "最大退款金额(元)", "最小退款金额(元)", "涉及患者数", "操作员数"}; + + for (int i = 0; i < headers.length; i++) { + Cell cell = headerRow.createCell(i); + cell.setCellValue(headers[i]); + cell.setCellStyle(headerStyle); + } + + // 数据行 + int rowIndex = 3; + for (HashMap data : dataList) { + Row row = sheet.createRow(rowIndex++); + + String[] keys = {"dimension_name", "dimension_value", "refund_count", "total_refund_amount", + "avg_refund_amount", "max_refund_amount", "min_refund_amount", + "unique_patients", "unique_operators"}; + + for (int i = 0; i < keys.length; i++) { + Cell cell = row.createCell(i); + Object value = data.get(keys[i]); + + if (value != null) { + if (keys[i].contains("amount")) { + cell.setCellValue(Double.parseDouble(value.toString())); + } else if (keys[i].contains("count") || keys[i].contains("patients") || keys[i].contains("operators")) { + cell.setCellValue(Integer.parseInt(value.toString())); + } else { + cell.setCellValue(value.toString()); + } + } else { + cell.setCellValue(""); + } + cell.setCellStyle(dataStyle); + } + } + + // 设置列宽 + for (int i = 0; i < headers.length; i++) { + sheet.setColumnWidth(i, 2000); + } + } + + /** + * 创建标题样式 + */ + private CellStyle createTitleStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + font.setFontHeightInPoints((short) 16); + style.setFont(font); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + return style; + } + + /** + * 创建表头样式 + */ + private CellStyle createHeaderStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + style.setFont(font); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setBorderTop(CellStyle.BORDER_THIN); + style.setBorderBottom(CellStyle.BORDER_THIN); + style.setBorderLeft(CellStyle.BORDER_THIN); + style.setBorderRight(CellStyle.BORDER_THIN); + style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + style.setFillPattern(CellStyle.SOLID_FOREGROUND); + return style; + } + + /** + * 创建数据样式 + */ + private CellStyle createDataStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setBorderTop(CellStyle.BORDER_THIN); + style.setBorderBottom(CellStyle.BORDER_THIN); + style.setBorderLeft(CellStyle.BORDER_THIN); + style.setBorderRight(CellStyle.BORDER_THIN); + return style; + } + + /** + * 创建汇总样式 + */ + private CellStyle createSummaryStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + style.setFont(font); + style.setAlignment(CellStyle.ALIGN_LEFT); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + return style; + } +} diff --git a/src/main/java/com/saye/hospitalgd/controller/FinancialReconciliation/RefundStatisticsController.java b/src/main/java/com/saye/hospitalgd/controller/FinancialReconciliation/RefundStatisticsController.java new file mode 100644 index 0000000..1a9b23e --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/controller/FinancialReconciliation/RefundStatisticsController.java @@ -0,0 +1,240 @@ +package com.saye.hospitalgd.controller.FinancialReconciliation; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.saye.hospitalgd.commons.date.DateDUtil; +import com.saye.hospitalgd.commons.log.ExceptionDUtil; +import com.saye.hospitalgd.commons.log.LogUtil; +import com.saye.hospitalgd.model.Dicinfo; +import com.saye.hospitalgd.service.FinancialReconciliation.RefundStatisticsService; +import com.saye.hospitalgd.service.system.DicinfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 退款数据统计报表 + * @date 2024/12/19 10:00 + */ +@Api(tags = "退款数据统计报表") +@Controller +@RequestMapping("/refundStatistics") +public class RefundStatisticsController { + + @Autowired + private RefundStatisticsService refundStatisticsService; + + @Autowired + private DicinfoService dicinfoService; + + /** + * @description: 到退款统计报表页面 + * @author thuang + * @date 2024/12/19 10:00 + * @version 1.0 + */ + @RequestMapping("/toRefundStatistics") + public String toRefundStatistics(ModelMap modelMap) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + + // 默认查询最近365天的数据(一年) + calendar.add(Calendar.DATE, -365); + Date startDate = calendar.getTime(); + + String startTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, startDate); + String endTime = DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd); + + modelMap.addAttribute("startTime", startTime); + modelMap.addAttribute("endTime", endTime); + + //支付方式 + List payType = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE"); + modelMap.addAttribute("payTypeList", payType); + + //退款类型 + List refundType = dicinfoService.findDicinfoTreeNodeList("REFUND_TYPE"); + modelMap.addAttribute("refundTypeList", refundType); + + } catch (Exception e) { + e.printStackTrace(); + } + return "financialReconciliation/refundStatistics"; + } + + /** + * @description: 查询退款统计报表数据 + * @author thuang + * @date 2024/12/19 10:00 + * @version 1.0 + */ + @RequestMapping("/findRefundStatistics") + @ResponseBody + @ApiOperation("查询退款统计报表数据") + public HashMap findRefundStatistics( + @ApiParam("开始时间") String startTime, + @ApiParam("结束时间") String endTime, + @ApiParam("支付方式") String payType, + @ApiParam("退款类型") String refundType, + @ApiParam("统计维度") String dimension, + @ApiParam("页码") int page, + @ApiParam("每页数量") int limit) { + + HashMap responseMap = new HashMap(); + + try { + HashMap map = new HashMap(); + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("payType", payType); + map.put("refundType", refundType); + map.put("dimension", dimension); + + PageHelper.startPage(page, limit); + PageInfo> pageInfo = new PageInfo>(refundStatisticsService.findRefundStatistics(map)); + + responseMap.put("code", 0); + responseMap.put("msg", "OK"); + responseMap.put("count", pageInfo.getTotal()); + responseMap.put("data", pageInfo.getList()); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 获取退款统计汇总数据 + * @author thuang + * @date 2024/12/19 10:00 + * @version 1.0 + */ + @RequestMapping("/getRefundSummary") + @ResponseBody + @ApiOperation("获取退款统计汇总数据") + public HashMap getRefundSummary( + @ApiParam("开始时间") String startTime, + @ApiParam("结束时间") String endTime, + @ApiParam("支付方式") String payType, + @ApiParam("退款类型") String refundType) { + + HashMap responseMap = new HashMap(); + + try { + HashMap map = new HashMap(); + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("payType", payType); + map.put("refundType", refundType); + + HashMap summaryData = refundStatisticsService.getRefundSummary(map); + + responseMap.put("code", 0); + responseMap.put("msg", "OK"); + responseMap.put("data", summaryData); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 获取退款趋势数据 + * @author thuang + * @date 2024/12/19 10:00 + * @version 1.0 + */ + @RequestMapping("/getRefundTrend") + @ResponseBody + @ApiOperation("获取退款趋势数据") + public HashMap getRefundTrend( + @ApiParam("开始时间") String startTime, + @ApiParam("结束时间") String endTime, + @ApiParam("支付方式") String payType, + @ApiParam("退款类型") String refundType) { + + HashMap responseMap = new HashMap(); + + try { + HashMap map = new HashMap(); + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("payType", payType); + map.put("refundType", refundType); + + List> trendData = refundStatisticsService.getRefundTrend(map); + + responseMap.put("code", 0); + responseMap.put("msg", "OK"); + responseMap.put("data", trendData); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 导出退款统计报表 + * @author thuang + * @date 2024/12/19 10:00 + * @version 1.0 + */ + @RequestMapping("/exportRefundStatistics") + @ResponseBody + @ApiOperation("导出退款统计报表") + public HashMap exportRefundStatistics( + @ApiParam("开始时间") String startTime, + @ApiParam("结束时间") String endTime, + @ApiParam("支付方式") String payType, + @ApiParam("退款类型") String refundType, + @ApiParam("统计维度") String dimension) { + + HashMap responseMap = new HashMap(); + + try { + HashMap map = new HashMap(); + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("payType", payType); + map.put("refundType", refundType); + map.put("dimension", dimension); + + String fileName = refundStatisticsService.exportRefundStatistics(map); + + responseMap.put("code", 0); + responseMap.put("msg", "导出成功"); + responseMap.put("fileName", fileName); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "导出失败,原因:" + msg); + } + return responseMap; + } +} + + diff --git a/src/main/java/com/saye/hospitalgd/controller/HisDetailController.java b/src/main/java/com/saye/hospitalgd/controller/HisDetailController.java index d779c18..928c104 100644 --- a/src/main/java/com/saye/hospitalgd/controller/HisDetailController.java +++ b/src/main/java/com/saye/hospitalgd/controller/HisDetailController.java @@ -160,12 +160,12 @@ public class HisDetailController { List> list = hisDetailService.findHisDetail(map); - // 支付方式 - 不再使用字典转换,直接显示原始值 - // List pay_type = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE"); - // HashMap peyTypeMap = new HashMap<>(); - // for (Dicinfo dicinfo : pay_type) { - // peyTypeMap.put(dicinfo.getDicvalue(), dicinfo.getDicname()); - // } + // 支付方式 + List pay_type = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE"); + HashMap payTypeMap = new HashMap<>(); + for (Dicinfo dicinfo : pay_type) { + payTypeMap.put(dicinfo.getDicvalue(), dicinfo.getDicname()); + } // 业务类型 List biz_type = dicinfoService.findDicinfoTreeNodeList("BIZ_TYPE"); @@ -196,9 +196,9 @@ public class HisDetailController { String biztype = StringDUtil.changeNullToEmpty(hashMap.get("BIZTYPE")); hashMap.put("BIZTYPE", bizTypeMap.get(biztype)); - // 支付方式 - 直接使用原始值,不进行字典转换 - // String paytype = StringDUtil.changeNullToEmpty(hashMap.get("PAYTYPE")); - // hashMap.put("PAYTYPE", peyTypeMap.get(paytype)); + // 支付方式字典转换 + String paytype = StringDUtil.changeNullToEmpty(hashMap.get("PAYTYPE")); + hashMap.put("PAYTYPE", payTypeMap.get(paytype)); } diff --git a/src/main/java/com/saye/hospitalgd/controller/MilitaryInsuranceController.java b/src/main/java/com/saye/hospitalgd/controller/MilitaryInsuranceController.java new file mode 100644 index 0000000..8244db1 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/controller/MilitaryInsuranceController.java @@ -0,0 +1,277 @@ +package com.saye.hospitalgd.controller; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.saye.hospitalgd.commons.date.DateDUtil; +import com.saye.hospitalgd.commons.excel.ExportXLSX; +import com.saye.hospitalgd.commons.excel.HashMapConversionImpl; +import com.saye.hospitalgd.commons.excel.IConversionByExport; +import com.saye.hospitalgd.commons.log.ExceptionDUtil; +import com.saye.hospitalgd.commons.log.LogUtil; +import com.saye.hospitalgd.commons.string.StringDUtil; +import com.saye.hospitalgd.model.Dicinfo; +import com.saye.hospitalgd.model.StatusDefine; +import com.saye.hospitalgd.service.HisDetailService; +import com.saye.hospitalgd.service.system.DicinfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; + +import java.io.File; +import java.math.BigDecimal; +import java.util.*; + +/** + * @author thuang + * @version 1.0 + * @description: 军保对账统计 + * @date 2024/10/16 15:00 + */ +@Api(value = "军保对账统计相关接口") +@Controller +@RequestMapping("/militaryInsurance") +public class MilitaryInsuranceController { + + @Autowired + private HisDetailService hisDetailService; + + @Autowired + private DicinfoService dicinfoService; + + @RequestMapping("/toMilitaryInsurance") + public String toMilitaryInsurance(ModelMap modelMap) { + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + + calendar.add(Calendar.DATE, -1); + Date startDate = calendar.getTime(); + + String startTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, startDate); + String endTime = DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd); + + modelMap.addAttribute("startTime", startTime); + modelMap.addAttribute("endTime", endTime); + + // 业务类型 + List biz_type = dicinfoService.findDicinfoTreeNodeList("BIZ_TYPE"); + modelMap.addAttribute("bizTypeList", biz_type); + + return "financialReconciliation/militaryInsurance"; + } + + /** + * @description: 查询军保明细记录 (paytype=3) + * @author thuang + * @date 2024/10/16 15:00 + * @version 1.0 + */ + @ApiOperation(value = "查询军保明细记录", notes = "") + @GetMapping("/findMilitaryInsuranceDetail") + @ResponseBody + public HashMap findMilitaryInsuranceDetail(@ApiParam(value = "开始时间") String startTime, + @ApiParam(value = "结束时间") String endTime, + @ApiParam(value = "模糊查询字段") String likeFiled, + @ApiParam(value = "页码") int page, + @ApiParam(value = "每页数量") int limit) { + HashMap responseMap = new HashMap<>(); + + try { + HashMap map = new HashMap(); + map.put("payType", "3"); // 固定查询paytype=3的数据 + map.put("startTime", startTime); + map.put("endTime", endTime); + map.put("likeFiled", likeFiled); + + PageHelper.startPage(page, limit); + PageInfo> pageInfo = new PageInfo>(hisDetailService.findHisDetail(map)); + + responseMap.put("code", 0); + responseMap.put("msg", "OK"); + responseMap.put("count", pageInfo.getTotal()); + responseMap.put("data", pageInfo.getList()); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + + return responseMap; + } + + /** + * @description: 查询军保记录统计数据 + * @author thuang + * @date 2024/10/16 15:00 + * @version 1.0 + */ + @RequestMapping("/findMilitaryInsuranceCountData") + @ResponseBody + @ApiOperation(value = "查询军保记录统计数据", notes = "") + public HashMap findMilitaryInsuranceCountData(@RequestBody HashMap map) { + HashMap responseMap = new HashMap(); + + String errCode = "0"; + String errMsg = ""; + + try { + // 固定查询paytype=3的数据 + map.put("payType", "3"); + + // 如果没有传递时间参数,设置默认查询今日数据 + if (map.get("startTime") == null || "".equals(map.get("startTime"))) { + map.put("startTime", DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd) + " 00:00:00"); + } + if (map.get("endTime") == null || "".equals(map.get("endTime"))) { + map.put("endTime", DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd) + " 23:59:59"); + } + + List> hisDetailCount = hisDetailService.findHisDetailCountData(map); + + if (hisDetailCount != null && hisDetailCount.size() > 0) { + responseMap.put("money", hisDetailCount.get(0).get("MONEY")); + responseMap.put("num", hisDetailCount.get(0).get("NUM")); + } else { + responseMap.put("money", "0"); + responseMap.put("num", "0"); + } + + } catch (Exception e) { + e.printStackTrace(); + errCode = "999"; + errMsg = "查询军保记录统计数据失败,原因:" + e.getMessage(); + responseMap.put("money", "0"); + responseMap.put("num", "0"); + } + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + + return responseMap; + } + + /** + * @description: 导出军保明细 + * @author thuang + * @date 2024/10/16 15:00 + * @version 1.0 + */ + @RequestMapping("/exportMilitaryInsuranceDetail") + @ResponseBody + @ApiOperation(value = "导出军保明细", notes = "") + public HashMap exportMilitaryInsuranceDetail(@RequestBody HashMap map) { + HashMap responseMap = new HashMap(); + String errCode = "0"; + String errMsg = ""; + String dlName = ""; + String fileName = ""; + + String dowloadName = StringDUtil.changeNullToEmpty(map.get("dowloadName")); + + try { + // 固定查询paytype=3的数据 + map.put("payType", "3"); + List> list = hisDetailService.findHisDetail(map); + + // 支付方式字典 + List pay_type = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE"); + HashMap payTypeMap = new HashMap<>(); + for (Dicinfo dicinfo : pay_type) { + payTypeMap.put(dicinfo.getDicvalue(), dicinfo.getDicname()); + } + + // 业务类型 + List biz_type = dicinfoService.findDicinfoTreeNodeList("BIZ_TYPE"); + HashMap bizTypeMap = new HashMap<>(); + for (Dicinfo dicinfo : biz_type) { + bizTypeMap.put(dicinfo.getDicvalue(), dicinfo.getDicname()); + } + + for (HashMap hashMap : list) { + String paymethod = StringDUtil.changeNullToEmpty(hashMap.get("PAYMETHOD")); + if ("1".equals(paymethod)) { + hashMap.put("PAYMETHOD", "门诊"); + } else if ("2".equals(paymethod)) { + hashMap.put("PAYMETHOD", "住院"); + } else { + hashMap.put("PAYMETHOD", ""); + } + + String tradingStatus = StringDUtil.changeNullToEmpty(hashMap.get("TRADINGSTATUS")); + if ("1".equals(tradingStatus)) { + hashMap.put("TRADINGSTATUS", "收款记录"); + } else if ("2".equals(tradingStatus)) { + hashMap.put("TRADINGSTATUS", "退款记录"); + } else { + hashMap.put("TRADINGSTATUS", ""); + } + + String biztype = StringDUtil.changeNullToEmpty(hashMap.get("BIZTYPE")); + hashMap.put("BIZTYPE", bizTypeMap.get(biztype)); + + // 支付方式字典转换 + String paytype = StringDUtil.changeNullToEmpty(hashMap.get("PAYTYPE")); + hashMap.put("PAYTYPE", payTypeMap.get(paytype)); + } + + if (list.size() > 0) { + // 定义标题头和文件名 + String[] DISTANCE_HEADERNAME = {"交易状态", "业务类型", "支付方式", "交易时间", "交易日期", "操作员", "总金额", "平台交易号", "his订单号", "HIS交易ID", "患者id", "患者姓名", "来源"}; + String[] sqlKey = {"TRADINGSTATUS", "BIZTYPE", "PAYTYPE", "TRADETIME", "TRADE_DATE", "HISOPERCODE", "AMOUNT", "PLATFORMTRANSID", "HISTRANSID", "HISTRANSID", "PATIENTID", "PATIENTNAME", "SOURCE"}; + + List rulList = new ArrayList(list); + + // 创建工作表 + ExportXLSX exportXLS = new ExportXLSX(DISTANCE_HEADERNAME, sqlKey, ExportXLSX.A3, false); + + exportXLS.setTitleName(dowloadName); + + IConversionByExport conversion = new HashMapConversionImpl(); + exportXLS.setConversion(conversion); + + exportXLS.setData(rulList); + + exportXLS.modifyWidthOfHeader("5000", 0); + exportXLS.modifyWidthOfHeader("5000", 1); + exportXLS.modifyWidthOfHeader("5000", 2); + exportXLS.modifyWidthOfHeader("5000", 3); + exportXLS.modifyWidthOfHeader("5000", 4); + exportXLS.modifyWidthOfHeader("5000", 5); + exportXLS.modifyWidthOfHeader("8000", 6); + exportXLS.modifyWidthOfHeader("5000", 7); + exportXLS.modifyWidthOfHeader("5000", 8); + exportXLS.modifyWidthOfHeader("5000", 9); + exportXLS.modifyWidthOfHeader("5000", 10); + exportXLS.modifyWidthOfHeader("10000", 11); + + // 文件名称 + // 产生4位长度的随机码(由字母和数字组成) + String randomStr = StringDUtil.generateRandomCodeForLength(4); + dlName = DateDUtil.DateToStr(DateDUtil.yyyyMMddHHmmss, new Date()) + randomStr; + fileName = dlName + ".xlsx"; + + String uploadPath = StatusDefine.filePath + "/MilitaryInsurance/"; + File uploadPathFile = new File(uploadPath); + if (!uploadPathFile.exists()) uploadPathFile.mkdirs(); + + String savePath = uploadPath + fileName; + exportXLS.execGenerateExcel(savePath); + } + + } catch (Exception e) { + errCode = "999"; + errMsg = "未知异常:" + ExceptionDUtil.getDetailExceptionMsg(e); + LogUtil.error(this.getClass(), "@@@系统出错!【" + errMsg + "】"); + } + + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + responseMap.put("dlName", "MilitaryInsurance/" + fileName); + return responseMap; + } + +} diff --git a/src/main/java/com/saye/hospitalgd/controller/system/FinanceUserController.java b/src/main/java/com/saye/hospitalgd/controller/system/FinanceUserController.java new file mode 100644 index 0000000..ae85ff4 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/controller/system/FinanceUserController.java @@ -0,0 +1,270 @@ +package com.saye.hospitalgd.controller.system; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.saye.hospitalgd.commons.date.DateDUtil; +import com.saye.hospitalgd.commons.string.StringDUtil; +import com.saye.hospitalgd.commons.uuid.UUIDGenerator; +import com.saye.hospitalgd.model.FinanceUser; +import com.saye.hospitalgd.service.NotifyService; +import com.saye.hospitalgd.service.system.FinanceUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 财务人员管理控制器 + * @date 2024/12/19 18:00 + */ +@Api(tags = "财务人员管理") +@Controller +@RequestMapping("/financeUser") +public class FinanceUserController { + + @Autowired + private FinanceUserService financeUserService; + + @Autowired + private NotifyService notifyService; + + /** + * @description: 到财务人员管理页面 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/toFinanceUser") + public String toFinanceUser(ModelMap modelMap) { + return "system/financeUser"; + } + + /** + * @description: 到财务人员管理测试页面 + * @author thuang + * @date 2024/12/19 18:30 + * @version 1.0 + */ + @RequestMapping("/toFinanceUserTest") + public String toFinanceUserTest(ModelMap modelMap) { + return "system/financeUser_test"; + } + + /** + * @description: 查询财务人员列表 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/findFinanceUserPageList") + @ResponseBody + @ApiOperation("查询财务人员列表") + public HashMap findFinanceUserPageList( + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "wechatName", required = false) String wechatName, + @RequestParam(value = "phone", required = false) String phone, + @RequestParam(value = "isActive", required = false) String isActive, + @RequestParam(value = "page", defaultValue = "1") int page, + @RequestParam(value = "limit", defaultValue = "20") int limit) { + + HashMap responseMap = new HashMap(); + + try { + HashMap map = new HashMap(); + map.put("name", name); + map.put("wechatName", wechatName); + map.put("phone", phone); + map.put("isActive", isActive); + + PageHelper.startPage(page, limit); + PageInfo pageInfo = new PageInfo(financeUserService.findFinanceUserPageList(map)); + + responseMap.put("code", 0); + responseMap.put("msg", "OK"); + responseMap.put("count", pageInfo.getTotal()); + responseMap.put("data", pageInfo.getList()); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 添加财务人员 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/addFinanceUser") + @ResponseBody + @ApiOperation("添加财务人员") + public HashMap addFinanceUser(@RequestBody FinanceUser financeUser) { + + HashMap responseMap = new HashMap(); + + try { + financeUser.setId(UUIDGenerator.getUUID()); + financeUser.setCreateTime(DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss)); + financeUser.setModifyTime(DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss)); + if (StringDUtil.changeNullToEmpty(financeUser.getIsActive()).equals("")) { + financeUser.setIsActive("1"); + } + + // 如果有手机号,尝试通过手机号获取OpenID + if (financeUser.getPhone() != null && !financeUser.getPhone().trim().isEmpty()) { + try { + String openId = notifyService.getUserOpenIdByPhone(financeUser.getPhone()); + financeUser.setOpenId(openId); + } catch (Exception e) { + // 获取OpenID失败不影响添加财务人员,只记录日志 + System.err.println("根据手机号获取OpenID失败: " + e.getMessage()); + } + } + + financeUserService.addFinanceUser(financeUser); + + responseMap.put("code", 0); + responseMap.put("msg", "添加成功"); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "添加失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 修改财务人员 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/updateFinanceUser") + @ResponseBody + @ApiOperation("修改财务人员") + public HashMap updateFinanceUser(@RequestBody FinanceUser financeUser) { + + HashMap responseMap = new HashMap(); + + try { + financeUser.setModifyTime(DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss)); + + // 如果有手机号,尝试通过手机号获取OpenID + if (financeUser.getPhone() != null && !financeUser.getPhone().trim().isEmpty()) { + try { + String openId = notifyService.getUserOpenIdByPhone(financeUser.getPhone()); + financeUser.setOpenId(openId); + } catch (Exception e) { + // 获取OpenID失败不影响修改财务人员,只记录日志 + System.err.println("根据手机号获取OpenID失败: " + e.getMessage()); + } + } + + financeUserService.updateFinanceUser(financeUser); + + responseMap.put("code", 0); + responseMap.put("msg", "修改成功"); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "修改失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 删除财务人员 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/deleteFinanceUser") + @ResponseBody + @ApiOperation("删除财务人员") + public HashMap deleteFinanceUser(@RequestParam("id") @ApiParam("财务人员ID") String id) { + + HashMap responseMap = new HashMap(); + + try { + financeUserService.deleteFinanceUser(id); + + responseMap.put("code", 0); + responseMap.put("msg", "删除成功"); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "删除失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 根据ID查询财务人员 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/findFinanceUserById") + @ResponseBody + @ApiOperation("根据ID查询财务人员") + public HashMap findFinanceUserById(@RequestParam("id") @ApiParam("财务人员ID") String id) { + + HashMap responseMap = new HashMap(); + + try { + FinanceUser financeUser = financeUserService.findFinanceUserById(id); + + responseMap.put("code", 0); + responseMap.put("msg", "查询成功"); + responseMap.put("data", financeUser); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } + + /** + * @description: 获取所有启用的财务人员 + * @author thuang + * @date 2024/12/19 18:00 + * @version 1.0 + */ + @RequestMapping("/findActiveFinanceUsers") + @ResponseBody + @ApiOperation("获取所有启用的财务人员") + public HashMap findActiveFinanceUsers() { + + HashMap responseMap = new HashMap(); + + try { + List financeUsers = financeUserService.findActiveFinanceUsers(); + + responseMap.put("code", 0); + responseMap.put("msg", "查询成功"); + responseMap.put("data", financeUsers); + } catch (Exception e) { + e.printStackTrace(); + String msg = e.getMessage(); + responseMap.put("code", 1); + responseMap.put("msg", "查询失败,原因:" + msg); + } + return responseMap; + } +} diff --git a/src/main/java/com/saye/hospitalgd/controller/update_dicinfo.sql b/src/main/java/com/saye/hospitalgd/controller/update_dicinfo.sql deleted file mode 100644 index 3c3fff2..0000000 --- a/src/main/java/com/saye/hospitalgd/controller/update_dicinfo.sql +++ /dev/null @@ -1,36 +0,0 @@ --- 更新HIS支付方式字典表,适配你的四种支付方式 - --- 1. 更新现有的PAY_TYPE字典值,确保与汇总统计逻辑匹配 - --- 现金支付保持为5 -UPDATE `dicinfo` SET `dicvalue` = '4' WHERE `diccode` = 'f0230cea94134322982d45544255ee8f' AND `parent_code` = 'PAY_TYPE'; - --- 微信支付改为1(扫码支付) -UPDATE `dicinfo` SET `dicname` = '微信支付', `dicvalue` = '1' WHERE `diccode` = '48c8044ee33649bcaf64181b570c1c75' AND `parent_code` = 'PAY_TYPE'; - --- 银行卡支付保持为1,但改名为扫码支付 -UPDATE `dicinfo` SET `dicname` = '扫码支付', `dicvalue` = '1' WHERE `diccode` = 'a6ef5f470ae744a4ae1571825ddb8ca5' AND `parent_code` = 'PAY_TYPE'; - --- 2. 新增聚合支付和军保支付 -INSERT INTO `dicinfo` VALUES ('juhezf001', '聚合支付', '1', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 6); -INSERT INTO `dicinfo` VALUES ('junbao001', '军保支付', '3', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 7); - --- 3. 确保字典表结构正确 --- 最终PAY_TYPE字典应该是: --- 扫码支付(包含微信、聚合) -> 1 --- 银行卡支付 -> 2 --- 军保支付 -> 3 --- 现金支付 -> 4 --- 其他 -> 5 - --- 如果需要重新整理,可以删除旧数据重新插入: -/* -DELETE FROM `dicinfo` WHERE `parent_code` = 'PAY_TYPE' AND `diccode` != 'PAY_TYPE'; - -INSERT INTO `dicinfo` VALUES ('pay_type_001', '扫码支付', '1', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 1); -INSERT INTO `dicinfo` VALUES ('pay_type_002', '银行卡支付', '2', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 2); -INSERT INTO `dicinfo` VALUES ('pay_type_003', '军保支付', '3', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 3); -INSERT INTO `dicinfo` VALUES ('pay_type_004', '现金支付', '4', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 4); -INSERT INTO `dicinfo` VALUES ('pay_type_005', '其他', '5', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 5); -*/ - diff --git a/src/main/java/com/saye/hospitalgd/controller/update_dicinfo_exact.sql b/src/main/java/com/saye/hospitalgd/controller/update_dicinfo_exact.sql deleted file mode 100644 index c24792d..0000000 --- a/src/main/java/com/saye/hospitalgd/controller/update_dicinfo_exact.sql +++ /dev/null @@ -1,24 +0,0 @@ --- 严格按照四种HIS支付方式配置字典表(用户自定义编码) --- HIS支付方式:现金、微信、聚合支付、军保支付 - --- 1. 清理现有PAY_TYPE数据(保留父节点) -DELETE FROM `dicinfo` WHERE `parent_code` = 'PAY_TYPE' AND `diccode` != 'PAY_TYPE'; - --- 2. 添加严格匹配的四种支付方式字典(用户自定义PayType编码) --- 现金 -> PayType: 5 -INSERT INTO `dicinfo` VALUES ('his_pay_001', '现金', '5', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 1); - --- 微信 -> PayType: 1 -INSERT INTO `dicinfo` VALUES ('his_pay_002', '微信', '1', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 2); - --- 聚合支付 -> PayType: 2 -INSERT INTO `dicinfo` VALUES ('his_pay_003', '聚合支付', '2', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 3); - --- 军保支付 -> PayType: 3 -INSERT INTO `dicinfo` VALUES ('his_pay_004', '军保支付', '3', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 4); - --- 其他未知支付方式 -> PayType: 4 -INSERT INTO `dicinfo` VALUES ('his_pay_005', '其他', '4', 'PAY_TYPE', '2024-01-01 00:00:00', '2024-01-01 00:00:00', 5); - --- 验证插入结果 -SELECT * FROM `dicinfo` WHERE `parent_code` = 'PAY_TYPE' ORDER BY `sort_no`; diff --git a/src/main/java/com/saye/hospitalgd/mapper/FinancialReconciliation/RefundStatisticsMapper.java b/src/main/java/com/saye/hospitalgd/mapper/FinancialReconciliation/RefundStatisticsMapper.java new file mode 100644 index 0000000..d1e8d87 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/mapper/FinancialReconciliation/RefundStatisticsMapper.java @@ -0,0 +1,42 @@ +package com.saye.hospitalgd.mapper.FinancialReconciliation; + +import org.apache.ibatis.annotations.Mapper; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 退款数据统计报表Mapper + * @date 2024/12/19 10:00 + */ +@Mapper +public interface RefundStatisticsMapper { + + /** + * 查询退款统计报表数据 + * @param map 查询参数 + * @return 退款统计数据列表 + * @throws Exception + */ + List> findRefundStatistics(HashMap map) throws Exception; + + /** + * 获取退款统计汇总数据 + * @param map 查询参数 + * @return 退款统计汇总数据 + * @throws Exception + */ + HashMap getRefundSummary(HashMap map) throws Exception; + + /** + * 获取退款趋势数据 + * @param map 查询参数 + * @return 退款趋势数据列表 + * @throws Exception + */ + List> getRefundTrend(HashMap map) throws Exception; +} + + diff --git a/src/main/java/com/saye/hospitalgd/mapper/OperatorMapper.java b/src/main/java/com/saye/hospitalgd/mapper/OperatorMapper.java index 04f1f72..f338e5b 100644 --- a/src/main/java/com/saye/hospitalgd/mapper/OperatorMapper.java +++ b/src/main/java/com/saye/hospitalgd/mapper/OperatorMapper.java @@ -18,6 +18,8 @@ public interface OperatorMapper { List> findAllOperatorByCode(HashMap map) throws Exception; + List> findMilitaryOperators(HashMap map) throws Exception; + void addOperator(HashMap map) throws Exception; void updateOperatorByCode(HashMap map) throws Exception; diff --git a/src/main/java/com/saye/hospitalgd/mapper/system/FinanceUserMapper.java b/src/main/java/com/saye/hospitalgd/mapper/system/FinanceUserMapper.java new file mode 100644 index 0000000..c27224b --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/mapper/system/FinanceUserMapper.java @@ -0,0 +1,68 @@ +package com.saye.hospitalgd.mapper.system; + +import com.saye.hospitalgd.model.FinanceUser; +import org.apache.ibatis.annotations.Mapper; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 财务人员Mapper接口 + * @date 2024/12/19 18:00 + */ +@Mapper +public interface FinanceUserMapper { + + /** + * 查询财务人员列表 + * @param map 查询参数 + * @return 财务人员列表 + */ + List findFinanceUserPageList(HashMap map); + + /** + * 添加财务人员 + * @param financeUser 财务人员信息 + */ + void addFinanceUser(FinanceUser financeUser); + + /** + * 修改财务人员 + * @param financeUser 财务人员信息 + */ + void updateFinanceUser(FinanceUser financeUser); + + /** + * 删除财务人员 + * @param id 财务人员ID + */ + void deleteFinanceUser(String id); + + /** + * 根据ID查询财务人员 + * @param id 财务人员ID + * @return 财务人员信息 + */ + FinanceUser findFinanceUserById(String id); + + /** + * 获取所有启用的财务人员 + * @return 启用的财务人员列表 + */ + List findActiveFinanceUsers(); +} + + + + + + + + + + + + + diff --git a/src/main/java/com/saye/hospitalgd/model/FinanceUser.java b/src/main/java/com/saye/hospitalgd/model/FinanceUser.java new file mode 100644 index 0000000..52fef78 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/model/FinanceUser.java @@ -0,0 +1,36 @@ +package com.saye.hospitalgd.model; + +import lombok.Data; + +/** + * @author thuang + * @version 1.0 + * @description: 财务人员实体类 + * @date 2024/12/19 18:00 + */ +@Data +public class FinanceUser { + + private String id; // 主键ID + private String name; // 姓名 + private String wechatName; // 微信名 + private String phone; // 手机号 + private String openId; // 微信OpenID + private String isActive; // 启用状态(1:启用 0:禁用) + private String createTime; // 创建时间 + private String modifyTime; // 修改时间 + private String remark; // 备注 +} + + + + + + + + + + + + + diff --git a/src/main/java/com/saye/hospitalgd/scheduler/job/BankGetData.java b/src/main/java/com/saye/hospitalgd/scheduler/job/BankGetData.java index de8c459..254527a 100644 --- a/src/main/java/com/saye/hospitalgd/scheduler/job/BankGetData.java +++ b/src/main/java/com/saye/hospitalgd/scheduler/job/BankGetData.java @@ -39,11 +39,12 @@ public class BankGetData implements Job { HashMap wlifSearchMap = new HashMap<>(); wlifSearchMap.put("FUBS", "1"); List> thirdFtpConfigList = thirdFtpConfigService.findThirdFtpConfigList(searchMap); - List> wlConfigList = thirdFtpConfigService.findWLIF(searchMap); + List> wlConfigList = thirdFtpConfigService.findWLIF(wlifSearchMap); for (int i = 0; i < thirdFtpConfigList.size(); i++) { + HashMap hashMap = thirdFtpConfigList.get(i); String execute_class = StringDUtil.changeNullToEmpty(hashMap.get("EXECUTE_CLASS")); diff --git a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/BankGetDataByWXAPI.java b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/BankGetDataByWXAPI.java index c293eef..7796fc9 100644 --- a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/BankGetDataByWXAPI.java +++ b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/BankGetDataByWXAPI.java @@ -80,6 +80,7 @@ public class BankGetDataByWXAPI { // 如果没问题 解析返回的集合 if ("0".equals(errCode)) { String list = StringDUtil.changeNullToEmpty(jsonObject.get("list")); + log.info("微信获取对账单返回数据:" + list); List bankbillHistories = JSONArray.parseArray(list, BankbillHistory.class); // 如果有数据 diff --git a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/HISGetDataMethodByJH.java b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/HISGetDataMethodByJH.java index a117fe4..f4523f0 100644 --- a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/HISGetDataMethodByJH.java +++ b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/HISGetDataMethodByJH.java @@ -75,6 +75,8 @@ public class HISGetDataMethodByJH { operatorsCodeStr=operatorsCodeStr.substring(0,operatorsCodeStr.length()-1); } + log.info("HIS获取数据定时任务【"+name+"】开始执行,操作员号:【"+operatorsCodeStr+"】,获取日期:【"+trade_date+"】"); + //全部支付方式 List pay_type = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE"); HashMap payTypeMap = new HashMap<>(); @@ -145,11 +147,29 @@ public class HISGetDataMethodByJH { for (int i = 0; i < hisBillList.size(); i++) { HashMap hisBillHashMap = hisBillList.get(i); - //先判断关键id是否为空 ,为空的这条记录就作废了,可能之后会有现金记录进入,此id仍为空,到时需要另加判断 + //获取PowerTranID和ReceiptNO作为唯一标识 String powerTranID = StringDUtil.changeNullToEmpty(hisBillHashMap.get("powerTranID")); - if ("".equals(powerTranID)){ + String receiptNO = StringDUtil.changeNullToEmpty(hisBillHashMap.get("receiptNO")); + String hisTransId = StringDUtil.changeNullToEmpty(hisBillHashMap.get("hisTransId")); + + // 修改跳过逻辑:只有当关键业务信息都缺失时才跳过 + // 检查是否有足够的业务信息来处理这条记录 + String patientId = StringDUtil.changeNullToEmpty(hisBillHashMap.get("patientID")); + String amount = StringDUtil.changeNullToEmpty(hisBillHashMap.get("amount")); + String tradeTime = StringDUtil.changeNullToEmpty(hisBillHashMap.get("tradeTime")); + + // 只有当缺少关键业务信息时才跳过(患者ID、金额、交易时间都为空) + if ("".equals(patientId) && "".equals(amount) && "".equals(tradeTime)){ + log.warn("跳过缺少关键业务信息的记录: powerTranID={}, receiptNO={}, hisTransId={}", + powerTranID, receiptNO, hisTransId); continue; } + + // 对于没有唯一标识的记录,记录警告但继续处理 + if ("".equals(powerTranID) && "".equals(receiptNO) && "".equals(hisTransId)){ + log.warn("处理无唯一标识的记录: patientID={}, amount={}, tradeTime={}", + patientId, amount, tradeTime); + } //数据类型 1-门诊 2-住院 无需修改 String payMethod = StringDUtil.changeNullToEmpty(hisBillHashMap.get("visitzOrg")); @@ -168,23 +188,17 @@ public class HISGetDataMethodByJH { String originalPayType = StringDUtil.changeNullToEmpty(hisBillHashMap.get("payType")); String payType = convertPayTypeByDictionary(originalPayType, payTypeMap); - //交易时间 - String tradeTime = StringDUtil.changeNullToEmpty(hisBillHashMap.get("tradeTime")); - //操作员 String hisOperCode = StringDUtil.changeNullToEmpty(hisBillHashMap.get("hisOperCode")); - //交易金额 - String amount = StringDUtil.changeNullToEmpty(hisBillHashMap.get("amount")); - //说明 String remarks = ""; - //银商订单号 - String platformTransId = StringDUtil.changeNullToEmpty(hisBillHashMap.get("powerTranID")); - - //患者 ID - String patientId = StringDUtil.changeNullToEmpty(hisBillHashMap.get("patientID")); + //银商订单号:优先使用PowerTranID,如果为空则使用ReceiptNO或HisTransId + String platformTransId = powerTranID; + if ("".equals(platformTransId)) { + platformTransId = "".equals(receiptNO) ? hisTransId : receiptNO; + } //患者姓名 String patientName = StringDUtil.changeNullToEmpty(hisBillHashMap.get("patientName")); diff --git a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/ReconciliationMethod.java b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/ReconciliationMethod.java index c34421f..4f510dd 100644 --- a/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/ReconciliationMethod.java +++ b/src/main/java/com/saye/hospitalgd/scheduler/jobMethod/ReconciliationMethod.java @@ -47,7 +47,7 @@ public class ReconciliationMethod { HisbillsHistoryService hisbillsHistoryService = GetBeanUtil.getBean(HisbillsHistoryServiceImpl.class); - + OperatorService operatorService = GetBeanUtil.getBean(OperatorServiceImpl.class); //记录是第几次对账 int managerNum = 0; @@ -56,6 +56,12 @@ public class ReconciliationMethod { searchMap.put("trade_date", trade_date); searchMap.put("is_ok", 1); + //查询军保操作员,用于排除军保账单 + List> militaryOperators = operatorService.findMilitaryOperators(new HashMap<>()); + if (militaryOperators != null && militaryOperators.size() > 0) { + searchMap.put("excludeMilitaryOperators", militaryOperators); + } + //先判断是否已生成 List> reconciliationLog = reconciliationLogService.findReconciliationLogByParam(searchMap); @@ -803,6 +809,22 @@ public class ReconciliationMethod { } reconciliationLogService.insertReconciliationLog(addMap); + + // 对账完成后发送消息通知 + try { + NotifyService notifyService = (NotifyService) GetBeanUtil.getBean("notifyServiceImpl"); + if (notifyService != null) { + String status = "0".equals(errCode) ? "1" : "0"; // 1:成功 0:失败 + String message = "0".equals(errCode) ? "对账完成" : errMsg; + notifyService.sendReconciliationNotify(trade_date, status, message); + System.out.println("对账通知发送完成,日期:" + trade_date + ",状态:" + ("1".equals(status) ? "成功" : "失败")); + } + } catch (Exception e) { + System.err.println("发送对账通知失败:" + e.getMessage()); + e.printStackTrace(); + // 消息推送失败不影响对账结果 + } + } catch (Exception e) { e.printStackTrace(); errCode = "999"; diff --git a/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/RefundStatisticsService.java b/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/RefundStatisticsService.java new file mode 100644 index 0000000..c77c869 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/RefundStatisticsService.java @@ -0,0 +1,47 @@ +package com.saye.hospitalgd.service.FinancialReconciliation; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 退款数据统计报表服务接口 + * @date 2024/12/19 10:00 + */ +public interface RefundStatisticsService { + + /** + * 查询退款统计报表数据 + * @param map 查询参数 + * @return 退款统计数据列表 + * @throws Exception + */ + List> findRefundStatistics(HashMap map) throws Exception; + + /** + * 获取退款统计汇总数据 + * @param map 查询参数 + * @return 退款统计汇总数据 + * @throws Exception + */ + HashMap getRefundSummary(HashMap map) throws Exception; + + /** + * 获取退款趋势数据 + * @param map 查询参数 + * @return 退款趋势数据列表 + * @throws Exception + */ + List> getRefundTrend(HashMap map) throws Exception; + + /** + * 导出退款统计报表 + * @param map 查询参数 + * @return 导出文件名 + * @throws Exception + */ + String exportRefundStatistics(HashMap map) throws Exception; +} + + diff --git a/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/impl/RefundStatisticsServiceImpl.java b/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/impl/RefundStatisticsServiceImpl.java new file mode 100644 index 0000000..bb8112b --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/FinancialReconciliation/impl/RefundStatisticsServiceImpl.java @@ -0,0 +1,92 @@ +package com.saye.hospitalgd.service.FinancialReconciliation.impl; + +import com.saye.hospitalgd.commons.excel.RefundStatisticsExportXLSX; +import com.saye.hospitalgd.commons.log.ExceptionDUtil; +import com.saye.hospitalgd.mapper.FinancialReconciliation.RefundStatisticsMapper; +import com.saye.hospitalgd.service.FinancialReconciliation.RefundStatisticsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 退款数据统计报表服务实现类 + * @date 2024/12/19 10:00 + */ +@Service +@Transactional +public class RefundStatisticsServiceImpl implements RefundStatisticsService { + + private static final Logger log = LoggerFactory.getLogger(RefundStatisticsServiceImpl.class); + + @Autowired + private RefundStatisticsMapper refundStatisticsMapper; + + @Override + public List> findRefundStatistics(HashMap map) throws Exception { + try { + return refundStatisticsMapper.findRefundStatistics(map); + } catch (Exception e) { + log.info("查询退款统计报表数据失败", e); + throw e; + } + } + + @Override + public HashMap getRefundSummary(HashMap map) throws Exception { + try { + return refundStatisticsMapper.getRefundSummary(map); + } catch (Exception e) { + log.error("获取退款统计汇总数据失败", e); + throw e; + } + } + + @Override + public List> getRefundTrend(HashMap map) throws Exception { + try { + return refundStatisticsMapper.getRefundTrend(map); + } catch (Exception e) { + log.error("获取退款趋势数据失败", e); + throw e; + } + } + + @Override + public String exportRefundStatistics(HashMap map) throws Exception { + try { + // 获取统计数据 + List> dataList = refundStatisticsMapper.findRefundStatistics(map); + + // 获取汇总数据 + HashMap summaryData = refundStatisticsMapper.getRefundSummary(map); + + // 创建导出文件 + String fileName = "退款统计报表_" + System.currentTimeMillis() + ".xlsx"; + String filePath = System.getProperty("user.dir") + File.separator + "downloadFile" + File.separator + fileName; + + // 确保目录存在 + File file = new File(filePath); + File parentDir = file.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + + // 导出Excel + RefundStatisticsExportXLSX exportXLSX = new RefundStatisticsExportXLSX(); + exportXLSX.exportRefundStatistics(dataList, summaryData, filePath); + + return fileName; + } catch (Exception e) { + log.error("导出退款统计报表失败", e); + throw e; + } + } +} diff --git a/src/main/java/com/saye/hospitalgd/service/NotifyService.java b/src/main/java/com/saye/hospitalgd/service/NotifyService.java new file mode 100644 index 0000000..a4d428c --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/NotifyService.java @@ -0,0 +1,41 @@ +package com.saye.hospitalgd.service; + +import com.saye.hospitalgd.model.FinanceUser; + +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 消息推送服务接口 + * @date 2024/12/19 18:00 + */ +public interface NotifyService { + + /** + * 发送对账完成通知 + * @param tradeDate 对账日期 + * @param status 对账状态 (1:成功 0:失败) + * @param message 对账消息 + * @throws Exception 异常 + */ + void sendReconciliationNotify(String tradeDate, String status, String message) throws Exception; + + /** + * 获取用户OpenID + * @param wechatName 微信名 + * @return OpenID + * @throws Exception 异常 + */ + String getUserOpenId(String wechatName) throws Exception; + + /** + * 根据手机号获取用户OpenID + * @param phone 手机号 + * @return OpenID + * @throws Exception 异常 + */ + String getUserOpenIdByPhone(String phone) throws Exception; +} + + diff --git a/src/main/java/com/saye/hospitalgd/service/OperatorService.java b/src/main/java/com/saye/hospitalgd/service/OperatorService.java index 1cd6f38..4fa876b 100644 --- a/src/main/java/com/saye/hospitalgd/service/OperatorService.java +++ b/src/main/java/com/saye/hospitalgd/service/OperatorService.java @@ -12,6 +12,8 @@ import java.util.List; public interface OperatorService { List> findAllOperator(HashMap map) throws Exception; + List> findMilitaryOperators(HashMap map) throws Exception; + void addOperator(HashMap map) throws Exception; void modifyOperator(HashMap map) throws Exception; diff --git a/src/main/java/com/saye/hospitalgd/service/impl/NotifyServiceImpl.java b/src/main/java/com/saye/hospitalgd/service/impl/NotifyServiceImpl.java new file mode 100644 index 0000000..9d3bd12 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/impl/NotifyServiceImpl.java @@ -0,0 +1,263 @@ +package com.saye.hospitalgd.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.saye.hospitalgd.commons.string.StringDUtil; +import com.saye.hospitalgd.model.FinanceUser; +import com.saye.hospitalgd.service.NotifyService; +import com.saye.hospitalgd.service.system.FinanceUserService; +import com.saye.hospitalgd.service.system.ServiceParamsService; +import com.saye.hospitalgd.util.HttpClientUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 消息推送服务实现类 + * @date 2024/12/19 18:00 + */ +@Service +public class NotifyServiceImpl implements NotifyService { + + private static final Logger log = LoggerFactory.getLogger(NotifyServiceImpl.class); + + @Autowired + private FinanceUserService financeUserService; + + @Autowired + private ServiceParamsService serviceParamsService; + + @Override + public void sendReconciliationNotify(String tradeDate, String status, String message) throws Exception { + try { + // 获取所有启用的财务人员 + List financeUsers = financeUserService.findActiveFinanceUsers(); + + if (financeUsers == null || financeUsers.isEmpty()) { + log.info("没有启用的财务人员,跳过消息推送"); + return; + } + + // 获取中转服务地址 + List> serviceParams = serviceParamsService.findParamValByParamCode("hgd_dmz"); + String transferUrl = StringDUtil.changeNullToEmpty(serviceParams.get(0).get("PARAM_VAL")); + if (transferUrl == null || transferUrl.trim().isEmpty()) { + log.error("未配置中转服务地址(hgd_dmz)"); + return; + } + + // 构建消息推送URL + String notifyUrl = transferUrl.endsWith("/") ? + transferUrl + "sendNotifyYJJ" : + transferUrl + "/sendNotifyYJJ"; + + // 为每个财务人员发送通知 + for (FinanceUser financeUser : financeUsers) { + if (financeUser.getOpenId() != null && !financeUser.getOpenId().trim().isEmpty()) { + sendNotifyToFinanceUser(financeUser, tradeDate, status, message, notifyUrl); + } else { + log.warn("财务人员 {} 没有OpenID,跳过消息推送", financeUser.getName()); + } + } + + } catch (Exception e) { + log.error("发送对账通知失败", e); + throw e; + } + } + + /** + * 发送通知给指定财务人员 + * @param financeUser 财务人员信息 + * @param tradeDate 对账日期 + * @param status 对账状态 + * @param message 对账消息 + * @param notifyUrl 通知URL + */ + private void sendNotifyToFinanceUser(FinanceUser financeUser, String tradeDate, String status, + String message, String notifyUrl) { + try { + // 构建通知参数 + HashMap notifyParams = new HashMap<>(); + notifyParams.put("openid", financeUser.getOpenId()); + notifyParams.put("tradeDate", tradeDate); + notifyParams.put("status", status); + notifyParams.put("message", message); + notifyParams.put("userName", financeUser.getName()); + + // 发送通知 + String response = HttpClientUtil.doPost(notifyUrl, notifyParams); + log.debug("发送对账通知响应: " + response); + + // 增加空值检查 + if (response == null || response.trim().isEmpty()) { + log.error("调用中转服务失败,返回为空,接收人: {}", financeUser.getName()); + return; + } + + JSONObject jsonResponse = JSON.parseObject(response); + // 兼容多种成功状态码格式 + Integer code = jsonResponse.getInteger("code"); + Integer errCode = jsonResponse.getInteger("errcode"); + Integer errCodeInt = jsonResponse.getInteger("errCode"); + + // 判断成功条件:code=0 或 errcode=0 或 errCode=0 或 errCode="0" + boolean isSuccess = (code != null && code == 0) || + (errCode != null && errCode == 0) || + (errCodeInt != null && errCodeInt == 0) || + "0".equals(jsonResponse.getString("errCode")); + + if (isSuccess) { + log.info("对账通知发送成功,接收人: {}", financeUser.getName()); + } else { + // 兼容多种错误消息字段:msg/errMsg + String errorMsg = jsonResponse.getString("msg"); + if (errorMsg == null || errorMsg.trim().isEmpty()) { + errorMsg = jsonResponse.getString("errMsg"); + } + log.error("对账通知发送失败,接收人: {}, 错误信息: {}", + financeUser.getName(), errorMsg); + } + + } catch (Exception e) { + log.error("发送对账通知异常,接收人: {}", financeUser.getName(), e); + } + } + + @Override + public String getUserOpenId(String wechatName) throws Exception { + try { + // 获取中转服务地址 + List> serviceParams = serviceParamsService.findParamValByParamCode("hgd_dmz"); + String transferUrl = StringDUtil.changeNullToEmpty(serviceParams.get(0).get("PARAM_VAL")); + if (transferUrl == null || transferUrl.trim().isEmpty()) { + throw new Exception("未配置中转服务地址(hgd_dmz)"); + } + + // 构建获取OpenID的URL + String openIdUrl = transferUrl.endsWith("/") ? + transferUrl + "getUserOpenId" : + transferUrl + "/getUserOpenId"; + + // 构建请求参数 + HashMap params = new HashMap<>(); + params.put("wechatName", wechatName); + + // 发送请求 + String response = HttpClientUtil.doPost(openIdUrl, params); + log.debug("获取OpenID响应: " + response); + + // 增加空值检查 + if (response == null || response.trim().isEmpty()) { + throw new Exception("调用中转服务失败,返回为空。请检查中转服务地址是否正确或网络是否可达"); + } + + JSONObject jsonResponse = JSON.parseObject(response); + // 兼容两种返回格式:code/errCode + Integer code = jsonResponse.getInteger("code"); + Integer errCode = jsonResponse.getInteger("errCode"); + + // 判断成功条件:code=0 或 errCode="0" + boolean isSuccess = (code != null && code == 0) || + (errCode != null && errCode == 0) || + "0".equals(jsonResponse.getString("errCode")); + + if (isSuccess) { + // 兼容两种数据字段:data/openid + String openId = jsonResponse.getString("data"); + if (openId == null || openId.trim().isEmpty()) { + openId = jsonResponse.getString("openid"); + } + + if (openId != null && !openId.trim().isEmpty()) { + log.info("成功获取OpenID: {} for 微信名: {}", openId, wechatName); + return openId; + } else { + throw new Exception("返回的OpenID为空"); + } + } else { + // 兼容两种错误消息字段:msg/errMsg + String errorMsg = jsonResponse.getString("msg"); + if (errorMsg == null || errorMsg.trim().isEmpty()) { + errorMsg = jsonResponse.getString("errMsg"); + } + throw new Exception("获取OpenID失败: " + errorMsg); + } + + } catch (Exception e) { + log.error("获取OpenID异常,微信名: {}", wechatName, e); + throw e; + } + } + + @Override + public String getUserOpenIdByPhone(String phone) throws Exception { + try { + // 获取中转服务地址 + List> serviceParams = serviceParamsService.findParamValByParamCode("hgd_dmz"); + String transferUrl = StringDUtil.changeNullToEmpty(serviceParams.get(0).get("PARAM_VAL")); + if (transferUrl == null || transferUrl.trim().isEmpty()) { + throw new Exception("未配置中转服务地址(hgd_dmz)"); + } + + // 构建获取OpenID的URL + String openIdUrl = transferUrl.endsWith("/") ? + transferUrl + "getUserOpenId" : + transferUrl + "/getUserOpenId"; + + + // 构建请求参数 + HashMap params = new HashMap<>(); + params.put("phone", phone); + params.put("yz", "joju@"); + + // 发送请求 + String response = HttpClientUtil.doPost(openIdUrl, params); + log.debug("根据手机号获取OpenID响应: " + response); + + // 增加空值检查 + if (response == null || response.trim().isEmpty()) { + throw new Exception("调用中转服务失败,返回为空。请检查中转服务地址是否正确或网络是否可达"); + } + + JSONObject jsonResponse = JSON.parseObject(response); + // 兼容两种返回格式:code/errCode + Integer code = jsonResponse.getInteger("code"); + Integer errCode = jsonResponse.getInteger("errCode"); + + // 判断成功条件:code=0 或 errCode="0" + boolean isSuccess = (code != null && code == 0) || + (errCode != null && errCode == 0) || + "0".equals(jsonResponse.getString("errCode")); + + if (isSuccess) { + String openId = jsonResponse.getString("openid"); + if (openId != null && !openId.trim().isEmpty()) { + log.info("成功根据手机号获取OpenID: {} for 手机号: {}", openId, phone); + return openId; + } else { + throw new Exception("返回的OpenID为空"); + } + } else { + // 兼容两种错误消息字段:msg/errMsg + String errorMsg = jsonResponse.getString("msg"); + if (errorMsg == null || errorMsg.trim().isEmpty()) { + errorMsg = jsonResponse.getString("errMsg"); + } + throw new Exception("根据手机号获取OpenID失败: " + errorMsg); + } + + } catch (Exception e) { + log.error("根据手机号获取OpenID异常,手机号: {}", phone, e); + throw e; + } + } +} + + diff --git a/src/main/java/com/saye/hospitalgd/service/impl/OperatorServiceImpl.java b/src/main/java/com/saye/hospitalgd/service/impl/OperatorServiceImpl.java index b063322..8e6ae23 100644 --- a/src/main/java/com/saye/hospitalgd/service/impl/OperatorServiceImpl.java +++ b/src/main/java/com/saye/hospitalgd/service/impl/OperatorServiceImpl.java @@ -29,6 +29,11 @@ public class OperatorServiceImpl implements OperatorService { return operatorMapper.findAllOperator(map); } + @Override + public List> findMilitaryOperators(HashMap map) throws Exception { + return operatorMapper.findMilitaryOperators(map); + } + @Override public void addOperator(HashMap map) throws Exception { String hisOperCode = StringDUtil.changeNullToEmpty(map.get("hisOperCode")); diff --git a/src/main/java/com/saye/hospitalgd/service/system/FinanceUserService.java b/src/main/java/com/saye/hospitalgd/service/system/FinanceUserService.java new file mode 100644 index 0000000..5352ba8 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/system/FinanceUserService.java @@ -0,0 +1,72 @@ +package com.saye.hospitalgd.service.system; + +import com.saye.hospitalgd.model.FinanceUser; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 财务人员服务接口 + * @date 2024/12/19 18:00 + */ +public interface FinanceUserService { + + /** + * 查询财务人员列表 + * @param map 查询参数 + * @return 财务人员列表 + * @throws Exception 异常 + */ + List findFinanceUserPageList(HashMap map) throws Exception; + + /** + * 添加财务人员 + * @param financeUser 财务人员信息 + * @throws Exception 异常 + */ + void addFinanceUser(FinanceUser financeUser) throws Exception; + + /** + * 修改财务人员 + * @param financeUser 财务人员信息 + * @throws Exception 异常 + */ + void updateFinanceUser(FinanceUser financeUser) throws Exception; + + /** + * 删除财务人员 + * @param id 财务人员ID + * @throws Exception 异常 + */ + void deleteFinanceUser(String id) throws Exception; + + /** + * 根据ID查询财务人员 + * @param id 财务人员ID + * @return 财务人员信息 + * @throws Exception 异常 + */ + FinanceUser findFinanceUserById(String id) throws Exception; + + /** + * 获取所有启用的财务人员 + * @return 启用的财务人员列表 + * @throws Exception 异常 + */ + List findActiveFinanceUsers() throws Exception; +} + + + + + + + + + + + + + diff --git a/src/main/java/com/saye/hospitalgd/service/system/impl/FinanceUserServiceImpl.java b/src/main/java/com/saye/hospitalgd/service/system/impl/FinanceUserServiceImpl.java new file mode 100644 index 0000000..df7bd22 --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/service/system/impl/FinanceUserServiceImpl.java @@ -0,0 +1,102 @@ +package com.saye.hospitalgd.service.system.impl; + +import com.saye.hospitalgd.mapper.system.FinanceUserMapper; +import com.saye.hospitalgd.model.FinanceUser; +import com.saye.hospitalgd.service.system.FinanceUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; + +/** + * @author thuang + * @version 1.0 + * @description: 财务人员服务实现类 + * @date 2024/12/19 18:00 + */ +@Service +@Transactional +public class FinanceUserServiceImpl implements FinanceUserService { + + private static final Logger log = LoggerFactory.getLogger(FinanceUserServiceImpl.class); + + @Autowired + private FinanceUserMapper financeUserMapper; + + @Override + public List findFinanceUserPageList(HashMap map) throws Exception { + try { + return financeUserMapper.findFinanceUserPageList(map); + } catch (Exception e) { + log.error("查询财务人员列表失败", e); + throw e; + } + } + + @Override + public void addFinanceUser(FinanceUser financeUser) throws Exception { + try { + financeUserMapper.addFinanceUser(financeUser); + } catch (Exception e) { + log.error("添加财务人员失败", e); + throw e; + } + } + + @Override + public void updateFinanceUser(FinanceUser financeUser) throws Exception { + try { + financeUserMapper.updateFinanceUser(financeUser); + } catch (Exception e) { + log.error("修改财务人员失败", e); + throw e; + } + } + + @Override + public void deleteFinanceUser(String id) throws Exception { + try { + financeUserMapper.deleteFinanceUser(id); + } catch (Exception e) { + log.error("删除财务人员失败", e); + throw e; + } + } + + @Override + public FinanceUser findFinanceUserById(String id) throws Exception { + try { + return financeUserMapper.findFinanceUserById(id); + } catch (Exception e) { + log.error("根据ID查询财务人员失败", e); + throw e; + } + } + + @Override + public List findActiveFinanceUsers() throws Exception { + try { + return financeUserMapper.findActiveFinanceUsers(); + } catch (Exception e) { + log.error("查询启用的财务人员失败", e); + throw e; + } + } +} + + + + + + + + + + + + + diff --git a/src/main/java/com/saye/hospitalgd/util/HttpClientUtil.java b/src/main/java/com/saye/hospitalgd/util/HttpClientUtil.java new file mode 100644 index 0000000..4f4680c --- /dev/null +++ b/src/main/java/com/saye/hospitalgd/util/HttpClientUtil.java @@ -0,0 +1,204 @@ +package com.saye.hospitalgd.util; + +import com.alibaba.fastjson.JSON; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; + +/** + * @author thuang + * @version 1.0 + * @description: HTTP客户端工具类,兼容JDK8 + * @date 2024/12/19 16:00 + */ +public class HttpClientUtil { + + private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class); + + /** + * 发送GET请求 + * @param url 请求URL + * @param headers 请求头(可为null) + * @return 响应结果 + */ + public static String doGet(String url, HashMap headers) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = null; + + try { + httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + httpGet.setHeader(key, headers.get(key)); + } + } + + response = httpClient.execute(httpGet); + + if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + result = EntityUtils.toString(entity, "UTF-8"); + } + } else { + log.error("GET请求失败,状态码: " + (response != null ? response.getStatusLine().getStatusCode() : "null")); + } + + } catch (Exception e) { + log.error("GET请求异常", e); + } finally { + try { + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + log.error("关闭HTTP连接异常", e); + } + } + + return result; + } + + /** + * 发送POST请求(JSON格式) + * @param url 请求URL + * @param data 请求数据(JSON对象) + * @return 响应结果 + */ + public static String doPost(String url, Object data) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = null; + + try { + httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("content-type", "application/json;charset=utf-8"); + + // 将数据转换为JSON字符串 + String jsonData = JSON.toJSONString(data); + StringEntity stringEntity = new StringEntity(jsonData, "UTF-8"); + stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + httpPost.setEntity(stringEntity); + + response = httpClient.execute(httpPost); + + if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + result = EntityUtils.toString(entity, "UTF-8"); + } + } else { + log.error("POST请求失败,状态码: " + (response != null ? response.getStatusLine().getStatusCode() : "null")); + } + + } catch (Exception e) { + log.error("POST请求异常", e); + } finally { + try { + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + log.error("关闭HTTP连接异常", e); + } + } + + return result; + } + + /** + * 发送POST请求(表单格式) + * @param url 请求URL + * @param params 请求参数 + * @return 响应结果 + */ + public static String doPostForm(String url, HashMap params) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = null; + + try { + httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("content-type", "application/x-www-form-urlencoded;charset=utf-8"); + + // 构建表单数据 + StringBuilder formData = new StringBuilder(); + if (params != null) { + for (String key : params.keySet()) { + if (formData.length() > 0) { + formData.append("&"); + } + formData.append(key).append("=").append(params.get(key)); + } + } + + StringEntity stringEntity = new StringEntity(formData.toString(), "UTF-8"); + httpPost.setEntity(stringEntity); + + response = httpClient.execute(httpPost); + + if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + result = EntityUtils.toString(entity, "UTF-8"); + } + } else { + log.error("POST表单请求失败,状态码: " + (response != null ? response.getStatusLine().getStatusCode() : "null")); + } + + } catch (Exception e) { + log.error("POST表单请求异常", e); + } finally { + try { + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + log.error("关闭HTTP连接异常", e); + } + } + + return result; + } +} + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/FinancialReconciliation/RefundStatisticsMapper.xml b/src/main/resources/mapper/FinancialReconciliation/RefundStatisticsMapper.xml new file mode 100644 index 0000000..16e4e0b --- /dev/null +++ b/src/main/resources/mapper/FinancialReconciliation/RefundStatisticsMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/HisDetailMapper.xml b/src/main/resources/mapper/HisDetailMapper.xml index 802656a..75b9803 100644 --- a/src/main/resources/mapper/HisDetailMapper.xml +++ b/src/main/resources/mapper/HisDetailMapper.xml @@ -190,10 +190,10 @@ and PayType = #{payType} - and TradeTime >= #{startTime} + and (TradeTime >= #{startTime} or trade_date >= #{startTime}) - and TradeTime <= #{endTime} + and (TradeTime <= #{endTime} or trade_date <= #{endTime}) and PlatformTransId like concat('%',concat(#{likeFiled},'%')) diff --git a/src/main/resources/mapper/HisbillsHistoryMapper.xml b/src/main/resources/mapper/HisbillsHistoryMapper.xml index 64a99b8..2ce2f1e 100644 --- a/src/main/resources/mapper/HisbillsHistoryMapper.xml +++ b/src/main/resources/mapper/HisbillsHistoryMapper.xml @@ -24,6 +24,12 @@ select * from hisbill_history where trade_date = #{trade_date} + + and HisOperCode not in + + #{operator.HISOPERCODE} + + + + insert into his_operator(HisOperCode, user_name, is_active, modify_time) values (#{hisOperCode}, #{userName}, #{is_active}, #{modify_time}) diff --git a/src/main/resources/mapper/TransactionDetailMapper.xml b/src/main/resources/mapper/TransactionDetailMapper.xml index 6229fd4..74ff6cc 100644 --- a/src/main/resources/mapper/TransactionDetailMapper.xml +++ b/src/main/resources/mapper/TransactionDetailMapper.xml @@ -80,6 +80,12 @@ inner join bankbill_history b on a.PlatformTransId = b.C_YSDDH where b.C_JYRQ >= #{startTime} and b.C_JYRQ <= #{endTime} + + and a.HisOperCode not in + + #{operator.HisOperCode} + + group by b.C_ZFFS, b.C_JYRQ @@ -107,10 +113,17 @@ , '' , '0' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a inner join (select * from bankbill_history where C_JYRQ = #{trade_date}) b - on a.PlatformTransId = b.C_YSDDH and a.TradingStatus = b.C_JYLX and a.Amount+0 = b.C_JYJE+0 + on a.PlatformTransId = b.C_SHDDH and a.TradingStatus = b.C_JYLX and a.Amount+0 = b.C_JYJE+0 @@ -137,11 +150,18 @@ , '1' , '1' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a left join (select * from bankbill_history where C_JYRQ = #{trade_date}) b - on a.PlatformTransId = b.C_YSDDH and a.TradingStatus = b.C_JYLX and a.Amount+0 = b.C_JYJE+0 - where b.C_YSDDH is null + on a.PlatformTransId = b.C_SHDDH and a.TradingStatus = b.C_JYLX and a.Amount+0 = b.C_JYJE+0 + where b.C_SHDDH is null @@ -168,10 +188,17 @@ , '2' , '1' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType!=#{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a right join (select * from bankbill_history where C_JYRQ = #{trade_date}) b - on a.PlatformTransId = b.C_YSDDH and a.TradingStatus = b.C_JYLX and a.Amount + 0 = b.C_JYJE + 0 + on a.PlatformTransId = b.C_SHDDH and a.TradingStatus = b.C_JYLX and a.Amount + 0 = b.C_JYJE + 0 where a.PlatformTransId is null @@ -200,7 +227,14 @@ , '' , '0' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a inner join (select * from cash_record where trade_date = #{trade_date}) b on a.HisOperCode = b.czyh @@ -231,7 +265,14 @@ , '1' , '1' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a left join (select * from cash_record where trade_date = #{trade_date}) b on a.HisOperCode = b.czyh @@ -263,7 +304,14 @@ , '2' , '1' , '1' - from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code}) a + from (select * from hisbill_history where trade_date = #{trade_date} and payType = #{cash_code} + + and HisOperCode not in + + #{operator.HisOperCode} + + + ) a right join (select * from cash_record where trade_date = #{trade_date}) b on a.HisOperCode = b.czyh diff --git a/src/main/resources/mapper/system/FinanceUserMapper.xml b/src/main/resources/mapper/system/FinanceUserMapper.xml new file mode 100644 index 0000000..906ccd3 --- /dev/null +++ b/src/main/resources/mapper/system/FinanceUserMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + INSERT INTO finance_user ( + id, + name, + wechat_name, + phone, + open_id, + is_active, + create_time, + modify_time, + remark + ) VALUES ( + #{id}, + #{name}, + #{wechatName}, + #{phone}, + #{openId}, + #{isActive}, + #{createTime}, + #{modifyTime}, + #{remark} + ) + + + + + UPDATE finance_user SET + name = #{name}, + wechat_name = #{wechatName}, + phone = #{phone}, + open_id = #{openId}, + is_active = #{isActive}, + modify_time = #{modifyTime}, + remark = #{remark} + WHERE id = #{id} + + + + + DELETE FROM finance_user WHERE id = #{id} + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/templates/financialReconciliation/hisDetail.html b/src/main/resources/templates/financialReconciliation/hisDetail.html index bfb7058..4076aa8 100644 --- a/src/main/resources/templates/financialReconciliation/hisDetail.html +++ b/src/main/resources/templates/financialReconciliation/hisDetail.html @@ -188,7 +188,18 @@ align: 'center', title: '支付方式', width: 120, - sort: false + sort: false, + templet: function (d) { + let result = ""; + for (let i = 0; i < payTypeList.length; i++) { + let obj = payTypeList[i]; + if (d.PAYTYPE === obj.dicvalue) { + result = obj.dicname; + break; + } + } + return result || d.PAYTYPE; + } }, diff --git a/src/main/resources/templates/financialReconciliation/militaryInsurance.html b/src/main/resources/templates/financialReconciliation/militaryInsurance.html new file mode 100644 index 0000000..f9ba101 --- /dev/null +++ b/src/main/resources/templates/financialReconciliation/militaryInsurance.html @@ -0,0 +1,351 @@ + + + + + 军保对账统计 + + + + + + + + + + + +
+
+
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+ + +
+
+
+ +
+
+
今日军保交易笔数
+
0
+
+
+
今日军保交易总金额
+
¥0.00
+
+
+ +
+ 军保对账统计明细 +   +
+
+
+ +
+ + + + diff --git a/src/main/resources/templates/financialReconciliation/refundStatistics.html b/src/main/resources/templates/financialReconciliation/refundStatistics.html new file mode 100644 index 0000000..fce279e --- /dev/null +++ b/src/main/resources/templates/financialReconciliation/refundStatistics.html @@ -0,0 +1,514 @@ + + + + + 退款统计报表 + + + + + + + + + + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+
退款总笔数
+
0
+
+
+
退款总金额(元)
+
0.00
+
+
+
平均退款金额(元)
+
0.00
+
+
+
涉及患者数
+
0
+
+
+
操作员数
+
0
+
+
+ + +
+
+ 退款趋势分析 +
+
+
+ + +
+
    +
  • 全部统计
  • +
  • 按日期统计
  • +
  • 按支付方式统计
  • +
  • 按退款类型统计
  • +
+
+ + +
+ 退款统计明细 +   +
+
+
+ +
+ + + + diff --git a/src/main/resources/templates/system/financeUser.html b/src/main/resources/templates/system/financeUser.html new file mode 100644 index 0000000..aea4ed5 --- /dev/null +++ b/src/main/resources/templates/system/financeUser.html @@ -0,0 +1,349 @@ + + + + + 财务人员管理 + + + + + + + + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+ 财务人员管理 +
+
+
+
+ + + + + + + diff --git a/src/main/resources/templates/system/financeUser_test.html b/src/main/resources/templates/system/financeUser_test.html new file mode 100644 index 0000000..0ad90a8 --- /dev/null +++ b/src/main/resources/templates/system/financeUser_test.html @@ -0,0 +1,69 @@ + + + + + 财务人员管理测试 + + + + + + +
+

财务人员管理功能测试

+ +
+ + +
+ +
+ 测试结果将显示在这里... +
+
+ + + + + + + + + + + + + + + + +