package com.ynxbd.common.action ;
import com.ynxbd.ali.helper.AliHelper ;
import com.ynxbd.common.action.base.BaseAction ;
import com.ynxbd.common.action.pay.PEnum ;
import com.ynxbd.common.bean.HisTransaction ;
import com.ynxbd.common.bean.enums.MerchantEnum ;
import com.ynxbd.common.bean.pay.Bill ;
import com.ynxbd.common.bean.pay.Recipe ;
import com.ynxbd.common.bean.pay.Register ;
import com.ynxbd.common.config.db.DataBase ;
import com.ynxbd.common.dao.RecipeDao ;
import com.ynxbd.common.dao.RegisterDao ;
import com.ynxbd.common.dao.his.HisAccountDao ;
import com.ynxbd.common.helper.common.AesHelper ;
import com.ynxbd.common.helper.common.DateHelper ;
import com.ynxbd.common.result.JsonResult ;
import com.ynxbd.common.result.Result ;
import com.ynxbd.common.result.ResultEnum ;
import com.ynxbd.common.result.ServiceException ;
import com.ynxbd.common.service.PayService ;
import com.ynxbd.wx.wxfactory.WxPayHelper ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.struts2.convention.annotation.Action ;
import org.apache.struts2.convention.annotation.Namespace ;
import java.util.* ;
/ * *
* @Author wsq
* @Date 2021 / 4 / 7 13 : 25
* @Copyright @ 2020 云南新八达科技有限公司 All rights reserved .
* /
@Slf4j
@Namespace ( "/accounts" )
public class AccountsAction extends BaseAction {
/ * *
* 查询对账报表
* < p >
* 注 : 预约对账因按财务要求 , 只能按就诊日期统计
* 如 : 2016年12月30号预约2017年1月5号 则这笔帐是算在2017年1月这个周期内
* 如果在就诊日期前取消预约则算在 2016年12月这个周期内
* 如 : 2017年1月4号取消预约 则2016年12月这个周期内有一笔正交易 2017年1月这个周期内有一笔负交易
* /
@Action ( "getStatement" )
public Result getStatement ( String begDate , String endDate ) {
log . info ( "[对账]查询对账报表 begDate={}, endDate={}" , begDate , endDate ) ;
if ( begDate = = null | | endDate = = null ) {
return Result . error ( ResultEnum . PARAM_IS_BLANK ) ;
}
int days = DateHelper . intervalDays ( begDate , endDate , true ) ;
if ( days > 31 | | days < 0 ) {
return Result . error ( "[对账]查询起止日期间隔不能超过31天" ) ;
}
long begTime = System . currentTimeMillis ( ) ; // 结束时间
JsonResult jsonResult = new HisAccountDao ( ) . getStatement ( begDate , endDate ) ;
if ( ! jsonResult . success ( ) ) {
return Result . error ( jsonResult . getMessage ( ) ) ;
}
List < HisTransaction > dataList = jsonResult . getDataMapList ( HisTransaction . class , "Item" ) ;
long endTime = System . currentTimeMillis ( ) ; // 结束时间
String takeTime = ( endTime - begTime ) + "ms" ; // 耗时
log . info ( "[对账]查询对账报表-耗时:[{}]" , takeTime ) ;
return Result . success ( dataList ) ;
}
/ * *
* [ HIS ] 查询交易流水
*
* @param begDate 开始日期
* @param endDate 结束日期
* @param tradeNo His交易流水号
* @param bankTransNo bankTransNo
* @param dateType 日期类型 : { 0 : 交易日期 , 1 : 就诊日期 }
* @param isContainsRefund 是否包含负交易 : { 0 : 不包含负交易 , 当使用此参数时 , 负交易对应的正交易也将不会出现 ; 1包含负交易 }
* @param isUpdateState 是否需要校验数据
* /
@Action ( "getTransaction" )
public Result getTransaction ( String begDate , String endDate , String tradeNo , String bankTransNo , Integer dateType , Integer isContainsRefund , Boolean isUpdateState ) {
if ( isUpdateState = = null ) {
isUpdateState = false ;
}
log . info ( "[对账] 查询交易流水 begDate={}, endDate={}, tradeNo={}, bankTransNo={}, dateType={}, isContainsRefund={}" , begDate , endDate , tradeNo , bankTransNo , dateType , isContainsRefund ) ;
if ( begDate = = null | | endDate = = null | | tradeNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
begDate = DateHelper . getMoveDate ( begDate , - 2 ) ;
endDate = DateHelper . getMoveDate ( endDate , 2 ) ;
// 日期参数不合法
if ( begDate = = null | | endDate = = null ) {
return Result . error ( ResultEnum . PARAM_DATE_ERROR ) ;
}
JsonResult jsonResult = new HisAccountDao ( ) . getTransaction ( begDate , endDate , tradeNo , dateType , isContainsRefund ) ;
if ( jsonResult . isTimeout ( ) ) { // 请求超时
return Result . error ( ResultEnum . INTERFACE_HIS_REQ_TIMEOUT ) ;
}
if ( ! jsonResult . success ( ) ) {
return Result . error ( ResultEnum . INTERFACE_HIS_NO_DATA , jsonResult . getMessage ( ) ) ;
}
List < HisTransaction > resultList = jsonResult . getDataMapList ( HisTransaction . class , "Item" ) ;
if ( resultList . size ( ) = = 0 ) {
return Result . error ( ResultEnum . INTERFACE_HIS_INVOKE_ERROR ) ;
}
if ( ! isUpdateState ) { // 不更新
return Result . success ( resultList ) ;
}
// 更新HisStatus状态
Map < String , Object > dataMap = new HashMap < > ( ) ;
dataMap . put ( "list" , resultList ) ;
PEnum pEnum = null ;
try {
pEnum = PEnum . getByOrderNo ( bankTransNo , tradeNo ) ;
} catch ( ServiceException e ) {
log . info ( e . getMessage ( ) ) ;
}
if ( pEnum = = null | | bankTransNo = = null ) {
return Result . success ( dataMap ) ;
}
String timePoint = DateHelper . getMoveMinute ( DateHelper . getCurDateTime ( ) , - 20 ) ;
boolean isResult = false ;
switch ( pEnum ) {
case RECIPE : // 处方
RecipeDao recipeDao = new RecipeDao ( ) ;
Recipe recipe = recipeDao . selectStatusErrOrder ( bankTransNo , tradeNo , timePoint ) ;
if ( recipe ! = null ) {
isResult = recipeDao . updateHisStatus ( bankTransNo , tradeNo , timePoint ) ;
if ( isResult ) {
log . info ( "[处方]调用HIS接口状态矫正成功" ) ;
}
}
break ;
case REG : // 挂号
RegisterDao regDao = new RegisterDao ( ) ;
Register reg = regDao . selectStatusErrOrder ( bankTransNo , tradeNo , timePoint ) ;
if ( reg ! = null ) {
isResult = regDao . updateHisStatus ( bankTransNo , tradeNo , timePoint ) ;
if ( isResult ) {
log . info ( "[挂号]调用HIS接口状态矫正成功" ) ;
}
}
break ;
case IN_HOSP : // 住院预交金
return Result . error ( ResultEnum . SYSTEM_SERVICE_CLOSE ) ;
default :
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
dataMap . put ( "isUpdate" , isResult ) ; // 是否发生修改
return Result . success ( dataMap ) ;
}
/ * *
* [ HIS ] 根据发票号查询交易流水
*
* @param invoiceNum 发票号
* @param begDate 开始日期
* @param endDate 结束日期
* @param dateType 日期类型 : { 0 : 交易日期 , 1 : 就诊日期 }
* @param isContainsRefund 是否包含负交易 : { 0 : 不包含负交易 , 当使用此参数时 , 负交易对应的正交易也将不会出现 ; 1包含负交易 }
* /
@Action ( "getTransactionByInvoiceNum" )
public Result getTransactionByInvoiceNum ( String invoiceNum , String begDate , String endDate , Integer dateType , Integer isContainsRefund ) {
log . info ( "[对账] 查询交易流水 invoiceNum={}" , invoiceNum ) ;
if ( invoiceNum = = null | | begDate = = null | | endDate = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
begDate = DateHelper . getMoveDate ( begDate , - 2 ) ;
endDate = DateHelper . getMoveDate ( endDate , 2 ) ;
// 日期参数不合法
if ( begDate = = null | | endDate = = null ) {
return Result . error ( ResultEnum . PARAM_DATE_ERROR ) ;
}
JsonResult JsonResult = new HisAccountDao ( ) . getTransactionByFPNum ( invoiceNum , begDate , endDate , dateType , isContainsRefund ) ;
if ( JsonResult . isTimeout ( ) ) { // 请求超时
return Result . error ( ResultEnum . INTERFACE_HIS_REQ_TIMEOUT ) ;
}
if ( ! JsonResult . success ( ) ) {
return Result . error ( ResultEnum . INTERFACE_HIS_NO_DATA , JsonResult . getMessage ( ) ) ;
}
List < HisTransaction > dataList = JsonResult . getDataMapList ( HisTransaction . class , "Item" ) ;
if ( dataList . size ( ) = = 0 ) {
return Result . error ( ResultEnum . INTERFACE_HIS_INVOKE_ERROR ) ;
}
return Result . success ( dataList ) ;
}
/ * *
* 查询退费详情
* /
@Action ( "getRefund" )
public Result getRefund ( String outTradeNo , String bankTransNo , String outRefundNo ) {
try {
if ( outTradeNo = = null | | outRefundNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
MerchantEnum merchantEnum = MerchantEnum . getMerchantEnumByOutTradeNo ( outTradeNo ) ;
Bill bill = PayService . queryRefund ( merchantEnum , outTradeNo , bankTransNo , outRefundNo ) ;
return bill = = null ? Result . error ( ) : Result . success ( bill ) ;
} catch ( ServiceException e ) {
return Result . error ( e ) ;
}
}
/ * *
* 查询退费订单集
*
* @param outTradeNo 订单号
* @return 订单信息
* /
@Action ( "getRefundList" )
public Result getRefundList ( String outTradeNo ) {
try {
if ( outTradeNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
List < Bill > billList = WxPayHelper . queryRefundList ( outTradeNo ) ;
return Result . success ( billList ) ;
} catch ( ServiceException e ) {
return Result . error ( e ) ;
}
}
/ * *
* 查询退费订单集 ( 含退费时间 )
*
* @param outTradeNo 订单号
* @return 订单信息
* /
@Action ( "queryRefundInfoList" )
public Result queryRefundInfoList ( String outTradeNo ) {
try {
if ( outTradeNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
List < Bill > billList = WxPayHelper . queryRefundInfoList ( outTradeNo ) ;
return Result . success ( billList ) ;
} catch ( ServiceException e ) {
return Result . error ( e ) ;
}
}
/ * *
* [ 查询账单 ] 供给第三方调用
*
* @param billDate 账单日期
* @param billType 账单类型
* @param callNo 调用码
* @param isCompose 是否组合订单
* @param isIncludeHis 是否包含HIS订单
* /
@Action ( "getBill" )
public Result getBill ( String billDate , String billType , String callNo , Boolean isCompose , Boolean isIncludeHis ) {
log . info ( "[查询账单] date={}, billType={}, callNo={}, isIncludeHis={}" , billDate , billType , callNo , isIncludeHis ) ;
if ( billType = = null | | billDate = = null | | callNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
if ( ! DateHelper . isValidDate ( billDate , DateHelper . DateEnum . yyyy_MM_dd ) ) {
return Result . error ( ResultEnum . PARAM_DATE_ERROR ) ;
}
if ( DateHelper . isToday ( billDate ) ) {
return Result . error ( ResultEnum . DATE_IS_TODAY ) ;
}
if ( billDate . equals ( DateHelper . getMoveDate ( new Date ( ) , - 1 ) )
& & ! DateHelper . isCurTimeOver ( "10:10:00" ) ) {
return Result . error ( "查询前一天的数据,需在今天10点10分之后" ) ;
}
if ( isIncludeHis = = null ) {
isIncludeHis = true ;
}
if ( isCompose = = null ) {
isCompose = false ;
}
if ( ! WxPayHelper . ALL . equals ( billType ) & & ! WxPayHelper . REFUND . equals ( billType ) & & ! WxPayHelper . SUCCESS . equals ( billType ) ) {
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
MerchantEnum merchantEnum = MerchantEnum . getMerchantEnumByCode ( callNo ) ;
if ( merchantEnum = = null ) {
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
List < Bill > billList ;
try {
switch ( merchantEnum ) {
case WX :
billList = WxPayHelper . queryBill ( billType , billDate , isCompose ) ;
break ;
case ALI :
billList = AliHelper . queryBill ( billType , billDate , isCompose ) ;
break ;
default :
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
} catch ( ServiceException e ) {
return Result . error ( e ) ;
}
if ( ! isIncludeHis ) {
return Result . success ( billList ) ;
}
String nextDate = DateHelper . getMoveDate ( billDate , - 1 ) ;
String type = " and length(openid) " + ( merchantEnum . equals ( MerchantEnum . WX ) ? "> 26 " : "< 26 " ) ;
List < Bill > recipeList = DataBase . select ( "select outTradeNo, bankTransNo, tradeNo as hisTradeNo, payMoney as money from pay where updateTime between ? and DATE_ADD(?,INTERVAL 1 DAY) and outTradeNo is not null and outTradeNo != '' " + type , Bill . class , ps - > {
ps . setString ( 1 , nextDate + " 23:45" ) ;
ps . setString ( 2 , billDate + " 00:15" ) ;
} ) ;
List < Register > regList = DataBase . select ( "select outTradeNo, bankTransNo, tradeNo, payMoney, regType, refundResult from register where updateTime between ? and DATE_ADD(?,INTERVAL 1 DAY) and outTradeNo is not null and outTradeNo != '' " + type , Register . class , ps - > {
ps . setString ( 1 , nextDate + " 23:45" ) ;
ps . setString ( 2 , billDate + " 00:15" ) ;
} ) ;
boolean isBreak ;
Bill addBill ;
String outTradeNo , bankTransNo , tradeNo ;
int tradeNoLen ;
for ( Bill bill : billList ) {
isBreak = false ;
outTradeNo = bill . getOutTradeNo ( ) ;
bill . setHisBills ( new ArrayList < > ( ) ) ;
for ( Register regItem : regList ) {
if ( outTradeNo . equals ( regItem . getOutTradeNo ( ) ) ) {
addBill = new Bill ( ) ;
tradeNo = regItem . getTradeNo ( ) ;
bankTransNo = regItem . getBankTransNo ( ) ;
if ( ( "1" . equals ( regItem . getRegType ( ) ) | | "3" . equals ( regItem . getRegType ( ) ) ) & & "OK" . equals ( regItem . getRefundResult ( ) ) ) {
tradeNoLen = tradeNo . length ( ) ;
if ( ( ( bankTransNo . length ( ) + 4 ) = = tradeNoLen ) & & tradeNoLen > 24 & & bankTransNo . equals ( tradeNo . substring ( 0 , tradeNoLen - 4 ) ) ) {
addBill . setHisNegTradeNo ( "R" + tradeNo ) ;
}
}
addBill . setHisTradeNo ( tradeNo ) ;
addBill . setMoney ( regItem . getPayMoney ( ) ) ;
bill . getHisBills ( ) . add ( addBill ) ;
isBreak = true ;
}
}
if ( ! isBreak ) {
for ( Bill item : recipeList ) {
if ( outTradeNo . equals ( item . getOutTradeNo ( ) ) ) {
addBill = new Bill ( ) ;
addBill . setMoney ( item . getMoney ( ) ) ;
addBill . setHisTradeNo ( item . getHisTradeNo ( ) ) ;
bill . getHisBills ( ) . add ( addBill ) ;
}
}
}
}
return Result . success ( billList ) ;
}
/ * *
* [ 查询账单 ] 供微官网对账使用
*
* @param billDate 账单日期
* @param billType 账单类型
* @param callNo 调用码
* @param key 调用key
* /
@Action ( "downBillData" )
public Result downBillData ( String billDate , String billType , String callNo , String key ) {
log . info ( "[查询账单] date={}, billType={}, callNo={}, sys={}" , billDate , billType , callNo , key ) ;
if ( billType = = null | | billDate = = null | | callNo = = null ) {
return Result . error ( ResultEnum . PARAM_IS_DEFECT ) ;
}
if ( ! DateHelper . getCurDate ( ) . equals ( AesHelper . deCode ( key ) ) ) {
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
if ( ! DateHelper . isValidDate ( billDate , DateHelper . DateEnum . yyyy_MM_dd ) ) {
return Result . error ( ResultEnum . PARAM_DATE_ERROR ) ;
}
if ( DateHelper . isToday ( billDate ) ) {
return Result . error ( ResultEnum . DATE_IS_TODAY ) ;
}
if ( billDate . equals ( DateHelper . getMoveDate ( new Date ( ) , - 1 ) )
& & ! DateHelper . isCurTimeOver ( "10:10:00" ) ) {
return Result . error ( "查询前一天的数据,需在今天10点10分之后" ) ;
}
if ( ! WxPayHelper . ALL . equals ( billType ) & & ! WxPayHelper . REFUND . equals ( billType ) & & ! WxPayHelper . SUCCESS . equals ( billType ) ) {
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
MerchantEnum merchantEnum = MerchantEnum . getMerchantEnumByCode ( callNo ) ;
if ( merchantEnum = = null ) {
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
String data ;
try {
switch ( merchantEnum ) {
case WX :
data = WxPayHelper . downWxBillData ( billType , billDate ) ;
break ;
case ALI :
data = AliHelper . downAliBillData ( billType , billDate ) ;
break ;
default :
return Result . error ( ResultEnum . PARAM_IS_INVALID ) ;
}
} catch ( ServiceException e ) {
return Result . error ( e ) ;
}
return Result . success ( data ) ;
}
}