<!--左侧操作界面  -->
<template>
  <el-form label-position="left" ref="form" label-width="120px" :model="form" :size="defaultFormItemSize" style="padding:20px;width:400px" v-loading.fullscreen.lock="fullscreenLoading">
    <el-form-item label="问答模式：">
      <el-select v-model="form.pattern" placeholder="请选择" @change="patternChange">
        <el-option v-for="item in ModeOfSpeaking.getList()" :key="item.id" :label="item.name" :value="item.name">
        </el-option>
      </el-select>
    </el-form-item>
    <!-- <el-form-item label="模型选择：">
      <el-cascader v-model="form.model_name" ref="modelCascader" :options="modelList" :props='{ label: "name", value: "name", emitPath: false }' @change="changeModel"></el-cascader>
    </el-form-item> -->
    <el-form-item label="服务选择：">
      <el-select ref="serveCascader" v-model="form.model_name" placeholder="请选择">
        <el-option v-for="item in serveList" :key="item.createUserId" :label="item.serviceName" :value="item.versionName">
        </el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="Temperature：">
      <el-slider v-model="temperature" :format-tooltip="formatTooltip" @change="form.temperature = temperature / 100"></el-slider>
    </el-form-item>
    <el-form-item label="历史对话轮数：">
      <el-input-number v-model="form.heistoryRotate" :min="0" :max="10"></el-input-number>
    </el-form-item>
    <el-form-item label="提示词：" style="">
      <div style="display: flex;flex-direction: row;align-items: center;">
        <el-select v-model="promptTemplate" filterable placeholder="提示词" value-key="templateId" @change="templateControllerChange" clearable>
          <el-option v-for="item in templateControllerList" :key="item.templateId" :label="item.label" :value="item">
          </el-option>
        </el-select>
        <el-switch @change="changePromptTemplate" style="margin-left: 10px;" v-model="isPromptTemplate" active-color="#13ce66" inactive-color="#ff4949">
        </el-switch>
      </div>
    </el-form-item>
    <el-form-item label-width="0px" v-if="form.prompt_template">
      <div style="background-color: #f3f3f3;padding: 10px;border-radius: 10px;white-space: pre-wrap;    display: inline-flex;">
        {{ form.prompt_template }}
      </div>
    </el-form-item>
    <el-form-item label-width="0px" v-if="form.pattern == '专业知识库问答'">
      <el-collapse value="1">
        <el-collapse-item name="1">
          <template slot="title">知识库配置</template>
          <el-form-item label="请选择知识库：" style="margin-bottom:30px">
            <el-select ref="knowledgeSelect" v-model="form.knowledgeConfige.knowledge_base_name" placeholder="请选择" @change="changeKnowledge">
              <el-option v-for="item in knowledgeList" :key="item.knowledgeId" :label="item.knowledgeName" :value="item.knowledgeName">
              </el-option>
            </el-select>

            <div class="el-upload__tip">{{knowledgeDescribe}}</div>

          </el-form-item>
          <el-form-item label="匹配知识条数：" style="margin-bottom:30px">
            <el-input-number v-model="form.knowledgeConfige.top_k" :min="1" :max="20"></el-input-number>
          </el-form-item>
          <el-form-item label="匹配精度：">
            <el-slider v-model="knowledgeScoreThreshold" :format-tooltip="formatTooltip" @change="form.knowledgeConfige.score_threshold = knowledgeScoreThreshold / 100"></el-slider>
          </el-form-item>
        </el-collapse-item>
      </el-collapse>
    </el-form-item>
    <el-form-item label-width="0px" v-if="form.pattern == '搜索引擎问答'">
      <el-collapse value="1">
        <el-collapse-item name="1">
          <template slot="title">搜索引擎配置</template>
          <el-form-item label="选择搜索引擎：" style="margin-bottom:30px">
            <el-select ref="searchSelect" v-model="form.searchConfige.search_engine_name" placeholder="请选择" @change="changeSe">
              <el-option v-for="item in [{ label: 'bing', value: 'bing' }, { label: 'duckduckgo', value: 'duckduckgo' }]" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="匹配搜索结果条数：">
            <el-input-number v-model="form.searchConfige.top_k" :min="1" :max="20"></el-input-number>
          </el-form-item>
        </el-collapse-item>
      </el-collapse>
    </el-form-item>
    <el-form-item label-width="0px" v-if="form.pattern == '基于文件问答'">
      <el-collapse value="1">
        <el-collapse-item name="1">
          <template slot="title">文件配置</template>
          <el-form-item label="上传文件：" style="margin-bottom:30px">
            <el-button @click="clickUp" :size="defaultFormItemSize" type="primary">选择文件</el-button>
            <input style="display:none" ref="upFile" type="file" @change="fileinfo($event.target.files)" multiple accept=".html, .md, .json, .jsonl, .csv, .pdf, .png, .jpg, .jpeg, .bmp, .eml, .msg, .epub, .xlsx, .xls, .ipynb, .odt, .py, .rst, .rtf, .srt, .toml, .tsv, .docx, .doc, .xml, .ppt, .pptx, .txt, .htm">
            <div class="el-upload__tip">可上传HTML, MD, JSON, JSONL, CSV, PDF, PNG, JPG, JPEG, BMP, EML, MSG, EPUB, XLSX, XLSD, IPYNB, ODT, PY, RST, RTF, SRT, TOML, TSV, DOCX, DOC, XML, PPT, PPTX, TXT, HTM文件</div>
            <div class="itemFile" v-for="(item,index) in files" :key="item.name"><i class="el-icon-document" style="color:#909399;margin-right:5px"></i>{{ item.name }}
              <i class="el-icon-circle-close" style="color:#0092FF;cursor: pointer;" @click="clearFile(index)"></i>
            </div>
            <el-button style="display:block;margin-top:10px" :size="defaultFormItemSize" type="primary" @click="uploadFiles" :disabled="files.length===0">上传</el-button>

          </el-form-item>
          <el-form-item label="匹配知识条数：" style="margin-bottom:30px">
            <el-input-number v-model="form.fileConfige.top_k" :min="1" :max="20"></el-input-number>
          </el-form-item>
          <el-form-item label="知识匹配分数阈值：">
            <el-slider v-model="fileThreshold" :format-tooltip="formatTooltip" @change="form.fileConfige.score_threshold = fileThreshold / 100"></el-slider>
          </el-form-item>
        </el-collapse-item>
      </el-collapse>
    </el-form-item>
    <!-- <el-form-item label-width="0px" v-if="form.pattern == '知识图谱问答'">
      <el-collapse value="1">
        <el-collapse-item name="1">
          <template slot="title">知识图谱配置</template>
          <el-form-item label="请选择知识图谱：" style="margin-bottom:30px">
            <el-select ref="knowledgeSelect" v-model="form.knowledgeGraphConfige. knowledge_graph_name" placeholder="请选择">
              <el-option v-for="item in []" :key="item.knowledgeId" :label="item.knowledgeGraphName" :value="item.knowledgeGraphName">
              </el-option>
            </el-select>

          </el-form-item>
          <el-form-item label="匹配知识条数：" style="margin-bottom:30px">
            <el-input-number v-model="form.knowledgeGraphConfige.top_k" :min="1" :max="20"></el-input-number>
          </el-form-item>
          <el-form-item label="匹配精度：">
            <el-slider v-model="knowledgeScoreThreshold" :format-tooltip="formatTooltip" @change="form.knowledgeGraphConfige.score_threshold = knowledgeGraphThreshold / 100"></el-slider>
          </el-form-item>
        </el-collapse-item>
      </el-collapse>
    </el-form-item> -->
  </el-form>
</template>

<script>
import { KnowledgeManage, MyModel, ModelVersion, TemplateController, ModelDeployment } from '@/api/gptController.js'
import promptWordTemplate from '../promptWordTemplate'
export default {
  data() {
    return {
      knowledgeDescribe: '',
      files: [],
      fullscreenLoading: false,
      isPromptTemplate: true,
      promptTemplate: '',
      templateControllerList: [],
      modelList: [],
      serveList: [],
      activeModelList: [],
      loading: undefined,
      temperature: 70,
      knowledgeList: [],
      knowledgeScoreThreshold: 50,
      fileThreshold: 50,
      knowledgeGraphThreshold: 50,
      form: {
        pattern: '通用智能问答', // 对话模式
        model_name: undefined, // 模型名称
        temperature: 0.7,
        prompt_template: '',
        heistoryRotate: 10, // 历史对话轮数
        knowledgeConfige: {
          // 知识库配置
          knowledge_base_name: '',
          top_k: 1,
          score_threshold: 0.5
        },
        searchConfige: {
          // 搜索引擎配置
          search_engine_name: 'bing',
          top_k: 1
        },
        fileConfige: {
          // 文件对哈配置
          top_k: 1,
          score_threshold: 0.5,
          knowledge_id: undefined,
          // max_tokens: 0,
          prompt_name: 'default'
        },
        knowledgeGraphConfige: {
          // 知识图谱对话
          knowledge_graph_name: '',
          top_k: 1,
          score_threshold: 0.5
        }
      },
      filesForm: {
        filesArr: undefined,
        chunk_size: 250,
        chunk_overlap: 50,
        zh_title_enhance: false
      }
    }
  },

  components: {},

  computed: {},
  watch: {
    form: {
      handler(newVal, oldVal) {
        this.$emit('chatForm', this.form)
      },
      deep: true, // 是否深度监听
      immediate: true // 是否在组件创建时立即执行回调函数
    }
  },
  mounted() {
    this.getKnowledgeList()
    // this.getModelList()
    this.getTemplateControllerList()
    this.getServeList()
  },

  methods: {
    getTemplateControllerList() {
      TemplateController.listForTree(this, {})
        .then((res) => {
          this.templateControllerList = res.data.map((item) => {
            return {
              templateId: item.templateId,
              label: item.templateName,
              value: item.templateContent,
              parameterFormat: item.parameterFormat
            }
          })
        })
        .catch((e) => {
          console.log(e)
        })
    },
    getServeList() {
      ModelDeployment.canUseList(this, {})
        .then((res) => {
          console.log(res)
          this.serveList = res?.data?.dataList
          this.form.model_name = this.serveList[0].versionName
        })
        .catch((e) => {
          console.log(e)
        })
    },
    getModelList() {
      MyModel.listForTree(this, {})
        .then((res) => {
          this.modelList = res.data.map((item) => {
            return {
              id: item.modelId,
              name: item.modelName,
              // prettier-ignore
              children: item.modelVersionList === [] ? [] : item.modelVersionList.map((item2) => {
                return { id: item2.versionId, name: item2.versionName }
              })
            }
          })

          this.getActiveModelList()
        })
        .catch((e) => {
          console.log(e)
        })
    },
    getKnowledgeList() {
      let params = {}
      KnowledgeManage.load(this, params)
        .then((res) => {
          this.knowledgeList = res.data
        })
        .catch((e) => {
          console.log(e)
        })
    },
    getActiveModelList() {
      // 获取当前挂载上的模型列表
      let params = {}
      ModelVersion.listModels(this, params)
        .then((res) => {
          this.activeModelList = res.data
          if (this.activeModelList.length === 0) {
            this.form.model_name = this.modelList[0].children[0].name
            this.switchModel(this.modelList[0].children[0].id)
          } else {
            this.form.model_name = this.activeModelList[0]
          }
        })
        .catch((e) => {
          console.log(e)
        })
    },
    openLoading(text) {
      this.loading = this.$loading({
        lock: true,
        text: text,
        customClass: 'myLoading',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.9)'
      })

      // loading.close();
    },
    formatTooltip(val) {
      return val / 100
    },
    switchModel(versionId) {
      // 切换模型
      this.openLoading('LLM模型加载中')
      ModelVersion.change(this, { versionId: versionId })
        .then((res) => {
          this.loading.close()
        })
        .catch((e) => {
          this.loading.close()
          console.log(e)
        })
    },
    changeModel(data) {
      // 修改模型
      // this.openLoading('LLM模型加载中')
      let id = this.$refs.modelCascader.getCheckedNodes()[0].data.id
      this.switchModel(id)
    },
    changeKnowledge(data) {
      // 修改知识库
      // this.openLoading('知识库加载中')
      this.knowledgeDescribe = this.knowledgeList.filter((item) => {
        return item.knowledgeName === data
      })[0].knowledgeDescribe
    },
    changeSe(data) {
      // 修改模型引擎
      // this.openLoading('模型引擎加载中')
      // console.log(this.$refs.searchSelect);
    },
    templateControllerChange(data) {
      if (!data) {
        this.form.prompt_template = ''
        return
      }
      this.$dialog
        .show(
          data.label,
          promptWordTemplate,
          {
            area: ['50%', '40%']
          },
          { data: data }
        )
        .then((res) => {
          this.form.prompt_template = res
        })
        .catch((e) => {
          this.promptTemplate = undefined
        })
    },
    changePromptTemplate() {
      this.$bus.$emit('isPromptTemplate', this.isPromptTemplate)
    },
    fileinfo(files) {
      for (const key in files) {
        if (Object.hasOwnProperty.call(files, key)) {
          const element = files[key]
          if (this.files.map((item) => item.name).indexOf(element.name) === -1) {
            this.files.push(element)
            this.filesForm.filesArr = this.files
          } else {
            console.log('重复上传')
          }
        }
      }
    },
    clickUp() {
      this.$refs.upFile.click()
    },

    clearFile(index) {
      this.files.splice(index, 1)
    },
    uploadFiles() {
      this.fullscreenLoading = true
      let params = this.filesForm
      this.upload('/2api/knowledge_base/upload_temp_docs', params, false)
        .then((res) => {
          this.$message.success('上传成功')
          this.fullscreenLoading = false
          this.form.fileConfige.knowledge_id = res.data.id
        })
        .catch((e) => {
          console.log(e)
        })
    },
    patternChange() {
      // console.log(111);
      // Object.assign(this.$data.form, this.$options.data().form);
    }
  }
}
</script>
<style scoped>
.myLoading .el-loading-spinner i {
  font-size: 24px !important;
}
.el-upload__tip {
  line-height: normal;
  font-size: 12px !important;
}
</style>
