config.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <div class="main-container">
  3. <div style="position: absolute;top: 0;left: 0;width: 100%;padding: 0 20px">
  4. <h4 style="margin-bottom: 10px"></h4>
  5. <div style="color: #666666;">在这里更新您的知识库详细信息,尤其是解析方法。</div>
  6. <a-divider style="margin-top: 20px" />
  7. </div>
  8. <div class="main-container-lf">
  9. <div class="main-container-lf-down">
  10. <a-form ref="formRef" :rules="rules" :model="form" :style="{width:'100%'}" layout="vertical"
  11. @submit="handleSubmit">
  12. <a-form-item field="name" label="知识库名称">
  13. <a-input v-model="form.name" placeholder="请输入" />
  14. </a-form-item>
  15. <a-form-item field="section" label="知识库图片">
  16. <a-space direction="vertical" :style="{ width: '100%' }">
  17. <a-upload
  18. :auto-upload="false"
  19. :fileList="file ? [file] : []"
  20. :show-file-list="false"
  21. @change="onChange"
  22. @progress="onProgress"
  23. >
  24. <template #upload-button>
  25. <div
  26. :class="`arco-upload-list-item${
  27. file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
  28. }`"
  29. >
  30. <div
  31. class="arco-upload-list-picture custom-upload-avatar"
  32. v-if="file && file.url"
  33. >
  34. <img :src="file.url" />
  35. <div class="arco-upload-list-picture-mask">
  36. <IconEdit />
  37. </div>
  38. <a-progress
  39. v-if="file.status === 'uploading' && file.percent < 100"
  40. :percent="file.percent"
  41. type="circle"
  42. size="mini"
  43. :style="{
  44. position: 'absolute',
  45. left: '50%',
  46. top: '50%',
  47. transform: 'translateX(-50%) translateY(-50%)',
  48. }"
  49. />
  50. </div>
  51. <div class="arco-upload-picture-card" v-else>
  52. <div class="arco-upload-picture-card-text">
  53. <IconPlus />
  54. <div style="margin-top: 10px; font-weight: 600">上传</div>
  55. </div>
  56. </div>
  57. </div>
  58. </template>
  59. </a-upload>
  60. </a-space>
  61. </a-form-item>
  62. <a-form-item field="section" label="描述">
  63. <a-textarea placeholder="" v-model="form.description" allow-clear />
  64. </a-form-item>
  65. <!-- <a-form-item field="section" label="语言" :rules="[{match:/section one/,message:'请选择'}]">-->
  66. <!-- <a-select v-model="form.section" placeholder="请选择" allow-clear>-->
  67. <!-- <a-option value="0">中文</a-option>-->
  68. <!-- <a-option value="1">英文</a-option>-->
  69. <!-- </a-select>-->
  70. <!-- </a-form-item>-->
  71. <a-form-item field="section" label="嵌入模型">
  72. <a-space direction="vertical" size="large">
  73. <a-select :size="'large'" v-model="form.embd_id" :style="{width:'100%'}" placeholder="请选择 ..." :disabled="kbObj.chunk_num>0 || kbObj.token_num>0" allow-clear>
  74. <a-optgroup :label="index" v-for="(item,index) in modelList" :key=index>
  75. <a-option
  76. v-for="(obj) in item"
  77. :key='obj.fid'
  78. :value="obj.llm_name"
  79. >
  80. {{obj.llm_name}}
  81. </a-option>
  82. </a-optgroup>
  83. </a-select>
  84. </a-space>
  85. </a-form-item>
  86. <a-form-item field="parser_id" label="解析方法">
  87. <a-select v-model="form.parser_id" placeholder="请选择" :disabled="kbObj.chunk_num>0 || kbObj.token_num>0" allow-clear>
  88. <a-option v-for="item in parser_ids" :key="item.value" :label="item.name" :value="item.value"></a-option>
  89. </a-select>
  90. </a-form-item>
  91. <a-form-item field="slider" label="块Token数">
  92. <a-slider v-model="form.chunk_token_num" :min="0" :max="2048" show-input />
  93. </a-form-item>
  94. <a-form-item label="布局识别" >
  95. <a-space direction="vertical" size="large">
  96. <a-switch v-model="form.layout_recognize" />
  97. </a-space>
  98. </a-form-item>
  99. <a-form-item field="raptor" label="使用召回增强RAPTOR策略">
  100. <a-space direction="vertical" size="large">
  101. <a-switch v-model="form.use_raptor" />
  102. </a-space>
  103. </a-form-item>
  104. <div v-if="form.use_raptor">
  105. <a-form-item field="prompt" label="提示词">
  106. <a-textarea
  107. v-model="form.prompt"
  108. style="height: 10rem;border: 1px solid var(--color-fill-3);border-radius: 4px" placeholder="请填写提示词" />
  109. </a-form-item>
  110. <a-form-item field="slider" label="最大token数">
  111. <a-slider v-model="form.max_token" :min="0" :max="2048" show-input/>
  112. </a-form-item>
  113. <a-form-item field="slider" label="阈值" >
  114. <a-slider v-model="form.threshold" :step="0.01" :min="0" :max="1" show-input/>
  115. </a-form-item>
  116. <a-form-item field="slider" label="最大聚类数">
  117. <a-slider v-model="form.max_cluster" :min="1" :max="1024" show-input/>
  118. </a-form-item>
  119. <a-form-item field="slider" label="随机种子" v-model="form.random_seed">
  120. <a-input-number v-model="form.random_seed" :style="{width:'300px',marginRight:'1rem',borderRadius:'4px'}"
  121. placeholder="请输入" class="input-demo" :min="10" :max="100" />
  122. <a-button type="primary" @click="randomNumber">
  123. <icon-plus />
  124. </a-button>
  125. </a-form-item>
  126. </div>
  127. <a-form-item>
  128. <div style="width: 100%;text-align: right">
  129. <a-space>
  130. <a-button type="primary" html-type="submit">保存</a-button>
  131. <!-- <a-button @click="$refs.formRef.resetFields()">Reset</a-button>-->
  132. </a-space>
  133. </div>
  134. </a-form-item>
  135. </a-form>
  136. </div>
  137. </div>
  138. <div class="main-container-rt">
  139. <section data-inspector-line="34" data-inspector-column="4"
  140. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
  141. class="categoryPanelWrapper___yI4rY"><h4
  142. class="ant-typography topTitle___tNiB9 css-dev-only-do-not-override-1wxecgq" data-inspector-line="37"
  143. data-inspector-column="10"
  144. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">"General"
  145. 分块方法说明</h4>
  146. <p data-inspector-line="40" data-inspector-column="10"
  147. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"><p>
  148. 支持的文件格式为<b>DOCX、EXCEL、PPT、IMAGE、PDF、TXT</b>。</p>
  149. <p>此方法将简单的方法应用于块文件:</p>
  150. <p>
  151. </p>
  152. <li>系统将使用视觉检测模型将连续文本分割成多个片段。</li>
  153. <li>接下来,这些连续的片段被合并成Token数不超过“Token数”的块。</li>
  154. <p></p></p>
  155. <h4 class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="45"
  156. data-inspector-column="10"
  157. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">
  158. "General" 示例</h4><span class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="48"
  159. data-inspector-column="10"
  160. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">提出以下屏幕截图以促进理解。</span>
  161. <div data-inspector-line="49" data-inspector-column="10"
  162. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
  163. class="ant-row imageRow___C3Xpb css-dev-only-do-not-override-1wxecgq"
  164. style="margin-left: -5px; margin-right: -5px; row-gap: 10px;display: flex; margin-top: 20px;width: 100%">
  165. <img
  166. data-inspector-line="32" data-inspector-column="8"
  167. data-inspector-relative-path="src\components\svg-icon.tsx" src="../../../assets/images/step1.png" alt=""
  168. width="50%">
  169. <img
  170. data-inspector-line="32" data-inspector-column="8"
  171. data-inspector-relative-path="src\components\svg-icon.tsx" src="../../../assets/images/step2.png" alt=""
  172. width="50%">
  173. </div>
  174. <h4 class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="60"
  175. data-inspector-column="10"
  176. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">
  177. General 对话示例</h4>
  178. <div class="ant-divider css-dev-only-do-not-override-1wxecgq ant-divider-horizontal" data-inspector-line="63"
  179. data-inspector-column="10"
  180. data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
  181. role="separator"></div>
  182. <a-divider style="margin-top: 20px" />
  183. </section>
  184. </div>
  185. </div>
  186. </template>
  187. <script lang="ts" setup>
  188. import { onMounted, onBeforeMount, reactive, ref } from "vue";
  189. import { Message } from "@arco-design/web-vue";
  190. import { queryModelList,kbUpdate } from "@/api/kbList";
  191. const props = defineProps(['kbtenantInfo'])
  192. // const emit = defineEmits(['upTabdateItem'])
  193. const kbtenantInfo = props.kbtenantInfo;
  194. // 解析方法列表
  195. let parser_ids = kbtenantInfo.parser_ids.split(",").map((item) => {
  196. const [value1, value2] = item.split(":");
  197. return {
  198. name: value2,
  199. value: value1
  200. };
  201. });
  202. let kbObj = reactive({});
  203. const form = reactive({
  204. name: kbObj.name,
  205. avatar: '',//
  206. max_token: 600,
  207. threshold: 0.32,
  208. max_cluster: 233,
  209. random_seed: 1500,
  210. chunk_token_num: 128,
  211. use_raptor: false,
  212. pages: {},
  213. prompt: "请总结以下段落。 小心数字,不要编造。 段落如下:\n" +
  214. " {cluster_content}\n" +
  215. "以上就是你需要总结的内容。",
  216. description: "",
  217. language: "English",
  218. permission: "",
  219. embd_id: "BAAI/bge-large-zh-v1.5",
  220. parser_id: kbObj.parser_id,
  221. layout_recognize: true
  222. });
  223. const rules = {
  224. name: [
  225. {
  226. required: true,
  227. message:'知识库名称不允许为空',
  228. },
  229. ],
  230. }
  231. let visible = ref(false);
  232. let loading = ref(false);
  233. const formRef = ref(null);
  234. const modelList = ref({});
  235. const file = ref();
  236. const onChange = (_, currentFile) => {
  237. file.value = currentFile;
  238. convertImageToBase64(file.value.file).then((result)=>{
  239. form.avatar = result;
  240. })
  241. };
  242. function convertImageToBase64(file) {
  243. return new Promise((resolve, reject) => {
  244. const reader = new FileReader();
  245. reader.onloadend = function() {
  246. resolve(reader.result);
  247. };
  248. reader.onerror = reject;
  249. reader.readAsDataURL(file);
  250. });
  251. }
  252. const onProgress = (currentFile) => {
  253. file.value = currentFile;
  254. };
  255. const handleSubmit = async ({ values, errors }) => {
  256. if (errors){
  257. return;
  258. }
  259. console.log(form);
  260. let parms = {
  261. name: form.name,
  262. avatar: form.avatar,
  263. description: form.description,
  264. language: form.language,
  265. permission: form.permission,
  266. embd_id: form.embd_id,
  267. parser_id: form.parser_id,
  268. parser_config: {
  269. chunk_token_num: form.chunk_token_num,
  270. layout_recognize: form.layout_recognize,
  271. },
  272. kb_id: kbObj.id,
  273. }
  274. if(form.layout_recognize){
  275. parms.parser_config.raptor = {
  276. use_raptor: form.use_raptor,
  277. prompt: form.prompt,
  278. max_token: form.max_token,
  279. threshold: form.threshold,
  280. max_cluster: form.max_cluster,
  281. random_seed: form.random_seed,
  282. };
  283. }
  284. try {
  285. const data = await kbUpdate(parms);
  286. if(data.code == '0'){
  287. Message.success("配置成功");
  288. // window.location.reload();
  289. }
  290. // visible.value = false;
  291. // emit('upTabdateItem')
  292. } catch (err) {
  293. // you can report use errorHandler or other
  294. }
  295. };
  296. function randomNumber() {
  297. // 生成一个介于min和max之间的随机整数(包含min和max)
  298. const min = 1; // 最小值
  299. const max = 10000; // 最大值
  300. form.random_seed = Math.floor(Math.random() * (max - min + 1)) + min;
  301. }
  302. const onChangeRAPTOR = () => {
  303. console.log(form);
  304. };
  305. const handleClick = () => {
  306. visible.value = true;
  307. };
  308. const handleBeforeOk = (done) => {
  309. formRef.value.validate().then(res => {
  310. console.log("form:", form);
  311. if (!form.name) {
  312. done(false);
  313. } else {
  314. console.log("请求数据");
  315. }
  316. });
  317. };
  318. const handleCancel = () => {
  319. visible.value = false;
  320. };
  321. const handleOpened =(el) => {
  322. Object.assign(form,{
  323. });
  324. formRef.value.resetFields();
  325. }
  326. const queryModel = async (params) => {
  327. try {
  328. const data = await queryModelList(params);
  329. // console.log(data.data, '大模型列表');
  330. modelList.value = data.data
  331. } catch (err) {
  332. // you can report use errorHandler or other
  333. } finally {
  334. }
  335. };
  336. const changekbObj = (value) => {
  337. kbObj = value;
  338. console.log(kbObj, 'kbObj');
  339. // if(kbObj.avatar){
  340. // file.value.url = kbObj.avatar
  341. // }
  342. let configObj = {
  343. name: kbObj.name,
  344. avatar: kbObj.avatar,
  345. chunk_token_num: kbObj.parser_config ? kbObj.parser_config.chunk_token_num : 128,
  346. pages: kbObj.pages,
  347. description: kbObj.description,
  348. language: "English",
  349. permission: kbObj.permission,
  350. embd_id: "BAAI/bge-large-zh-v1.5",
  351. parser_id: kbObj.parser_id,
  352. layout_recognize: kbObj.parser_config ? kbObj.parser_config.layout_recognize:false,
  353. }
  354. let raptor = {}
  355. if(kbObj.parser_config && kbObj.parser_config.raptor){
  356. raptor = kbObj.parser_config.raptor;
  357. Object.assign(form,{
  358. ...configObj,
  359. ...raptor,
  360. });
  361. }else{
  362. Object.assign(form,configObj);
  363. }
  364. }
  365. defineExpose({
  366. changekbObj
  367. })
  368. onBeforeMount(()=>{
  369. queryModel({})
  370. })
  371. onMounted(()=>{
  372. })
  373. </script>
  374. <script lang="ts">
  375. import { IconEdit, IconPlus } from "@arco-design/web-vue/es/icon";
  376. export default {
  377. name: "config",
  378. components: { IconPlus, IconEdit },
  379. methods: {}
  380. };
  381. </script>
  382. <style scoped lang="less">
  383. .main-container {
  384. position: relative;
  385. display: flex;
  386. justify-content: space-between;
  387. height: 100%;
  388. overflow: auto;
  389. //background: #626aea;
  390. background: var(--color-bg-2);
  391. padding-top: 80px;
  392. &-lf {
  393. width: 40%;
  394. //height: 100%;
  395. //border: 1px solid #cccccc;
  396. border-radius: 10px;
  397. //border: 1px solid var(--color-fill-3);
  398. &-top {
  399. width: 100%;
  400. height: 60px;
  401. line-height: 60px;
  402. //background: rgb(var(--primary-6));
  403. //color: #ffffff;
  404. //text-align: center;
  405. }
  406. &-down {
  407. padding: 20px;
  408. width: 100%;
  409. }
  410. }
  411. &-form-item-extra {
  412. width: 100%;
  413. height: 20rem;
  414. border: 1px solid var(--color-fill-3);
  415. border-radius: 6px;
  416. overflow: hidden;
  417. &-top {
  418. width: 100%;
  419. height: 40px;
  420. line-height: 40px;
  421. border-bottom: 1px solid var(--color-fill-3);
  422. //background: rgb(var(--primary-6));
  423. color: #999999;
  424. text-align: center;
  425. }
  426. &-down {
  427. width: 92%;
  428. margin-left: 4%;
  429. margin-top: 30px;
  430. }
  431. &-btn {
  432. width: 96%;
  433. text-align: right;
  434. margin-top: 1rem;
  435. }
  436. }
  437. &-rt {
  438. width: 60%;
  439. //background: #626aea;
  440. //border: 1px solid #cccccc;
  441. border-radius: 10px;
  442. overflow: hidden;
  443. padding: 20px;
  444. section {
  445. width: 100%;
  446. //color: #333333;
  447. color: var(--color-text-1);
  448. }
  449. }
  450. }
  451. </style>