| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- <template>
- <a-button type="text" @click="handleClick" size="small">
- <template #icon>
- <icon-tool />
- </template>
- </a-button>
- <a-modal
- v-model:visible="visible"
- title=" "
- @before-open="handleOpened"
- @cancel="handleCancel"
- :footer="false"
- title-align="start"
- width="900px"
- >
- <a-tabs default-active-key="1">
- <a-tab-pane key="1">
- <template #title>
- <icon-calendar />
- 解析方法
- </template>
- <div style="width: 100%">
- <div style="display: flex; align-items: center">
- <div> 解析方法:</div>
- <div style="margin-left: 10px">
- <a-select v-model="form.parser_id" placeholder="请选择">
- <a-option
- v-for="item in parser_ids"
- :key="item.value"
- :label="item.name"
- :value="item.value"
- ></a-option>
- </a-select>
- </div>
- </div>
- <div class="parser">
- <a-form
- ref="formRef"
- :rules="rules"
- :model="form"
- auto-label-width
- @submit="handleSubmit"
- >
- <a-divider
- style="margin-top: 10px"
- v-if="form.parser_id === 'naive'"
- />
- <a-form-item
- field="slider"
- label="块Token数"
- v-if="form.parser_id === 'naive'"
- >
- <a-slider
- v-model="form.chunk_token_num"
- :min="0"
- :max="2048"
- show-input
- />
- </a-form-item>
- <a-divider
- style="margin-top: 10px"
- v-if="
- form.parser_id === 'naive' ||
- form.parser_id === 'qa' ||
- form.parser_id === 'manual' ||
- form.parser_id === 'laws' ||
- form.parser_id === 'book'
- "
- />
- <a-form-item
- field="raptor"
- label="使用召回增强RAPTOR策略"
- v-if="
- form.parser_id === 'naive' ||
- form.parser_id === 'qa' ||
- form.parser_id === 'manual' ||
- form.parser_id === 'laws' ||
- form.parser_id === 'book'
- "
- >
- <a-space direction="vertical" size="large">
- <a-switch
- v-model="form.use_raptor"
- @change="onChangeRAPTOR"
- />
- </a-space>
- </a-form-item>
- <div v-if="form.use_raptor">
- <a-form-item field="prompt" label="提示词">
- <a-textarea
- v-model="form.prompt"
- style="
- height: 10rem;
- border: 1px solid var(--color-fill-3);
- border-radius: 4px;
- "
- placeholder="请填写提示词"
- />
- </a-form-item>
- <a-form-item field="slider" label="最大token数">
- <a-slider
- v-model="form.max_token"
- :min="0"
- :max="2048"
- show-input
- />
- </a-form-item>
- <a-form-item field="slider" label="阈值">
- <a-slider
- v-model="form.threshold"
- :step="0.01"
- :min="0"
- :max="1"
- show-input
- />
- </a-form-item>
- <a-form-item field="slider" label="最大聚类数">
- <a-slider
- v-model="form.max_cluster"
- :min="1"
- :max="1024"
- show-input
- />
- </a-form-item>
- <a-form-item
- field="slider"
- label="随机种子"
- v-model="form.random_seed"
- :rules="[
- { type: 'number', min: 5, message: 'slider is min than 5' },
- ]"
- >
- <a-input-number
- v-model="form.random_seed"
- :style="{
- width: '300px',
- marginRight: '1rem',
- borderRadius: '4px',
- }"
- placeholder="请输入"
- class="input-demo"
- :min="10"
- :max="100"
- />
- <a-button type="primary" @click="randomNumber">
- <icon-plus />
- </a-button>
- </a-form-item>
- </div>
- <a-form-item>
- <div style="width: 100%; text-align: right">
- <a-button @click="visible = false">取消</a-button>
- <a-button
- style="margin-left: 10px"
- type="primary"
- html-type="submit"
- >确定
- </a-button>
- </div>
- </a-form-item>
- </a-form>
- </div>
- </div>
- </a-tab-pane>
- <a-tab-pane key="2">
- <template #title>
- <icon-clock-circle />
- 创建解析块
- </template>
- <div class="details">
- <div class="details-header">
- <div
- style="
- display: flex;
- align-items: center;
- justify-content: flex-end;
- "
- >
- <a-radio-group
- v-model="radio"
- type="button"
- style="margin-right: 10px"
- @change="onRadioChange"
- >
- <a-radio value="1">全文</a-radio>
- <a-radio value="2">省略</a-radio>
- </a-radio-group>
- <a-popover position="bottom">
- <a-button
- type="outline"
- class="button"
- style="margin-right: 10px"
- >批量
- <icon-down style="margin-left: 4px" />
- </a-button>
- <template #content>
- <a-space direction="vertical">
- <a-checkbox
- :model-value="checkedAll"
- :indeterminate="indeterminate"
- @change="handleChangeAll"
- style="margin-left: 10px"
- >
- 选择所有
- </a-checkbox>
- </a-space>
- <a-divider style="margin: 10px 0" />
- <p>
- <a-button
- type="text"
- class="button"
- style="color: #2a2a2b"
- @click="addBlock(1)"
- >
- <template #icon>
- <icon-check-circle />
- </template>
- 启用选定的
- </a-button>
- </p>
- <p>
- <a-button
- type="text"
- class="button"
- style="color: #2a2a2b"
- @click="addBlock(0)"
- >
- <template #icon>
- <icon-close-circle />
- </template>
- 禁用选定的
- </a-button>
- </p>
- <a-divider style="margin: 10px 0" />
- <p>
- <a-button
- type="text"
- class="button"
- style="color: #2a2a2b"
- @click="addBlock(3)"
- >
- <template #icon>
- <icon-delete />
- </template>
- 删除选定的
- </a-button>
- </p>
- </template>
- </a-popover>
- <a-space
- direction="vertical"
- size="large"
- style="margin-right: 10px"
- class="space_search"
- v-show="!isBtn"
- >
- <a-input-search
- :style="{ width: '220px' }"
- v-model="form.keywords"
- @input="getList()"
- allow-clear
- @clear.stop="getList()"
- placeholder="搜索"
- />
- </a-space>
- <a-button
- type="outline"
- class="button"
- style="margin-right: 10px"
- v-show="isBtn"
- @click.stop="isBtn = !isBtn"
- >
- <template #icon>
- <icon-search />
- </template>
- </a-button>
- <a-popover position="bottom">
- <a-button
- type="outline"
- class="button"
- style="margin-right: 10px"
- >
- <icon-sort />
- </a-button>
- <template #content>
- <a-radio-group
- v-model="available_int"
- direction="vertical"
- size="large"
- @change="onChangeavailable"
- >
- <a-radio :value="''">所有</a-radio>
- <a-radio :value="1">启用</a-radio>
- <a-radio :value="0">禁用</a-radio>
- </a-radio-group>
- </template>
- </a-popover>
- <addDetails
- :item="item"
- @canplaythrough="canplaythrough"
- ></addDetails>
- </div>
- </div>
- <a-divider style="margin-top: 10px" />
- <div class="groupMain">
- <a-spin :loading="isLoading" :tip="tip">
- <a-checkbox-group v-model="data" @change="handleChange">
- <div
- class="groupList"
- :class="{
- groupActive: keyBg == index,
- groupNoActive: keyBg != index,
- }"
- v-for="(item, index) in listData"
- :key="index"
- >
- <a-checkbox :value="item.chunk_id"></a-checkbox>
- <div
- class="groupList-content emphaRed"
- @click="groupListContentClick(index)"
- @dblclick="contentClick(item)"
- v-html="item.content_with_weight"
- >
- </div>
- <div class="groupList-right">
- <a-switch
- v-model="item.available_int"
- :checked-value="1"
- :unchecked-value="0"
- @change="handleChangeStatus(item)"
- />
- </div>
- </div>
- </a-checkbox-group>
- </a-spin>
- </div>
- </div>
- <eidtDetails
- ref="eidtDil"
- :item="eidtDilinfo"
- v-model:eidtDilVisible="eidtDilVisible"
- @canplaythrough="canplaythrough"
- ></eidtDetails>
- </a-tab-pane>
- </a-tabs>
- </a-modal>
- </template>
- <script lang="ts" setup>
- import {
- onMounted,
- onBeforeMount,
- reactive,
- ref,
- computed,
- watch,
- } from 'vue';
- import { Message } from '@arco-design/web-vue';
- import {
- kbdocumentchangeparser,
- achunkCreate,
- queryChunkList,
- chunkSwitch,
- chunkRm,
- achunkGet,
- } from '@/api/kbList';
- import addDetails from '@/views/dmx/knowledgeLib/addDetails.vue';
- import eidtDetails from '@/views/dmx/knowledgeLib/eidtDetails.vue';
- const visible = ref(false);
- const loading = ref(false);
- const radio = ref('1');
- const keyBg = ref('');
- const eidtDil = ref();
- const eidtDilVisible = ref(false);
- const eidtDilinfo = reactive({});
- const props = defineProps(['kbtenantInfo', 'item', 'kbdetail']);
- // const emit = defineEmits(['upTabdateItem'])
- let threshold = computed(() => {
- return form.threshold / 100;
- });
- const kbtenantInfo = props.kbtenantInfo;
- let parser_ids = kbtenantInfo.parser_ids.split(',').map((item) => {
- const [value1, value2] = item.split(':');
- return {
- name: value2,
- value: value1,
- };
- });
- // 过滤解析方法
- const filterParserArr = [
- 'naive',
- 'qa',
- 'resume',
- 'manual',
- 'book',
- 'laws',
- 'one',
- ];
- const isBtn = ref(true);
- const closeSlelct = () => {
- window.addEventListener('click', (event) => {
- if (!event.target.closest('.space_search') && !isBtn.value) {
- isBtn.value = true;
- // form.keywords = '';
- }
- });
- };
- watch(isBtn, (val) => {
- if (!val) {
- closeSlelct();
- }
- });
- const form = reactive({
- parser_id: '',
- doc_id: props.item.id,
- max_token: 698,
- threshold: 0.3,
- max_cluster: 233,
- random_seed: 1500,
- chunk_token_num: 128,
- use_raptor: false,
- keywords: '',
- pages: {},
- prompt:
- '请总结以下段落。 小心数字,不要编造。 段落如下:\n' +
- ' {cluster_content}\n' +
- '以上就是你需要总结的内容。',
- });
- const formRef = ref(null);
- const rules = {
- prompt: [
- {
- required: true,
- message: '提示词不允许为空',
- },
- ],
- };
- const listData = ref([]);
- const formatter = (value) => {
- return value / 100;
- };
- function randomNumber() {
- // 生成一个介于min和max之间的随机整数(包含min和max)
- const min = 1; // 最小值
- const max = 10000; // 最大值
- form.random_seed = Math.floor(Math.random() * (max - min + 1)) + min;
- }
- const handleSubmit = async ({ values, errors }) => {
- if (!errors) {
- let data = await kbdocumentchangeparser({
- parser_id: form.parser_id,
- doc_id: form.doc_id,
- parser_config: {
- raptor: {
- use_raptor: form.use_raptor,
- prompt: form.prompt,
- max_token: form.max_token,
- threshold: form.threshold,
- max_cluster: form.max_cluster,
- random_seed: form.random_seed,
- },
- chunk_token_num: form.chunk_token_num,
- pages: [],
- },
- });
- if (data.code == 0) {
- Message.success('配置成功');
- } else {
- Message.error('配置失败');
- }
- visible.value = false;
- }
- };
- const handleClick = () => {
- visible.value = true;
- };
- const handleCancel = () => {
- visible.value = false;
- };
- const contentClick = async (item) => {
- try {
- const data = await achunkGet({
- chunk_id: item.chunk_id,
- });
- // console.log(data.data);
- Object.assign(eidtDilinfo, data.data);
- eidtDilVisible.value = true;
- } catch (error) {
- Message.error('获取失败');
- }
- };
- const handleOpened = (el) => {
- // console.log('props',props.kbtenantInfo);
- console.log('props', props.item);
- // console.log('props',props.kbdetail);
- console.log(parser_ids, 'parser_ids');
- let parser_id = props.item.parser_id;
- parser_ids.forEach((item) => {
- if (item.name == parser_id) {
- form.parser_id = item.value;
- }
- });
- // Object.assign(form,{
- // name: '',// 用户名
- // nameJoin: '',// 昵称
- // post: '',// 岗位
- // txt: '',// 备注
- // });
- // formRef.value.resetFields();
- console.log(props.item.id);
- };
- const onChangeRAPTOR = () => {};
- const indeterminate = ref(false);
- const checkedAll = ref(false);
- const data = ref([]);
- const switchType = ref(false);
- const available_int = ref('');
- const onRadioChange = () => {
- console.log(radio.value);
- };
- //批量操作
- const handleChangeAll = (value) => {
- indeterminate.value = false;
- if (value) {
- checkedAll.value = true;
- listData.value.forEach((item) => {
- data.value.push(item.chunk_id);
- });
- } else {
- checkedAll.value = false;
- data.value = [];
- }
- };
- const handleChange = (values) => {
- data.value = values;
- };
- //批量启用删除禁用
- const addBlock = (type) => {
- if (data.value.length == 0) {
- Message.error('请选择要操作的数据');
- return;
- }
- if (type == 3) {
- deleteChunk();
- } else {
- let params = {
- chunk_ids: data.value,
- available_int: type,
- doc_id: props.item.id,
- };
- chunkSwitch(params).then((res) => {
- if (res.code == 0) {
- Message.success('操作成功');
- getList();
- checkedAll.value = false;
- data.value = [];
- } else {
- Message.error('操作失败');
- }
- });
- }
- };
- const groupListContentClick = (value) => {
- keyBg.value = value;
- };
- const onChangeavailable = () => {
- getList();
- };
- const handleChangeStatus = (val) => {
- updateChunkStatus(val);
- };
- const isLoading = ref(true);
- // 自定义加载提示文本
- const tip = '加载中,请稍候...';
- //获取列表
- const getList = async () => {
- let params = {
- doc_id: props.item.id,
- keywords: form.keywords,
- page: 1,
- size: 10000,
- };
- if (available_int.value !== '') {
- params.available_int = available_int.value;
- }
- await queryChunkList(params).then((res) => {
- if (res.code == 0) {
- listData.value = res.data.chunks;
- isLoading.value = false;
- listData.value = listData.value.map((item) => {
- item.available_int = parseInt(item.available_int);
- return item;
- });
- }
- });
- };
- //更新列表
- const canplaythrough = () => {
- getList();
- };
- //启用禁用
- const updateChunkStatus = (val) => {
- let params = {
- chunk_ids: [val.chunk_id],
- available_int: val.available_int,
- doc_id: props.item.id,
- };
- chunkSwitch(params).then((res) => {
- console.log(res);
- if (res.code == 0) {
- Message.success('更新成功');
- getList();
- } else {
- Message.error('更新失败');
- }
- });
- };
- //删除
- const deleteChunk = () => {
- let params = {
- chunk_ids: data.value,
- doc_id: props.item.id,
- };
- chunkRm(params).then((res) => {
- console.log(res);
- if (res.code == 0) {
- Message.success('删除成功');
- getList();
- } else {
- Message.error('删除失败');
- }
- });
- };
- onBeforeMount(() => {
- getList();
- });
- onMounted(() => {});
- </script>
- <style scoped lang="less">
- .parser {
- width: 100%;
- ::v-deep .arco-btn-outline:hover,
- .arco-btn-outline,
- .arco-btn-outline[type='button'] {
- color: #2a2a2b;
- border: 1px solid #2a2a2b;
- }
- .button {
- //color: #2a2a2b!important;
- }
- }
- ::-webkit-scrollbar {
- display: none;
- }
- .groupMain {
- width: 100%;
- height: 500px;
- overflow: auto;
- display: flex;
- justify-content: center;
- .groupList {
- display: flex;
- padding: 24px;
- border-radius: 8px;
- //background: #eff8ff;
- border: 1px solid #f0f0f0;
- margin-bottom: 20px;
- overflow: auto;
- .groupList-content {
- width: 700px;
- //height: 100px;
- overflow: auto;
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- color: #2a2a2b;
- font-size: 14px;
- font-family: Inter;
- position: relative;
- }
- }
- }
- :deep(.emphaRed em) {
- color: red !important;
- }
- .groupActive {
- background: #eff8ff;
- }
- .groupNoActive {
- background: var(--color-bg-1);
- color: var(--color-text-1);
- }
- </style>
|