Merge branch 'main' of github.com:maxkb-dev/maxkb

This commit is contained in:
shaohuzhang1 2023-12-15 14:22:31 +08:00
commit 40dfe39294
18 changed files with 255 additions and 58 deletions

View File

@ -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
}

View File

@ -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
)
}
/**

View File

@ -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>

View File

@ -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;

View File

@ -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'
})
]
)

View File

@ -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)
})

View File

@ -254,6 +254,10 @@ h4 {
word-break: break-all;
}
.pre-line {
white-space: pre-line;
}
/*
内容部分 自适应高度
*/

View File

@ -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)

View File

@ -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
})

View File

@ -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">

View 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>

View File

@ -1,6 +1,6 @@
<template>
<login-layout>
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
<h4 class="mb-24">忘记密码</h4>
<el-form
class="register-form"

View File

@ -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"

View File

@ -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">

View File

@ -1,6 +1,6 @@
<template>
<login-layout>
<LoginContainer subTitle="欢迎使用 MaxKB 管理平台">
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
<h4 class="mb-24">修改密码</h4>
<el-form
class="reset-password-form"

View File

@ -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
})
}
}
}

View File

@ -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('删除成功')

View File

@ -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"