package thyyxxk.webserver.service.medicalinsurance;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.envionment.MedinsurConfig;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.Capacity;
import thyyxxk.webserver.constants.Message;
import thyyxxk.webserver.constants.YesOrNo;
import thyyxxk.webserver.constants.frntsheet.CaseClassification;
import thyyxxk.webserver.constants.sidicts.*;
import thyyxxk.webserver.dao.his.medicalinsurance.SiLogDao;
import thyyxxk.webserver.dao.his.medicalinsurance.SiManageDao;
import thyyxxk.webserver.dao.his.medicalinsurance.SiSetlinfoDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.CodeName;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.ZyInactpatient;
import thyyxxk.webserver.entity.medicalinsurance.log.SiLog;
import thyyxxk.webserver.entity.medicalinsurance.manage.AtoRcvTrd;
import thyyxxk.webserver.entity.medicalinsurance.manage.CatalogueContrast;
import thyyxxk.webserver.entity.medicalinsurance.manage.InsSetlDetlChkRslt;
import thyyxxk.webserver.entity.medicalinsurance.manage.InstSetlLdgChkBrf;
import thyyxxk.webserver.entity.medicalinsurance.manage.InstStlLdgChk;
import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.ClinicDiseinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.ClinicRegistration;
import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.ClinicRxinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.EmergencyOprninfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.EmergencyRescueinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.deptmanage.DeptInfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.deptmanage.DeptInfoQuery;
import thyyxxk.webserver.entity.medicalinsurance.manage.deptmanage.MedStaffQuery;
import thyyxxk.webserver.entity.medicalinsurance.manage.detailanalyse.*;
import thyyxxk.webserver.entity.medicalinsurance.manage.examination.BilgItemInfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.frontsheet.Baseinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.frontsheet.BriefSheet;
import thyyxxk.webserver.entity.medicalinsurance.manage.frontsheet.Diseinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.frontsheet.Icuinfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.frontsheet.Oprninfo;
import thyyxxk.webserver.entity.medicalinsurance.manage.orderinfo.ActOrder;
import thyyxxk.webserver.entity.medicalinsurance.manage.setllist.SetllistQualityControlInquiry;
import thyyxxk.webserver.entity.medicalinsurance.manage.setllist.SetllistQuantityCountInquiry;
import thyyxxk.webserver.entity.medicalinsurance.setlinfo.SiSetlinfo;
import thyyxxk.webserver.entity.medicalinsurance.setlinfo.SlctSetlPrm;
import thyyxxk.webserver.http.websocket.SocketV2;
import thyyxxk.webserver.http.websocket.dto.WebSocketByUserCode;
import thyyxxk.webserver.service.hutoolcache.DeptCache;
import thyyxxk.webserver.service.hutoolcache.RegionCache;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.utils.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * @description: 医保管理服务，包涵项目对照等
 * @author: DingJie
 * @create: 2021/6/2914:44
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SiManageService {
    private static final String RESULT_CODE = "infcode";
    private static final String ERROR_MESSAGE = "err_msg";
    private static final String OUTPUT = "output";
    private final ExecService exec;
    private final SiUploadService upldServcie;
    private final SiDownloadService dldService;
    private final SiManageDao dao;
    private final SiSetlinfoDao setlinfoDao;
    private final SiLogDao logDao;
    private final RegionCache regionCache;
    private final DeptCache deptCache;
    private final UserCache userCache;
    private final SocketV2 intergrationPlatformSocket;
    private final MedinsurConfig cfg;

    public ResultVo<String> uploadCatalogueContrast(CatalogueContrast prm) {
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_CATALOGUE_CONTRAST);
        JSONArray data = new JSONArray();
        setListType(prm);
        List<String> codes = new ArrayList<>();
        prm.getList().forEach(item -> {
            codes.add(item.getCode());
            JSONObject catalogue = new JSONObject();
            catalogue.put("fixmedins_hilist_id", item.getCode());
            catalogue.put("fixmedins_hilist_name", item.getName());
            catalogue.put("list_type", prm.getListType());
            catalogue.put("med_list_codg", item.getNationalCode());
            catalogue.put("begndate", DateUtil.formatDatetime(prm.getBeginDate()));
            catalogue.put("enddate", DateUtil.formatDatetime(prm.getEndDate()));
            data.add(catalogue);
        });
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_CATALOGUE_CONTRAST);
        if (null == result) {
            return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
        }
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            dao.updateUploadedFlag(prm.getTable(), YesOrNo.YES.getCode(), codes);
            return ResultVoUtil.success("上传目录对照成功。");
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<String> revokeCatalogueContrast(CatalogueContrast prm) {
        setListType(prm);
        JSONObject input = exec.makeTradeHeader(SiFunction.REVOKE_CATALOGUE_CONTRAST);
        JSONObject data = new JSONObject();
        data.put("fixmedins_code", cfg.getHospId());
        data.put("fixmedins_hilist_id", prm.getChargeCode());
        data.put("list_type", prm.getListType());
        data.put("med_list_codg", prm.getNationalCode());
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_CATALOGUE_CONTRAST);
        if (null == result) {
            return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
        }
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            dao.updateUploadedFlag2(prm.getTable(), prm.getChargeCode());
            return ResultVoUtil.success("撤销目录对照成功。");
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    private void setListType(CatalogueContrast prm) {
        String table = "yp_zd_dict";
        switch (prm.getType()) {
            case 1:
                prm.setListType(ListType.WEST_PATENT.getCode());
                break;
            case 2:
                prm.setListType(ListType.HERBAL.getCode());
                break;
            case 3:
                prm.setListType(ListType.SERVICE.getCode());
                table = "zd_charge_item";
                break;
            case 4:
                prm.setListType(ListType.SUPPLY.getCode());
                table = "zd_charge_item";
                break;
        }
        prm.setTable(table);
    }

    public ResultVo<String> autoRecoveryTrade(AtoRcvTrd atoRcvTrd) {
        String userId = TokenUtil.getInstance().getTokenUserId();
        Integer recoveryTradePermission = dao.recoveryTradePermission(userId);
        if (null == recoveryTradePermission || recoveryTradePermission == 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有冲正交易的权限！");
        }
        JSONObject input = exec.makeTradeHeader(SiFunction.AUTO_RECOVERY_TRADE);
        String ref = JSONObject.toJSONString(atoRcvTrd);
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.AUTO_RECOVERY_TRADE);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, atoRcvTrd.getPsnNo()));
        return SiUtil.makeReturnWithoutOutput(result, "冲正成功。");
    }

    private String getAreaStmt() {
        String hospArea = cfg.getHospArea();
        if (null == hospArea || hospArea.length() < 4) {
            throw new BizException(ExceptionEnum.INVALID_PARAM, "请先配置医疗机构医保区划！");
        }
        String areaHeader = hospArea.substring(0, 2);
        return  "'" + areaHeader + "%'";
    }

    public ResultVo<String> institutionSettlementLedgerCheck(InstStlLdgChk instStlLdgChk) {
        String areaStmt = getAreaStmt();
        String startdate = DateUtil.getDayStartTime(instStlLdgChk.getStmtBegndate());
        String enddate = DateUtil.getDayEndTime(instStlLdgChk.getStmtEnddate());
        String acctStatement = instStlLdgChk.getAcctPayFlag() == 1 ? "(fund_pay_sumamt+acct_pay)!=0" : "fund_pay_sumamt!=0";
        String acctStatement2 = instStlLdgChk.getAcctPayFlag() == 1 ? "(fund_pay+psn_acct_pay)!=0" : "fund_pay!=0";

        List<InstSetlLdgChkBrf> setlBrfs = instStlLdgChk.getMode() == 1 ?
                dao.selectSetlChkBrfsWithInsutype(instStlLdgChk.getClrType(), instStlLdgChk.getInsutype(),
                        instStlLdgChk.getSetlOptins(), startdate, enddate, acctStatement, areaStmt) :
                dao.selectSetlinfoBrfsForHisCheck(instStlLdgChk.getClrType(), startdate, enddate);
        if (instStlLdgChk.getMode() == 1 && ClrType.mzClrType(instStlLdgChk.getClrType())) {
            setlBrfs.addAll(dao.selectYbydzfSetlChkBrfs(instStlLdgChk.getClrType(), instStlLdgChk.getInsutype(),
                    instStlLdgChk.getSetlOptins(), startdate, enddate, acctStatement2, areaStmt));
        }

        fillInstStlLdgChk(instStlLdgChk, setlBrfs);

        if (instStlLdgChk.getMode() == 2) {
            if (instStlLdgChk.getClrType().equals("11")) {
                List<String> mzVisitIds = dao.selectHisMzBrfsForHisCheck(startdate, enddate);
                List<String> unfoundTempList = new ArrayList<>();
                for (InstSetlLdgChkBrf setl : setlBrfs) {
                    if (!mzVisitIds.contains(setl.getVisitId())) {
                        unfoundTempList.add(setl.getVisitId());
                    }
                }
                if (unfoundTempList.isEmpty()) {
                    return ResultVoUtil.success("对账结果：平。对账结果说明：结算笔数：" + setlBrfs.size());
                }
                int offset = 0;
                for (String visitId : unfoundTempList) {
                    String[] arr = visitId.split("_");
                    if (dao.mzDepositCount(arr[0], arr[1]) == 0) {
                        log.info("not found visitId: {}", visitId);
                        offset += 1;
                    }
                }
                if (offset == 0) {
                    return ResultVoUtil.success("对账结果：平。对账结果说明：结算笔数：" + setlBrfs.size());
                }
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
                        "对账结果：不平。对账结果说明：有" + offset + "条医保结算没有找到对应的HIS门诊收费。");
            }

            List<InstSetlLdgChkBrf> hisBrfs = dao.selectHisZyBrfsForHisCheck(startdate, enddate);
            if (hisBrfs.size() != setlBrfs.size()) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
                        "对账结果：不平。对账结果说明：医保结算笔数：" + setlBrfs.size() + "；HIS结算笔数：" + hisBrfs.size());
            }

            return ResultVoUtil.success("对账结果：平。对账结果说明：结算笔数：" + hisBrfs.size() +
                                        "，医疗费总额：" + instStlLdgChk.getMedfeeSumamt() + "，基金支付总额：" + instStlLdgChk.getFundPaySumamt());

        }

        if (null != instStlLdgChk.getAcctPayFlag() && instStlLdgChk.getAcctPayFlag() == 2) {
            instStlLdgChk.setAcctPay(BigDecimal.ZERO);
        }
        JSONObject input = exec.makeTradeHeader(SiFunction.INSTITUTION_SETTLEMENT_LEDGER_CHECK);
        String ref = JSONObject.toJSONStringWithDateFormat(instStlLdgChk, "yyyy-MM-dd");
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.INSTITUTION_SETTLEMENT_LEDGER_CHECK);
        if (null == result) {
            return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
        }
        if (null == result.getInteger(RESULT_CODE)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (result.getIntValue(RESULT_CODE) == 0) {
            JSONObject output = result.getJSONObject(OUTPUT);
            JSONObject info = output.getJSONObject("stmtinfo");
            String setlOptins = info.getString("setl_optins");
            Admdvs admdvs = Admdvs.get(setlOptins);
            String optins;
            if (null == admdvs) {
                optins = regionCache.get(setlOptins);
            } else {
                optins = admdvs.getName();
            }
            String rslt;
            if (info.getString("stmt_rslt").equals(StmtRslt.CORRECT.getCode())) {
                rslt = StmtRslt.CORRECT.getName();
            } else {
                rslt = StmtRslt.WRONG.getName();
            }
            String dscr = info.getString("stmt_rslt_dscr");
            if (StringUtil.isBlank(dscr)) {
                dscr = "结算笔数：" + setlBrfs.size() +
                       "，医疗费总额：" + instStlLdgChk.getMedfeeSumamt() + "，基金支付总额：" + instStlLdgChk.getFundPaySumamt();
            }
            String data = "【清算机构：" + optins + "】对账结果：" + rslt + "。对账结果说明：" + dscr;
            if (rslt.equals(StmtRslt.CORRECT.getName())) {
                return ResultVoUtil.success(data);
            }
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, data);
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    private void fillInstStlLdgChk(InstStlLdgChk instStlLdgChk, List<InstSetlLdgChkBrf> brfs) {
        BigDecimal medfeesum = new BigDecimal("0");
        BigDecimal acctpaysum = new BigDecimal("0");
        BigDecimal psnCashPay = new BigDecimal("0");
        BigDecimal fundpaysum = new BigDecimal("0");
        for (InstSetlLdgChkBrf brf : brfs) {
            medfeesum = DecimalUtil.add(medfeesum, brf.getMedfeeSumamt());
            acctpaysum = DecimalUtil.add(acctpaysum, brf.getAcctPay());
            psnCashPay = DecimalUtil.add(psnCashPay, brf.getPsnCashPay());
            fundpaysum = DecimalUtil.add(fundpaysum, brf.getFundPaySumamt());
            if (null != brf.getHospPartAmt()) {
                fundpaysum = DecimalUtil.minus(fundpaysum, brf.getHospPartAmt());
            }
        }
        instStlLdgChk.setMedfeeSumamt(medfeesum);
        instStlLdgChk.setAcctPay(acctpaysum);
        instStlLdgChk.setCashPayamt(psnCashPay);
        instStlLdgChk.setFundPaySumamt(fundpaysum);
        instStlLdgChk.setFixmedinsSetlCnt(brfs.size());
    }

    public ResultVo<List<InsSetlDetlChkRslt>> institutionSettlementDetailCheck(InstStlLdgChk setlChk) {
        String areaStmt = getAreaStmt();
        String startdate = DateUtil.getDayStartTime(setlChk.getStmtBegndate());
        String enddate = DateUtil.getDayEndTime(setlChk.getStmtEnddate());
        if (setlChk.getMode() == 2) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "暂不支持HIS与医保的明细对账。");
        }
        String acctStatement = setlChk.getAcctPayFlag() == 1 ? "(fund_pay_sumamt+acct_pay)!=0" : "fund_pay_sumamt!=0";
        String acctStatement2 = setlChk.getAcctPayFlag() == 1 ? "(fund_pay+psn_acct_pay)!=0" : "fund_pay!=0";
        List<InstSetlLdgChkBrf> setlBrfs = dao.selectSetlChkBrfs(setlChk.getClrType(), setlChk.getSetlOptins(), startdate, enddate, acctStatement, areaStmt);
        if (ClrType.mzClrType(setlChk.getClrType())) {
            setlBrfs.addAll(dao.selectYbydzfSetlChkBrfs2(setlChk.getClrType(), setlChk.getSetlOptins(), startdate, enddate, acctStatement2, areaStmt));
        }

        fillInstStlLdgChk(setlChk, setlBrfs);
        String snowId = SnowFlakeId.instance().nextId();
        String filename = snowId + ".txt";
        StringBuilder fsIn = new StringBuilder();
        for (InstSetlLdgChkBrf item : setlBrfs) {
            fsIn.append(item.getSetlId()).append("\t")
                    .append(item.getMdtrtId()).append("\t")
                    .append(item.getPsnNo()).append("\t")
                    .append(item.getMedfeeSumamt()).append("\t")
                    .append(item.getFundPaySumamt()).append("\t")
                    .append(item.getAcctPay()).append("\t")
                    .append(setlChk.getRefdSetlFlag()).append("\n");
        }
        try {
            Files.write(Paths.get(filename), fsIn.toString().getBytes());
            String zipFile = ZipUtil.zip(filename);
            ZipUtil.deleteFile(filename);
            String fsUploadIn = "{\"filename\": \"" + filename + ".zip\", \"fixmedins_code\": \"" +
                                cfg.getHospId() + "\", \"in\": " + Arrays.toString(ZipUtil.zipFileToBytes(zipFile)) + "}";
            ResultVo<String> uplRes = upldServcie.uploadFile(JSONObject.parseObject(fsUploadIn));
            ZipUtil.deleteFile(zipFile);
            if (uplRes.getCode().equals(ExceptionEnum.SUCCESS.getCode())) {
                setlChk.setFileQuryNo(uplRes.getData());
            }
        } catch (IOException e) {
            log.error("医药机构费用结算对明细账出错", e);
        }
        JSONObject input = exec.makeTradeHeader(SiFunction.INSTITUTION_SETTLEMENT_DETAIL_CHECK);
        String ref = JSONObject.toJSONStringWithDateFormat(setlChk, "yyyy-MM-dd");
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.INSTITUTION_SETTLEMENT_DETAIL_CHECK);
        if (null == result) {
            return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
        }
        if (null == result.getInteger(RESULT_CODE)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (result.getIntValue(RESULT_CODE) == 0) {
            JSONObject output = result.getJSONObject(OUTPUT);
            JSONObject fileinfo = output.getJSONObject("fileinfo");
            String filePath = dldService.downloadFile(fileinfo.getString("file_qury_no"), fileinfo.getString("filename"));
            Queue<String> queue = SiUtil.readTxtFile(filePath);
            if (null == queue || queue.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未能成功获取到对账结果。");
            }
            List<InsSetlDetlChkRslt> list = new ArrayList<>();
            while (!queue.isEmpty()) {
                String item = queue.poll();
                String[] arr = item.split("\t");
                InsSetlDetlChkRslt rslt = new InsSetlDetlChkRslt(arr);
                if (!Objects.equals("对账成功", rslt.getMemo())) {
                    list.add(rslt);
                }
            }
            return ResultVoUtil.success(list);
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<Map<String, Object>> selectSetlinfos(SlctSetlPrm prm) {
        String areaStmt = getAreaStmt();
        QueryWrapper<SiSetlinfo> wrapper = new QueryWrapper<>();
        if (StringUtil.notBlank(prm.getInsutype())) {
            wrapper.eq("insutype", prm.getInsutype());
        }
        if (StringUtil.notBlank(prm.getPatNo())) {
            wrapper.and(i -> i.like("pat_no", prm.getPatNo()).or().like("psn_name", prm.getPatNo()));
        }
        String begndate = DateUtil.formatDatetime(prm.getStmtBegndate(), "yyyy-MM-dd") + " 00:00:00.000";
        String enddate = DateUtil.formatDatetime(prm.getStmtEnddate(), "yyyy-MM-dd") + " 23:59:59.999";
        wrapper.eq(prm.getMode() == 1 ? "clr_type" : "setl_type", prm.getClrType());
        wrapper.eq("revoked", YesOrNo.NO.getCode());
        wrapper.apply("setl_time>='" + begndate + "'");
        wrapper.apply("setl_time<='" + enddate + "'");
        if (prm.getMode() == 1) {
            wrapper.apply(prm.getAcctPayFlag() == 1 ? "(fund_pay_sumamt+acct_pay)!=0" : "fund_pay_sumamt!=0");
            wrapper.apply("insuplc_admdvs like " + areaStmt);
        }
        List<SiSetlinfo> list = setlinfoDao.selectList(wrapper);

        if (null == list || list.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到符合条件的数据。");
        }

        // 增加科室，诊断，接诊医生
        // 住院 21 9902 99940 22  门诊 11 9901 14 53
        List<ZyInactpatient> zybr = new ArrayList<>();
        List<Map> mzbr = new ArrayList<>();
        // list数据拆分len一组
        List<List<SiSetlinfo>> result = new ArrayList<>();
        int len = 80;
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<SiSetlinfo> subList = list.subList(i * len, (Math.min((i + 1) * len, size)));
            result.add(subList);
        }
        if ("21".equals(prm.getClrType()) || "9902".equals(prm.getClrType()) || "99940".equals(prm.getClrType())
            || "22".equals(prm.getClrType())) {
            for (List<SiSetlinfo> l : result) {
                List<ZyInactpatient> zyList = setlinfoDao.selectZyPatient(l);
                zybr.addAll(zyList);
            }
        } else {
            for (List<SiSetlinfo> l : result) {
                List<Map> mzList = setlinfoDao.selectMzPatient(l);
                mzbr.addAll(mzList);
            }
        }
        Map<String, ZyInactpatient> zyMap = new HashMap<>();
        Map<String, Map> mzMap = new HashMap<>();
        for (ZyInactpatient s : zybr) {
            zyMap.put(s.getInpatientNo() + "|" + s.getAdmissTimes(), s);
        }
        for (Map t : mzbr) {
            mzMap.put(t.get("patNo") + "|" + t.get("times"), t);
        }

        Map<String, Object> map = new HashMap<>(Capacity.TWO);
        Map<String, String> optinsMap = new HashMap<>();
        List<CodeName> optinList = new ArrayList<>();

        if (prm.getMode() == 1 && ClrType.mzClrType(prm.getClrType())) {
            List<CodeName> ydybzfClrOptins = dao.selectYdybzfClrOptins(prm.getClrType(), prm.getInsutype(), begndate, enddate, areaStmt);
            for (CodeName item : ydybzfClrOptins) {
                Admdvs admdvs = Admdvs.get(item.getCode());
                if (null == admdvs) {
                    item.setName(regionCache.get(item.getCode()));
                } else {
                    item.setName(admdvs.getName());
                }
                if (!optinsMap.containsKey(item.getCode())) {
                    optinsMap.put(item.getCode(), item.getName());
                }
            }
        }

        list.forEach(item -> {
            Admdvs admdvs = Admdvs.get(item.getClrOptins());
            if (null == admdvs) {
                item.setClrOptinsName(regionCache.get(item.getClrOptins()));
            } else {
                item.setClrOptinsName(admdvs.getName());
            }
            if (!optinsMap.containsKey(item.getClrOptins())) {
                optinsMap.put(item.getClrOptins(), item.getClrOptinsName());
            }

            // 添加科室，诊断，接诊医生
            if (!zyMap.isEmpty()) {
                ZyInactpatient br = zyMap.get(item.getPatNo().trim() + "|" + item.getTimes());
                if (br != null) {
                    item.setDept(br.getDept());
                    item.setDoctor(br.getJobDoctor());
                    item.setMainDiagnosis(br.getClinicDiagStr());
                } else {
                    log.info("住院号：{} 没有病人信息", item.getPatNo());
                }
            } else {
                if (!mzMap.isEmpty()) {
                    Map m = mzMap.get(item.getPatNo().trim() + "|" + item.getTimes());
                    if (m != null) {
                        item.setDept(String.valueOf(m.get("dept")));
                        item.setDoctor(String.valueOf(m.get("doctor")));
                        item.setMainDiagnosis(String.valueOf(m.get("zyzd")));
                    } else {
                        log.info("住院号：{} 没有病人信息", item.getPatNo());
                    }
                }
            }

            FilterUtil.filterCodeToName(item);
        });
        map.put("list", list);
        for (Map.Entry<String, String> entry : optinsMap.entrySet()) {
            optinList.add(new CodeName(entry.getKey(), entry.getValue()));
        }
        map.put("optins", optinList);
        return ResultVoUtil.success(map);
    }

    public ResultVo<String> detailAnalyse(String patNo, int times, int ledger, int type) {
        SiFunction function = type == 1 ? SiFunction.ITEMIZED_REVIEW_ANALYSIS_SERVICES_BEFORE
                : SiFunction.ITEMIZED_REVIEW_ANALYSIS_SERVICES_MIDDLE;
        String logpart = type == 1 ? "明细审核事前分析" : "明细审核事中分析";
        JSONObject input = exec.makeTradeHeader(function);
        MainPart mainPart = new MainPart();
        FsiHisDataDto hisDataDto = new FsiHisDataDto();
        hisDataDto.setFixmedinsCode(cfg.getHospId());
        hisDataDto.setFixmedinsName(cfg.getHospName());
        mainPart.setFsiHisDataDto(hisDataDto);
        mainPart.setSyscode("csthyy");
        mainPart.setTaskId(SnowFlakeId.instance().nextId());
        mainPart.setTrigScen("1");

        PatientDtos patientDtos = dao.selectPatientDto(patNo, times);
        FsiEncounterDtos fsiEncounterDtos = dao.selectFsiEncounterDto(patNo, times, cfg.getHospId(), cfg.getHospLevel());
        fsiEncounterDtos.setAdmDeptName(deptCache.getDeptName(fsiEncounterDtos.getAdmDeptCodg()));
        fsiEncounterDtos.setDscgDeptCodg(fsiEncounterDtos.getAdmDeptCodg());
        fsiEncounterDtos.setDscgDeptName(fsiEncounterDtos.getAdmDeptName());

        List<FsiDiagnoseDtos> fsiDiagnoseDtos = dao.selectFsiDiagnoseDtos(patNo, times);
        fsiEncounterDtos.setFsiDiagnoseDtos(fsiDiagnoseDtos);

        String setlId = dao.selectSetlId(patNo, times);
        List<FsiOrderDtos> tempFsiOrderDtos = dao.selectFsiOrderDtos(patNo, times, setlId);
        Map<String, Integer> distinctOrderMap = new HashMap<>();
        List<FsiOrderDtos> fsiOrderDtos = new ArrayList<>();
        tempFsiOrderDtos.forEach(item -> {
            if (!distinctOrderMap.containsKey(item.getRxId())) {
                distinctOrderMap.put(item.getRxId(), 1);
                item.setDrordDrProfttl(DrordDrProfttl.getCodeByHisCode(item.getDrordDrProfttl()));
                fsiOrderDtos.add(item);
            }
        });

        fsiEncounterDtos.setFsiOrderDtos(fsiOrderDtos);

        patientDtos.setFsiEncounterDtos(fsiEncounterDtos);
        mainPart.setPatientDtos(patientDtos);

        String ref = JSONObject.toJSONStringWithDateFormat(mainPart, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, function);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, patNo, times, ledger, infcode, "psn_no"));
        return SiUtil.makeReturnWithoutOutput(result, "分析结果。");
    }

    public ResultVo<String> deptInfoUpload(DeptInfo deptInfo) {
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_DEPARTMENT_INFO);
        String ref = JSONObject.toJSONStringWithDateFormat(deptInfo, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("deptinfo", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_DEPARTMENT_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        return SiUtil.makeReturnWithoutOutput(result, "科室信息上传成功。");
    }

    public ResultVo<String> deptInfoBatchUpload(List<DeptInfo> deptInfos) {
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_DEPARTMENT_INFO_IN_BATCH);
        String ref = JSONArray.toJSONStringWithDateFormat(deptInfos, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("deptinfo", JSONArray.parseArray(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_DEPARTMENT_INFO_IN_BATCH);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        return SiUtil.makeReturnWithoutOutput(result, "科室信息批量上传成功。");
    }

    public ResultVo<String> deptInfoModify(DeptInfo deptInfo) {
        JSONObject input = exec.makeTradeHeader(SiFunction.MODIFY_DEPARTMENT_INFO);
        String ref = JSONObject.toJSONStringWithDateFormat(deptInfo, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("deptinfo", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.MODIFY_DEPARTMENT_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        return SiUtil.makeReturnWithoutOutput(result, "科室信息变更成功。");
    }

    public ResultVo<String> deptInfoDelete(DeptInfo deptInfo) {
        JSONObject input = exec.makeTradeHeader(SiFunction.REVOKE_DEPARTMENT_INFO);
        JSONObject data = new JSONObject();
        data.put("hosp_dept_codg", deptInfo.getHospDeptCodg());
        data.put("hosp_dept_name", deptInfo.getHospDeptName());
        data.put("begntime", DateUtil.formatDatetime(deptInfo.getBegntime(), "yyyy-MM-dd"));
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_DEPARTMENT_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        logDao.insert(new SiLog(input, result, null, null, null, infcode, null));
        return SiUtil.makeReturnWithoutOutput(result, "科室信息撤销成功。");
    }

    public ResultVo<JSONArray> queryDeptInfo() {
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_DEPARTMENT_INFO);
        String staffId = TokenUtil.getInstance().getTokenUserId();
        DeptInfoQuery query = new DeptInfoQuery();
        query.setOpterType("1");
        query.setOpter(staffId);
        query.setOpterName(userCache.getEmployeeName(staffId));
        query.setInfno(SiFunction.QUERY_DEPARTMENT_INFO.getCode());
        query.setMsgid(input.getString("msgid"));
        query.setInfTime(input.getString("inf_time"));
        query.setMdtrtareaAdmvs(cfg.getHospArea());
        query.setFixmedinsCode(cfg.getHospId());
        query.setFixmedinsName(cfg.getHospName());
        query.setSignNo(input.getString("sign_no"));
        query.setInfver(cfg.getApiVersion());
        String ref = JSONObject.toJSONString(query);
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_DEPARTMENT_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            JSONObject output = result.getJSONObject(OUTPUT);
            if (null == output) {
                return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
            }
            JSONArray details = output.getJSONArray("feedetail");
            if (null == details || details.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
            }
            return ResultVoUtil.success(details);
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<JSONArray> queryMedStaffInfo(MedStaffQuery query) {
        String ref = JSONObject.toJSONString(query);
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_MEDICAL_STAFF_INFO);
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_MEDICAL_STAFF_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            JSONObject output = result.getJSONObject(OUTPUT);
            if (null == output) {
                return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
            }
            JSONArray details = output.getJSONArray("feedetail");
            if (null == details || details.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
            }
            return ResultVoUtil.success(details);
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<JSONObject> queryExaminationExInfo(BilgItemInfo bilgItemInfo) {
        String ref = JSONObject.toJSONString(bilgItemInfo);
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_MUTUAL_ACCREDIT_INFO);
        input.getJSONObject("input").put("bilgiteminfo", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_MUTUAL_ACCREDIT_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            return ResultVoUtil.success(result.getJSONObject(OUTPUT));
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<JSONObject> queryExaminationDetail(String psnNo, String reportNo) {
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_DIAGNOSIS_REPORT_DETAIL);
        JSONObject rptdetailinfo = new JSONObject();
        rptdetailinfo.put("psn_no", psnNo);
        rptdetailinfo.put("rpotc_no", reportNo);
        rptdetailinfo.put("fixmedins_code", cfg.getHospId());
        input.getJSONObject("input").put("rptdetailinfo", rptdetailinfo);
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_DIAGNOSIS_REPORT_DETAIL);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            return ResultVoUtil.success(result.getJSONObject(OUTPUT));
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<String> modifySetllistState(String psnNo, String setlId, int type) {
        JSONObject input = exec.makeTradeHeader(SiFunction.MODIFY_SI_SETTLE_STATE);
        JSONObject data = new JSONObject();
        data.put("psn_no", psnNo);
        data.put("setl_id", setlId);
        data.put("stas_type", type);    // 0未提交，1已提交
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.MODIFY_SI_SETTLE_STATE);
        return SiUtil.makeReturnWithoutOutput(result, "结算清单状态修改成功。");
    }

    public ResultVo<JSONObject> querySetllistInfo(String psnNo, String setlId) {
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_SI_SETTLE_INFO);
        JSONObject data = new JSONObject();
        data.put("psn_no", psnNo);
        data.put("setl_id", setlId);
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_SI_SETTLE_INFO);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            return ResultVoUtil.success(result.getJSONObject(OUTPUT));
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<JSONObject> querySetllistQualityControl(SetllistQualityControlInquiry inquiry) {
        String ref = JSONObject.toJSONString(inquiry);
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_SI_SETTLE_QUALITY_CONTROL);
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_SI_SETTLE_QUALITY_CONTROL);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            return ResultVoUtil.success(result.getJSONObject(OUTPUT));
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<JSONObject> querySetllistQuantityCount(SetllistQuantityCountInquiry inquiry) {
        String ref = JSONObject.toJSONStringWithDateFormat(inquiry, "yyyy-MM-dd HH:mm:ss");
        JSONObject input = exec.makeTradeHeader(SiFunction.QUERY_SI_SETTLE_QUANTITY_COUNT);
        input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.QUERY_SI_SETTLE_QUANTITY_COUNT);
        Integer infcode = result.getInteger(RESULT_CODE);
        if (null == infcode) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错：" + result.getString("message"));
        }
        if (infcode == 0) {
            return ResultVoUtil.success(result.getJSONObject(OUTPUT));
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
    }

    public ResultVo<List<BriefSheet>> selectSheets(String month, Integer status) {
        String begin = month + "-01 00:00:00.000";
        String end = DateUtil.getMonthEndtime(month);
        return ResultVoUtil.success(dao.selectSheets(begin, end, status));
    }

    public ResultVo<String> uploadFrontSheetBatch(List<BriefSheet> list) {
        int total = list.size();
        for (int i = 0; i < total; i++) {
            BriefSheet sheet = list.get(i);
            ResultVo<String> uploadRes = uploadFrontSheet(sheet.getPatNo(), sheet.getTimes());
            if (Objects.equals(uploadRes.getCode(), ExceptionEnum.SUCCESS.getCode())) {
                dao.updateFrontSheetUploadedFlag(sheet.getPatNo(), sheet.getTimes());
                sendUploadSheetErrorMessage(sheet, uploadRes.getData(), 0, (i + 1), total);
            } else {
                sendUploadSheetErrorMessage(sheet, uploadRes.getMessage(), 1, (i + 1), total);
            }
        }
        return ResultVoUtil.success("病案首页信息上传完成。");
    }

    public ResultVo<String> uploadFrontSheet(String patNo, int times) {
        String hospCode = cfg.getHospId();
        Baseinfo baseinfo = dao.selectFrontSheetBaseInfo(patNo, times, hospCode);
        baseinfo.setCtd(CaseClassification.getWjwCodeByHisCode(baseinfo.getCtd()));
        List<Diseinfo> diseinfos = dao.selectYbDisdiags(patNo, times, hospCode);
        if (null == diseinfos || diseinfos.isEmpty()) {
            diseinfos = dao.selectFrontSheetDiseInfo(patNo, times, hospCode);
        }
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_FRONT_SHEET_INFO);
        String base = JSONObject.toJSONStringWithDateFormat(baseinfo, "yyyy-MM-dd");
        String dise = JSONArray.toJSONString(diseinfos);

        List<Icuinfo> icuinfos = new ArrayList<>();
        Icuinfo icuinfo = new Icuinfo();
        icuinfo.setValiFlag("0");
        icuinfo.setIptMedcasHmpgSn(diseinfos.get(0).getIptMedcasHmpgSn());
        icuinfo.setMdtrtSn(diseinfos.get(0).getMdtrtSn());
        icuinfos.add(icuinfo);
        String icu = JSONArray.toJSONString(icuinfos);

        List<Oprninfo> oprninfos = dao.selectFrontSheetSurgeries(patNo, times);
        if (oprninfos.isEmpty()) {
            Oprninfo oprninfo = new Oprninfo();
            oprninfo.setValiFlag("0");
            oprninfos.add(oprninfo);
        }
        for (Oprninfo oprninfo : oprninfos) {
            oprninfo.setIptMedcasHmpgSn(patNo + "_" + times + "_" + oprninfo.getOprnOprtSn());
            oprninfo.setMdtrtSn(diseinfos.get(0).getMdtrtSn());
        }
        String oprn = JSONArray.toJSONString(oprninfos);
        input.getJSONObject("input").put("baseinfo", JSONObject.parseObject(base));
        input.getJSONObject("input").put("diseinfo", JSONArray.parseArray(dise));
        input.getJSONObject("input").put("oprninfo", JSONArray.parseArray(oprn));
        input.getJSONObject("input").put("icuinfo", JSONArray.parseArray(icu));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_FRONT_SHEET_INFO);
        return SiUtil.makeReturnWithoutOutput(result, "病案首页信息上传成功。");
    }

    public void sendUploadSheetErrorMessage(BriefSheet sheet, String msg, int type, int index, int total) {
        JSONObject obj = new JSONObject();
        obj.put("name#患者姓名|1", sheet.getName());
        obj.put("patNo#住院号|2", sheet.getPatNo());
        obj.put("times#住院次数|3", sheet.getTimes());
        obj.put("dismissDate#出院时间|4", DateUtil.formatDatetime(sheet.getDismissDate()));
        obj.put("dismissDept#出院科室|5", sheet.getDismissDept());
        obj.put("deptLeader#科室主任编码|6", sheet.getDeptLeader());
        obj.put("deptLeaderName#科室主任姓名|7", sheet.getDeptLeaderName());
        obj.put("leaderDoctor#主任（副主任）医师编码|8", sheet.getLeaderDoctor());
        obj.put("leaderDoctorName#主任（副主任）医师姓名|9", sheet.getLeaderDoctorName());
        obj.put("mainDoctor#主治医师编码|10", sheet.getMainDoctor());
        obj.put("mainDoctorName#主治医师姓名|11", sheet.getMainDoctorName());
        obj.put("admissDoctor#住院医师编码|12", sheet.getAdmissDoctor());
        obj.put("admissDoctorName#住院医师姓名|13", sheet.getAdmissDoctorName());
        obj.put("dutyNurse#责任护士编码|14", sheet.getDutyNurse());
        obj.put("dutyNurseName#责任护士姓名|15", sheet.getDutyNurseName());
        obj.put("qualityControlDoctor#质控医师编码|18", sheet.getQualityControlDoctor());
        obj.put("qualityControlDoctorName#质控医师姓名|19", sheet.getQualityControlDoctorName());
        obj.put("qualityControlNurse#质控护士编码|20", sheet.getQualityControlNurse());
        obj.put("qualityControlNurseName#质控护士姓名|21", sheet.getQualityControlNurseName());
        obj.put("message#上传结果|22", msg.length() > 500 ? msg.substring(0, 500) : msg);
        obj.put("type#类型|23", type);
        obj.put("total", total);
        obj.put("index", index);
        obj.put("jdtType", "upload");
        obj.put("title", String.format("住院号：【%s】，住院次数：【%d】。", sheet.getPatNo(), sheet.getTimes()));
        String message = SocketMsg.socketVo(Message.JDT_MESSAGE, obj);

        intergrationPlatformSocket.sendMessageByUserCode(
                WebSocketByUserCode
                        .create(TokenUtil.getInstance().getTokenUserId(), message)
        );

        log.info("发送信息通知：{}", obj.toJSONString());
    }

    public ResultVo<String> uploadActOrder(String patNo, int times) {
        List<ActOrder> actOrders = dao.selectActOrders(patNo, times, cfg.getHospId());
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_ACT_ORDER);
        String ref = JSONArray.toJSONStringWithDateFormat(actOrders, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("data", JSONArray.parseArray(ref));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_ACT_ORDER);
        return SiUtil.makeReturnWithoutOutput(result, "医嘱记录上传成功。");
    }

    public ResultVo<String> uploadClinicRecord(String patNo, int times) {
        ClinicRegistration clinicRegistration = dao.selectClinicRegistration(patNo, times);
        List<ClinicDiseinfo> diseinfos = dao.selectClinicDiseinfo(patNo, times);
        List<ClinicRxinfo> rxinfos = dao.selectClinicRxinfo(patNo, times);
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_CLINIC_RECORD);
        String rgstinfo = JSONObject.toJSONStringWithDateFormat(clinicRegistration, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("rgstinfo", JSONObject.parseObject(rgstinfo));
        input.getJSONObject("input").put("caseinfo", new JSONArray());
        String diseinfo = JSONArray.toJSONString(diseinfos);
        input.getJSONObject("input").put("diseinfo", JSONArray.parseArray(diseinfo));
        String rxinfo = JSONArray.toJSONStringWithDateFormat(rxinfos, "yyyy-MM-dd HH:mm:ss");
        input.getJSONObject("input").put("rxinfo", JSONArray.parseArray(rxinfo));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_CLINIC_RECORD);
        return SiUtil.makeReturnWithoutOutput(result, "门急诊诊疗记录上传成功。");
    }

    public ResultVo<String> uploadEmergencyRecord(String patNo, int times) {
        List<EmergencyOprninfo> oprninfos = dao.selectEmergencyOprninfos(patNo, times);
        List<EmergencyRescueinfo> rescueinfos = new ArrayList<>();
        String oprninfo = JSONArray.toJSONString(oprninfos);
        String rescueinfo = JSONArray.toJSONString(rescueinfos);
        JSONObject input = exec.makeTradeHeader(SiFunction.UPLOAD_EMERGENCY_RECORD);
        input.getJSONObject("input").put("oprninfo", JSONArray.parseArray(oprninfo));
        input.getJSONObject("input").put("rescinfo", JSONArray.parseArray(rescueinfo));
        JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_EMERGENCY_RECORD);
        return SiUtil.makeReturnWithoutOutput(result, "急诊留观手术及抢救信息上传成功。");
    }

    public ResultVo<List<Map<String, Object>>> selectSetlPrescription(String mdtrtId) {
        List<Map<String, Object>> result = dao.selectSetlPrescription(mdtrtId);
        return ResultVoUtil.success(result);
    }

    public ResultVo<Map<String, Object>> selectMzBl(String patNo, int times) {
        Map<String, Object> result = dao.selectMzBl(patNo, times);
        return ResultVoUtil.success(result);
    }
}
