<template>
  <div class="searchTool">
    <div class="searchToolTitle">
      {{ title }}选择
    </div>
    <div class="searchToolContent">
      <div v-show="showBut">
        <el-button @click="showText = true" style="margin-bottom:10px;">上传附件</el-button> <el-button
          type="danger">批量删除</el-button>
      </div>
      <MyTable :tableData="tableDate.tableData" :tableColumn="tableDate.tableColumn" :key="tableDate.keyCount"
        :tableConfiger="tableDate.tableConfiger" :controlsWidth="tableDate.controlsWidth"
        :tableHeight="showBut ? tableHeight - 60 : tableHeight" v-infinite-scroll="loadMore"
        :infinite-scroll-disabled="disabled" :infinite-scroll-distance="50" @chooseData="chooseData">
        <template #jqlxdm="{ row }">
          {{ getTage('06000000', dict.JQLB) }}
        </template>
        <template #xlLx="{ row }">
          <DictTag tag="D_GS_XS_LX" :value="row.xlLx" :tag="false" :options="dict.D_GS_XS_LX"></DictTag>
        </template>
      </MyTable>
    </div>
    <div class="searchToolFooter"> <el-button type="primary" class="establishBut" @click.stop="getText"
        :loading="loading">智能分析</el-button>

    </div>
  </div>
  <!-- 文字解析 -->
  <ExtractionText v-model="showText" @change="getFileList"></ExtractionText>
</template>

<script setup>
import { onMounted, ref, reactive, watch } from 'vue'
import MyTable from "@/components/aboutTable/MyTable.vue";
import ExtractionText from "@/components/ExtractionText/index.vue";
import { lzJcjPjdbSelectPage, tbGsxtBqglSelect, yyfxAdd, completions } from '@/api/semanticAnalysis'
import { qcckGet } from "@/api/qcckApi.js";
import { getCurrentInstance } from 'vue'
import { ParsingText } from '@/api/qcckApi'
import emitter from "@/utils/eventBus.js";
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
const { proxy } = getCurrentInstance()
const props = defineProps({
  dict: {
    type: Object,
    default: {}
  },
  title: {
    type: String,
    default: ''
  }

})
// const title=ref('警情')
const route = useRoute()
const emit = defineEmits(['update:modelValue'])
const tally = ref([])
const dataList = ref()
const showText = ref(false);
let tableDate = reactive({
  tableData: [],
  keyCount: 0,
  tableConfiger: {
    rowHieght: 61,
    showSelectType: "radio",
    loading: false,
    haveControls: false,
  },
  tableHeight: 0,
  total: 0,
  pageConfiger: {
    pageSize: 20,
    pageCurrent: 1
  }, //分页
  controlsWidth: 200, //操作栏宽度
  tableColumn: []
});
// 警情
const particulars = [{
  label: "警情编号",
  prop: "jjdbh"
},
{
  label: "警情类型",
  prop: "jqlxdm",
  showSolt: true
}, {
  label: "警情内容",
  prop: "bjnr",
  showOverflowTooltip: true
}]
// 线索
const thread = [{
  label: "线索名称",
  prop: "xsMc",

}, {
  label: "线索编号",
  prop: "xsBh",
}, {
  label: "线索类型",
  prop: "xlLx",
  showSolt: true
},
{
  label: "线索内容",
  prop: "xsNr",
  showOverflowTooltip: true
}]
// 附件
const fjColumn = [{
  label: "附件编号",
  prop: "fjdz",

}, {
  label: "附件名称",
  prop: "fjmc",
}, {
  label: "附件内容",
  prop: "text",
  showOverflowTooltip: true
}]
tableDate.tableColumn = particulars
const showBut = ref(false)
// 保存到数据库的数据
const saveData = ref({})
// 存储选中的类型
const selectType = ref('警情')
onMounted(() => {
  tabHeightFn();
  gettbJqListPage()
  // 获取选择框的值
  emitter.on('changeTab', (res) => {
    tally.value = res
  })
  // 获取弹窗的值
  emitter.on('getData', (res) => {
    showBut.value = false
    tableDate.pageConfiger.pageCurrent = 1
    selectType.value = res.text
    switch (res.text) {
      case '警情':
        tableDate.tableColumn = particulars
        gettbJqListPage()
        break;
      case '情报线索':
        tableDate.tableColumn = thread
        gettbClListPage()
        break;
      case '案件':
        break;
      default:
        showBut.value = true
        tableDate.tableColumn = fjColumn
        tableDate.tableData = []
        break;
    }
  })
})


const tableHeight = ref()
const tabHeightFn = () => {
  tableHeight.value = window.innerHeight - 480;
  window.onresize = function () {
    tabHeightFn();
  };
};
const disabled = ref(false);
const loadMore = () => {
  if (tableDate.total == tableDate.tableData.length) {
    disabled.value = true
  } else {
    tableDate.pageConfiger.pageCurrent++;
    gettbJqListPage();
  }
};
// 警情请求
const gettbJqListPage = () => {
  tableDate.tableConfiger.loading = true;
  lzJcjPjdbSelectPage({
    pageCurrent: tableDate.pageConfiger.pageCurrent,
    pageSize: tableDate.pageConfiger.pageSize,
  }).then(res => {
    tableDate.tableData = tableDate.pageConfiger.pageCurrent == 1 ? res.records || [] : tableDate.tableData.concat(res.records || []);
    tableDate.total = res.total;
  }).finally(() => {
    tableDate.tableConfiger.loading = false;
  })
}
//线索请求
const gettbClListPage = () => {
  tableDate.tableConfiger.loading = true;
  const params = {
    pageCurrent: tableDate.pageConfiger.pageCurrent,
    pageSize: tableDate.pageConfiger.pageSize,
  }
  qcckGet(params, '/mosty-gsxt/qbcj/selectPage').then(res => {
    tableDate.tableData = tableDate.pageConfiger.pageCurrent == 1 ? res.records || [] : tableDate.tableData.concat(res.records || []);
    tableDate.total = res.total;
  }).catch(() => {
  }).finally(() => {
    tableDate.tableConfiger.loading = false;
  })
}
// 获取附件的信息
const getFileList = (val) => {
  tableDate.tableData.push(val)
}

const chooseData = (val) => {
  if (val.length > 0) {
    dataList.value = val[0]
  } else {
    dataList.value = ''
  }
  // 01是警情和线索案件
  // 02是文件
  switch (selectType.value) {
    case '警情':
      saveData.value.sjlyid = val[0].jjdbh
      saveData.value.tqlx = '01'
      break
    case '情报线索':
      saveData.value.sjlyid = val[0].id
      saveData.value.tqlx = '01'
      break;
    case '案件':
      break;
    default:
      console.log(val);
      saveData.value.fj = val.length > 0 ? val[0].fjdz : ''
      saveData.value.tqlx = '02'
      break;
  }

}
const getTage = (val, zd) => {
  if (zd) {
    let tag = zd.find(item => {
      return item.dm == val
    })
    return tag ? tag.zdmc : ''
  }
}
const bqList = reactive({
  sfBq: [],
  XwBq: []
})

const getBq = () => {
  tbGsxtBqglSelect({ bqLx: '01' }).then(res => {
    bqList.sfBq = res
  })
  tbGsxtBqglSelect({ bqLx: '02' }).then(res => {
    bqList.XwBq = res
  })
}
getBq()
const loading = ref(false)
const getText = async (val) => {
  if (tally.value.length == 0) {
    proxy.$message({ type: "error", message: "请先选择标签" });
    return
  }
  console.log(dataList.value);

  if (!dataList.value) {
    proxy.$message({ type: "error", message: "请选择分析的内容" });
    return
  }
  const findSf = tally.value.find(item => item.value == "10011400")
  const findXw = tally.value.find(item => item.value == "10011500")
  let sfBq = []
  let XwBq = []
  if (findSf) {
    sfBq = bqList.sfBq.map(v => {
      return `  - 50${v.bqDm}:${v.bqMc}`
    }).join('');
  }
  if (findXw) {
    XwBq = bqList.XwBq.map(v => {
      return `  - 60${v.bqDm}:${v.bqMc}`
    }).join('');
  }
  // 获取行为标签和身份标签
  let obj = {
    model: "deepseek-32b",
    prompt: `# 角色定位\n你是一名资深警务人员，尤其擅长对警情、案件、线索等非结构化文本数据进行阅读理解，并从中提取各种对象特征信息进行结构化，并总结各种对象之间的关联关系。\n`,
    max_tokens: 1000,
  }
  const strTow = `\n## 注意\n- 返回json格式以键值对的形式，以标签代码为key，标签名为name，提取的值为content。例如：[{40050900:{name:非法运输、买卖、储存、使用罂粟壳,content:-}}]；\n\n# 警情信息\n  - `
  const strThree = `\n## 任务\n根据警情信息识别对象信息，以及对象之间的关联关系。最后以json形式输出，不要做任何解释。直接给出完整的json\n`
  const strFive = `\n## 注意点\n- 地址信息能够根据上下文信息按照省、市、县、街道/乡镇、路名分段补全并标准化。例如:四川省 成都市 高新区 桂溪街道 交子大道11号\n- 对象之间的关联关系由对象类型、对象id、关系类型、目标对象类型、目标对象id 5个属性组成。\n`
  const marks = tally.value.map(v => {
    return `  - ${v.value}:${v.label}`
  }).join('');
  obj.prompt = obj.prompt + marks + sfBq + XwBq + strFive + strThree + strTow
  let time = '时间必须按照 YYYY-MM-DD HH:mm:ss 的格式 \n'
  let str = ""
  switch (selectType.value) {
    case '警情':
      str = dataList.value.bcjjnr ? dataList.value.bcjjnr : '' + dataList.value.bjnr
      break
    case '情报线索':
      str = dataList.value.xsNr
      break;
    case '案件':
      break;
    default:
      str = dataList.value.text
      break;
  }
  obj.prompt = obj.prompt + time + str
  saveData.value.qqcs = JSON.stringify(obj.prompt)
  handleFx(obj)
}
function simpleExtractJSON(text) {
  // 找到第一个 [
  const startIndex = text.indexOf('[');
  if (startIndex === -1) return null;

  // 找到最后一个完整的 }
  let lastBraceIndex = text.lastIndexOf('}');
  if (lastBraceIndex === -1) return null;

  // 确保 } 后面没有其他字符（除了空格和换行）
  let endIndex = lastBraceIndex + 1;

  // 截取从 [ 到最后一个 } 的内容，然后加上 ]
  let jsonString = text.substring(startIndex, endIndex) + ']';

  try {
    return JSON.parse(jsonString);
  } catch (error) {
    console.error("简单修复失败:", error);
    return null;
  }
}
const handleFx = (val) => {
  ElMessageBox.prompt('请输入名称', '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    inputPattern:
      /^(?!s*$).+/,
    inputErrorMessage: '请输入名称',
  })
    .then(({ value }) => {
      loading.value = true
      completions(val).then(res => {
        //   console.log(res,"分析报告数据");
        let jsonString
        let jsonMatch = res.choices[0].text.match(/\[[\s\S]*?\]/g);
        if (!jsonMatch) {
          jsonMatch = simpleExtractJSON(res.choices[0].text)
          jsonString = jsonMatch;
        } else {
          jsonString = jsonMatch[0];
        }
        if (jsonMatch) {
          const promes = {
            fxlb: selectType.value,
            fxmc: value,
            tqjg: JSON.stringify(jsonString),//提取结果
            xyjg: res.choices[0].text,
            ...saveData.value
          }
          yyfxAdd(promes).then(res => {
            proxy.$message({ type: "success", message: "添加成功" });
            emitter.emit('getYyfxSelectPage')
            emitter.emit('getlistData', JSON.stringify(jsonString))
            emitter.emit('showDetails', false)
          }).catch(err => {
            console.log(err, "xxxxx");
            proxy.$message({ type: "error", message: "添加失败" });
          })
        } else {
          proxy.$message({ type: "error", message: "解析失败，请重新上传分析" });
        }
      }).catch(err => {
        console.log(err, 'vvvv');
      }).finally(() => {
        loading.value = false
      })
    })
    .catch((err) => {
      console.log(err);
    })
}


</script>

<style lang="scss" scoped>
.searchTool {
  margin-top: 10px;
  background-color: #fff;
  color: #000;
  padding: 16px 20px;
  border-radius: 5px;

  .searchToolTitle {
    font-size: 18px;
    font-family: 'verdana';
    position: relative;
  }

  .searchToolContent {
    // width: 100%;
    margin-top: 16px;
  }

  .searchToolTitle::after {
    content: "";
    display: block;
    position: absolute;
    bottom: 0px;
    left: 0px;
    width: 80px;
    border-radius: 5px;
    height: 4px;
    background-color: #0386fb;
    background: linear-gradient(90deg, #0aa1ff 2%, #ffffff 100%);
  }
}

.searchToolFooter {
  height: 50px;
  display: flex;
  justify-content: center;

  .establishBut {
    width: 200px;
    margin-top: 10px;
    height: 40px;
  }
}
</style>
