<script setup lang="ts">
import { log } from "console";
import moment from "moment";
import { h, nextTick, onMounted, reactive, ref, watch } from "vue";
import {
  formatNumber,
  parseThousandSeparatedNumber,
  wrapTreeNode,
} from "../../../options/serveice";
import request from "../../../request/requestConfig";
import {
  getFieldEnumTree,
  getFieldGetFieEnumList,
  handleGetANALYSISRULEDetail,
  handleGetANALYSISRULEList,
  handleGetMonthINCAnalysis,
  handleSynchroSENTENCE,
  handleTranslateSentence,
} from "../service";
import "./RobotDialogueBox.less";
// @ts-ignore
import detailText from "./detailText";
import axios from "axios";
import { marked } from "marked";

// 判断是否已经展开了对话框
const showDialogBox = ref<boolean>(false);
// 对话框记录
// type: 1 机器人  2 用户   text: 对话框中显示的文字 用户的是直接赋值上去 机器人回复要用v-html出现 isFirst: 只有默认初始的第一局才是true 后面都是false true的时候要显示点击标签
// haveTable:  true 时对话框显示表格  tableData 对话框显示的表格内容  columns 对话框表格 显示的列
let dialogueList = reactive<any>([]);
// 搜索的文字
const searchText = ref<string>();
// 是否让最新的对话框 是加载效果
const isNewDialogLoading = ref<boolean>(false);
// 这一次对话框出现之后问问题的id
const thisQuestionId = ref<any>();
// 第一个对话框出现的tab
const clickTabList: any = [
  { label: "基础信息", value: 1 },
  { label: "经营数据", value: 2 },
  { label: "在营商家", value: 3 },
  { label: "招商分析", value: 4 },
  { label: "收银监管", value: 5 },
  { label: "车辆归属", value: 6 },
  { label: "财务状况", value: 7 },
];
// 当前选中的查询tab
const selectTab = ref<number>(0);
// 当前打印的内容
const printWord = ref<any>();
// 当前是否在打印
const isPrinting = ref<boolean>(false);
// 预警类型的枚举对象
const descObjRef = ref<any>();
const descListRef = ref<any>();
// 业态的枚举类型
const tradeObjRef = ref<any>();
// 打印过程中的加载效果
const printingLoading = ref<boolean>(false);
// 打印过程中加载效果的文字
const printingLoadingText = ref<string>("");
// 是否展开底部的选择标签
const bottomSelect = ref<boolean>(false);
// 判断是否进入了巡检
const duringInspection = ref<boolean>(false);
// 巡检的索引
const inspectionIndex = ref<number>(0);
// 输入框的实例对象
const inputRef = ref<any>();
// 省份信息
const baseInfoObj = ref<any>();
let saveData = localStorage.getItem("baseInfoObj");
if (saveData) {
  baseInfoObj.value = JSON.parse(saveData);
}
// 自己语义对话框的id
let dialogueIdObj = reactive<any>({});

let allID = ref<string>(
  `370,504,373,369,502,368,371,382,478,364,365,366,509,367,803,756,363,381,480,479,708,372,646,496,805,362,477,380,383,656,476,710,494,694,475,714,378,658,507,490,379,489,421,377,376,426,492,819,716,474,811,499,659,428,418,416,429,384,516,941,652,943,522,473,514,445,448,430,518,385,517,417,419,431,446,520,420,513,503,525,434,432,521,422,450,436,515,505,519,524,435,508,444,498,442,439,440,433,511,500,594,510,606,600,443,451,471,501,463,707,460,466,462,456,592,453,465,495,464,706,468,470,963,967,955,951`
);

// deepseek的语言角色说明
const deepseekDesc =
  ref<string>(`你是一个负责将用户查询路由到后台API的智能助手。系统中有以下接口可以调用：
预警接口: 
        接口地址: EShangApiMain/BusinessProject/GetAccountWarningList,
        接口ID: 37,
        用途：查询服务区、全部服务区的预警信息,
        触发关键词: 预警类型,
经营数据: 
        接口地址:CommercialApi/Revenue/GetMonthlyBusinessAnalysis,
        接口ID: 21,
        用途：查询服务区、全部服务区经营数据,
        触发关键词: 经营数据,     
在营商家: 
        接口地址: EShangApiMain/BusinessProject/GetPeriodWarningList,
        接口ID: 29,
        用途: 查询服务区在营商家、项目数量，盈利情况,
        触发关键词: 在营商家,          
项目情况: 
        接口地址: EShangApiMain/BusinessProject/GetAccountWarningList,
        接口ID: 2,
        用途：查询客单数量、客单均价,
        触发关键词: 项目情况,   
财务状况:  
        接口地址: EShangApiMain/Finance/GetContractExcuteAnalysis,
        接口ID: 35,
        用途：查询服务区的财务状况,
        触发关键词: 财务状况,         
车辆归属: 
        接口地址: CommercialApi/BigData/GetProvinceVehicleTreeList,
        接口ID: 33,
        用途：查询服务区的车流情况,
        触发关键词: 车辆归属, 
招商: 
        接口地址:EShangApiMain/Revenue/GetBusinessAnalysisReport,
        接口ID: 31,
        用途：查询服务区的招商数据,
        触发关键词: 招商,   
单车价值: 
        接口地址: EShangApiMain/Analysis/GetRevenueEstimateList,
        接口ID: 27,
        用途：查询服务区单车价值评估数据,
        触发关键词: 单车价值,     
资产坪效: 
        接口地址: EShangApiMain/Analysis/GetASSETSPROFITSTreeList,
        接口ID: 23,
        用途：分析服务区门店资产平效,
        触发关键词: SERVERPART_IDS, Start_DATE, End_DATE 等,
SABFI|商业适配指数: 
        接口地址:CommercialApi/Revenue/GetShopSABFIList,
        接口ID: 25,
        用途：查询服务区门店商业适配指数,
        触发关键词: SABFI|商业适配指数, 
销售|营收|收入|经营情况: 
        接口地址:EShangApiMain/Revenue/GetRevenueReport,
        接口ID: 4,
        用途：查询营收数据,
        触发关键词: 销售|营收|收入|经营情况,
商家情况|商家盈利: 
        接口地址:EShangApiMain/BusinessProject/GetPeriodWarningList,
        接口ID: 3,
        用途：查询客单数量、客单均价,
        触发关键词:商家情况|商家盈利,  
同比|环比|同环比: 
        接口地址: EShangApiMain/Revenue/GetRevenueYOYQOQ,
        接口ID: 11,
        用途: 查询营收同环比,
        触发关键词: 同比|环比|同环比,
节假日|元旦|春节|清明节|劳动节|端午节|中秋节|国庆节|清明|五一|端午|中秋|国庆|暑假|暑期|春运: 
        接口地址: CommercialApi/Revenue/GetServerpartINCAnalysis,
        接口ID: 15,
        用途：查询节日营收（含同比）,
        触发关键词: 节假日|元旦|春节|清明节|劳动节|端午节|中秋节|国庆节|清明|五一|端午|中秋|国庆|暑假|暑期|春运,          
客单均价|客单: 
        接口地址:CommercialApi/Revenue/GetMonthINCAnalysis,
        接口ID: 19,
        用途：查询客单数量、客单均价,
        触发关键词: 客单均价|客单,  
车流|入区: 
        接口地址:CommercialApi/Revenue/GetMonthINCAnalysis,
        接口ID: 1,
        用途：查询客单数量、客单均价,
        触发关键词: 车流|入区,        
基础信息:
        接口地址: CommercialApi/BaseInfo/GetServerpartInfo,
        接口ID: 17,
        用途：查询服务区基础信息,
        触发关键词: 基础信息,  
在触发关键词中的|字符，表示或者的意思，
你的任务是：
    根据用户的自然语言查询,识别用户想要调用的一个或多个API；
    不需要返回思考过程，最终只输出API接口ID，无需其他文字说明，若多个接口返回则把接口ID放在一个数组中
        `);

onMounted(() => {
  // 默认在初始显示的

  // 请求枚举
  handleGetFieldEnum();
});

// 展开机器人的方法  第一次要执行默认打招呼语 如果已经有了对话记录 就只是展开
const handleGetShowDailogBox = async () => {
  if (dialogueList && dialogueList.length > 0) {
    await nextTick(() => {
      showDialogBox.value = true;
      emit("handleShowAi", true);
    });
    inputRef.value?.focus();
    console.log("dialogueList", dialogueList);
    // 给每个带有isVHtml 的对话框 赋值上对应的VHtml
    const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
    console.log("allBoxes", allBoxes);

    dialogueList.forEach((item: any, index: number) => {
      if (item.isVHtml) {
        allBoxes[index].innerHTML = item.VHtml;
      }
    });
  } else {
    isNewDialogLoading.value = true;
    let obj: any = {
      type: 1,
      text: "",
      isFirst: true,
      isOver: false,
    };
    dialogueList.push(obj);
    showDialogBox.value = true;
    emit("handleShowAi", true);
    setTimeout(() => {
      dialogueList[0].text = "猜你想了解：";
      dialogueList[0].isOver = true;
      isNewDialogLoading.value = false;
      nextTick(() => {
        // 聚焦
        console.log("inputRef.value", inputRef.value);
        inputRef.value?.focus();
      });
    }, 1000);
  }
};
// 关闭对话框
const handleCloseDialogbox = async () => {
  console.log("dialogueList", dialogueList);

  const allBoxes = document.querySelectorAll(".dialogueTextBox-text");

  // 等待 nextTick 确保 DOM 更新
  await nextTick(() => {
    if (allBoxes && allBoxes.length > 0) {
      const lastBox = allBoxes[allBoxes.length - 1];

      // 获取最后一个对话框的对象
      let obj: any = dialogueList[dialogueList.length - 1];
      obj.isOver = true; // 标记为结束
      isPrinting.value = false; // 停止打印

      // 确保 obj.VHtml 存在并赋值
      if (obj.VHtml) {
        lastBox.innerHTML = obj.VHtml;
        console.log("lastBox", lastBox);
      } else {
        console.warn("VHtml is empty or undefined", obj);
      }
    }
  });

  // 关闭对话框
  showDialogBox.value = false;
  emit("handleShowAi", false);
};
// 添加对话内容的方法
const handleAddDialogList = (text: string) => {
  let userObj: any = {
    type: 2,
    text: text,
    isFirst: false,
  };
  let robotObj: any = {
    type: 1,
    text: "",
    isFirst: false,
  };

  dialogueList.push(userObj);
  handleScrollToBottom();
  dialogueList.push(robotObj);
  handleScrollToBottom();
  isNewDialogLoading.value = true;
};
// 只添加人的问题
const handleAddUserDialog = (text: string) => {
  let userObj: any = {
    type: 2,
    text: text,
    isFirst: false,
  };
  dialogueList.push(userObj);
  handleScrollToBottom();
};
// 只添加机器人的回话
const handleAddRobotDialog = () => {
  let robotObj: any = {
    type: 1,
    text: "",
    isFirst: false,
  };
  dialogueList.push(robotObj);
  handleScrollToBottom();
  isNewDialogLoading.value = true;
};
// 给最后一个对话框赋值上结果 且关闭加载效果
const handleLastUpdate = (str: any) => {
  dialogueList[dialogueList.length - 1].text = str;
  dialogueList[dialogueList.length - 1].isOver = true;
  isNewDialogLoading.value = false;
  handleScrollToBottom();
};

// 给多层级树状表格结构加上rowKey
const handleSetRowKeyTable = (list: any) => {
  console.log("list", list);

  if (list && list.length > 0) {
    let res: any = JSON.parse(JSON.stringify(list));
    res.forEach((item: any, index: number) => {
      item.rowKey = `${index + 1}`;
      if (item.children && item.children.length > 0) {
        item.children.forEach((subItem: any, subIndex: number) => {
          subItem.rowKey = `${index + 1}-${subIndex + 1}`;
          if (subItem.children && subItem.children.length > 0) {
            subItem.children.forEach((thirdItem: any, thirdIndex: number) => {
              thirdItem.rowKey = `${index + 1}-${subIndex + 1}-${
                thirdIndex + 1
              }`;
              if (thirdItem.children && thirdItem.children.length > 0) {
                thirdItem.children.forEach(
                  (fourthItem: any, fourthIndex: number) => {
                    fourthItem.rowKey = `${index + 1}-${subIndex + 1}-${
                      thirdIndex + 1
                    }-${fourthIndex + 1}`;
                    if (fourthItem.children && fourthItem.children.length > 0) {
                      fourthItem.children.forEach(
                        (fifthItem: any, fifthIndex: number) => {
                          fourthItem.rowKey = `${index + 1}-${subIndex + 1}-${
                            thirdIndex + 1
                          }-${fourthIndex + 1}-${fifthIndex + 1}`;
                        }
                      );
                    }
                  }
                );
              }
            });
          }
        });
      }
    });
    return res;
  } else {
    return [];
  }
};

// 配置请求的方法
const handleConfigRequest = async (
  url: any,
  params: any,
  detail: any,
  config: any,
  answer?: any
) => {
  // url 请求地址  params 参数  detail 配置项详情   config 配置输出结果的格式  answer 拿到回答问题的数据
  let data: any;
  console.log("handleConfigRequest");

  // if (config.acceptVerbs === "get") {
  //   data = await request.get(url, params);
  // } else {
  //   data = await request.post(url, params);
  // }

  try {
    if (config.acceptVerbs === "get") {
      // 尝试发起 GET 请求
      data = await request.get(url, params);
    } else {
      // 尝试发起 POST 请求
      data = await request.post(url, params);
    }
  } catch (error) {
    // 捕获请求错误，并返回 false，防止代码中断
    console.error("请求发生错误:", error);
    data = false; // 或者根据需要返回其他值
  }

  console.log("dssadasconfig", config);
  console.log("detail", detail);
  console.log("data22321", data);
  if (
    data === false ||
    (data.Result_Code !== 100 && data.Result_Code !== 200)
  ) {
    return false;
  }

  // 系统默认
  if (detail.RULE_SOURCE === 1000) {
    // object 输出 data.Result_Data
    if (config.responseFormat === "object") {
      return data.Result_Data;
    } else if (config.responseFormat === "List") {
      return data.Result_Data.List;
    } else if (config.responseFormat === "nestingList") {
      let resultNest: any = handleSetRowKeyTable(
        wrapTreeNode(data.Result_Data.List)
      );
      // 如果是要计算合计值 且需要的输出对象是个对话的话
      if (config.calculateTotal) {
        return handleGetListSumObj(resultNest, config.totalField);
      }
      return resultNest;
    }
  } else {
    // 用户自定义
    if (config.responseFormat === "nestingList") {
      data = handleSetRowKeyTable(wrapTreeNode(data.Result_Data.List));
    } else if (config.responseFormat === "object") {
      return data.Result_Data;
    } else {
      data = handleSetRowKeyTable(data.Result_Data.List);
    }

    // 如果接口返回的数据 子集不是用children命令的 那么就得转一下 把那个命令的 变成 children
    if (config?.shopList) {
      if (data && data.length > 0) {
        data.forEach((item: any) => {
          if (item[config?.shopList] && item[config?.shopList].length > 0) {
            item.children = item[config?.shopList];
            item[config?.shopList] = null;
          } else {
            if (item.children && item.children.length > 0) {
              item.children.forEach((subItem: any) => {
                if (
                  subItem[config?.shopList] &&
                  subItem[config?.shopList].length > 0
                ) {
                  subItem.children = subItem[config?.shopList];
                  subItem[config?.shopList] = null;
                } else {
                  if (subItem.children && subItem.children.length > 0) {
                    subItem.children.forEach((thirdItem: any) => {
                      if (
                        thirdItem[config?.shopList] &&
                        thirdItem[config?.shopList].length > 0
                      ) {
                        thirdItem.children = thirdItem[config?.shopList];
                        thirdItem[config?.shopList] = null;
                      } else {
                        if (
                          thirdItem.children &&
                          thirdItem.children.length > 0
                        ) {
                          thirdItem.children.forEach((fourthItem: any) => {
                            if (
                              fourthItem[config?.shopList] &&
                              fourthItem[config?.shopList].length > 0
                            ) {
                              fourthItem.children =
                                fourthItem[config?.shopList];
                              fourthItem[config?.shopList] = null;
                            }
                          });
                        }
                      }
                    });
                  }
                }
              });
            }
          }
        });
      }
    }
    let newRes: any;
    // 根据输出结果的的配置 去处理接口返回的结果
    // 先判断是单个服务区 还是多个服务区

    if (answer?.ServerpartId && answer?.ServerpartId.indexOf(",") === -1) {
      console.log("config3232", config);
      //   单个服务区 那么要去掉合计和片区层 只展示服务区层即以下
      if (config?.serverpart) {
        if (data && data.length > 0) {
          data.forEach((item: any, index: number) => {
            if (config?.serverpart === 1) {
              newRes = [item];
            } else {
              if (item.children && item.children.length > 0) {
                item.children.forEach((subItem: any, subIndex: number) => {
                  if (config?.serverpart === 2) {
                    newRes = [subItem];
                  } else {
                    if (subItem.children && subItem.children.length > 0) {
                      subItem.children.forEach(
                        (thirdItem: any, thirdIndex: number) => {
                          if (config?.serverpart === 3) {
                            newRes = [thirdItem];
                          } else {
                            if (
                              thirdItem.children &&
                              thirdItem.children.length > 0
                            ) {
                              thirdItem.children.forEach(
                                (fourthItem: any, fourthIndex: number) => {
                                  if (config?.serverpart === 4) {
                                    newRes = [fourthItem];
                                  }
                                }
                              );
                            }
                          }
                        }
                      );
                    }
                  }
                });
              }
            }
          });
        }
      } else {
        // 不需要处理服务区的 就输出原本的格式
        newRes = data;
      }
    } else {
      //   多个服务区就不做处理了
      newRes = data;
    }
    console.log("newRes", newRes);

    // 判断一下showLevel 只显示哪一层
    console.log("dasdas", config);

    let finalRes: any = [];

    if (config.showLevel) {
      if (newRes && newRes.length > 0) {
        newRes.forEach((item: any) => {
          if (config.showLevel === 1) {
            finalRes.push(item);
          }
          if (item.children && item.children.length > 0) {
            item.children.forEach((subItem: any) => {
              if (config.showLevel === 2) {
                finalRes.push(subItem);
              }
              if (subItem.children && subItem.children.length > 0) {
                subItem.children.forEach((thirdItem: any) => {
                  if (config.showLevel === 3) {
                    finalRes.push(thirdItem);
                  }
                  if (thirdItem.children && thirdItem.children.length > 0) {
                    thirdItem.children.forEach((fourthItem: any) => {
                      if (config.showLevel === 4) {
                        finalRes.push(fourthItem);
                      }
                    });
                  }
                });
              }
            });
          }
        });
      }
    } else {
      finalRes = newRes;
    }

    return finalRes;
  }
};

// 判断一下 是不是要数据的某几项合计值 写一个方法在外面 需要的时候判断
const handleGetListSumObj = (list: any, str: any) => {
  // list 从这个数据源里面拿到 合计数据  str 用，号隔开的 需要哪几个字段的合计值
  if (str) {
    // 存累计值的
    let sumObj: any = {};
    for (let key in str) {
      if (key === "sum") {
        if (str[key].indexOf(",") === -1) {
          list.forEach((item: any) => {
            if (item[str[key]]) {
              if (sumObj[str[key] + "sum"]) {
                sumObj[str[key] + "sum"] += Number(item[str[key]]);
              } else {
                sumObj[str[key] + "sum"] = Number(item[str[key]]);
              }
            }
          });
        } else {
          let strList: any = str[key].split(",");
          if (strList && strList.length > 0) {
            strList.forEach((item: any) => {
              list.forEach((subItem: any) => {
                if (subItem[item]) {
                  if (sumObj[item + "sum"]) {
                    sumObj[item + "sum"] += Number(subItem[item]);
                  } else {
                    sumObj[item + "sum"] = Number(subItem[item]);
                  }
                }
              });
            });
          }
        }
      } else if (key === "greaterThan0") {
        if (str[key].indexOf(",") === -1) {
          list.forEach((item: any) => {
            if (item[str[key]] > 0) {
              if (sumObj[str[key] + "greaterThan0"]) {
                sumObj[str[key] + "greaterThan0"] += 1;
              } else {
                sumObj[str[key] + "greaterThan0"] = 1;
              }
            }
          });
        } else {
          let strList: any = str[key].split(",");
          if (strList && strList.length > 0) {
            strList.forEach((item: any) => {
              list.forEach((subItem: any) => {
                if (subItem[item]) {
                  if (sumObj[item + "greaterThan0"]) {
                    sumObj[item + "greaterThan0"] += 1;
                  } else {
                    sumObj[item + "greaterThan0"] = 1;
                  }
                }
              });
            });
          }
        }
      } else if (key === "lessThan0") {
        if (str[key].indexOf(",") === -1) {
          list.forEach((item: any) => {
            if (item[str[key]] < 0) {
              if (sumObj[str[key] + "lessThan0"]) {
                sumObj[str[key] + "lessThan0"] += 1;
              } else {
                sumObj[str[key] + "lessThan0"] = 1;
              }
            }
          });
        } else {
          let strList: any = str[key].split(",");
          if (strList && strList.length > 0) {
            strList.forEach((item: any) => {
              list.forEach((subItem: any) => {
                if (subItem[item]) {
                  if (sumObj[item + "lessThan0"]) {
                    sumObj[item + "lessThan0"] += 1;
                  } else {
                    sumObj[item + "lessThan0"] = 1;
                  }
                }
              });
            });
          }
        }
      }
    }
    console.log("sumObj", sumObj);
    // 给输出的全部数据都格式化一下
    // for (let key in sumObj) {
    //   if (typeof sumObj[key] === "number") {
    //     sumObj[key] = formatNumber(sumObj[key]);
    //   }
    // }
    sumObj.dataLength = list.length;

    // 第二级的数量合计
    let smallSum: number = 0;
    list.forEach((item: any) => {
      if (item.children && item.children.length > 0) {
        item.children.forEach((subItem: any) => {
          smallSum +=
            subItem.children && subItem.children.length > 0
              ? subItem.children.length
              : 0;
        });
      }
    });
    sumObj.smallSum = smallSum;
    return sumObj;
  }
};

// 封装一下 拿到入参的方法
const handleGetReq = (configDetail: any, answer?: any) => {
  let req: any = {};
  let newReq: any = configDetail?.PARAM_TEMPLATE
    ? JSON.parse(configDetail?.PARAM_TEMPLATE)
    : ""; // 入参
  let newPARSING_RULES: any = configDetail?.PARSING_RULES
    ? JSON.parse(configDetail?.PARSING_RULES)
    : ""; // 对应的规则

  console.log("newReq", newReq);
  console.log("newPARSING_RULES", newPARSING_RULES);

  if (newReq) {
    for (let key in newReq) {
      let realKey: any = newPARSING_RULES[key];
      if (realKey) {
        let currentUser: any = {
          ProvinceCode: "340000",
          pushProvinceCode: "340000",
        };
        // formatType   0：数值  1：字段  2：取缓存  3：取年份  4: 取月份  5：取日期 6：取当年 7：取前一年 8: 取当年的月份 9：取当前的首月 10：自定义  11: 取选中的服务区里面的值
        // 当formatType 为10的时候  now  判断是不是要现在时间 true|false  afterOrBefore 往当前时间前推还是后推 after|before  count 前推或后推几个月 startOrEnd start|end  dateType 显示格式 1 YYYY 2 YYYY-MM 3 YYYY-MM-DD 4 YYYYMM
        // fieldName 就是去resData里面去字段    value  formatType为0的时候直接取值  haveDefault 判断是否有默认值 如果是true即使answer中无值 也能取到默认值 一般用在日期时间上
        // 当formatType为7的时候 取判断 value  1：取前一年  2：取前一个月 3：取前一天
        if (realKey.formatType === 1) {
          req[key] = answer[realKey.fieldName];
        } else if (realKey.formatType === 0) {
          req[key] = realKey.value;
        } else if (realKey.formatType === 2) {
          req[key] = currentUser[realKey.fieldName];
        } else if (realKey.formatType === 3) {
          req[key] = answer[realKey.fieldName]
            ? moment(answer[realKey.fieldName]).format("YYYY")
            : realKey.haveDefault
            ? moment().format("YYYY")
            : "";
        } else if (realKey.formatType === 4) {
          req[key] = answer[realKey.fieldName]
            ? moment(answer[realKey.fieldName]).format("YYYYMM")
            : realKey.haveDefault
            ? moment().format("YYYYMM")
            : "";
        } else if (realKey.formatType === 5) {
          req[key] = answer[realKey.fieldName]
            ? moment(answer[realKey.fieldName]).format("YYYY-MM-DD")
            : realKey.haveDefault
            ? moment().format("YYYY-MM-DD")
            : "";
        } else if (realKey.formatType === 6) {
          req[key] = moment().format("YYYY");
        } else if (realKey.formatType === 7) {
          req[key] =
            realKey.value === 1
              ? moment().subtract(1, "year").format("YYYY")
              : realKey.value === 2
              ? moment().subtract(1, "m").format("YYYYMM")
              : realKey.value === 3
              ? moment().subtract(1, "d").format("YYYY-MM-DD")
              : "";
        } else if (realKey.formatType === 8) {
          req[key] = moment().format("MM");
        } else if (realKey.formatType === 9) {
          req[key] = moment().startOf("year").format("YYYYMM");
        } else if (realKey.formatType === 10) {
          if (realKey.now) {
            if (realKey.startOrEnd === "start") {
              req[key] = moment().startOf("month");
            } else if (realKey.startOrEnd === "end") {
              req[key] = moment().endOf("month");
            }

            if (realKey.dateType === 1) {
              req[key] = moment(req[key]).format("YYYY");
            } else if (realKey.dateType === 2) {
              req[key] = moment(req[key]).format("YYYY-MM");
            } else if (realKey.dateType === 3) {
              req[key] = moment(req[key]).format("YYYY-MM-DD");
            } else if (realKey.dateType === 4) {
              req[key] = moment(req[key]).format("YYYYMM");
            }
          } else {
            if (realKey.afterOrBefore === "after") {
              req[key] = moment().add(realKey.count, "month");
            } else if (realKey.afterOrBefore === "before") {
              req[key] = moment().subtract(realKey.count, "month");
            }
            if (realKey.startOrEnd === "start") {
              req[key] = moment(req[key]).startOf("month");
            } else if (realKey.startOrEnd === "end") {
              req[key] = moment(req[key]).endOf("month");
            }

            if (realKey.dateType === 1) {
              req[key] = moment(req[key]).format("YYYY");
            } else if (realKey.dateType === 2) {
              req[key] = moment(req[key]).format("YYYY-MM");
            } else if (realKey.dateType === 3) {
              req[key] = moment(req[key]).format("YYYY-MM-DD");
            } else if (realKey.dateType === 4) {
              req[key] = moment(req[key]).format("YYYYMM");
            }
          }
        } else if (realKey.formatType === 11) {
          req[key] = props.currentServerPartDetail?.[realKey.fieldName] ?? "";
        }
      }
    }
  }

  return req;
};

// 去解析配置项 输出结果
const handleAnalyzeConfig = async (configDetail: any, answer: any) => {
  // configDetail 配置内容   answer 回答问题接口返回的内容
  console.log("configDetail321321", configDetail);

  let newReq: any = configDetail?.PARAM_TEMPLATE
    ? JSON.parse(configDetail?.PARAM_TEMPLATE)
    : ""; // 入参
  let OUTPUT_FORMAT: any = configDetail?.OUTPUT_FORMAT
    ? JSON.parse(configDetail?.OUTPUT_FORMAT)
    : ""; // 输出格式
  let newRESPONSE_CONFIG: any =
    OUTPUT_FORMAT?.responseType === "text"
      ? configDetail?.RESPONSE_CONFIG
      : configDetail?.RESPONSE_CONFIG
      ? JSON.parse(configDetail?.RESPONSE_CONFIG)
      : ""; // 出参
  let newPARSING_RULES: any = configDetail?.PARSING_RULES
    ? JSON.parse(configDetail?.PARSING_RULES)
    : ""; // 对应的规则

  console.log("newReq", newReq);
  console.log("newRESPONSE_CONFIG", newRESPONSE_CONFIG);
  console.log("newPARSING_RULES", newPARSING_RULES);
  console.log("OUTPUT_FORMAT", OUTPUT_FORMAT);
  console.log("configDetail", configDetail);

  // 配置请求的参数
  let req: any = handleGetReq(configDetail, answer);
  console.log("req2", req);

  // 给post的请求 的参数 需要包一层的包一层
  if (OUTPUT_FORMAT) {
    if (OUTPUT_FORMAT.paramsFormat === "searchModel") {
      let newReq: any = {
        SearchParameter: {
          ...req,
        },
      };
      req = newReq;
    }
  }

  // 判断是不是有了全部数据  如果有参数是未填写的且可以取默认数据
  // 判断req里面全空值
  let haveALLNull: boolean = true;
  for (let key in req) {
    if (req[key]) {
      haveALLNull = false;
    }
  }

  console.log("reqreqreqreqreq", req);
  if (!req.ServerpartId) {
    req.ServerpartId = allID.value;
  }

  // 配置请求
  // 接口返回的结果
  let result: any;
  if (haveALLNull) {
    result = configDetail?.ANALYSISRULE_DESC ?? "";
  } else {
    if (OUTPUT_FORMAT) {
      result = await handleConfigRequest(
        configDetail?.API_ENDPOINT,
        req,
        configDetail,
        OUTPUT_FORMAT,
        answer
      );
    }
  }

  // if (!result) {
  //   return {
  //     api: configDetail?.API_ENDPOINT,
  //     nowReq: req,
  //     needReq: JSON.parse(configDetail?.PARAM_TEMPLATE),
  //     dataType: 'noData'
  //   };
  // }

  // 根据输出结果的配置 去修改实际值
  console.log("dsadsadasf", result);
  console.log("OUTPUT_FORMAT", OUTPUT_FORMAT);
  console.log("answer", answer);
  console.log("newRESPONSE_CONFIG", newRESPONSE_CONFIG);

  let newResult: any;
  // 判断responseType 格式是否为 text 一般都为json  function时 说明调用这个组件的某个方法
  if (OUTPUT_FORMAT.responseType === "text") {
    newResult = newRESPONSE_CONFIG
      .replace(/"/g, "'")
      .replace(/{{(.*?)}}/g, (_: any, expression: any) => {
        try {
          // 使用 eval 执行模板字符串中的 JavaScript 表达式
          // 注意：eval 存在安全风险，实际使用中需小心。
          return eval(expression.trim()); // 执行并返回结果
        } catch (error) {
          console.error("错误：", error);
          return ""; // 出现错误时返回空字符串
        }
      });

    // newResult = newRESPONSE_CONFIG.replace(
    //   /\{\{(.*?)\}\}/g,
    //   (_: any, expression: any) => {
    //     try {
    //       // 创建一个安全的执行上下文
    //       const func = new Function(
    //         ...Object.keys({
    //           moment: window.moment,
    //           answer,
    //           result,
    //           formatNumber,
    //         }),
    //         `return (${expression});`
    //       );
    //       return func(
    //         ...Object.values({
    //           moment: window.moment,
    //           answer,
    //           result,
    //           formatNumber,
    //         })
    //       );
    //     } catch (e) {
    //       console.error("模板解析错误：", expression, e);
    //       return "";
    //     }
    //   }
    // );
  } else if (OUTPUT_FORMAT.responseType === "function") {
    await handleGetConfigFun(
      OUTPUT_FORMAT.responseFunName,
      req.ServerpartId,
      result
    );
    return null;
  } else {
    newResult = result;
    // if (OUTPUT_FORMAT.responseFormat === "object") {
    // newResult = result;
    // } else {
    // newResult = handleChangeTableList(result, newRESPONSE_CONFIG);
    // }
  }

  console.log("newResult", newResult);
  return newResult;
};
// 去循环处理一个数组里面的数据 是否符合配置项的要求
const handleChangeTableList = (list: any, config: any) => {
  if (list && list.length > 0) {
    let res: any = [];
    list.forEach((item: any) => {
      let obj: any = handleChangeListItem(item);
      obj = handleChangeObj(obj, config);
      res.push(obj);
    });
    return res;
  } else {
    return [];
  }
};

// 判断如果数组的一个对象里面的一个字段是对象的话 就要把这个对象里面的值拆到外面来
const handleChangeListItem = (item: any, parentKey?: any) => {
  if (item) {
    let obj: any = {};
    for (let key in item) {
      if (
        typeof item[key] === "object" &&
        item[key] !== null &&
        key !== "children"
      ) {
        let newObj: any = handleChangeListItem(item[key], key);
        for (let smallKey in newObj) {
          obj[`${key}${smallKey}`] = newObj[smallKey];
        }
      } else {
        obj[key] = item[key];
      }
    }
    return obj;
  }
};

// 处理对象
const handleChangeObj = (obj: any, config: any) => {
  if (obj) {
    let newObj: any = JSON.parse(JSON.stringify(obj));
    for (let key in config) {
      if (newObj[key] || key === "Name") {
        let configObj: any = config[key];
        for (let samllKey in configObj) {
          // 判断是不是要以万元为单位
          if (configObj["isTenThousand"] && samllKey === "isTenThousand") {
            newObj[key] =
              typeof newObj[key] === "number"
                ? newObj[key] / 10000
                : formatNumber(
                    parseThousandSeparatedNumber(newObj[key]) / 10000
                  );
          }
          // 判断是不是要加上百分比
          if (configObj["isRate"] && samllKey === "isRate") {
            newObj[key] = newObj[key] + "%";
          }
          // 判断是不是金额 金额的话 要加上千分号
          if (configObj["isMoney"] && samllKey === "isMoney") {
            newObj[key] =
              typeof newObj[key] === "number"
                ? formatNumber(newObj[key])
                : formatNumber(parseThousandSeparatedNumber(newObj[key]));
          }
          // 判断这个字段 是不是像片区 服务区 门店 这样的 多个字段显示同一列的 如果是 就改值 只有prop(key)为Name的时候 才会有这个
          if (configObj["multipleNames"]) {
            // 单列多名称的优先级  priority越前面的优先级越低
            let priority: any = configObj["multipleNames"].split(",");
            if (priority && priority.length > 0) {
              priority.forEach((item: any) => {
                if (newObj[item]) {
                  newObj[key] = newObj[item];
                }
              });
            }
          }
        }
      }
    }

    if (newObj.children && newObj.children.length > 0) {
      newObj.children = handleChangeTableList(newObj.children, config);
    }
    return newObj;
  } else {
    return {};
  }
};

// 给一个对象 对象里面有字段的值是对象 输出拆了的对象数据到老对象中
const disasseListObj = (obj: any) => {
  let old: any = {};
  for (let key in obj) {
    if (
      typeof obj[key] === "object" &&
      obj[key] !== null &&
      key !== "children"
    ) {
      let smallObj: any = obj[key];
      for (let smallKey in smallObj) {
        old[`${key}${smallKey}`] = smallObj[smallKey];
      }
    } else {
      old[key] = obj[key];
    }
  }
  console.log("old", old);

  return old;
};

// 拆解对象字段到外面那个字段里面去
const disassembleObjects = (obj: any, parentKey: any) => {
  let res: any = [];
  let addKey: any = {};
  if (obj["name"]) {
    addKey = {
      key: parentKey,
      name: obj["name"],
    };
  }
  if (obj["children"]) {
    console.log("children", obj["children"]);
    let list: any = handleChangeShow(obj["children"], addKey);
    console.log("fdjksfjsd", list);
    if (list && list.length > 0) {
      list.forEach((item: any) => {
        res.push(item);
      });
    }
  }

  for (let key in obj) {
    if (
      key !== "name" &&
      key !== "children" &&
      typeof obj[key] === "object" &&
      obj[key] !== null
    ) {
      let list: any = disassembleObjects(obj[key], key);
      if (list && list.length > 0) {
        list.forEach((item: any) => {
          res.push(item);
        });
      }
    }
  }

  return res;
};

// 表格显示字段的递归处理
const handleChangeShow = (obj: any, addObj?: any) => {
  let columnsList: any = [];
  for (let key in obj) {
    let newObj: any = obj[key];

    // descObjRef

    columnsList.push({
      width: newObj.width,
      label: newObj.label,
      prop: newObj.prop,
      align: newObj.align,
      "show-overflow-tooltip": true,
      isSlot: newObj.isSlot,
      isMoney: newObj.isMoney,
      isRate: newObj.isRate,
      showDic: newObj.showDic,
      DicObj: newObj.DicObj,
    });
  }
  return columnsList;
};
// 格式化列表单元格
const renderCell = (row: any, column: any) => {
  const value = row[column.prop];
  // 根据列类型格式化显示
  if (column.isMoney) {
    return `<span style="text-align: right">${formatNumber(value)}</span>`;
  }
  if (column.isRate) {
    return `<span style="color: ${
      value > 0 ? "green" : "red"
    };text-align: right">${value}%</span>`;
  }

  return `<span>${value}</span>`;
};

// 如果请求接口的结果是对象中的某个参数 且这个对象可能是多级的 最后输出最终字段  只能取一个字段
const handleGetResFieldRes = (obj: any, config: any) => {
  let str: string = "";
  for (let key in config) {
    if (config[key] && obj[key]) {
      str = handleGetResFieldRes(obj[key], config[key]);
    } else if (obj[key] && !config[key]) {
      str = obj[key];
    }
  }
  if (str) {
    return str;
  } else {
    return "暂无数据";
  }
};

// 给巡检添加自定义文字输出的方法
const handleInspectionDialogueBox = async (detail: any, otherObj?: any) => {
  // 要输出的文字内容
  let str: string = `${
    props.currentServerPartDetail.SERVERPART_NAME
  }：<span class="style4">天气情况：${
    props.currentServerPartDetail.weatherModel
      ? `<span class="style5">${"今天"}(${moment().format("YYYY-MM-DD")})${
          detail.weatherModel.DAY_WEATHER
        }转${detail.weatherModel.NIGHT_WEATHER}，气温${
          detail.weatherModel.NIGHT_AIR_TEMPERATURE
        }℃~${
          detail.weatherModel.DAY_AIR_TEMPERATURE
        }℃</span><span class="style5">${"明天"}(${moment()
          .add(1, "d")
          .format("YYYY-MM-DD")})${detail.tmwWeatherModel.DAY_WEATHER}转${
          detail.tmwWeatherModel.NIGHT_WEATHER
        }，气温${detail.tmwWeatherModel.NIGHT_AIR_TEMPERATURE}℃~${
          detail.tmwWeatherModel.DAY_AIR_TEMPERATURE
        }℃</span>`
      : "暂无天气数据"
  }</span><span class="style4">实时路况：<span class="style5">${
    detail?.roadConditions
      ? `${
          detail?.roadConditions?.EXPRESSWAY_NAME
            ? detail?.roadConditions?.EXPRESSWAY_NAME + "："
            : ""
        }${
          detail?.roadConditions?.evaluation.status_desc || ""
        }(${moment().format("MM月DD日 HH时mm分")})`
      : "暂无实况车流数据"
  } </span></span><span class="style4">车辆归属：${
    detail?.provinceListTooltip && detail?.provinceListTooltip.length > 0
      ? `${detail?.provinceListTooltip
          .map((item: any) => {
            return `<span class="style5">${moment(
              moment().startOf("year")
            ).format("YYYY年MM月")}至${moment().format("YYYY年MM月")}${
              detail?.SERVERPART_NAME || ""
            }总入区车流：${formatNumber(item.TotalCount || 0)}</span>${
              item.children && item.children.length > 0
                ? item.children
                    .map((subItem: any) => {
                      return `<span class="style5">${
                        subItem.ProvinceOrCityName
                      }：占比：${formatNumber(
                        (subItem.TotalCount / item.TotalCount) * 100
                      )}%，Top3：${
                        subItem.children && subItem.children.length > 0
                          ? subItem.children
                              .map((thirdItem: any, thirdIndex: number) => {
                                return thirdItem.ProvinceOrCityName !== "其他"
                                  ? `${thirdItem.ProvinceOrCityName}${
                                      thirdIndex + 1 !== subItem.children.length
                                        ? "、"
                                        : ""
                                    }`
                                  : "";
                              })
                              .join("")
                          : ""
                      }</span>`;
                    })
                    .join("")
                : ""
            }`;
          })
          .join("")}`
      : "暂无车辆归属地数据"
  }</span>${
    otherObj
      ? `${
          otherObj?.businessText
            ? `<span class="style4">经营数据：</span><span class="style4">${otherObj?.businessText}</span>`
            : ""
        }${
          otherObj?.merchantText
            ? `<span class="style4">在营商家：${otherObj?.merchantText}</span>`
            : ""
        }`
      : ""
  }`;
  // 解除对话框的加载效果
  isNewDialogLoading.value = false;
  // 拿到最后一个对话框的数据
  let obj: any = JSON.parse(
    JSON.stringify(dialogueList[dialogueList.length - 1])
  );
  // 给对话框赋值上要打印的内容
  obj.VHtml = str;
  // 让对话框知道 这个文字是要打印的
  dialogueList[dialogueList.length - 1] = {
    ...obj,
    isVHtml: true,
  };
  await nextTick();

  // 文字通过打字机效果实现
  const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
  const lastBox: any = allBoxes[allBoxes.length - 1];
  if (lastBox) {
    const lastContent = str;
    isPrinting.value = true;
    await handlePrintWord(lastBox, lastContent);
  }

  dialogueList[dialogueList.length - 1].isOver = true;
};

// 配置对话框表格的样式 或 文字样式
const handleConfigItemTable = async (
  tableData: any,
  configObj: any,
  answer: any
) => {
  let str: string = "";

  if (typeof tableData === "string") {
    str = tableData.toString();
  } else if (typeof tableData === "object" && tableData !== null) {
    // 输出结果的对象
    let resultObj: any = configObj?.RESPONSE_CONFIG
      ? JSON.parse(configObj.RESPONSE_CONFIG)
      : "";
    if (resultObj) {
      str = handleGetResFieldRes(tableData, resultObj);
    }
  } else {
    let obj: any = JSON.parse(
      JSON.stringify(dialogueList[dialogueList.length - 1])
    );
    str = obj.text;
  }

  isNewDialogLoading.value = false;
  let obj: any = JSON.parse(
    JSON.stringify(dialogueList[dialogueList.length - 1])
  );
  if (str) {
    obj.VHtml = str;
  }

  dialogueList[dialogueList.length - 1] = {
    ...obj,
    isVHtml: true,
  };
  await nextTick();

  // 文字通过打字机效果实现
  const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
  const lastBox: any = allBoxes[allBoxes.length - 1];
  if (lastBox) {
    const lastContent = str;
    isPrinting.value = true;
    await handlePrintWord(lastBox, lastContent);
  }

  // 判断是否需要出现表格
  if (configObj.ENABLE_TABLE === 1) {
    // 如果有表格的话 配置列表的显示列
    if (configObj) {
      let resObj: any = JSON.parse(configObj.RESPONSE_CONFIG);
      let columns: any = [];
      if (resObj) {
        columns = handleChangeShow(resObj);
        console.log("columns", columns);
      }
      let obj: any = JSON.parse(
        JSON.stringify(dialogueList[dialogueList.length - 1])
      );
      console.log("configObjconfigObjconfigObjconfigObj", configObj);
      // 显示的时间设置
      let timeStr: string = "";
      let OUTPUT_FORMAT: any;
      if (configObj.OUTPUT_FORMAT) {
        OUTPUT_FORMAT = JSON.parse(configObj.OUTPUT_FORMAT);
        console.log("OUTPUT_FORMAT", OUTPUT_FORMAT);
        if (
          (OUTPUT_FORMAT.DateFormat || OUTPUT_FORMAT.DateFormat === 0) &&
          (OUTPUT_FORMAT.DateType || OUTPUT_FORMAT.DateType === 0)
        ) {
          let time = "";
          if (OUTPUT_FORMAT.DateType === 0) {
            let startTime: string = answer?.StartDate;
            let endTime: string = answer?.EndDate;
            if (OUTPUT_FORMAT.DateFormat === 0) {
              startTime = moment(startTime).format("YYYY/MM/DD");
              endTime = moment(endTime).format("YYYY/MM/DD");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              startTime = moment(startTime).format("YYYY/MM");
              endTime = moment(endTime).format("YYYY/MM");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              startTime = moment(startTime).format("YYYY");
              endTime = moment(endTime).format("YYYY");
            }
            time = `${startTime}-${endTime}`;
          } else if (OUTPUT_FORMAT.DateType === 1) {
            let startTime: string = answer?.StartDate;
            if (OUTPUT_FORMAT.DateFormat === 0) {
              startTime = moment(startTime).format("YYYY/MM/DD");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              startTime = moment(startTime).format("YYYY/MM");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              startTime = moment(startTime).format("YYYY");
            }
            time = `${startTime}`;
          } else if (OUTPUT_FORMAT.DateType === 2) {
            let endTime: string = answer?.EndDate;
            if (OUTPUT_FORMAT.DateFormat === 0) {
              endTime = moment(endTime).format("YYYY/MM/DD");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              endTime = moment(endTime).format("YYYY/MM");
            } else if (OUTPUT_FORMAT.DateFormat === 1) {
              endTime = moment(endTime).format("YYYY");
            }
            time = `${endTime}`;
          }
          timeStr = time;
        } else {
          timeStr = `${answer?.StartDate ? answer?.StartDate : ""}${
            answer?.EndDate ? "-" + answer?.EndDate : ""
          }`;
        }
      }

      // let newText: string = await handleUseDeepseekTableSummarize(
      //   tableData,
      //   columns
      // );
      // console.log("newText", newText);

      dialogueList[dialogueList.length - 1] = {
        ...obj,
        haveTable: true,
        tableData: tableData,
        ENABLE_CHART: configObj.ENABLE_CHART === 1,
        ENABLE_PDF_EXPORT: configObj.ENABLE_PDF_EXPORT === 1,
        ENABLE_VIEW_MORE: configObj.ENABLE_VIEW_MORE === 1,
        columns: columns,
        PARAM_FIELD: configObj?.PARAM_FIELD,
        RESPONSE_FIELD: configObj?.RESPONSE_FIELD,
        // deepseekContent: marked(newText),
        text: answer?.RevenueAnalysis || "",
        // OUTPUT_FORMAT && !(tableData && tableData.length > 0)
        //   ? OUTPUT_FORMAT.noDataText
        //   : `为您查找${timeStr || ""}相关数据:`,
      };
      isNewDialogLoading.value = false;
    }
  } else {
    let obj: any = JSON.parse(
      JSON.stringify(dialogueList[dialogueList.length - 1])
    );
    dialogueList[dialogueList.length - 1] = {
      ...obj,
      ENABLE_CHART: configObj.ENABLE_CHART === 1,
      ENABLE_PDF_EXPORT: configObj.ENABLE_PDF_EXPORT === 1,
      ENABLE_VIEW_MORE: configObj.ENABLE_VIEW_MORE === 1,
      PARAM_FIELD: configObj?.PARAM_FIELD,
      RESPONSE_FIELD: configObj?.RESPONSE_FIELD,
    };
    isNewDialogLoading.value = false;
  }

  // 是否出现  图表输出   导出为PDF  “查看更多”功能

  // else {
  //   // 不需要出现表格时 直接给最新对话框的text赋值就好
  //   let obj: any = JSON.parse(
  //     JSON.stringify(dialogueList[dialogueList.length - 1])
  //   );
  //   dialogueList[dialogueList.length - 1] = {
  //     ...obj,
  //     text: `${tableData}`,
  //   };
  //   isNewDialogLoading.value = false;
  // }

  handleScrollToBottom();
};

// 将滚动条滚动到底部  一般触发时间为打字机效果 和 提问的时候
const handleScrollToBottom = () => {
  const div: any = document.getElementById("dialogContent");
  setTimeout(() => {
    nextTick(() => {
      if (div) {
        div.scrollTop = div.scrollHeight; // 将 scrollTop 设置为 scrollHeight，滚动到最底部
      }
    });
  }, 100);
};

// 给巡检拿到对话框标签里面的问题的回答 输出为纯文字
const handleInspectionQuestions = async (text: string) => {
  const req: any = {
    Sentence: text,
    ProvinceCode: "340000",
    DialogCode: thisQuestionId.value || "",
  };
  const data = await handleTranslateSentence(req);
  let configDetail: any;
  let res: any;
  const configList: any = await handleGetANALYSISRULEList({
    searchParameter: {
      ANALYSISRULE_IDS: data?.AnalysisRuleId,
      current: 1,
      pageSize: 10,
    },
    sortstr: "RULE_PRIORITY asc",
    PageIndex: 1,
    pagesize: 999999,
  });
  // 请求列表的时候 已经根据优先级排序 第一个就是优先级最高的 直接取值就可以
  if (configList && configList.length > 0) {
    configDetail = configList[0];
  }
  console.log("configDetail", configDetail);
  // 如果拿到值就根据配置去调用接口 拿到数据 输出数据
  if (configDetail) {
    const tableData = await handleAnalyzeConfig(configDetail, data);
    console.log("tableData3", tableData);
    res = tableData;
  }
  return res;
};

// 清除对应的模型的自己的id
const handleDelteModalCode = (bigObjValue?: number) => {
  if (!bigObjValue) {
    return;
  }
  nextTick(() => {
    dialogueIdObj[bigObjValue] = null;
    console.log("dialogueIdObj", dialogueIdObj);
  });
};

// 调用回答问题的接口
const handleAnswerQuestions = async (bigObjValue?: number) => {
  // 给deepseek那边写的数据格式
  let deepseekDataList: any = [];
  console.log("dialogueIdObj", dialogueIdObj);

  const req: any = {
    Sentence: searchText.value,
    ProvinceCode: "340000",
    // DialogCode:thisQuestionId.value,
    DialogCode:
      bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]
        ? dialogueIdObj[bigObjValue]
        : "",
  };
  // 需要在对话框中的效果就是 输入问题之后 出现问问题和回答的对话框之后 就删除对话框内容 但是接口搜索还是需要显示内容
  searchText.value = "";
  const data = await handleTranslateSentence(req);
  console.log("data", data);

  // deepseek的判断的语义id
  // 太慢了 先注释
  // const deepseekIds = await handleUseDeepseekSemantics(req.Sentence);
  // console.log("datadeepseek的判断的语义id", deepseekIds);

  let searchRes: string = "";
  let returnData: any;
  // 去拿到这个id的配置明细
  // 添加判断 可能会有多个id  单个id的时候 直接调用详情接口拿到数据 多个id去请求列表接口 拿到优先级高的 直接给configDetail赋值
  let configDetail: any;
  if (data.ServerpartId) {
    // if (data.ShowMapPoint) {
    //   //  全部服务区圆点变灰色
    //   emit("handleEnterySearch");
    //   // 查询到的服务区 变为亮黄色
    //   emit("handleLightServerpart", data.ServerpartId);
    // }

    if (data?.ServerpartInfoList && data?.ServerpartInfoList.length > 0) {
      if (data?.AnalysisRuleId) {
      } else {
        let obj: any = JSON.parse(
          JSON.stringify(dialogueList[dialogueList.length - 1])
        );
        let str: string = ``;
        data?.ServerpartInfoList.forEach((item: any) => {
          if (str) {
            str += `、${item.SERVERPART_NAME}`;
          } else {
            str = `${item.SERVERPART_NAME}`;
          }
        });
        dialogueList[dialogueList.length - 1] = {
          ...obj,
          text: data?.RevenueAnalysis.split("{")[0] || "",
          // `已标注${str}的地图位置`
        };
        isNewDialogLoading.value = false;
      }
    }
    if (data?.RevenueAnalysis) {
      //再判断这次查询是否有文字结果返回 如果有的话 再进行判断 是要根据语义 调用接口 还是 直接输出这段文字
      if (data?.AnalysisRuleId) {
        // 文字通过打字机效果实现
        const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
        const lastBox: any = allBoxes[allBoxes.length - 1];
        if (lastBox) {
          // const lastContent = `<span class="style4">为您查找相关数据</span>`;
          // let newShowText: string = await handleUseDeepseekOptimize(
          //   data?.RevenueAnalysis
          // );
          const lastContent = `<span class="style4">${data?.RevenueAnalysis}</span>`;
          // const lastContent = `<span class="style4">${
          //   newShowText || ""
          // }</span>`;
          isPrinting.value = true;
          await handlePrintWord(lastBox, lastContent);
        }

        const configList: any = await handleGetANALYSISRULEList({
          searchParameter: {
            ANALYSISRULE_IDS: data?.AnalysisRuleId,
            current: 1,
            pageSize: 10,
          },
          sortstr: "RULE_PRIORITY asc",
          PageIndex: 1,
          pagesize: 999999,
        });
        console.log("configList", configList);
        if (configList && configList.length > 0) {
          for (let i = 0; i < configList.length; i++) {
            configDetail = configList[i];
            if (configDetail) {
              const tableData = await handleAnalyzeConfig(configDetail, data);
              if (tableData) {
                await handleConfigItemTable(tableData, configDetail, data);
              }
              let res = JSON.parse(
                JSON.stringify(dialogueList[dialogueList.length - 1])
              );
              res.ruleDetail = configDetail;
              res.RevenueAnalysis = data.RevenueAnalysis;
              deepseekDataList.push(res);
            }
          }
        }

        console.log("deepseekDataList", deepseekDataList);
        // 2025-2-12  下面这个是按照优先级去调用的 先注释 要改成多个都可以调用
        // 请求列表的时候 已经根据优先级排序 第一个就是优先级最高的 直接取值就可以
        // if (configList && configList.length > 0) {
        //   configDetail = configList[0];
        // }

        // console.log("configDetail", configDetail);
        // // 如果拿到值就根据配置去调用接口 拿到数据 输出数据
        // if (configDetail) {
        //   const tableData = await handleAnalyzeConfig(configDetail, data);
        //   returnData = tableData;
        //   console.log("tableData", tableData);

        //   // 如果拿到值了 就去配这个对话框显示表格的样式 或文字样式
        //   if (tableData) {
        //     await handleConfigItemTable(tableData, configDetail, data);
        //   }
        // }
      } else {
        // handleLastUpdate("为您查找相关数据");
        // handleLastUpdate(data?.RevenueAnalysis.split("{")[0] || "");
        handleLastUpdate(data?.RevenueAnalysis || "");
      }
    }
  } else {
    // 因为现在不止 基础信息 是 没有服务区 但是有配置id的情况  所以要加一下判断
    if (data?.AnalysisRuleId) {
      // 直接搜基础信息 因为没有服务区的输出 即使有配置id也不会去请求 这里判断一下 如果有配置id 还是按照配置id去调用
      if (req.Sentence.indexOf("基础信息") !== -1) {
        // 文字通过打字机效果实现
        const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
        const lastBox: any = allBoxes[allBoxes.length - 1];
        if (lastBox) {
          // const lastContent = `<span class="style4">为您查找相关数据</span>`;
          // let newShowText: string = await handleUseDeepseekOptimize(
          //   data?.RevenueAnalysis
          // );
          const lastContent = `<span class="style4">${data?.RevenueAnalysis}</span>`;
          // const lastContent = `<span class="style4">${
          //   newShowText || ""
          // }</span>`;
          isPrinting.value = true;
          await handlePrintWord(lastBox, lastContent);
        }
        // 去拿到这个id的配置明细
        // 添加判断 可能会有多个id  单个id的时候 直接调用详情接口拿到数据 多个id去请求列表接口 拿到优先级高的 直接给configDetail赋值
        let configDetail: any;
        const configList: any = await handleGetANALYSISRULEList({
          searchParameter: {
            ANALYSISRULE_IDS: data?.AnalysisRuleId,
            current: 1,
            pageSize: 10,
          },
          sortstr: "RULE_PRIORITY asc",
          PageIndex: 1,
          pagesize: 999999,
        });
        console.log("configList", configList);
        // 请求列表的时候 已经根据优先级排序 第一个就是优先级最高的 直接取值就可以
        if (configList && configList.length > 0) {
          configDetail = configList[0];
        }
        console.log("configDetail3232", configDetail);
        // 如果拿到值就根据配置去调用接口 拿到数据 输出数据
        if (configDetail) {
          const tableData = await handleAnalyzeConfig(configDetail, data);
          console.log("tableData3", tableData);
          // 如果拿到值了 就去配这个对话框显示 表格或者打字机样式
          if (tableData) {
            await handleConfigItemTable(tableData, configDetail, data);
          }
        }
      } else if (req.Sentence.indexOf("预警类型") !== -1) {
        emit("handleChangeRightFilterInDialogue", "6");
        handleSetWarningData(true);
      }
    } else {
      console.log("noRuleId");
      handleLastUpdate("小驿还无法理解，请换个说法，我会不停努力学习的！");
      searchRes = "查询失败";
    }
  }
  console.log('3333');
  
  // 问完去调日志接口记录 且在没有对话框id的时候 存一个对话框id
  const logData: any = await handleSynchroSENTENCE({
    // DIALOG_CODE: thisQuestionId.value,
    DIALOG_CODE: bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]
        ? dialogueIdObj[bigObjValue]
        : "",
    SENTENCE_CONTENT: req.Sentence,
    SENTENCE_RESULT: data?.RevenueAnalysis || "查询失败",
    SENTENCE_TYPE: data?.SentenceType,
    SENTENCE_STATE:
      searchRes === "查询失败" || data?.RevenueAnalysis === "无法识别。"
        ? 0
        : 1,
    OPERATE_DATE: moment().format("YYYY-MM-DD HH:mm:ss"),
    STAFF_NAME: "新项目",
    ANALYSISRULE_ID: data?.AnalysisRuleId,
    // STAFF_ID
  });
  if (bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]) {
  } else {
    if (bigObjValue) {
      dialogueIdObj[bigObjValue] = logData?.DIALOG_CODE;
    }
  }
  console.log('4444');

  console.log("dialogueList", dialogueList);
  console.log("searchRes", searchRes);
  console.log("data?.RevenueAnalysis", data?.RevenueAnalysis);

  // return searchRes === "查询失败" || data?.RevenueAnalysis === "无法识别。"
  //   ? false
  //   : {
  //       ...dialogueList[dialogueList.length - 1],
  //       RevenueAnalysis: data?.RevenueAnalysis || "",
  //     };
  return searchRes === "查询失败" || data?.RevenueAnalysis === "无法识别。"
    ? false
    : deepseekDataList;
};

// 提问的方法
const handleSubmit = async (text: string, bigObjValue: number) => {
  console.log("bigObjValue", bigObjValue);

  searchText.value = text || "";
  // 先添加对话内容
  handleAddDialogList(text);
  // 调用回答问题的接口
  const data = await handleAnswerQuestions(bigObjValue);
  return data;
  // inputRef.value?.focus();

  // 无论怎么样都 都隐藏悬浮框
  // emit("handleHiddenSuspended");
  // if (searchText.value) {
  //   // 判断一下输入框的文字 是不是巡检的 不是的走语义
  //   if (searchText.value === "开启巡检" || searchText.value === "开始巡检") {
  //     handleAddDialogList(searchText.value);
  //     inspectionIndex.value = 0;
  //     servicepartInspection(0, true);
  //   } else if (searchText.value === "继续巡检") {
  //     handleAddDialogList(searchText.value);
  //     servicepartInspection(inspectionIndex.value, true);
  //   } else {
  //     // 先添加对话内容
  //     handleAddDialogList(searchText.value);
  //     // 调用回答问题的接口
  //     await handleAnswerQuestions();
  //     inputRef.value?.focus();
  //   }
  // }
};

// 点击标签调用的方法
const handleClickTab = async (value: number) => {
  // 判断现在是不是在打印 在打印的话就不能执行
  if (isPrinting.value) {
    return;
  }

  // 无论怎么样都 都隐藏悬浮框
  emit("handleHiddenSuspended");
  if (selectTab.value === value) {
    selectTab.value = 0;
    return;
  } else {
    selectTab.value = value;
  }
  if (value === 0) return;

  console.log("handleClickTab", props.currentServerPartDetail);

  let searchObj: any = {
    1: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}基础信息`,
    2: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}经营数据`,
    3: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}在营商家`,
    4: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}招商分析`,
    5: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}收银监管`,
    6: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}车辆归属`,
    7: `${props.currentServerPartDetail?.SERVERPART_NAME || ""}财务状况`,
  };
  // 先添加对话内容
  handleAddDialogList(searchObj[value]);
  searchText.value = searchObj[value];
  handleAnswerQuestions();

  // // 拿到配置列表 拿到这个内容的配置内容
  // const configDetail: any = await handleGetConfigList(searchObj[value]);
  // if (value === 1) {
  //   handleServerpartBasicInfo(configDetail);

  // }
};

// 调用配置列表 根据现在点击的这一项类型 来查出对应的配置详情id
const handleGetConfigList = async (str: string) => {
  const data = await handleGetANALYSISRULEList({
    searchParameter: {
      ANALYSISRULE_IDS: "",
      current: 1,
      pageSize: 10,
    },
    pagesize: 999999,
    PageIndex: 1,
  });
  console.log("data", data);
  let detailObj: number = 0;
  if (data && data.length > 0) {
    data.forEach((item: any) => {
      if (str.indexOf(item.TRIGGER_WORDS) !== -1) {
        detailObj = item;
      }
    });
  }

  console.log("detailObj", detailObj);
  return detailObj;
};

// 判断入参中是否含有空值
const handleHaveNullValue = (obj: any) => {
  let res: boolean = false;
  for (let key in obj) {
    if (obj[key]) {
    } else {
      res = true;
    }
  }
  return res;
};

// 输出服务区基础数据的方法
const handleServerpartBasicInfo = async (config: any) => {
  console.log("config", config);
  // 取入参
  const req: any = handleGetReq(config, null);
  console.log("req", req);
  // 判断入参里面是否有空值 如果有空值 就直接输出安徽驿达的基础信息
  let haveNull: boolean = handleHaveNullValue(req);

  // 调用接口 取数据
  let data: any;
  if (!haveNull) {
    // 输出格式
    let OUTPUT_FORMAT: any = config?.OUTPUT_FORMAT
      ? JSON.parse(config?.OUTPUT_FORMAT)
      : "";

    if (OUTPUT_FORMAT) {
      data = await handleConfigRequest(
        config?.API_ENDPOINT,
        req,
        config,
        OUTPUT_FORMAT,
        null
      );
    }
  } else {
    data = {
      ServerpartInfo: {
        SERVERPART_INFO: detailText.YDdesc ?? "",
      },
    };
  }

  console.log("data213", data);
  if (data) {
    isNewDialogLoading.value = false;
    let obj: any = JSON.parse(
      JSON.stringify(dialogueList[dialogueList.length - 1])
    );
    dialogueList[dialogueList.length - 1] = {
      ...obj,
      isVHtml: true,
      VHtml: data.ServerpartInfo.SERVERPART_INFO || "",
    };

    await nextTick();

    const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
    const lastBox: any = allBoxes[allBoxes.length - 1];
    if (lastBox) {
      const lastContent = data.ServerpartInfo.SERVERPART_INFO || "";
      isPrinting.value = true;
      await handlePrintWord(lastBox, lastContent);
      let obj: any = JSON.parse(
        JSON.stringify(dialogueList[dialogueList.length - 1])
      );
      dialogueList[dialogueList.length - 1] = {
        ...obj,
        isOver: true,
      };
    }
  }
};

// 给最新的对话添加打字机效果
const handlePrintWord = async (
  element: HTMLElement,
  htmlContent: string,
  speed = 20
) => {
  return new Promise<void>((resolve) => {
    let i = 0;
    const tempDiv = document.createElement("div");
    tempDiv.innerHTML = htmlContent;
    printWord.value = htmlContent;

    const tagStack: HTMLElement[] = [element];

    const typeCharacter = async () => {
      if (i < tempDiv.innerHTML.length && isPrinting.value) {
        // 1. 检测 handleWait()
        const handleWaitRegex = /handleWait\((.*?)\)/;
        const restContent = tempDiv.innerHTML.slice(i);
        const waitMatch = handleWaitRegex.exec(restContent);

        if (waitMatch && waitMatch.index === 0) {
          const param: string = waitMatch[1].trim().replace(/^["']|["']$/g, "");
          await handleWait(param);
          i += waitMatch[0].length;
        }
        // 2. 检测 moment().startOf() 和 moment().format()
        else if (restContent.startsWith("moment().")) {
          const momentRegex = /(moment\(\)\.(startOf|format)\(.*?\))/;
          const momentMatch = momentRegex.exec(restContent);
          if (momentMatch) {
            const momentExpression = momentMatch[1]; // 提取整个表达式
            let parsedResult = "";

            try {
              if (momentExpression.includes("startOf")) {
                const unit = momentExpression.match(
                  /startOf\(['"](\w+)['"]\)/
                )?.[1];
                parsedResult = moment()
                  .startOf(unit as any)
                  .format("YYYY-MM-DD HH:mm:ss");
              } else if (momentExpression.includes("format")) {
                const formatString = momentExpression.match(
                  /format\(['"](.*?)['"]\)/
                )?.[1];
                parsedResult = moment().format(formatString);
              }
            } catch (error) {
              console.error("Moment 解析失败:", error);
            }

            // 将解析的结果打印到屏幕
            const textNode = document.createTextNode(parsedResult);
            tagStack[tagStack.length - 1].appendChild(textNode);

            i += momentMatch[0].length; // 跳过 moment 表达式
          }
        }
        // 3. 正常字符或标签处理
        else {
          const char = tempDiv.innerHTML.charAt(i);
          if (char === "<") {
            const tagEnd = tempDiv.innerHTML.indexOf(">", i);
            const tagContent = tempDiv.innerHTML.slice(i, tagEnd + 1);
            const isClosingTag = tagContent.startsWith("</");

            if (isClosingTag) {
              tagStack.pop();
            } else {
              const range = document.createRange();
              const fragment = range.createContextualFragment(tagContent);
              const newElement = fragment.firstChild as HTMLElement;
              tagStack[tagStack.length - 1].appendChild(newElement);
              if (!tagContent.endsWith("/>")) {
                tagStack.push(newElement);
              }
            }
            i = tagEnd + 1;
          } else {
            const textNode = document.createTextNode(
              char === "\n" ? "\n" : char
            );
            tagStack[tagStack.length - 1].appendChild(textNode);
            i++;
          }
        }

        setTimeout(typeCharacter, speed);
        handleScrollToBottom();
      } else {
        isPrinting.value = false;
        resolve();
      }
    };

    typeCharacter();
  });
};

// 打印过程中的加载效果
const handleWait = async (str: string) => {
  return new Promise<void>((resolve) => {
    printingLoading.value = true;
    printingLoadingText.value = str;
    setTimeout(() => {
      printingLoading.value = false;
      printingLoadingText.value = "";
      resolve(); // 确保在加载效果完成后调用 resolve
    }, 2000); // 1秒延迟
  });
};

// 打字机延迟函数
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

// 停止打印机事件
const handleStopPrint = () => {
  isPrinting.value = false;
  if (duringInspection.value) {
    closeInspection();
  }
};

// 显示数据图表
const handleShowDataPie = () => {};
// 跳转查看更多
const handleGoSearchMore = () => {
  window.open("http://saas.eshangtech.com/cloud/");
};
// 导出为pdf
const handleExportPDF = () => {};

// 传入的数据
const props = defineProps<{
  currentServerPartDetail: any;
  allServerPartIdList: any;
}>();

// 传入的方法
const emit = defineEmits<{
  (e: "handleLightServerpart", infoList: any): void; // 高亮查到的图层
  (e: "handleEnterySearch"): void; // 全部服务区圆点置灰
  (e: "handleWarningMap", warningData: any): void; // 全部服务区圆点置灰
  (e: "handleAreaInspection", index: number): void; // 全部服务区圆点置灰
  (e: "handleHiddenSuspended"): void; // 隐藏掉悬浮框
  (e: "handleShowAi", value: boolean): void; // 将ai对话是否显示 跟主页说
  (e: "handleChangeRightFilterInDialogue", id: any): void; // 屏蔽右边的选择项改变的watch
}>();

// 监听当前选择的服务区
watch(
  () => props.currentServerPartDetail,
  (newVal, oldVal) => {
    if (newVal) {
      // 不在巡检状态
      if (selectTab.value !== 0 && !duringInspection.value) {
        console.log("new", newVal);
        console.log("old", oldVal);
        handleClickTab(selectTab.value);
      }
    }
  },
  { deep: true }
);

// 处理单元格数据
const handleFormatter = (
  row: any,
  column: any,
  cellValue: any,
  index: number
) => {
  return h("div", { style: "text-align:center" }, [
    JSON.stringify(row), // 显示列的 label
  ]);
};

// 拿枚举数据
const handleGetFieldEnum = async () => {
  // 预警类型
  const waringList = await getFieldGetFieEnumList({
    FieldexPlain_Field: "WARNING_TYPE",
  });
  if (waringList && waringList.length > 0) {
    const list: any = [];
    const obj: any = {};
    const descList: any = [];
    const descObj: any = {};
    waringList.forEach((item: any) => {
      list.push({ label: item.FieldEnum_Name, value: item.FieldEnum_Value });
      obj[item.FieldEnum_Value] = item.FieldEnum_Name;
      descList.push({
        label: item.FieldEnum_Desc,
        value: item.FieldEnum_Value,
      });
      descObj[item.FieldEnum_Value] = item.FieldEnum_Desc;
    });

    descObjRef.value = obj;
    descListRef.value = list;
    console.log("descObjRef.value", descObjRef.value);
  }

  // 经营业态
  const BusinessTradeIdsList = await getFieldEnumTree({
    FieldExplainField: "BusinessTradeIds",
  });

  if (BusinessTradeIdsList && BusinessTradeIdsList.length > 0) {
    let BusinessTradeIdsObj: any = {};
    BusinessTradeIdsList.forEach((item: any) => {
      BusinessTradeIdsObj[item.value] = item.label;
      if (item.children && item.children.length > 0) {
        item.children.forEach((subItem: any) => {
          BusinessTradeIdsObj[subItem.value] = subItem.label;
        });
      }
    });
    console.log("BusinessTradeIdsObj", BusinessTradeIdsObj);

    tradeObjRef.value = BusinessTradeIdsObj;
  }
};

// 经营业态的方法
const handleGetBusinessTrade = async () => {
  showDialogBox.value = true;
  emit("handleShowAi", true);
  handleAddDialogList(
    `${props.currentServerPartDetail?.SERVERPART_NAME || ""}经营业态`
  );
  setTimeout(() => {
    handleLastUpdate("");
  }, 1000);
};

// 预警类型的方法
const handleSetWarningData = async (noAdd?: boolean) => {
  showDialogBox.value = true;
  emit("handleShowAi", true);
  if (noAdd) {
  } else {
    handleAddDialogList(
      `${props.currentServerPartDetail?.SERVERPART_NAME || ""}预警类型`
    );
  }
  setTimeout(() => {
    nextTick(() => {
      dialogueList[dialogueList.length - 1].isOver = true;
      dialogueList[dialogueList.length - 1].text =
        "请您选择具体想要查询的预警类型：";
      dialogueList[dialogueList.length - 1].isWarningSelect = true;
      isNewDialogLoading.value = false;
    });
  }, 1000);
};

// 选择的具体预警类型
const handleSelectWarning = async (value: number) => {
  handleAddDialogList(
    `${props.currentServerPartDetail?.SERVERPART_NAME || ""}${
      descObjRef.value[Number(value)] || "预警类型"
    }`
  );
  console.log("value", value);
  console.log("props?.currentServerPartDetail", props?.currentServerPartDetail);
  const req: any = {
    WarningType: value,
    ShowNormal: true,
    ServerpartId: props?.currentServerPartDetail
      ? props?.currentServerPartDetail.SERVERPART_ID
      : props?.allServerPartIdList.toString(),
  };
  const warningData = await handleGetMonthINCAnalysis(req);
  console.log("warningData", warningData);
  let result: string = "";
  if (props?.currentServerPartDetail) {
    if (warningData && warningData.length > 0) {
      let obj: any = {};
      let str: string = "";
      let objShopName: any = {};
      warningData.forEach((item: any) => {
        if (obj[item.WARNING_TYPE] && obj[item.WARNING_TYPE].length > 0) {
          let old: any = obj[item.WARNING_TYPE];
          old.push(item);
          obj[item.WARNING_TYPE] = old;
        } else {
          let res: any = [];
          res.push(item);
          obj[item.WARNING_TYPE] = res;
        }

        if (
          objShopName[item.WARNING_TYPE] &&
          objShopName[item.WARNING_TYPE].length > 0
        ) {
          let old: any = objShopName[item.WARNING_TYPE];
          old += `，${item.SERVERPARTSHOP_NAME}`;
          objShopName[item.WARNING_TYPE] = old;
        } else {
          let old: any = objShopName[item.WARNING_TYPE];
          old = `${item.SERVERPARTSHOP_NAME}`;
          objShopName[item.WARNING_TYPE] = old;
        }
      });
      console.log("obj", obj);
      console.log("objShopName", objShopName);
      if (obj) {
        for (let key in obj) {
          let itemStr: string = `
          ${descObjRef.value[key]}：${objShopName[key]},共${obj[key].length}条;`;
          str += itemStr;
        }
      }
      result = `${props?.currentServerPartDetail.SERVERPART_NAME}预警类型，存在：${str}
      的情况，您可以鼠标移动到具体服务区查看情况。`;
    } else {
      result = `${props?.currentServerPartDetail.SERVERPART_NAME}暂无预警数据`;
    }
  } else {
    let serverpartId: any = [];
    if (warningData && warningData.length > 0) {
      warningData.forEach((item: any) => {
        if (serverpartId.indexOf(item.SERVERPART_ID) === -1) {
          serverpartId.push(item.SERVERPART_ID);
        }
      });
    }
    result = `${descObjRef.value[Number(value)]}，共有${
      serverpartId.length || 0
    } 对服务区，存在${warningData.length || 0}条${
      descObjRef.value[Number(value)]
    } 的情况，您可以鼠标移动到具体服务区查看情况。`;
  }
  console.log("result", result);
  if (result) {
    isNewDialogLoading.value = false;
    let obj: any = JSON.parse(
      JSON.stringify(dialogueList[dialogueList.length - 1])
    );
    dialogueList[dialogueList.length - 1] = {
      ...obj,
      isVHtml: true,
      VHtml: result || "",
    };

    await nextTick();

    const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
    const lastBox: any = allBoxes[allBoxes.length - 1];
    if (lastBox) {
      const lastContent = result || "";
      isPrinting.value = true;
      await handlePrintWord(lastBox, lastContent);
      let obj: any = JSON.parse(
        JSON.stringify(dialogueList[dialogueList.length - 1])
      );
      dialogueList[dialogueList.length - 1] = {
        ...obj,
        isOver: true,
      };
    }
  }
  emit("handleEnterySearch");
  emit("handleWarningMap", warningData);
};

// 配置中调用预警的输出  id 为服务区id  warningData为配置请求出来的结果
const handleWarningConfig = async (id: any, warningData: any) => {
  emit("handleChangeRightFilterInDialogue", "6");
  let result: string = "";
  let SERVERPART_NAME: string = "";
  if (id) {
    if (warningData && warningData.length > 0) {
      let obj: any = {};
      let str: string = "";
      let objShopName: any = {};
      warningData.forEach((item: any) => {
        if (item.SERVERPART_NAME) {
          SERVERPART_NAME = item.SERVERPART_NAME;
        }

        if (obj[item.WARNING_TYPE] && obj[item.WARNING_TYPE].length > 0) {
          let old: any = obj[item.WARNING_TYPE];
          old.push(item);
          obj[item.WARNING_TYPE] = old;
        } else {
          let res: any = [];
          res.push(item);
          obj[item.WARNING_TYPE] = res;
        }

        if (
          objShopName[item.WARNING_TYPE] &&
          objShopName[item.WARNING_TYPE].length > 0
        ) {
          let old: any = objShopName[item.WARNING_TYPE];
          old += `，${item.SERVERPARTSHOP_NAME}`;
          objShopName[item.WARNING_TYPE] = old;
        } else {
          let old: any = objShopName[item.WARNING_TYPE];
          old = `${item.SERVERPARTSHOP_NAME}`;
          objShopName[item.WARNING_TYPE] = old;
        }
      });
      console.log("obj", obj);
      console.log("objShopName", objShopName);
      if (obj) {
        for (let key in obj) {
          let itemStr: string = `
          ${descObjRef.value[key]}：${objShopName[key]},共${obj[key].length}条;`;
          str += itemStr;
        }
      }
      result = `${SERVERPART_NAME || "-"}预警类型，存在：${str}
      的情况，您可以鼠标移动到具体服务区查看情况。`;
    } else {
      result = `${SERVERPART_NAME || "-"}暂无预警数据`;
    }
  }
  console.log("result", result);
  if (result) {
    isNewDialogLoading.value = false;
    let obj: any = JSON.parse(
      JSON.stringify(dialogueList[dialogueList.length - 1])
    );
    dialogueList[dialogueList.length - 1] = {
      ...obj,
      isVHtml: true,
      VHtml: result || "",
    };

    await nextTick();

    const allBoxes = document.querySelectorAll(".dialogueTextBox-text");
    const lastBox: any = allBoxes[allBoxes.length - 1];
    if (lastBox) {
      const lastContent = result || "";
      isPrinting.value = true;
      await handlePrintWord(lastBox, lastContent);
      let obj: any = JSON.parse(
        JSON.stringify(dialogueList[dialogueList.length - 1])
      );
      dialogueList[dialogueList.length - 1] = {
        ...obj,
        isOver: true,
      };
    }
  }
  emit("handleEnterySearch");
  emit("handleWarningMap", warningData);
};

// 直接根据配置的方法名称直接调用那个方法  type 调用的是哪个方法  id 服务区id 可以为空  warningData 请求出来的数据
const handleGetConfigFun = async (type: string, id: any, warningData: any) => {
  // 配置直接调用的方法列表
  let configFunObj: any = {
    handleWarningConfig: (id: any, warningData: any) =>
      handleWarningConfig(id, warningData),
  };
  if (type && configFunObj[type]) {
    await configFunObj[type](id, warningData);
  }
};

// 服务区巡检
const servicepartInspection = (index?: number, inInput?: boolean) => {
  searchText.value = "";
  if (inInput) {
  } else {
    // 第一次由手动调用
    if (inspectionIndex.value === 0) {
      // 用户提问 机器人回答的加载框添加
      handleAddDialogList("服务区巡检");
    } else {
      // 只给机器人加回答对话框
      handleAddRobotDialog();
    }
  }

  // 进入巡检
  duringInspection.value = true;
  emit("handleAreaInspection", inspectionIndex.value);
};
// 关闭巡检 且 直接暂停打印
const handleCloseInspection = () => {
  duringInspection.value = false;
  isPrinting.value = false;
};
// 关闭巡检
const closeInspection = () => {
  duringInspection.value = false;
  // inspectionIndex.value = 0;
};

// 2025-02-08 更新内容
// 传入配置的规则id 去调用方法 最后输出
const handleGetAnswerID = async (
  id: any,
  questionText: string,
  bigObjValue: number
) => {
  let deepseekDataList: any = [];
  const req: any = {
    Sentence: questionText,
    ProvinceCode: "340000",
    // DialogCode: thisQuestionId.value || "",
    DialogCode:
      bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]
        ? dialogueIdObj[bigObjValue]
        : "",
  };
  // 需要在对话框中的效果就是 输入问题之后 出现问问题和回答的对话框之后 就删除对话框内容 但是接口搜索还是需要显示内容
  searchText.value = "";
  const data = await handleTranslateSentence(req);

  // 去拿到这个id的配置明细
  // 添加判断 可能会有多个id  单个id的时候 直接调用详情接口拿到数据 多个id去请求列表接口 拿到优先级高的 直接给configDetail赋值
  let configDetail: any;
  const configList: any = await handleGetANALYSISRULEList({
    searchParameter: {
      // ANALYSISRULE_IDS: id,
      ANALYSISRULE_IDS: data.AnalysisRuleId ? data.AnalysisRuleId : id,
      current: 1,
      pageSize: 10,
    },
    sortstr: "RULE_PRIORITY asc",
    PageIndex: 1,
    pagesize: 999999,
  });
  console.log("configList", configList);
  // 请求列表的时候 已经根据优先级排序 第一个就是优先级最高的 直接取值就可以
  if (configList && configList.length > 0) {
    // configDetail = configList[0];
    for (let i = 0; i < configList.length; i++) {
      configDetail = configList[i];
      if (configDetail) {
        const tableData = await handleAnalyzeConfig(configDetail, data);
        if (tableData) {
          await handleConfigItemTable(tableData, configDetail, data);
        }
        let res = JSON.parse(
          JSON.stringify(dialogueList[dialogueList.length - 1])
        );
        res.ruleDetail = configDetail;
        res.RevenueAnalysis = data.RevenueAnalysis;
        deepseekDataList.push(res);
      }
    }
  }
  // let stop: boolean = false;
  // if (configDetail) {
  //   const tableData = await handleAnalyzeConfig(configDetail, data);
  //   console.log("tableData2", tableData);
  //   // 如果拿到值了 就去配这个对话框显示表格的样式 或文字样式
  //   if (tableData) {
  //     await handleConfigItemTable(tableData, configDetail, data);
  //     console.log("handleConfigItemTable");
  //   } else {
  //     stop = true;
  //   }
  // } else {
  //   stop = true;
  // }
  // if (stop) {
  //   return false;
  // }

  // console.log("handleGetAnswerID", dialogueList);
  // console.log("data", data);

  const logData: any = await handleSynchroSENTENCE({
    // DIALOG_CODE: thisQuestionId.value,
    DIALOG_CODE: bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]
        ? dialogueIdObj[bigObjValue]
        : "",
    SENTENCE_CONTENT: req.Sentence,
    SENTENCE_RESULT: data?.RevenueAnalysis || "查询失败",
    SENTENCE_TYPE: data?.SentenceType,
    SENTENCE_STATE: data?.RevenueAnalysis === "无法识别。" ? 0 : 1,
    OPERATE_DATE: moment().format("YYYY-MM-DD HH:mm:ss"),
    STAFF_NAME: "新项目",
    ANALYSISRULE_ID: data?.AnalysisRuleId,
    // STAFF_ID
  });
  // if (thisQuestionId.value) {
  // } else {
  //   thisQuestionId.value = logData?.DIALOG_CODE;
  // }
  if (bigObjValue && dialogueIdObj && dialogueIdObj[bigObjValue]) {
  } else {
    if (bigObjValue) {
      dialogueIdObj[bigObjValue] = logData?.DIALOG_CODE;
    }
  }

  // return data?.RevenueAnalysis === "无法识别。"
  //   ? dialogueList[dialogueList.length - 1].tableData &&
  //     dialogueList[dialogueList.length - 1].tableData.length > 0
  //     ? dialogueList[dialogueList.length - 1]
  //     : false
  //   : {
  //       ...dialogueList[dialogueList.length - 1],
  //       RevenueAnalysis: data?.RevenueAnalysis || "",
  //     };
  return data?.RevenueAnalysis === "无法识别。"
    ? dialogueList[dialogueList.length - 1].tableData &&
      dialogueList[dialogueList.length - 1].tableData.length > 0
      ? deepseekDataList
      : false
    : deepseekDataList;
};

// 2025-02-07 更新内容
// 尝试用 deepseek 对显示的表格数据进行分析并生成总结性的语言
const handleUseDeepseekTableSummarize = async (
  tableData: any,
  columns?: any
) => {
  let tableJSON: string = "";
  let columnJSON: string = "";
  if (tableData && tableData.length > 0) {
    tableJSON = JSON.stringify(tableData);
  }
  if (columns && columns.length > 0) {
    columnJSON = JSON.stringify(columns);
  }

  let questionText: string = `表格数据的JSON格式内容为${tableJSON},表格重点显示的字段JSON为${columnJSON},根据重点显示的字段分析表格数据，并给出总结性的语言给客户展示讲解`;
  console.log("questionText", questionText);

  try {
    const timeoutPromise = new Promise((resolve) => {
      setTimeout(() => resolve(""), 60000);
    });
    // 使用 Promise.race 来竞争 handleGetDeepseek 和 timeoutPromise
    let resText: any = await Promise.race([
      handleGetDeepseek(questionText),
      timeoutPromise,
    ]);
    // let resText = await handleGetDeepseek(questionText);
    let res =
      resText.data && resText.data.choices && resText.data.choices.length > 0
        ? resText.data.choices[0].message.content
        : "";
    console.log("resText", resText);
    return res;
  } catch (error) {
    console.error("请求出错:", error);
    return "为您查找相关数据";
  }
};

// 2025-02-06 更新内容
// 用deepseek来优化语义返回的为您查找相关数据本身的文字
const handleUseDeepseekOptimize = async (text: string) => {
  if (!text) {
    return "为您查找相关数据";
  }

  let questionText: string = `根据自然语言语义完善修改这段话，要求：返回结果只有修改后的语句，没有其他的思考过程、分析过程 ，语句内容：${text}`;
  console.log("questionText", questionText);
  try {
    const timeoutPromise = new Promise((resolve) => {
      setTimeout(() => resolve("为您查找相关数据"), 30000);
    });
    // 使用 Promise.race 来竞争 handleGetDeepseek 和 timeoutPromise
    let resText: any = await Promise.race([
      handleGetDeepseek(questionText),
      timeoutPromise,
    ]);
    // let resText = await handleGetDeepseek(questionText);
    let res =
      resText.data && resText.data.choices && resText.data.choices.length > 0
        ? resText.data.choices[0].message.content
        : "为您查找相关数据";
    console.log("resText", resText);
    return res;
  } catch (error) {
    console.error("请求出错:", error);
    return "为您查找相关数据";
  }
};

// 调用deepseek的方法
const handleGetDeepseek = async (questionText: any) => {
  let modal = {
    // model: "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
    model: "deepseek-chat",
    messages: [{ role: "user", content: questionText }],
    stream: false,
    max_tokens: 1500,
    stop: ["null"],
    temperature: 0.7,
    top_p: 0.7,
    top_k: 50,
    frequency_penalty: 0.5,
    n: 1,
    response_format: {
      type: "text",
    },
  };
  // const options = {
  //   method: "POST",
  //   headers: {
  //     Authorization:
  //       "Bearer sk-nynbgbtnmsffijgkttoimqkptetivviwuqrdhbuclgbmvnsq",
  //     "Content-Type": "application/json",
  //   },
  //   body: JSON.stringify(modal),
  // };
  // const response: any = await fetch(
  //   "https://api.siliconflow.cn/v1/chat/completions",
  //   options
  // );
  const options = {
    method: "POST",
    headers: {
      Authorization: "Bearer sk-d47e0bdc7fd249f29d2f0dba807d46f0",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(modal),
  };
  // const response: any = await
  // const response: any = await fetch(
  //   "https://api.deepseek.com/v1/chat/completions",
  //   options
  // );

  const config = {
    method: "post",
    maxBodyLength: Infinity,
    url: "https://api.deepseek.com/v1/chat/completions",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
      Authorization: "Bearer sk-d47e0bdc7fd249f29d2f0dba807d46f0",
    },
    data: modal,
  };

  const data = await axios(config);
  console.log("dhsajkhdlsajkhdaksjd", data);
  return data;
};

// 用deepseek来识别语义 拿到规则id
const handleUseDeepseekSemantics = async (searchText: string) => {
  let questionText: string = `${deepseekDesc.value}${searchText}`;
  console.log("questionText", questionText);

  try {
    const timeoutPromise = new Promise((resolve) => {
      setTimeout(() => resolve([]), 30000);
    });
    // 使用 Promise.race 来竞争 handleGetDeepseek 和 timeoutPromise
    let resText: any = await Promise.race([
      handleGetDeepseek(questionText),
      timeoutPromise,
    ]);
    // let resText = await handleGetDeepseek(questionText);
    let res =
      resText.data && resText.data.choices && resText.data.choices.length > 0
        ? resText.data.choices[0].message.content
        : [];
    console.log("resText", resText);
    return res;
  } catch (error) {
    console.error("请求出错:", error);
    return [];
  }

  // const ids = await handleGetDeepseek(questionText);
  // console.log("dsakjdhasidha", ids);
};

// 监听对话框记录
watch(
  () => dialogueList,
  (newVal, oldVal) => {
    console.log("new", newVal);
    console.log("old", oldVal);
    // 当只有在巡检中 且检测到对话框列表发生变化时 进入
    if (newVal && newVal.length > 0 && duringInspection.value) {
      let lastObj: any = dialogueList[dialogueList.length - 1];
      if (lastObj.isOver) {
        inspectionIndex.value += 1;
        servicepartInspection(inspectionIndex.value);
      }
    }
  },
  { deep: true }
);

// 底部tab的显示
const handleShowTabList = () => {
  bottomSelect.value = !bottomSelect.value;
};

defineExpose({
  handleGetBusinessTrade: () => {
    handleGetBusinessTrade();
  },
  handleSetWarningData: () => {
    handleSetWarningData();
  },
  descObjRef,
  descListRef,
  handleClickTab,
  selectTab,
  handleSelectWarning,
  handleInspectionDialogueBox,
  closeInspection,
  duringInspection,
  handleInspectionQuestions,
  showDialogBox,
  handleSubmit,
  handleGetAnswerID,
  handleDelteModalCode,
});
</script>

<template>
  <div class="expandBox" v-if="showDialogBox">
    <!-- 展开后的顶部机器人图标和文字 -->
    <div class="boxTop">
      <img
        class="closeIcon"
        src="@/assets/ai/AiIcon.png"
        @click="handleCloseDialogbox()"
      />
      <span class="titleText">商业智能助理小驿，为您服务：</span>
    </div>
    <div class="dialogBox">
      <!-- 实际的对话框方框 -->
      <div id="dialogContent" class="dialogContent">
        <div
          :class="`dialogueBoxItem dialogueBoxItem${index + 1}`"
          v-for="(item, index) in dialogueList"
          :key="index"
          :style="{
            justifyContent: item.type === 1 ? 'flex-start' : 'flex-end',
          }"
        >
          <img
            v-if="item.type === 1"
            class="robotIcon"
            src="@/assets/ai/profileIcon.png"
          />
          <div class="dialogueTextBox">
            <div class="dialogueTextBox-text">
              {{ item.text || "" }}
            </div>
            <!-- <div
              class="deepseekContent"
              v-if="item.deepseekContent"
              v-html="item.deepseekContent"
            ></div> -->
            <div
              class="loadingBox"
              v-if="isNewDialogLoading && index === dialogueList.length - 1"
              v-loading="
                isNewDialogLoading && index === dialogueList.length - 1
              "
            ></div>

            <div
              v-if="item.isFirst && item.isOver"
              style="margin-top: 8px"
              class="firstClickTab"
            >
              <div
                v-for="(item, index) in clickTabList"
                :key="index"
                :class="
                  selectTab === item.value
                    ? 'clickItem selctClickItem'
                    : 'clickItem'
                "
                @click="handleClickTab(item.value)"
              >
                {{ item.label || "" }}
              </div>
              <div
                v-if="!duringInspection"
                class="clickItem"
                @click="servicepartInspection(inspectionIndex)"
              >
                {{ inspectionIndex > 0 ? "继续巡检" : "服务区巡检" }}
              </div>
              <div
                v-if="duringInspection"
                class="clickItem"
                @click="handleCloseInspection()"
              >
                {{ "暂停巡检" }}
              </div>
              <!-- <img
                class="clearClick"
                src="@/assets/ai/clearIcon.png"
                @click="handleClickTab(0)"
              /> -->
            </div>

            <div v-if="item.isWarningSelect" class="firstClickTab">
              <div
                class="clickItem"
                style="display: block"
                v-for="(item, index) in descListRef"
                :key="index"
                @click="handleSelectWarning(item.value)"
              >
                {{ item.label || "" }}
              </div>
            </div>

            <div v-if="item.haveTable" style="margin-top: 8px">
              <el-table
                :data="item.tableData"
                :fit="true"
                tree-props="treeProps"
                row-key="rowKey"
                class="elTable"
                :max-height="500"
              >
                <el-table-column
                  v-for="(column, index) in item.columns"
                  :key="index"
                  :prop="column.prop"
                  :label="column.label"
                  :width="column.width"
                  :align="column.align"
                  :show-overflow-tooltip="true"
                  header-align="center"
                >
                  <!-- :formatter="handleFormatter" -->

                  <!-- 自定义表头内容 -->
                  <template #header>
                    <div v-html="column.label"></div>
                  </template>

                  <template #default="scope">
                    <template v-if="column.showDic">
                      {{
                        column.DicObj === "waringObj"
                          ? descObjRef[Number(scope.row[column.prop])]
                          : column.DicObj === "tradeObjRef"
                          ? tradeObjRef[Number(scope.row[column.prop])]
                          : ""
                      }}
                    </template>
                    <template v-else>
                      {{ scope.row[column.prop] }}
                    </template>
                  </template>

                  <!-- 默认的单元格内容渲染 -->
                  <!-- <template #default="{ row }">
                    <div
                      v-if="column.isSlot"
                      :style="{
                        justifyContent:
                          column.align === 'right'
                            ? 'flex-end'
                            : column.align === 'left'
                            ? 'flex-start'
                            : column.align === 'center'
                            ? 'center'
                            : '',
                      }"
                    >
                      <span v-html="renderCell(row, column)"></span>
                    </div>
                    <div v-else>
                      <span>{{ row[column.prop] }}</span>
                    </div>
                  </template> -->
                </el-table-column>
              </el-table>
            </div>

            <div
              class="moreOption"
              v-if="
                item.ENABLE_CHART ||
                item.ENABLE_PDF_EXPORT ||
                item.ENABLE_VIEW_MORE
              "
            >
              <span
                class="optionItem"
                v-if="item.ENABLE_CHART"
                @click="handleShowDataPie()"
                >查看数据图表</span
              >
              <span
                class="optionItem"
                v-if="item.ENABLE_CHART"
                @click="handleGoSearchMore()"
                >查看更多</span
              >
              <span
                class="optionItem"
                v-if="item.ENABLE_CHART"
                @click="handleExportPDF()"
                >导出为PDF</span
              >
            </div>

            <div
              style="width: 100%; height: 80px"
              v-if="printingLoading && index === dialogueList.length - 1"
              v-loading="printingLoading"
              :element-loading-text="printingLoadingText"
            ></div>
          </div>

          <img
            v-if="item.type === 2"
            class="userIcon"
            src="@/assets/ai/userIcon.png"
          />
        </div>
      </div>

      <!-- 输入框 -->
      <div class="inputBox">
        <el-input
          ref="inputRef"
          class="searchText"
          placeholder="Hi,您好！请输入您想了解的服务区..."
          v-model="searchText"
          @keyup.enter="handleSubmit"
          :disabled="isPrinting"
        />
        <!-- <img
          v-if="isPrinting"
          class="searchIcon"
          src="@/assets/ai/stopIcon.png"
          @click="handleStopPrint()"
        /> -->
        <!-- <img
          v-if="!isPrinting"
          class="searchIcon"
          src="@/assets/ai/searchIconBlue.png"
          @click="handleSubmit"
        /> -->
      </div>

      <div class="moreSelect">
        <div v-if="!bottomSelect" class="filterFixed">
          <img
            class="filterIcon"
            src="@/assets/ai/dropDown.png"
            @click="handleShowTabList()"
          />
        </div>
        <div class="filterBox" v-if="bottomSelect">
          <div class="filterList">
            <div
              v-for="(item, index) in clickTabList"
              :key="index"
              :class="
                selectTab === item.value
                  ? 'filterItem selectFilterItem'
                  : 'filterItem'
              "
              @click="handleClickTab(item.value)"
            >
              {{ item.label || "" }}
            </div>
            <div
              v-if="!duringInspection"
              class="filterItem"
              @click="servicepartInspection(inspectionIndex)"
            >
              {{ inspectionIndex > 0 ? "继续巡检" : "服务区巡检" }}
            </div>
            <div
              v-if="duringInspection"
              class="filterItem"
              @click="handleCloseInspection()"
            >
              {{ "暂停巡检" }}
            </div>
          </div>
          <img
            class="filterIcon"
            src="@/assets/ai/pullUp.png"
            @click="handleShowTabList()"
          />
        </div>
      </div>
    </div>
  </div>

  <div class="closeBox" v-else>
    <img
      class="closeIcon"
      src="@/assets/ai/AiIcon.png"
      @click="handleGetShowDailogBox()"
    />
  </div>
</template>