package com.kcim.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.kcim.common.constants.Constant;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.constants.SQLParameter;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.dao.model.*;
import com.kcim.dao.repository.*;
import com.kcim.service.CenterService;
import com.kcim.service.ReportService;
import com.kcim.vo.*;
import com.kcim.web.reponse.ReportResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 报表查询接口实现类
 * @author: Wang.YS
 * @create: 2023-11-01 20:41
 **/
@Service("ReportService")
@AllArgsConstructor
@Slf4j
public class ReportServiceImpl implements ReportService {
    CostReportRepository repository;

    CostReportColumnRepository costReportColumnRepository;

    CostColumnRepository costColumnRepository;

    CostReportRedirectRepository costReportRedirectRepository;

    CenterService centerService;

    CostReportIndexRepository costReportIndexRepository;
    @Override
    public Object getReportData(Integer current, Integer pageSize, String reportCode, Map<String, String> parameter) {
        CostReport report = repository.getReportByReportCode(Long.valueOf(reportCode));
        if(Objects.isNull(report)){
            log.error("未找到当前报表代码【"+reportCode+"】报表，请确认当前报表是否存在");
            throw new CostException("未找到当前报表代码报表，请确认当前报表是否存在");

        }
        //查询报表 获取主键列
        List<CostReportColumn> reportColumns = costReportColumnRepository.getReportColumnByReportCode(Long.valueOf(reportCode));
        if(CollectionUtils.isEmpty(reportColumns)){
            log.error("报表"+report.getName()+"未配置任何显示列，请先添加报表列再查询！");
            throw new CostException("报表"+report.getName()+"未配置任何显示列，请先添加报表列再查询！");
        }
        //获取主键列
        List<CostReportColumn> collect = reportColumns.stream().filter(f -> f.getPrimaryKey().equals(NumberConstant.ONE)).collect(Collectors.toList());
        //主键列校验
        if(CollectionUtils.isEmpty(collect)){
            log.error("报表【"+report.getName()+"】未添加主键列，请重新维护！");
            throw new CostException("报表【"+report.getName()+"】未添加主键列，请重新维护！");
        }
        List<Long> columnCodes = reportColumns.stream().map(CostReportColumn::getColumnCode).collect(Collectors.toList());

        //获取列代码
        List<CostColumn> costColumns = costColumnRepository.getColumnByColumnCode(columnCodes);
        if(CollectionUtils.isEmpty(costColumns)){
            throw new CostException("报表"+report.getName()+"无符合条件报表列数据");
        }
        Map<Long,CostColumn> costColumnMap = costColumns.stream().collect(Collectors.toMap(CostColumn::getCode, column -> column, (a, b) -> b));
        Map<Integer, List<CostColumn>> dataSourceGroup = costColumns.stream().collect(Collectors.groupingBy(CostColumn::getDataSource));


        //获取报表是否可以跳转数据及跳转列 及跳转报表code
        List<CostReportRedirect> redirectByReportCode = costReportRedirectRepository.getRedirectByReportCode(Long.valueOf(reportCode));
//        Map<Long,ReportRedirect> reportRedirectMap = redirectByReportCode.stream().collect(Collectors.toMap(ReportRedirect::getReportColumnCode, redirect -> redirect, (a, b) -> b));
        //此需求不一定符合实际情况  强制要求改动  单报表同一字段 实际运用过程过只会下钻 子类数据一张报表 不会存在多张 备注记录一下
        Map<Long, List<CostReportRedirect>> reportRedirectMap = redirectByReportCode.stream().collect(Collectors.groupingBy(CostReportRedirect::getReportColumnCode));

        //创建报表列标题 从字典中获取看是否存在已维护的标题 2023/7/12
//        Map<String, String> columnNameMap = sysDictDetailService.getDictionaryCodeNameMap(DirectoryConstant.REPORT_COLUMN_TEXT_MAP);
        DictDataVo dict = centerService.getDict(Constant.REPORT_COLUMN_TEXT_MAP);
        List<DictDataVo> dataVoList = dict.getDataVoList();
        Map<String, String> columnNameMap = new HashMap<>();
        Map<String, Integer> columnSortMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(dataVoList)){
            columnNameMap = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
            columnSortMap = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getSort, (a, b) -> b));
        }
        //获取主键列代码
        Long columnCode = collect.get(0).getColumnCode();
        //获取主键数据
        CostColumn costColumn = costColumnMap.get(columnCode);
        String keySql = costColumn.getSql();
        if(!CollectionUtils.isEmpty(parameter)){
            keySql = MatchParameter(keySql, parameter);
        }else {
            keySql = MatchParameter(keySql, new HashMap<>());
        }
        log.info("主键sql"+keySql);
        List<Map<String, Object>> keyList = sqlRunnerList(keySql);
        if(CollectionUtils.isEmpty(keyList)){
            log.error("报表"+report.getName()+"无符合条件主键数据"+keySql);
            throw new CostException("报表"+report.getName()+"无符合条件主键数据");
        }
        Integer totalCount = keyList.size();
        if (current ==null){
            current = 1;
        }
        if(pageSize ==null){
            pageSize = 100;
        }
        List<Map<String, Object>> maps = PageUtils.startPage(keyList, current, pageSize);
        List<CostColumn> calcFormulaList = dataSourceGroup.get(NumberConstant.ONE);
        List<Long> calcCode = new ArrayList<>();
        if(!CollectionUtils.isEmpty(calcFormulaList)){
           calcCode = calcFormulaList.stream().map(CostColumn::getCode).collect(Collectors.toList());
        }
        List<CostColumn> sqlList = dataSourceGroup.get(NumberConstant.TWO);
        List<Long> sqlCode = sqlList.stream().map(CostColumn::getCode).collect(Collectors.toList());

        List<CostReportColumn> calcReportColumn = new ArrayList<>();
        List<CostReportColumn> sqlReportColumn = new ArrayList<>();

        for (CostReportColumn reportColumn : reportColumns) {
            if(!CollectionUtils.isEmpty(calcCode)){
                if(calcCode.contains(reportColumn.getColumnCode())){
                    calcReportColumn.add(reportColumn);
                }
            }

            if(sqlCode.contains(reportColumn.getColumnCode())){
                sqlReportColumn.add(reportColumn);
            }
        }
        calcReportColumn.sort(Comparator.comparing(CostReportColumn::getSort));

        List<List<ReportVo>> vos = new ArrayList<>();
        ReportCodeModifyVo reportCodeModifyVo = new ReportCodeModifyVo();
        for(Map<String, Object> result:maps){
            if(CollectionUtils.isEmpty(result)){
               continue;
            }
            Map<String, Object> keyParameter = result.keySet().stream().collect(Collectors.toMap(s -> s, result::get, (a, b) -> b));
            List<ReportVo> dataVo = new ArrayList<>();
            //sql报表列
            if(!CollectionUtils.isEmpty(sqlReportColumn)){
                for(CostReportColumn column:sqlReportColumn){
                    Integer primaryKey = column.getPrimaryKey();
                    if(primaryKey.equals(NumberConstant.ONE)){
                        if(result.size()>1){
                            Map<String,String> modify = new HashMap<>();

                            for(String s:result.keySet()){
                                ReportVo vo = new ReportVo();
                                vo.setCode(column.getReportCode()+s);
                                vo.setValue(result.get(s));
                                dataVo.add(vo);
                                modify.put(column.getReportCode()+s,s);
                            }
                            reportCodeModifyVo.setReportCode(column.getColumnCode());
                            reportCodeModifyVo.setModifyReportCode(modify);
                        }else {
                            ReportVo vo = new ReportVo();
                            vo.setCode(column.getColumnCode().toString());
                            vo.setValue(result.values().stream().findFirst().get());
//                            modify.put(vo.getCode(),result.keySet().stream().findFirst().get());
                            dataVo.add(vo);
                        }
//                        reportCodeModifyVo.setReportCode(column.getColumnCode());
//                        reportCodeModifyVo.setModifyReportCode(modify);
                    }else {
                        ReportVo vo = new ReportVo();
                        vo.setCode(column.getColumnCode().toString());
                        CostColumn col = costColumnMap.get(column.getColumnCode());
                        String sql = col.getSql();
                        String handleSql ;
                        if(!CollectionUtils.isEmpty(parameter)){
                            handleSql = MatchParameter(sql, keyParameter,  parameter);
                        }else {
                            handleSql = MatchParameter(sql, keyParameter,new HashMap<>());
                        }
                        Object o = sqlRunner(handleSql);
//                        Integer dataType = col.getDataType();
//
//                        if(dataType != null&&dataType.equals(NumberConstant.THREE)){
//                            Integer decimalPlace = col.getDecimalPlace();
//                            if(o.equals("")){
//                                vo.setValue(BigDecimal.ZERO.setScale(decimalPlace,RoundingMode.HALF_UP));
//                            }else {
//                                BigDecimal value = new BigDecimal(o.toString());
//                                vo.setValue(value.setScale(decimalPlace,RoundingMode.HALF_UP));
//                            }
//                        }else {
                            vo.setValue(o);
//                        }
                        dataVo.add(vo);
                    }
                }
            }

            //添加计算公式算法
            if(!CollectionUtils.isEmpty(calcReportColumn)){
                for(CostReportColumn column:calcReportColumn){
                    Integer primaryKey = column.getPrimaryKey();
                    if(primaryKey.equals(NumberConstant.ONE)){
                        if(result.size()>1){
                            Map<String,String> modify = new HashMap<>();

                            for(String s:result.keySet()){
                                ReportVo vo = new ReportVo();
                                vo.setCode(column.getReportCode()+s);
                                vo.setValue(result.get(s));
                                dataVo.add(vo);
                                modify.put(column.getReportCode()+s,s);
                            }
                            reportCodeModifyVo.setReportCode(column.getColumnCode());
                            reportCodeModifyVo.setModifyReportCode(modify);
                        }else {
                            ReportVo vo = new ReportVo();
                            vo.setCode(column.getColumnCode().toString());
                            vo.setValue(result.values().stream().findFirst().get());
                            dataVo.add(vo);
                        }
                    }else {
                        ReportVo vo = new ReportVo();
                        vo.setCode(column.getColumnCode().toString());
                        CostColumn col = costColumnMap.get(column.getColumnCode());
                        String formula = col.getFormula();
                        BigDecimal formulaData = getFormulaData(formula, dataVo,column);
//                        Integer dataType = col.getDataType();
//                        if(dataType != null&&dataType.equals(NumberConstant.THREE)){
//                            Integer decimalPlace = col.getDecimalPlace();
//                            vo.setValue(formulaData.setScale(decimalPlace, RoundingMode.HALF_UP));
//                        }else {
                            vo.setValue(formulaData);
//                        }
                        dataVo.add(vo);
                    }
                }
            }
            vos.add(dataVo);
        }
        List<ReportTitleVo> titleVos = new ArrayList<>();
        for(CostReportColumn column:reportColumns){
            Integer primaryKey = column.getPrimaryKey();
            if(primaryKey.equals(NumberConstant.ONE)){
                if(reportCodeModifyVo.getReportCode() != null){
                    if(reportCodeModifyVo.getReportCode().equals(column.getColumnCode())){
                        Map<String, String> modifyReportCode = reportCodeModifyVo.getModifyReportCode();
                        List<String> primary = modifyReportCode.keySet().stream().map(modifyReportCode::get).collect(Collectors.toList());
                        for(String key:modifyReportCode.keySet()){
                            ReportTitleVo vo = new ReportTitleVo();
                            vo.setCode(key);
                            String columnName = modifyReportCode.get(key);
                            String name;
                            if(!CollectionUtils.isEmpty(columnNameMap)){
                                name = columnNameMap.get(columnName);
                                if(StringUtils.isEmpty(name)){
                                    name = columnName;
                                }
                            }else {
                                name = columnName;
                            }
                            vo.setName(name);
                            if(!CollectionUtils.isEmpty(columnSortMap)){
                                Integer sort = columnSortMap.get(columnName);
                                vo.setSort(sort != null ? sort : column.getSort());
                            }else {
                                vo.setSort(column.getSort());
                            }
                            vo.setHide(column.getHide());
                            vo.setFreeze(column.getFreeze());
                            vo.setSortStatus(column.getSortStatus());
                            // 2023/7/13 主键列为多个时候 需要用sql查出的列表作为 columnName 要求改造
                            vo.setColumnName(columnName);
                            vo.setSearch(column.getSearch());
                            List<CostReportRedirect> reportRedirects = reportRedirectMap.get(column.getColumnCode());
                            if(!CollectionUtils.isEmpty(reportRedirects)){
                                List<RedirectData> redirectDataList = new ArrayList<>();
                                for(CostReportRedirect redirect:reportRedirects){
                                    RedirectData redirectData = new RedirectData();
                                    redirectData.setRedirectReportCode(redirect.getRedirectReportCode());
                                    // 2023/7/13 主键列为多个时候 有跳转报表 把每个主键列都放进去 要求改造
                                    StringBuilder redirectParameter = setRedirectParameter(primary, redirect);
                                    redirectData.setRedirectParameter(redirectParameter.toString());
                                    redirectData.setRedirectReportName(redirect.getRedirectReportName());
                                    redirectDataList.add(redirectData);
                                }
                                vo.setRedirect(true);
                                vo.setRedirectData(redirectDataList);
                            }
                            titleVos.add(vo);
                        }
                    } else {
                        titleVos.add(getReportTitleVo(column.getColumnCode().toString(), column.getColumnHeaderText(), column, reportRedirectMap,reportCodeModifyVo,costColumnMap));
                    }
                }else {
                    titleVos.add(getReportTitleVo(column.getColumnCode().toString(), column.getColumnHeaderText(), column, reportRedirectMap, reportCodeModifyVo, costColumnMap));
                }
            }else {
                titleVos.add(getReportTitleVo(column.getColumnCode().toString(), column.getColumnHeaderText(), column, reportRedirectMap, reportCodeModifyVo, costColumnMap));
            }
        }
        ReportResponse response = new ReportResponse();
        titleVos.sort(Comparator.comparing(ReportTitleVo::getSort));
        response.setReportName(report.getName());
        response.setTitle(titleVos);
        response.setData(vos);
        response.setCurrent(current);
        response.setPageSize(pageSize);
        response.setTotalCount(totalCount);
        response.setTotalPage((int)Math.ceil((double)totalCount/pageSize));
        return response;
    }

    @Override
    public Object getReportIndex(Long reportCode) {
        CostReport report = repository.getReportByReportCode(reportCode);
        List<CostReportIndex> byReportCode = costReportIndexRepository.getByReportCode(Collections.singletonList(reportCode));
        if(!CollectionUtils.isEmpty(byReportCode)){
            report.setReportIndex(byReportCode);
        }
        return report;
    }


    private BigDecimal getFormulaData(String formula, List<ReportVo> dataVo, CostReportColumn column) {
        //找出公式当中所有代码
        String replace = formula.replace("[", "")
                .replace("]", "")
                .replace("-", ",")
                .replace("+", ",")
                .replace("*",",")
                .replace("/",",");
        ArrayList<String> codeList = CollUtil.newArrayList(replace.split(","));
        Map<Integer, String> codeMap = new ConcurrentHashMap<>();
        for (int j = 0; j < codeList.size(); j++) {
            codeMap.put(j, codeList.get(j));
        }
        List<String> expressions = ReUtil.findAll("[^0-9]", "+" + formula.replace("[", "")
                        .replace("]", "").trim(), 0)
                .stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
        // 得到预算表达式 得到所有表达式的Map  +  -  相关的
        Map<Integer, String> expressionMap = new ConcurrentHashMap<>();
        for (int k = 0; k < expressions.size(); k++) {
            expressionMap.put(k, expressions.get(k));
        }
        // 数字的索引和表达式的索引累加计算
        Set<Integer> codeSet = codeMap.keySet();
        List<Integer> codes = new ArrayList<>(codeSet);
        AtomicReference<BigDecimal> totalAmount = new AtomicReference<>();
        totalAmount.set(BigDecimal.ZERO);
        Map<String,Object> dataMap = dataVo.stream().collect(Collectors.toMap(ReportVo::getCode, ReportVo::getValue, (a, b) -> b));

        for (int i = 0; i < codes.size(); i++) {
            // 编号
            String code = codeMap.get(i);
            Object o = dataMap.get(code);
            if (Objects.isNull(o)) {
                continue;
            }
            if (StringUtils.isEmpty(o)) {
                o=BigDecimal.ZERO;
            }
            BigDecimal amount = new BigDecimal(o.toString());
            String str = expressionMap.get(i);
            if (str.equals("+")) {
                totalAmount.set(totalAmount.get().add(amount));
            } else if(str.contains("-")){
                totalAmount.set(totalAmount.get().subtract(amount));
            } else if(str.contains("*")){
                totalAmount.set(totalAmount.get().multiply(amount));
            } else if (str.contains("/")) {
                if(amount.compareTo(BigDecimal.ZERO)==0){
                    log.error("报表列【"+column.getColumnName()+"】公式除数为0,数据为【"+code+"】数据");
                    totalAmount.set(BigDecimal.ZERO) ;
                    break;
                }else {
                    totalAmount.set(totalAmount.get().divide(amount,4, RoundingMode.HALF_UP));
                }
            }
        }
        return totalAmount.get();
    }

    private static StringBuilder setRedirectParameter(List<String> primary, CostReportRedirect redirect) {
        StringBuilder redirectParameter = new StringBuilder(redirect.getRedirectParameter());
        if(!StringUtils.isEmpty(redirectParameter.toString())){
            if(redirectParameter.toString().contains("|")){
                String[] split = StrUtil.splitToArray(redirectParameter.toString(), "|");
                assert split != null;
                List<String> strings1 = Arrays.asList(split);
                List<String> strings = new ArrayList<>(strings1);
                List<String> collect1 = strings.stream().filter(primary::contains).collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(collect1)){
                    primary.removeAll(collect1);
                    if(!CollectionUtils.isEmpty(primary)){
                        for(String s: primary){
                            redirectParameter.append("|").append(s);
                        }
                    }
                }else {
                    for(String s: primary){
                        redirectParameter.append("|").append(s);
                    }
                }
            }else {
                boolean contains = false;
                for(String s: primary){
                    if (redirectParameter.toString().equals(s)) {
                        contains = true;
                        break;
                    }
                }
                if(contains){
                    primary.remove(redirectParameter.toString());
                }
                if(!CollectionUtils.isEmpty(primary)){
                    for(String s: primary){
                        redirectParameter.append("|").append(s);
                    }
                }


            }
        }else {
            for(String s: primary){
                redirectParameter = new StringBuilder(s + "|");
            }
            redirectParameter.deleteCharAt(redirectParameter.length() -1);

        }
        return redirectParameter;
    }


    private static ReportTitleVo getReportTitleVo(String column, String columnName, CostReportColumn reportColumn, Map<Long, List<CostReportRedirect>> reportRedirectMap, ReportCodeModifyVo reportCodeModifyVo, Map<Long, CostColumn> map) {
        ReportTitleVo vo = new ReportTitleVo();
        vo.setCode(column);
        vo.setName(columnName);
        vo.setSort(reportColumn.getSort()+100);
        vo.setHide(reportColumn.getHide());
        vo.setFreeze(reportColumn.getFreeze());
        vo.setColumnName(reportColumn.getColumnName());
        vo.setSortStatus(reportColumn.getSortStatus());
        vo.setSearch(reportColumn.getSearch());
        CostColumn computeColumn = map.get(Long.valueOf(column));
        if(Objects.nonNull(computeColumn)){
            vo.setDataType(computeColumn.getDataType());
            vo.setDecimalPlace(computeColumn.getDecimalPlace());
            String permil = computeColumn.getPermil();
            if(StringUtils.isEmpty(permil)){
                vo.setPermil(false);
            }else {
                vo.setPermil(permil.equals(NumberConstant.ONE_S));
            }


        }
        List<String> primary = new ArrayList<>();
        if(reportCodeModifyVo.getReportCode() != null){
            Map<String, String> modifyReportCode = reportCodeModifyVo.getModifyReportCode();
            List<String> collect = new ArrayList<>();
            modifyReportCode.forEach((key, v) -> collect.add(v));
            primary.addAll(collect);
        }
        //此需求不一定符合实际情况  强制要求改动  单报表同一字段 实际运用过程过只会下钻 子类数据一张报表 不会存在多张 备注记录一下
//            ReportRedirect redirect = reportRedirectMap.get(column.getColumnCode());
//            if(Objects.nonNull(redirect)){
//                vo.setRedirectReportCode(redirect.getRedirectReportCode());
//                vo.setRedirect(true);
//                vo.setRedirectParameter(redirect.getRedirectParameter());
//            }
        if(!CollectionUtils.isEmpty(primary)){
            List<CostReportRedirect> reportRedirects = reportRedirectMap.get(reportColumn.getColumnCode());
            if(!CollectionUtils.isEmpty(reportRedirects)){
                List<RedirectData> redirectDataList = new ArrayList<>();
                for(CostReportRedirect redirect:reportRedirects){
                    RedirectData redirectData = new RedirectData();
                    redirectData.setRedirectReportCode(redirect.getRedirectReportCode());
                    StringBuilder redirectParameter = setRedirectParameter(primary, redirect);
                    redirectData.setRedirectParameter(redirectParameter.toString());
                    redirectData.setRedirectReportName(redirect.getRedirectReportName());
                    redirectDataList.add(redirectData);
                }
                vo.setRedirect(true);
                vo.setRedirectData(redirectDataList);
            }
        }else {
            List<CostReportRedirect> reportRedirects = reportRedirectMap.get(reportColumn.getColumnCode());
            if(!CollectionUtils.isEmpty(reportRedirects)){
                List<RedirectData> redirectDataList = new ArrayList<>();
                for(CostReportRedirect redirect:reportRedirects){
                    RedirectData redirectData = new RedirectData();
                    redirectData.setRedirectReportCode(redirect.getRedirectReportCode());
                    redirectData.setRedirectParameter(redirect.getRedirectParameter());
                    redirectData.setRedirectReportName(redirect.getRedirectReportName());
                    redirectDataList.add(redirectData);
                }
                vo.setRedirect(true);
                vo.setRedirectData(redirectDataList);
            }
        }

        return vo;
    }

    private String MatchParameter(String sql, Map<String, Object> keyParameter, Map<String, String> parameter) {

        if(StringUtils.isEmpty(sql)){
            throw new CostException("无效自定义sql语句");
        }
        //替换主键

        if(!CollectionUtils.isEmpty(keyParameter)){
           for (String s : keyParameter.keySet()) {
                String key = "#" + s;
                if (sql.contains(key)) {
                    sql = sql.replace(key, keyParameter.get(s).toString());
                }
            }
        }
        sql = MatchSystemParameter(sql);
        //替换传参
        if(!CollectionUtils.isEmpty(parameter)){

            for(String s:parameter.keySet()){
                //拼接 #
                String sqlFilter = "#" + s;
                if (sql.contains(sqlFilter)) {
                    sql = sql.replace(sqlFilter, parameter.get(s));
                }
            }
        }
        if(sql.contains("#")){
            log.error("sql 所需条件未全部传递，请确认后再进行查询"+sql);
            throw new CostException("sql 所需条件未全部传递，请确认后再进行查询");
        }
        return sql;
    }



    private  String MatchParameter(String sql,String keyCode,String keyValue,Map<String,String> parameter) {
        if(StringUtils.isEmpty(sql)){
            throw new CostException("无效自定义sql语句");
        }
        //替换主键
        String key = "#" + keyCode;
        if (sql.contains(key)) {
            sql = sql.replace(key, keyValue);
        }

        sql = MatchSystemParameter(sql);
        //替换传参
        if(!CollectionUtils.isEmpty(parameter)){
            for(String s:parameter.keySet()){
                //拼接 #
                String sqlFilter = "#" + s;
                if (sql.contains(sqlFilter)) {
                    sql = sql.replace(sqlFilter, parameter.get(s));
                }
            }
        }
        if(sql.contains("#")){
            log.error("sql 所需条件未全部传递，请确认后再进行查询");
            throw new ClassCastException("sql 所需条件未全部传递，请确认后再进行查询");
        }
        return sql;
    }
    private  String MatchParameter(String sql,Map<String,String> parameter) {
        if(StringUtils.isEmpty(sql)){
            throw new CostException("无效自定义sql语句");
        }

        sql = MatchSystemParameter(sql);
        //替换传参
        if(!CollectionUtils.isEmpty(parameter)){
            for(String s:parameter.keySet()){
                //拼接 #
                String sqlFilter = "#" + s;
                if (sql.contains(sqlFilter)) {
                    sql = sql.replace(sqlFilter, parameter.get(s));
                }
            }
        }
        if(sql.contains("#")){
            log.error("sql 所需条件未全部传递，请确认后再进行查询"+sql);
            throw new CostException("sql 所需条件未全部传递，请确认后再进行查询");
        }
        return sql;
    }
    private  Object sqlRunner(String sql) {
//        List<Object> objects = SqlUtil.getresult(sql, Object.class);
        log.info("sqlRunner执行"+sql);
        Object objects = SqlRunner.db().selectObj(sql, Object.class);
        if(Objects.nonNull(objects)){
            Class<?> aClass = objects.getClass();
            if(objects instanceof Integer || objects instanceof Long || objects instanceof Double || objects instanceof Float){
                return Double.parseDouble(objects.toString());
            } else if (objects instanceof BigDecimal) {
                return objects;
            }else {
                return objects.toString();
            }
        }else{
            return "";
        }

    }
    private  List<Map<String, Object>>  sqlRunnerList(String sql) {
        return  SqlRunner.db().selectList(sql, String.class);
    }
    private static String MatchSystemParameter(String sql) {
        if(StringUtils.isEmpty(sql)){
            throw new CostException("无效自定义sql语句");
        }
        if (sql.contains(SQLParameter.HOSP_ID_CODE)) {
            sql = sql.replace(SQLParameter.HOSP_ID_CODE, String.valueOf(UserContext.getCurrentLoginHospId()));
        }
        if (sql.contains(SQLParameter.USER_CODE)) {
            sql = sql.replace(SQLParameter.USER_CODE, String.valueOf(UserContext.getCurrentUser().getId()));
        }
        return sql;
    }
}
