update:医保对账

This commit is contained in:
Yuan
2025-10-27 08:49:28 +08:00
parent 94e8850a40
commit 3e9a25dd38
32 changed files with 2134 additions and 38 deletions

View File

@@ -7,6 +7,7 @@
<result column="QUARTZ_GROUP" property="quartzGroup" jdbcType="VARCHAR" />
<result column="STATUS" property="status" jdbcType="VARCHAR" />
<result column="QUARTZ_CLASS" property="quartzClass" jdbcType="VARCHAR" />
<result column="QUARTZ_TYPE" property="quartzType" jdbcType="VARCHAR" />
<result column="REMARK" property="remark" jdbcType="VARCHAR" />
<result column="CREATEUSERID" property="createUserId" jdbcType="VARCHAR" />
<result column="EXPRESSION" property="expression" jdbcType="VARCHAR" />
@@ -16,12 +17,15 @@
<!-- 查询所有任务 -->
<select id="findAll" parameterType="HashMap" resultMap="BaseResultMap">
select bqc.CONFIGID,bqc.QUARTZ_NAME,bqc.QUARTZ_GROUP,bqc.STATUS,bqc.QUARTZ_CLASS,bqc.REMARK,bqc.CREATEUSERID,bqc.EXPRESSION,bqc.CREATE_TIME from base_quartz_config bqc
select bqc.CONFIGID,bqc.QUARTZ_NAME,bqc.QUARTZ_GROUP,bqc.STATUS,bqc.QUARTZ_CLASS,bqc.QUARTZ_TYPE,bqc.REMARK,bqc.CREATEUSERID,bqc.EXPRESSION,bqc.CREATE_TIME from base_quartz_config bqc
<where>
<if test="part_name!=null and part_name!=''">
<if test="quartz_name!=null and quartz_name!=''">
and bqc.QUARTZ_NAME like concat('%',concat(#{quartz_name},'%'))
</if>
<if test="part_type!=null and part_type!=''">
<if test="quartz_type!=null and quartz_type!=''">
and bqc.QUARTZ_TYPE = #{quartz_type}
</if>
<if test="configId!=null and configId!=''">
and bqc.CONFIGID = #{configId}
</if>
</where>
@@ -30,14 +34,14 @@
<!-- 根据id查询定时任务 -->
<select id="findEntityById" resultMap="BaseResultMap">
select CONFIGID,QUARTZ_NAME,QUARTZ_GROUP,STATUS,QUARTZ_CLASS,REMARK,CREATEUSERID,EXPRESSION,CREATE_TIME from base_quartz_config
select CONFIGID,QUARTZ_NAME,QUARTZ_GROUP,STATUS,QUARTZ_CLASS,QUARTZ_TYPE,REMARK,CREATEUSERID,EXPRESSION,CREATE_TIME from base_quartz_config
where CONFIGID=#{id}
</select>
<!-- 更新定时任务 -->
<update id="updateQuartzConfigByEntity" parameterType="com.saye.hospitalgd.model.BaseQuartzConfigEntity">
update base_quartz_config set QUARTZ_NAME=#{quartzName},QUARTZ_GROUP=#{quartzGroup},STATUS=#{status},QUARTZ_CLASS=#{quartzClass}
,REMARK=#{remark},CREATEUSERID=#{createUserId},EXPRESSION=#{expression}
,QUARTZ_TYPE=#{quartzType},REMARK=#{remark},CREATEUSERID=#{createUserId},EXPRESSION=#{expression}
where CONFIGID=#{configId}
</update>
@@ -53,14 +57,14 @@
<!-- 添加定时任务 -->
<insert id="addQuartz" parameterType="hashMap">
insert into base_quartz_config(configid, quartz_name, status, quartz_class, remark, createuserid, expression, create_time)
values(#{id},#{quartzName},#{status}, #{quartz_class}, #{remark}, #{createuserid}, #{expression}, #{create_time} )
insert into base_quartz_config(configid, quartz_name, status, quartz_class, quartz_type, remark, createuserid, expression, create_time)
values(#{id},#{quartzName},#{status}, #{quartz_class}, #{quartz_type}, #{remark}, #{createuserid}, #{expression}, #{create_time} )
</insert>
<!-- 更新定时任务信息 -->
<update id="updateQuartzConfigById">
update base_quartz_config set QUARTZ_NAME=#{quartzName},QUARTZ_GROUP=#{quartzGroup},QUARTZ_CLASS=#{quartzClass}
,REMARK=#{remark},EXPRESSION=#{expression}
,QUARTZ_TYPE=#{quartzType},REMARK=#{remark},EXPRESSION=#{expression}
where CONFIGID=#{configId}
</update>

View File

@@ -17,6 +17,10 @@
,trade_date
,his_wsdl_id
,HisTransId
,clr_type
,insutype
,ybzhAmount
,ybtcAmount
from hisbill_history
<where>
<if test="payType!=null and payType!=''">
@@ -97,24 +101,25 @@
<insert id="insertAllHisBillOriginalHY" parameterType="java.util.List">
insert into
hisbill_original_hy(VisitzOrg,BizType,PayType,Amount,ZFAmount,YBZHAmount,YBTCAmount,Receipt_no,PatientID,PatientName,TradeTime,HisTime,HisOperNum,PowerTranID,trade_date)
hisbill_original_hy(VisitzOrg,BizType,PayType,Amount,ZFAmount,YBZHAmount,YBTCAmount,Receipt_no,PatientID,PatientName,TradeTime,HisTime,HisOperNum,PowerTranID,trade_date,clr_type,insutype)
values
<foreach collection="list" index="index" item="itm" separator=",">
(
#{itm.visitzOrg},#{itm.bizType},#{itm.payType},#{itm.amount},#{itm.zfAmount},#{itm.ybzhAmount},#{itm.ybtcAmount},
#{itm.receiptNO},#{itm.patientID},#{itm.patientName},#{itm.tradeTime},#{itm.hisTime},#{itm.hisOperNum},#{itm.powerTranID},#{itm.trade_date}
#{itm.receiptNO},#{itm.patientID},#{itm.patientName},#{itm.tradeTime},#{itm.hisTime},#{itm.hisOperNum},#{itm.powerTranID},#{itm.trade_date},
#{itm.clrType},#{itm.insutype}
)
</foreach>
</insert>
<insert id="insertAllHisBillHistory" parameterType="java.util.List">
insert into
hisbill_history(PayMethod,TradingStatus,BizType,PayType,TradeTime,HisOperCode,Amount,remarks,PlatformTransId,PatientId,PatientName,trade_date,his_wsdl_id,HisTransId)
hisbill_history(PayMethod,TradingStatus,BizType,PayType,TradeTime,HisOperCode,Amount,remarks,PlatformTransId,PatientId,PatientName,trade_date,his_wsdl_id,HisTransId,clr_type,insutype,ybzhAmount,ybtcAmount)
values
<foreach collection="list" index="index" item="itm" separator=",">
(
#{itm.payMethod},#{itm.tradingStatus},#{itm.bizType},#{itm.payType},#{itm.tradeTime},#{itm.hisOperCode},#{itm.amount},#{itm.remarks},#{itm.platformTransId},#{itm.patientId}
,#{itm.patientName},#{itm.trade_date},#{itm.his_wsdl_id},#{itm.hisTransId}
,#{itm.patientName},#{itm.trade_date},#{itm.his_wsdl_id},#{itm.hisTransId},#{itm.clrType},#{itm.insutype},#{itm.ybzhAmount},#{itm.ybtcAmount}
)
</foreach>
</insert>
@@ -147,6 +152,10 @@
,trade_date
,his_wsdl_id
,HisTransId
,clr_type
,insutype
,ybzhAmount
,ybtcAmount
from hisbill_history
where trade_date=#{trade_date}
<if test="payType!=null and payType!=''">
@@ -162,7 +171,7 @@
<select id="findHisDetailByTimeAndYSDDH" parameterType="HashMap" resultType="HashMap">
select PayMethod,TradingStatus,BizType,PayType,TradeTime,HisOperCode,Amount,remarks,PlatformTransId,
PatientId,PatientName,HisTransId
PatientId,PatientName,HisTransId,clr_type,insutype,ybzhAmount,ybtcAmount
from hisbill_history
where trade_date=#{searchTime}
and PlatformTransId = #{c_ysddh}
@@ -177,7 +186,7 @@
</select>
<select id="findHisCashDetail" parameterType="HashMap" resultType="HashMap">
select PayMethod, TradingStatus, BizType, PayType, TradeTime, HisOperCode, Amount, remarks, PlatformTransId, PatientId, PatientName, trade_date, his_wsdl_id, HisTransId
select PayMethod, TradingStatus, BizType, PayType, TradeTime, HisOperCode, Amount, remarks, PlatformTransId, PatientId, PatientName, trade_date, his_wsdl_id, HisTransId, clr_type, insutype, ybzhAmount, ybtcAmount
from hisbill_history
where trade_date=#{trade_date} and PayType='5'
</select>
@@ -200,4 +209,23 @@
</if>
</where>
</select>
<!-- 医保对账按险种和清算类别分组统计不限制PayType -->
<select id="findMedicalInsuranceGroupData" parameterType="HashMap" resultType="HashMap">
select
insutype as INSUTYPE,
clr_type as CLR_TYPE,
count(1) as FIXMEDINS_SETL_CNT,
cast(IFNULL(sum(Amount),0) as decimal(19,2)) as MEDFEE_SUMAMT,
cast(IFNULL(sum(ybtcAmount),0) as decimal(19,2)) as FUND_PAY_SUMAMT,
cast(IFNULL(sum(ybzhAmount),0) as decimal(19,2)) as ACCT_PAY
from hisbill_history
where trade_date = #{trade_date}
and insutype is not null
and insutype != ''
and clr_type is not null
and clr_type != ''
group by insutype, clr_type
order by insutype, clr_type
</select>
</mapper>

View File

@@ -27,6 +27,9 @@
<if test="military_code != null and military_code != ''">
and PayType != #{military_code}
</if>
<if test="medical_insurance_code != null and medical_insurance_code != ''">
and PayType != #{medical_insurance_code}
</if>
</select>
<select id="findHisDetailByParam" parameterType="HashMap" resultType="HashMap">

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.saye.hospitalgd.mapper.MedicalInsuranceReconciliationMapper">
<!-- ResultMap for proper field mapping -->
<resultMap id="MedicalInsuranceResultMap" type="HashMap">
<result column="id" property="id" jdbcType="VARCHAR"/>
<result column="trade_date" property="trade_date" jdbcType="VARCHAR"/>
<result column="insutype" property="insutype" jdbcType="VARCHAR"/>
<result column="clr_type" property="clr_type" jdbcType="VARCHAR"/>
<result column="medfee_sumamt" property="medfee_sumamt" jdbcType="DECIMAL"/>
<result column="fund_pay_sumamt" property="fund_pay_sumamt" jdbcType="DECIMAL"/>
<result column="acct_pay" property="acct_pay" jdbcType="DECIMAL"/>
<result column="fixmedins_setl_cnt" property="fixmedins_setl_cnt" jdbcType="INTEGER"/>
<result column="stmt_rslt" property="stmt_rslt" jdbcType="VARCHAR"/>
<result column="stmt_rslt_dscr" property="stmt_rslt_dscr" jdbcType="VARCHAR"/>
<result column="api_result" property="api_result" jdbcType="VARCHAR"/>
<result column="create_time" property="create_time" jdbcType="VARCHAR"/>
<result column="modify_time" property="modify_time" jdbcType="VARCHAR"/>
</resultMap>
<!-- 插入医保对账结果 -->
<insert id="insertMedicalInsuranceReconciliationResult" parameterType="HashMap">
insert into medical_insurance_reconciliation_result (
id, trade_date, insutype, clr_type,
medfee_sumamt, fund_pay_sumamt, acct_pay, fixmedins_setl_cnt,
stmt_rslt, stmt_rslt_dscr, api_result,
create_time, modify_time
) values (
#{id}, #{trade_date}, #{insutype}, #{clr_type},
#{medfee_sumamt}, #{fund_pay_sumamt}, #{acct_pay}, #{fixmedins_setl_cnt},
#{stmt_rslt}, #{stmt_rslt_dscr}, #{api_result},
#{create_time}, #{modify_time}
)
</insert>
<!-- 批量插入医保对账结果 -->
<insert id="insertMedicalInsuranceReconciliationResultBatch" parameterType="java.util.List">
insert into medical_insurance_reconciliation_result (
id, trade_date, insutype, clr_type,
medfee_sumamt, fund_pay_sumamt, acct_pay, fixmedins_setl_cnt,
stmt_rslt, stmt_rslt_dscr, api_result,
create_time, modify_time
) values
<foreach collection="list" index="index" item="itm" separator=",">
(
#{itm.id}, #{itm.trade_date}, #{itm.insutype}, #{itm.clr_type},
#{itm.medfee_sumamt}, #{itm.fund_pay_sumamt}, #{itm.acct_pay}, #{itm.fixmedins_setl_cnt},
#{itm.stmt_rslt}, #{itm.stmt_rslt_dscr}, #{itm.api_result},
#{itm.create_time}, #{itm.modify_time}
)
</foreach>
</insert>
<!-- 查询医保对账结果 -->
<select id="findMedicalInsuranceReconciliationResult" parameterType="HashMap" resultMap="MedicalInsuranceResultMap">
select
id,
trade_date,
insutype,
clr_type,
medfee_sumamt,
fund_pay_sumamt,
acct_pay,
fixmedins_setl_cnt,
stmt_rslt,
stmt_rslt_dscr,
api_result,
DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') as create_time,
DATE_FORMAT(modify_time, '%Y-%m-%d %H:%i:%s') as modify_time
from medical_insurance_reconciliation_result
<where>
<if test="trade_date != null and trade_date != ''">
and trade_date = #{trade_date}
</if>
<if test="startDate != null and startDate != ''">
and trade_date &gt;= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
and trade_date &lt;= #{endDate}
</if>
<if test="insutype != null and insutype != ''">
and insutype = #{insutype}
</if>
<if test="clr_type != null and clr_type != ''">
and clr_type = #{clr_type}
</if>
<if test="clrType != null and clrType != ''">
and clr_type = #{clrType}
</if>
<if test="stmt_rslt != null and stmt_rslt != ''">
and stmt_rslt = #{stmt_rslt}
</if>
<if test="stmtRslt != null and stmtRslt != ''">
and stmt_rslt = #{stmtRslt}
</if>
</where>
order by create_time desc, trade_date desc, insutype, clr_type
</select>
<!-- 删除医保对账结果 -->
<delete id="deleteMedicalInsuranceReconciliationResult" parameterType="HashMap">
delete from medical_insurance_reconciliation_result
where trade_date = #{trade_date}
</delete>
</mapper>

View File

@@ -0,0 +1,476 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>医保对账结果查询</title>
<link rel="stylesheet" th:href="@{/layui/css/layui.css}">
<link rel="stylesheet" th:href="@{/css/common.css}">
<!-- 引入组件库 -->
<script th:src="@{/layui/jquery-3.4.1.min.js}"></script>
<script th:src="@{/layui/layui.js}"></script>
<script th:src="@{/js/common.js}"></script>
<style>
body {
background: #f2f2f2
}
#boxDiv {
background: #ffffff
}
#titleDiv {
overflow: visible;
}
.content {
padding: 0 8px;
}
.tableTitle {
height: 20px;
margin-top: 10px;
margin-bottom: 10px;
}
.tableTitle > * {
height: 20px;
line-height: 20px;
display: inline-block;
margin-right: 5px;
}
.tableName {
border-left: 3px solid #0000FF;
padding-left: 5px;
font-size: 16px;
font-weight: bold;
}
.selectDate {
font-size: 14px;
color: rgba(0, 0, 0, 0.65)
}
</style>
</head>
<body class="layui-layout-body">
<div id="boxDiv" style="left:8px;right: 8px;bottom:8px;top:8px;position:absolute;">
<div class="toolbar" id="titleDiv">
<div style="display: inline-block;">
<form class="layui-form">
<div class="layui-inline">
<label class="layui-form-label">日期选择</label>
<div class="layui-input-inline">
<input type="text" class="layui-input formWidthTwo" id="searchDate" placeholder=" ~ ">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">险种类型</label>
<div class="layui-input-inline">
<select id="insutype" class="layui-input formWidth">
<option value="">全部</option>
<option value="310">职工基本医疗保险</option>
<option value="390">城乡居民基本医疗保险</option>
<option value="510">公务员医疗补助</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">清算类别</label>
<div class="layui-input-inline">
<select id="clrType" class="layui-input formWidth">
<option value="">全部</option>
<option value="11">普通门诊</option>
<option value="21">住院</option>
<option value="31">门诊慢特病</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">对账结果</label>
<div class="layui-input-inline">
<select id="stmtRslt" class="layui-input formWidth">
<option value="">全部</option>
<option value="0"></option>
<option value="1">不平</option>
</select>
</div>
</div>
</form>
</div>
<div class="layui-inline">
<button class="layui-btn layui-btn-sm layui-btn-normal" data-type="search" id="search" onclick="search()">
<i class="layui-icon layui-icon-search"></i>查询
</button>
<button class="layui-btn layui-btn-sm layui-btn-warm" onclick="executeReconciliation()">
<i class="layui-icon layui-icon-refresh"></i>执行对账
</button>
<button class="layui-btn layui-btn-sm layui-btn-normal" onclick="exportExcel()">
<i class="layui-icon">&#xe67d;</i>导出
</button>
</div>
</div>
<div class="content">
<div class="tableTitle">
<span class="tableName">医保对账结果</span>
<span class="selectDate">&nbsp;</span>
</div>
<table id="demo" lay-filter="test"></table>
</div>
</div>
<!-- 详情弹窗 -->
<div id="detailDialog" style="display:none; padding: 20px;">
<table class="layui-table" lay-skin="line">
<tbody>
<tr>
<td style="width: 150px; font-weight: bold;">对账日期</td>
<td id="detail_trade_date"></td>
</tr>
<tr>
<td style="font-weight: bold;">险种类型</td>
<td id="detail_insutype"></td>
</tr>
<tr>
<td style="font-weight: bold;">清算类别</td>
<td id="detail_clr_type"></td>
</tr>
<tr>
<td style="font-weight: bold;">医疗费用总额</td>
<td id="detail_medfee_sumamt"></td>
</tr>
<tr>
<td style="font-weight: bold;">基金支付总额</td>
<td id="detail_fund_pay_sumamt"></td>
</tr>
<tr>
<td style="font-weight: bold;">账户支付金额</td>
<td id="detail_acct_pay"></td>
</tr>
<tr>
<td style="font-weight: bold;">结算笔数</td>
<td id="detail_fixmedins_setl_cnt"></td>
</tr>
<tr>
<td style="font-weight: bold;">对账结果</td>
<td id="detail_stmt_rslt"></td>
</tr>
<tr>
<td style="font-weight: bold;">对账结果描述</td>
<td id="detail_stmt_rslt_dscr"></td>
</tr>
<tr>
<td style="font-weight: bold;">接口调用结果</td>
<td id="detail_api_result"></td>
</tr>
<tr>
<td style="font-weight: bold;">创建时间</td>
<td id="detail_create_time"></td>
</tr>
</tbody>
</table>
</div>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="getInfo">详细信息</a>
</script>
</body>
<script th:inline="javascript">
let layer, laydate, table, form;
layui.use(['element', 'table', 'laydate', 'layer', 'form'], function () {
layer = layui.layer;
table = layui.table;
laydate = layui.laydate;
form = layui.form;
//表格加载
table.render({
elem: '#demo',
height: 'full-' + ($(".toolbar").height() + 60),
url: '/medicalInsuranceReconciliation/findMedicalInsuranceReconciliationResult',
title: '医保对账结果记录',
page: true,//开启分页
limit: 20,
limits: [20, 30, 50],
defaultToolbar: [],
id: 'test',
even: 'true',
cols: [
[
{type: 'numbers', title: '序号', width: 60},
{field: 'trade_date', title: '对账日期', align: 'center', width: 120},
{field: 'insutype', title: '险种类型', align: 'center', width: 100, templet: function(d){
if(d.insutype === '310') return '职工医保';
if(d.insutype === '390') return '居民医保';
if(d.insutype === '510') return '公务员补助';
return d.insutype;
}},
{field: 'clr_type', title: '清算类别', align: 'center', width: 100, templet: function(d){
if(d.clr_type === '11') return '普通门诊';
if(d.clr_type === '21') return '住院';
if(d.clr_type === '31') return '门诊慢特病';
return d.clr_type;
}},
{field: 'medfee_sumamt', title: '医疗费用总额', align: 'center', width: 130},
{field: 'fund_pay_sumamt', title: '基金支付总额', align: 'center', width: 130},
{field: 'acct_pay', title: '账户支付金额', align: 'center', width: 130},
{field: 'fixmedins_setl_cnt', title: '结算笔数', align: 'center', width: 100},
{field: 'stmt_rslt', title: '对账结果', align: 'center', width: 100, templet: function(d){
if(d.stmt_rslt === '0') {
return '<span style="color: green;">平</span>';
} else if(d.stmt_rslt === '1') {
return '<span style="color: red;">不平</span>';
} else {
return '<span style="color: orange;">异常</span>';
}
}},
{field: 'create_time', title: '创建时间', align: 'center', width: 160},
{title: '操作', align: 'center', width: 120, toolbar: '#barDemo', fixed: 'right'},
]
],
done: function (res, curr, count) {
// 表格加载完成后的回调
}
});
//时间控件
laydate.render({
elem: '#searchDate',
type: 'date',
range: '~',
done: function(value, date, endDate) {
console.log("laydate选择完成:", value); // 调试日志
}
});
// 表格工具栏事件
table.on('tool(test)', function (obj) {
let data = obj.data;
if (obj.event === 'getInfo') {
showDetail(data);
}
});
// 初始化:设置默认日期为前一天
let yesterday = getYesterdayDate();
console.log("初始化前一天日期:", yesterday); // 调试日志
// 直接设置日期值
$("#searchDate").val(yesterday + " ~ " + yesterday);
// 确保DOM更新后再查询
setTimeout(function() {
let currentVal = $("#searchDate").val();
console.log("延迟执行查询,当前日期输入框值:", currentVal);
// 如果日期设置失败,强制设置
if (!currentVal || currentVal.indexOf("~") === -1) {
console.log("日期设置失败,强制重新设置");
$("#searchDate").val(yesterday + " ~ " + yesterday);
}
search();
}, 200);
});
// 查询
function search(num) {
num = num === null ? 1 : num;
let url = "/medicalInsuranceReconciliation/findMedicalInsuranceReconciliationResult";
let param = {};
let date = $("#searchDate").val();
console.log("搜索日期:", date); // 调试日志
if (date !== '' && date.indexOf("~") > -1) {
let time = date.split("~");
let startDate = time[0].trim();
let endDate = time[1].trim();
param.startDate = startDate;
param.endDate = endDate;
console.log("日期参数:", param); // 调试日志
$(".selectDate").text(startDate + " ~ " + endDate);
} else if (date !== '' && date.indexOf("~") === -1) {
// 如果只有一个日期,设置为当天
param.startDate = date.trim();
param.endDate = date.trim();
console.log("单日期参数:", param); // 调试日志
$(".selectDate").text(date + " ~ " + date);
} else {
// 如果没有日期,默认使用前一天
let yesterday = getYesterdayDate();
param.startDate = yesterday;
param.endDate = yesterday;
console.log("默认前一天参数:", param); // 调试日志
$(".selectDate").text(yesterday + " ~ " + yesterday);
// 同时更新输入框
$("#searchDate").val(yesterday + " ~ " + yesterday);
}
// 确保至少有日期参数,防止查询所有数据
if (!param.startDate || !param.endDate) {
let yesterday = getYesterdayDate();
param.startDate = yesterday;
param.endDate = yesterday;
console.log("强制设置前一天参数:", param); // 调试日志
}
let insutype = $("#insutype").val();
if (insutype !== '') {
param.insutype = insutype;
}
let clrType = $("#clrType").val();
if (clrType !== '') {
param.clrType = clrType;
}
let stmtRslt = $("#stmtRslt").val();
if (stmtRslt !== '') {
param.stmtRslt = stmtRslt;
}
table.reload('test', {
method: 'get',
url: url,
where: param,
page: {
curr: num
}
});
}
// 执行医保对账
function executeReconciliation() {
layer.prompt({
title: '请输入对账日期',
formType: 0,
value: getCurrentDate(),
btn: ['确定', '取消']
}, function(value, index, elem){
layer.close(index);
let load = layer.load(1, {shade: [0.3, '#000']});
$.ajax({
url: '/medicalInsuranceReconciliation/executeMedicalInsuranceReconciliation',
type: 'POST',
data: {
trade_date: value
},
success: function(data) {
layer.close(load);
if(data.code === 0) {
layer.msg('对账执行成功!', {icon: 1, time: 2000}, function(){
search();
});
} else {
layer.alert('对账执行失败:' + data.msg, {icon: 2});
}
},
error: function() {
layer.close(load);
layer.alert('对账执行失败,请检查网络连接!', {icon: 2});
}
});
});
}
// 显示详情
function showDetail(data) {
$("#detail_trade_date").text(data.trade_date || '-');
let insutypeText = data.insutype;
if(data.insutype === '310') insutypeText = '310-职工基本医疗保险';
if(data.insutype === '390') insutypeText = '390-城乡居民基本医疗保险';
if(data.insutype === '510') insutypeText = '510-公务员医疗补助';
$("#detail_insutype").text(insutypeText || '-');
let clrTypeText = data.clr_type;
if(data.clr_type === '11') clrTypeText = '11-普通门诊';
if(data.clr_type === '21') clrTypeText = '21-住院';
if(data.clr_type === '31') clrTypeText = '31-门诊慢特病';
$("#detail_clr_type").text(clrTypeText || '-');
$("#detail_medfee_sumamt").text(data.medfee_sumamt || '0.00');
$("#detail_fund_pay_sumamt").text(data.fund_pay_sumamt || '0.00');
$("#detail_acct_pay").text(data.acct_pay || '0.00');
$("#detail_fixmedins_setl_cnt").text(data.fixmedins_setl_cnt || '0');
let stmtRsltText = data.stmt_rslt === '0' ? '平' : (data.stmt_rslt === '1' ? '不平' : '异常');
$("#detail_stmt_rslt").html('<span style="color: ' + (data.stmt_rslt === '0' ? 'green' : 'red') + ';">' + stmtRsltText + '</span>');
$("#detail_stmt_rslt_dscr").text(data.stmt_rslt_dscr || '-');
$("#detail_api_result").text(data.api_result || '-');
$("#detail_create_time").text(data.create_time || '-');
layer.open({
type: 1,
title: '医保对账详细信息',
shade: 0.3,
area: ['600px', '600px'],
content: $("#detailDialog")
});
}
// 导出
function exportExcel() {
let url = "/medicalInsuranceReconciliation/exportMedicalInsuranceReconciliationResult";
let param = {};
let date = $("#searchDate").val();
if (date !== '') {
let time = date.split("~");
param.startDate = time[0].trim();
param.endDate = time[1].trim();
}
param.insutype = $("#insutype").val();
param.clrType = $("#clrType").val();
param.stmtRslt = $("#stmtRslt").val();
let dowloadName = "医保对账结果";
param.dowloadName = dowloadName;
let load = layer.load();
AjaxPostJson(url, param, function (data) {
layer.close(load);
if (data.errCode === "0") {
let fileName = data.dlName;
location.href = '/download?fileName=' + fileName + '&dowloadName=' + dowloadName;
} else {
layer.alert(data.errMsg);
}
});
}
// 获取当前日期格式yyyy-MM-dd
function getCurrentDate() {
let date = new Date();
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0');
let day = String(date.getDate()).padStart(2, '0');
return year + '-' + month + '-' + day;
}
// 获取前一天日期格式yyyy-MM-dd
function getYesterdayDate() {
let date = new Date();
date.setDate(date.getDate() - 1); // 减一天
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0');
let day = String(date.getDate()).padStart(2, '0');
return year + '-' + month + '-' + day;
}
</script>
</html>

View File

@@ -0,0 +1,510 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>定时任务管理</title>
<link rel="stylesheet" th:href="@{/layui/css/layui.css}">
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/layui/jquery-3.4.1.min.js}"></script>
<script th:src="@{/layui/layui.js}"></script>
<script th:src="@{/js/common.js}"></script>
<script th:src="@{/js/rules.js}"></script>
<style>
body {
background: #f2f2f2
}
#boxDiv {
background: #ffffff
}
#titleDiv {
overflow: visible;
}
.content {
padding: 0 8px;
}
</style>
</head>
<body class="layui-layout-body">
<div id="boxDiv" style="left:8px;right: 8px;bottom:8px;top:8px;position:absolute;">
<div class="toolbar" id="titleDiv">
<div class="layui-inline">
<span>任务名称:</span>
<input type="text" id="searchName" placeholder="任务名称关键字" autocomplete="off" class="layui-input formWidth"/>
</div>
<div class="layui-inline">
<span>任务类型:</span>
<select id="searchType" class="layui-input formWidth">
<option value="">全部</option>
<option value="1">对账任务</option>
<option value="2">数据同步</option>
<option value="3">其他任务</option>
</select>
</div>
<div class="layui-inline">
<button class="layui-btn layui-btn-sm layui-btn-normal" data-type="search" id="search">
<i class="layui-icon">&#xe615;</i>查询
</button>
<button class="layui-btn layui-btn-sm layui-btn-normal" data-type="add" id="add">
<i class="layui-icon">&#xe654;</i>添加
</button>
<button class="layui-btn layui-btn-sm layui-btn-warm" onclick="refreshJobList()">
<i class="layui-icon layui-icon-refresh"></i>刷新任务状态
</button>
</div>
</div>
<table id="mainTable" lay-filter="quartzTable"></table>
<!-- 表格操作栏 -->
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
{{# if(d.status === '0'){ }}
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="start">启动</a>
{{# } else { }}
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="pause">暂停</a>
{{# } }}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
<!-- 状态列模板 -->
<script type="text/html" id="statusTpl">
{{# if(d.status === '0'){ }}
<span style="color: #FF5722;">已暂停</span>
{{# } else { }}
<span style="color: #5FB878;">运行中</span>
{{# } }}
</script>
<!-- 新增/编辑任务弹窗 -->
<div id="addQuartz" style="display:none;">
<form class="layui-form" style="margin-top:20px; padding-right: 20px;" lay-filter="quartzForm">
<input type="hidden" id="configId" name="configId"/>
<div class="layui-form-item">
<label class="layui-form-label">任务名称:</label>
<div class="layui-input-block">
<input type="text" id="quartzName" name="quartzName" required lay-verify="required"
autocomplete="off" placeholder="请输入任务名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">任务类型:</label>
<div class="layui-input-block">
<select id="jobType" name="jobType" lay-verify="required">
<option value="">请选择任务类型</option>
<option value="1">对账任务</option>
<option value="2">数据同步</option>
<option value="3">其他任务</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">任务类:</label>
<div class="layui-input-block">
<input type="text" id="quartz_class" name="quartz_class" required lay-verify="required"
autocomplete="off" placeholder="例如: com.saye.hospitalgd.scheduler.job.XXXJob"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">执行时间:</label>
<div class="layui-input-block">
<input type="radio" name="timeType" value="cron" title="Cron表达式" checked>
<input type="radio" name="timeType" value="simple" title="简单配置">
</div>
</div>
<div class="layui-form-item" id="cronDiv">
<label class="layui-form-label">Cron表达式:</label>
<div class="layui-input-block">
<input type="text" id="cronExpression" name="cronExpression"
autocomplete="off" placeholder="例如: 0 0 2 * * ? (每天凌晨2点执行)"
class="layui-input">
<div class="layui-form-mid layui-word-aux">
<a href="javascript:void(0);" onclick="showCronHelp()">Cron表达式帮助</a>
</div>
</div>
</div>
<div class="layui-form-item layui-hide" id="simpleDiv">
<label class="layui-form-label">执行频率:</label>
<div class="layui-input-inline" style="width: 80px;">
<input type="number" id="intervalValue" name="intervalValue" value="1"
autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline" style="width: 120px;">
<select id="intervalUnit" name="intervalUnit">
<option value="hour">小时</option>
<option value="day" selected></option>
<option value="week"></option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block">
<textarea id="remark" name="remark" placeholder="请输入任务备注说明"
class="layui-textarea"></textarea>
</div>
</div>
</form>
</div>
<!-- Cron帮助弹窗 -->
<div id="cronHelp" style="display:none; padding: 20px;">
<div style="line-height: 1.8;">
<p><strong>Cron表达式格式</strong>秒 分 时 日 月 周 [年]</p>
<p><strong>常用示例:</strong></p>
<ul style="list-style: disc; padding-left: 30px;">
<li><code>0 0 2 * * ?</code> - 每天凌晨2点执行</li>
<li><code>0 0 0/1 * * ?</code> - 每小时执行一次</li>
<li><code>0 0 12 * * ?</code> - 每天中午12点执行</li>
<li><code>0 0 1 1 * ?</code> - 每月1号凌晨1点执行</li>
<li><code>0 0 23 ? * MON-FRI</code> - 周一到周五晚上11点执行</li>
<li><code>0 0/30 * * * ?</code> - 每30分钟执行一次</li>
</ul>
<p><strong>特殊字符说明:</strong></p>
<ul style="list-style: disc; padding-left: 30px;">
<li><code>*</code> - 任意值</li>
<li><code>?</code> - 不指定值(用于日和周)</li>
<li><code>-</code> - 范围例如10-12</li>
<li><code>,</code> - 多个值例如MON,WED,FRI</li>
<li><code>/</code> - 递增例如0/15表示从0开始每15单位</li>
</ul>
</div>
</div>
</div>
</body>
<script>
let element, table, laydate, layer, form;
let isEditMode = false;
layui.use(['element', 'table', 'laydate', 'layer', 'form'], function () {
element = layui.element;
table = layui.table;
laydate = layui.laydate;
layer = layui.layer;
form = layui.form;
//表格加载
table.render({
elem: '#mainTable',
height: 'full-' + 58,
url: '/quartzConfig/findQuartzConfig',
title: '定时任务表',
page: true,//开启分页
limit: 20,
limits: [20, 30, 50],
defaultToolbar: [],
id: 'quartzTable',
cols: [
[
{type: 'numbers', title: '序号', width: 60},
{field: 'quartzName', title: '任务名称', width: 200},
{field: 'quartzClass', title: '任务类', minWidth: 300},
{field: 'quartzType', title: '任务类型', width: 100, templet: function (d) {
if (d.quartzType === '1') return '对账任务';
if (d.quartzType === '2') return '数据同步';
if (d.quartzType === '3') return '其他任务';
return d.quartzType || '-';
}},
{field: 'expression', title: 'Cron表达式', width: 150},
{field: 'status', title: '状态', width: 100, align: 'center', templet: '#statusTpl'},
{field: 'createTime', title: '创建时间', width: 160},
{fixed: 'right', title: '操作', align: 'center', width: 200, toolbar: '#barDemo'}
]
]
});
// 查询
$("#search").on('click', function () {
search();
});
// 新增
$("#add").on('click', function () {
isEditMode = false;
form.val('quartzForm', {
configId: '',
quartzName: '',
jobType: '',
quartz_class: '',
cronExpression: '0 0 2 * * ?',
intervalValue: '1',
intervalUnit: 'day',
remark: ''
});
layer.open({
type: 1,
title: "新增定时任务",
shade: 0.3,
area: ['600px', '90%'],
offset: 'auto',
content: $("#addQuartz"),
btn: ['保存', '取消'],
btnAlign: 'c',
success: function () {
form.render();
},
yes: function (index, layero) {
saveQuartz(index);
},
btn2: function () {
}
});
});
// 表格操作事件
table.on('tool(quartzTable)', function (obj) {
let data = obj.data;
if (obj.event === 'edit') {
editQuartz(data);
} else if (obj.event === 'start') {
changeStatus(data.id, '1');
} else if (obj.event === 'pause') {
changeStatus(data.id, '0');
} else if (obj.event === 'del') {
deleteQuartz(data.id);
}
});
// 监听时间类型切换
form.on('radio(timeType)', function (data) {
if (data.value === 'cron') {
$('#cronDiv').removeClass('layui-hide');
$('#simpleDiv').addClass('layui-hide');
} else {
$('#cronDiv').addClass('layui-hide');
$('#simpleDiv').removeClass('layui-hide');
}
});
// 初始查询
search();
});
// 查询
function search() {
let quartzName = $("#searchName").val();
let quartzType = $("#searchType").val();
table.reload('quartzTable', {
method: 'get',
url: '/quartzConfig/findQuartzConfig',
where: {
quartz_name: quartzName,
quartz_type: quartzType
},
page: {
curr: 1
}
});
}
// 编辑任务
function editQuartz(data) {
isEditMode = true;
form.val('quartzForm', {
configId: data.id,
quartzName: data.quartzName,
jobType: data.quartzType,
quartz_class: data.quartzClass,
cronExpression: data.expression,
remark: data.remark
});
layer.open({
type: 1,
title: "编辑定时任务",
shade: 0.3,
area: ['600px', '90%'],
offset: 'auto',
content: $("#addQuartz"),
btn: ['保存', '取消'],
btnAlign: 'c',
success: function () {
form.render();
},
yes: function (index, layero) {
saveQuartz(index);
},
btn2: function () {
}
});
}
// 保存任务
function saveQuartz(index) {
let quartzName = $("#quartzName").val();
let jobType = $("#jobType").val();
let quartzClass = $("#quartz_class").val();
let remark = $("#remark").val();
let configId = $("#configId").val();
if (!quartzName) {
layer.msg('请输入任务名称', {icon: 2});
return;
}
if (!jobType) {
layer.msg('请选择任务类型', {icon: 2});
return;
}
if (!quartzClass) {
layer.msg('请输入任务类', {icon: 2});
return;
}
// 获取cron表达式
let timeType = $("input[name='timeType']:checked").val();
let cronExpression = '';
if (timeType === 'cron') {
cronExpression = $("#cronExpression").val();
if (!cronExpression) {
layer.msg('请输入Cron表达式', {icon: 2});
return;
}
} else {
// 简单配置转换为cron表达式
let intervalValue = $("#intervalValue").val();
let intervalUnit = $("#intervalUnit").val();
if (intervalUnit === 'hour') {
cronExpression = '0 0 0/' + intervalValue + ' * * ?';
} else if (intervalUnit === 'day') {
cronExpression = '0 0 2 */' + intervalValue + ' * ?';
} else if (intervalUnit === 'week') {
cronExpression = '0 0 2 ? * MON/' + intervalValue;
}
}
let url = isEditMode ? '/quartzConfig/modifyQuartz' : '/quartzConfig/addNewQuartz';
let param = {
quartzName: quartzName,
jobType: jobType,
quartz_class: quartzClass,
time: cronExpression,
remark: remark
};
if (isEditMode) {
param.configId = configId;
}
let load = layer.load();
AjaxPostJson(url, param, function (data) {
layer.close(load);
if (data.errCode === "0") {
layer.msg('保存成功', {icon: 1, time: 1000}, function () {
layer.close(index);
search();
});
} else {
layer.alert(data.errMsg || '保存失败', {icon: 2});
}
});
}
// 修改状态
function changeStatus(configId, status) {
let statusText = status === '1' ? '启动' : '暂停';
layer.confirm('确定要' + statusText + '该任务吗?', {title: statusText + '任务'}, function (index) {
let url = '/quartzConfig/changestatus';
let param = {
configId: configId,
status: status
};
let load = layer.load();
AjaxPostJson(url, param, function (data) {
layer.close(load);
layer.close(index);
if (data.errCode === "0") {
layer.msg(statusText + '成功', {icon: 1, time: 1000}, function () {
search();
});
} else {
layer.alert(data.errMsg || statusText + '失败', {icon: 2});
}
});
});
}
// 删除任务
function deleteQuartz(configId) {
layer.confirm('确定删除该定时任务吗?删除后将无法恢复!', {title: '删除任务'}, function (index) {
let url = '/quartzConfig/deleteQuartz';
let param = {
configId: configId
};
let load = layer.load();
AjaxPostJson(url, param, function (data) {
layer.close(load);
layer.close(index);
if (data.errCode === "0") {
layer.msg('删除成功', {icon: 1, time: 1000}, function () {
search();
});
} else {
layer.alert(data.errMsg || '删除失败', {icon: 2});
}
});
});
}
// 刷新任务列表
function refreshJobList() {
let load = layer.load(1, {shade: [0.3, '#000']});
$.ajax({
url: '/quartzConfig/get_all_jobs',
type: 'POST',
dataType: 'json',
success: function (data) {
layer.close(load);
if (data.quartzJobsVOList) {
layer.msg('刷新成功,当前运行中的任务数:' + data.quartzJobsVOList.length, {icon: 1});
search();
} else {
layer.msg('刷新成功', {icon: 1});
search();
}
},
error: function () {
layer.close(load);
layer.alert('刷新失败,请检查网络连接!', {icon: 2});
}
});
}
// 显示Cron帮助
function showCronHelp() {
layer.open({
type: 1,
title: 'Cron表达式帮助',
shade: 0.3,
area: ['600px', '500px'],
content: $("#cronHelp")
});
}
</script>
</html>