Merge branch 'main' of github.com:maxkb-dev/maxkb
This commit is contained in:
commit
40dfe39294
@ -98,9 +98,28 @@ const putChatRecordLog: (
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标注段落列表信息
|
||||
* @param 参数
|
||||
* application_id, chart_id, chart_record_id
|
||||
*/
|
||||
const getMarkRecord: (
|
||||
applicaiton_id: String,
|
||||
chart_id: String,
|
||||
chart_record_id: String,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (applicaiton_id, chart_id, chart_record_id, loading) => {
|
||||
return get(
|
||||
`${prefix}/${applicaiton_id}/chat/${chart_id}/chat_record/${chart_record_id}/improve`,
|
||||
undefined,
|
||||
loading
|
||||
)
|
||||
}
|
||||
|
||||
export default {
|
||||
getChatLog,
|
||||
delChatLog,
|
||||
getChatRecordLog,
|
||||
putChatRecordLog
|
||||
putChatRecordLog,
|
||||
getMarkRecord
|
||||
}
|
||||
|
||||
@ -67,9 +67,10 @@ const delParagraph: (
|
||||
const postParagraph: (
|
||||
dataset_id: string,
|
||||
document_id: string,
|
||||
data: any
|
||||
) => Promise<Result<any>> = (dataset_id, document_id, data: any) => {
|
||||
return post(`${prefix}/${dataset_id}/document/${document_id}/paragraph`, data)
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (dataset_id, document_id, data, loading) => {
|
||||
return post(`${prefix}/${dataset_id}/document/${document_id}/paragraph`, data, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,9 +93,15 @@ const putParagraph: (
|
||||
dataset_id: string,
|
||||
document_id: string,
|
||||
paragraph_id: string,
|
||||
data: any
|
||||
) => Promise<Result<any>> = (dataset_id, document_id, paragraph_id, data: any) => {
|
||||
return put(`${prefix}/${dataset_id}/document/${document_id}/paragraph/${paragraph_id}`, data)
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (dataset_id, document_id, paragraph_id, data, loading) => {
|
||||
return put(
|
||||
`${prefix}/${dataset_id}/document/${document_id}/paragraph/${paragraph_id}`,
|
||||
data,
|
||||
undefined,
|
||||
loading
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -11,34 +11,41 @@
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" content="修改内容" placement="top">
|
||||
<el-tooltip
|
||||
v-if="data.improve_paragraph_id_list.length === 0"
|
||||
effect="dark"
|
||||
content="修改内容"
|
||||
placement="top"
|
||||
>
|
||||
<el-button text @click="editContent(data)">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" content="修改历史" placement="top">
|
||||
<el-button text @click="editContent(data)">
|
||||
<el-icon><Document /></el-icon>
|
||||
|
||||
<el-tooltip v-else effect="dark" content="修改标注" placement="top">
|
||||
<el-button text @click="editMark(data)">
|
||||
<AppIcon iconName="app-document-active" class="primary"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-divider direction="vertical" v-if="buttonData?.vote_status !== '-1'" />
|
||||
<el-button text disabled v-if="buttonData?.vote_status === '0'">
|
||||
<AppIcon iconName="app-like-color" class="primary"></AppIcon>
|
||||
<AppIcon iconName="app-like-color"></AppIcon>
|
||||
</el-button>
|
||||
|
||||
<el-button text disabled v-if="buttonData?.vote_status === '1'">
|
||||
<AppIcon iconName="app-oppose-color"></AppIcon>
|
||||
</el-button>
|
||||
<EditContentDialog ref="EditContentDialogRef" />
|
||||
<EditMarkDialog ref="EditMarkDialogRef" @refresh="refresh" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch, onMounted } from 'vue'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import EditContentDialog from '@/views/log/component/EditContentDialog.vue'
|
||||
import EditMarkDialog from '@/views/log/component/EditMarkDialog.vue'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
|
||||
const props = defineProps({
|
||||
@ -56,6 +63,7 @@ const props = defineProps({
|
||||
const emit = defineEmits(['update:data'])
|
||||
|
||||
const EditContentDialogRef = ref()
|
||||
const EditMarkDialogRef = ref()
|
||||
|
||||
const buttonData = ref(props.data)
|
||||
const loading = ref(false)
|
||||
@ -64,8 +72,13 @@ function editContent(data: any) {
|
||||
EditContentDialogRef.value.open(data)
|
||||
}
|
||||
|
||||
// function updateContent(data: any) {
|
||||
// emit('update:data', data)
|
||||
// }
|
||||
function editMark(data: any) {
|
||||
EditMarkDialogRef.value.open(data)
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
buttonData.value.improve_paragraph_id_list = []
|
||||
emit('update:data', buttonData.value)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="ai-chat">
|
||||
<div class="ai-chat" :class="log ? 'chart-log' : ''">
|
||||
<el-scrollbar ref="scrollDiv">
|
||||
<div ref="dialogScrollbar" class="ai-chat__content p-24">
|
||||
<div class="item-content mb-16">
|
||||
@ -324,6 +324,11 @@ onUpdated(() => {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
color: var(--app-text-color);
|
||||
&.chart-log {
|
||||
.ai-chat__content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
&__content {
|
||||
padding-top: 0;
|
||||
padding-bottom: 96px;
|
||||
|
||||
@ -245,7 +245,7 @@ export const iconMap: any = {
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M12.5 1.2666C12.568 1.28633 12.6306 1.32327 12.6812 1.37472L16.5472 5.30797C16.5788 5.34017 16.6047 5.37698 16.6242 5.4168H13.4459C12.9235 5.4168 12.5 4.99328 12.5 4.47085V1.2666Z',
|
||||
fill: 'currentColor'
|
||||
fill: '#2B5FD9'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M6.71305 7.72705C6.48293 7.72705 6.29639 7.9136 6.29639 8.14372V8.82554C6.29639 9.05565 6.48294 9.2422 6.71305 9.2422H13.2871C13.5172 9.2422 13.7038 9.05565 13.7038 8.82554V8.14372C13.7038 7.9136 13.5172 7.72705 13.2871 7.72705H6.71305Z',
|
||||
@ -427,11 +427,11 @@ export const iconMap: any = {
|
||||
[
|
||||
h('path', {
|
||||
d: 'M2.00497 14.6608H2.00518C2.00511 14.6609 2.00504 14.6609 2.00497 14.6608H0.666612C0.666097 14.6874 0.666707 5.33317 0.666612 5.29087H2.00518C2.00006 5.33305 1.98026 14.6344 2.00497 14.6608Z',
|
||||
fill: 'currentColor'
|
||||
fill: '#FFC60A'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M12.5717 5.28984H9.70096C10.1486 4.45673 10.3724 3.78809 10.3724 3.28394C10.3724 1.94718 9.40089 1.14037 8.5893 0.770777C8.04824 0.52438 7.5406 0.753754 7.35254 1.05296L4.5741 5.00545C4.44877 5.18374 4.24449 5.28984 4.02656 5.28984H3.33882C3.154 5.28984 3.00418 5.43966 3.00418 5.62448V14.3319C3.00418 14.5167 3.154 14.6665 3.33882 14.6665H11.1995C11.8409 14.6665 12.4029 14.2423 12.5717 13.6308L14.5687 8.37353C15.0274 7.05264 14.5687 5.28984 12.5717 5.28984Z',
|
||||
fill: 'currentColor'
|
||||
fill: '#FFC60A'
|
||||
})
|
||||
]
|
||||
)
|
||||
|
||||
@ -1,14 +1,40 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import paragraphApi from '@/api/paragraph'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
const useParagraphStore = defineStore({
|
||||
id: 'paragraph',
|
||||
state: () => ({}),
|
||||
actions: {
|
||||
async asyncPutParagraph(datasetId: string, documentId: string, paragraphId: string, data: any) {
|
||||
async asyncPutParagraph(
|
||||
datasetId: string,
|
||||
documentId: string,
|
||||
paragraphId: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
paragraphApi
|
||||
.putParagraph(datasetId, documentId, paragraphId, data)
|
||||
.putParagraph(datasetId, documentId, paragraphId, data, loading)
|
||||
.then((data) => {
|
||||
resolve(data)
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
async asyncDelParagraph(
|
||||
datasetId: string,
|
||||
documentId: string,
|
||||
paragraphId: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
paragraphApi
|
||||
.delParagraph(datasetId, documentId, paragraphId, loading)
|
||||
.then((data) => {
|
||||
resolve(data)
|
||||
})
|
||||
|
||||
@ -254,6 +254,10 @@ h4 {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pre-line {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
/*
|
||||
内容部分 自适应高度
|
||||
*/
|
||||
|
||||
@ -127,7 +127,7 @@ const paginationConfig = reactive({
|
||||
|
||||
watch(documentData, (list) => {
|
||||
let interval
|
||||
if (list.every((item) => item.status === '0')) {
|
||||
if (list.length > 0 && list.every((item) => item.status === '0')) {
|
||||
interval = setInterval(() => {
|
||||
getList(true)
|
||||
}, 6000)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer v-model="visible" size="50%" @close="closeHandel" class="chat-record-drawer">
|
||||
<el-drawer v-model="visible" size="600" @close="closeHandel" class="chat-record-drawer">
|
||||
<template #header>
|
||||
<h4>{{ application?.name }}</h4>
|
||||
</template>
|
||||
@ -72,7 +72,7 @@ const recordList = ref<chatType[]>([])
|
||||
|
||||
const paginationConfig = reactive({
|
||||
current_page: 1,
|
||||
page_size: 10,
|
||||
page_size: 20,
|
||||
total: 0
|
||||
})
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="保存至文档" prop="document">
|
||||
<el-cascader v-model="form.document" :props="LoadDocument" placeholder="请选择文档">
|
||||
<el-cascader v-model="form.document" :props="LoadDocument" placeholder="请选择文档" class="w-full">
|
||||
<template #default="{ node, data }">
|
||||
<span class="flex align-center">
|
||||
<AppAvatar v-if="!node.isLeaf" class="mr-12" shape="square" :size="24">
|
||||
|
||||
135
ui/src/views/log/component/EditMarkDialog.vue
Normal file
135
ui/src/views/log/component/EditMarkDialog.vue
Normal file
@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<el-dialog title="修改标注" v-model="dialogVisible" width="600" class="edit-mark-dialog">
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div class="flex-between">
|
||||
<h4 :id="titleId" :class="titleClass">修改标注</h4>
|
||||
<div class="text-right">
|
||||
<el-button text @click="isEdit = true" v-if="!isEdit">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
</el-button>
|
||||
<el-button text style="margin-left: 4px" @click="deleteParagraph">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-scrollbar>
|
||||
<div style="min-height: 250px; max-height: 350px" v-loading="loading">
|
||||
<el-form
|
||||
v-if="isEdit"
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
:rules="rules"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item prop="content">
|
||||
<el-input
|
||||
v-model="form.content"
|
||||
placeholder="请输入分段内容"
|
||||
maxlength="1024"
|
||||
show-word-limit
|
||||
:rows="15"
|
||||
type="textarea"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span v-else class="pre-line">{{ form?.content }}</span>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer" v-if="isEdit">
|
||||
<el-button @click.prevent="isEdit = false"> 取消 </el-button>
|
||||
<el-button type="primary" @click="submit(formRef)" :loading="loading"> 保存 </el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import logApi from '@/api/log'
|
||||
import useStore from '@/stores'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
const isEdit = ref(false)
|
||||
|
||||
const route = useRoute()
|
||||
const {
|
||||
params: { id }
|
||||
} = route as any
|
||||
|
||||
const { paragraph } = useStore()
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
const loading = ref(false)
|
||||
|
||||
const form = ref<any>({})
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
form.value = {}
|
||||
}
|
||||
})
|
||||
|
||||
function deleteParagraph() {
|
||||
paragraph
|
||||
.asyncDelParagraph(form.value.dataset, form.value.document, form.value.id, loading)
|
||||
.then(() => {
|
||||
emit('refresh')
|
||||
MsgSuccess('删除成功')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function getMark(data: any) {
|
||||
logApi.getMarkRecord(id as string, data.chat, data.id, loading).then((res: any) => {
|
||||
if (res.data.length > 0) {
|
||||
form.value = res.data[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const open = (data: any) => {
|
||||
getMark(data)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const submit = async (formEl: FormInstance) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
paragraph
|
||||
.asyncPutParagraph(
|
||||
form.value.dataset,
|
||||
form.value.document,
|
||||
form.value.id,
|
||||
{
|
||||
content: form.value.content
|
||||
},
|
||||
loading
|
||||
)
|
||||
.then((res) => {
|
||||
dialogVisible.value = false
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss" scope></style>
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
|
||||
<h4 class="mb-24">忘记密码</h4>
|
||||
<el-form
|
||||
class="register-form"
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
<template>
|
||||
<login-layout v-loading="loading">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
|
||||
<h2 class="mb-24">普通登录</h2>
|
||||
<el-form class="login-form" :rules="rules" :model="loginForm" ref="loginFormRef">
|
||||
<el-form
|
||||
class="login-form"
|
||||
:rules="rules"
|
||||
:model="loginForm"
|
||||
ref="loginFormRef"
|
||||
@keyup.enter="login"
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
size="large"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
|
||||
<h4 class="mb-24">用户注册</h4>
|
||||
<el-form class="register-form" :model="registerForm" :rules="rules" ref="registerFormRef">
|
||||
<el-form-item prop="username">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
|
||||
<h4 class="mb-24">修改密码</h4>
|
||||
<el-form
|
||||
class="reset-password-form"
|
||||
|
||||
@ -90,18 +90,13 @@ const open = (data: any) => {
|
||||
}
|
||||
const submitHandle = async () => {
|
||||
if (await paragraphFormRef.value?.validate()) {
|
||||
loading.value = true
|
||||
if (problemId.value) {
|
||||
paragraph
|
||||
.asyncPutParagraph(id, documentId, problemId.value, paragraphFormRef.value?.form)
|
||||
.asyncPutParagraph(id, documentId, problemId.value, paragraphFormRef.value?.form, loading)
|
||||
.then((res: any) => {
|
||||
emit('refresh', res.data)
|
||||
loading.value = false
|
||||
isEdit.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
} else {
|
||||
const obj =
|
||||
ProblemRef.value.problemList.length > 0
|
||||
@ -110,16 +105,10 @@ const submitHandle = async () => {
|
||||
...paragraphFormRef.value?.form
|
||||
}
|
||||
: paragraphFormRef.value?.form
|
||||
paragraphApi
|
||||
.postParagraph(id, documentId, obj)
|
||||
.then((res) => {
|
||||
emit('refresh')
|
||||
loading.value = false
|
||||
dialogVisible.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
paragraphApi.postParagraph(id, documentId, obj, loading).then((res) => {
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,14 +127,7 @@ function changeState(bool: Boolean, row: any) {
|
||||
is_active: bool
|
||||
}
|
||||
loading.value = true
|
||||
paragraph
|
||||
.asyncPutParagraph(id, documentId, row.id, obj)
|
||||
.then((res) => {
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
paragraph.asyncPutParagraph(id, documentId, row.id, obj, loading).then((res) => {})
|
||||
}
|
||||
|
||||
function deleteParagraph(row: any) {
|
||||
@ -143,7 +136,7 @@ function deleteParagraph(row: any) {
|
||||
confirmButtonClass: 'danger'
|
||||
})
|
||||
.then(() => {
|
||||
paragraphApi.delParagraph(id, documentId, row.id, loading).then(() => {
|
||||
paragraph.asyncDelParagraph(id, documentId, row.id, loading).then(() => {
|
||||
const index = paragraphDetail.value.findIndex((v) => v.id === row.id)
|
||||
paragraphDetail.value.splice(index, 1)
|
||||
MsgSuccess('删除成功')
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
<div class="p-24 pb-0">
|
||||
<h4>{{ active_provider?.name }}</h4>
|
||||
<div class="flex-between mt-16 mb-16">
|
||||
<el-button type="primary" @click="openCreateModel(active_provider)">创建模型</el-button>
|
||||
<el-button type="primary" @click="openCreateModel(active_provider)">添加模型</el-button>
|
||||
<el-input
|
||||
v-model="model_search_form.name"
|
||||
@change="list_model"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user