feat: chat log

This commit is contained in:
wangdan-fit2cloud 2025-06-11 14:45:12 +08:00
parent e9527bdd2b
commit 238821e96b
9 changed files with 237 additions and 144 deletions

View File

@ -0,0 +1,95 @@
<template>
<el-card
shadow="hover"
class="card-checkbox cursor"
:class="modelValue.includes(toModelValue) ? 'active' : ''"
@click="checked"
>
<div class="flex-between">
<div class="flex align-center">
<slot name="icon">
<KnowledgeIcon :type="data.type" />
</slot>
<slot></slot>
</div>
<el-checkbox v-bind:modelValue="modelValue.includes(toModelValue)" @change="checkboxChange">
</el-checkbox>
</div>
</el-card>
</template>
<script setup lang="ts">
import KnowledgeIcon from '@/views/knowledge/component/KnowledgeIcon.vue'
import { computed } from 'vue'
defineOptions({ name: 'CardCheckbox' })
const props = defineProps<{
data: any
modelValue: Array<any>
valueField?: string
}>()
const toModelValue = computed(() => (props.valueField ? props.data[props.valueField] : props.data))
// const isChecked = computed({
// get: () => props.modelValue.includes(toModelValue.value)),
// set: (val) => val
// })
const emit = defineEmits(['update:modelValue', 'change'])
const checked = () => {
const value = props.modelValue ? props.modelValue : []
if (props.modelValue.includes(toModelValue.value)) {
emit(
'update:modelValue',
value.filter((item) => item !== toModelValue.value),
)
} else {
emit('update:modelValue', [...value, toModelValue.value])
}
checkboxChange()
}
function checkboxChange() {
emit('change')
}
</script>
<style lang="scss">
.card-checkbox {
&.active {
border: 1px solid var(--el-color-primary);
}
input.checkbox[type='checkbox'] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
height: 14px;
width: 14px;
position: relative;
&::after {
position: absolute;
top: 0;
background-color: white;
color: #000;
height: 13px;
width: 13px;
visibility: visible;
text-align: center;
box-sizing: border-box;
border: var(--el-border);
border-radius: var(--el-border-radius-small);
box-sizing: content-box;
content: '';
}
&:checked::after {
content: '✓';
color: #ffffff;
border-color: var(--el-color-primary);
background: var(--el-color-primary);
}
}
}
</style>

View File

@ -20,6 +20,7 @@ import MdEditor from './markdown/MdEditor.vue'
import MdPreview from './markdown/MdPreview.vue' import MdPreview from './markdown/MdPreview.vue'
import MdEditorMagnify from './markdown/MdEditorMagnify.vue' import MdEditorMagnify from './markdown/MdEditorMagnify.vue'
import TagEllipsis from './tag-ellipsis/index.vue' import TagEllipsis from './tag-ellipsis/index.vue'
import CardCheckbox from './card-checkbox/index.vue'
export default { export default {
install(app: App) { install(app: App) {
app.component('LogoFull', LogoFull) app.component('LogoFull', LogoFull)
@ -43,5 +44,6 @@ export default {
app.component('MdEditor', MdEditor) app.component('MdEditor', MdEditor)
app.component('MdEditorMagnify', MdEditorMagnify) app.component('MdEditorMagnify', MdEditorMagnify)
app.component('TagEllipsis', TagEllipsis) app.component('TagEllipsis', TagEllipsis)
app.component('CardCheckbox', CardCheckbox)
}, },
} }

View File

@ -64,7 +64,7 @@ const ApplicationDetailRouter = {
icon: 'app-document', icon: 'app-document',
iconActive: 'app-document-active', iconActive: 'app-document-active',
title: 'views.chatLog.title', title: 'views.chatLog.title',
active: 'log', active: 'chat-log',
parentPath: '/application/:id/:type', parentPath: '/application/:id/:type',
parentName: 'ApplicationDetail' parentName: 'ApplicationDetail'
}, },

View File

@ -35,7 +35,7 @@ const useApplicationStore = defineStore('application', {
}) })
}, },
async asyncGetApplicationDataset(id: string, loading?: Ref<boolean>) { async asyncGetApplicationKnowledge(id: string, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
applicationApi applicationApi
.getApplicationDataset(id, loading) .getApplicationDataset(id, loading)

View File

@ -424,8 +424,8 @@ function mapToUrlParams(map: any[]) {
} }
onMounted(() => { onMounted(() => {
getDetail() // getDetail()
getAccessToken() // getAccessToken()
// changeDayHandle(history_day.value) // changeDayHandle(history_day.value)
}) })
</script> </script>

View File

@ -89,7 +89,15 @@
</el-dropdown> </el-dropdown>
</div> </div>
</template> </template>
<div> <div v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading">
<InfiniteScroll
:size="applicationList.length"
:total="paginationConfig.total"
:page_size="paginationConfig.page_size"
v-model:current_page="paginationConfig.current_page"
@load="getList"
:loading="loading"
>
<el-row v-if="applicationList.length > 0" :gutter="15"> <el-row v-if="applicationList.length > 0" :gutter="15">
<template v-for="(item, index) in applicationList" :key="index"> <template v-for="(item, index) in applicationList" :key="index">
<el-col <el-col
@ -201,6 +209,7 @@
</template> </template>
</el-row> </el-row>
<el-empty :description="$t('common.noData')" v-else /> <el-empty :description="$t('common.noData')" v-else />
</InfiniteScroll>
</div> </div>
</ContentContainer> </ContentContainer>
<CreateApplicationDialog ref="CreateApplicationDialogRef" /> <CreateApplicationDialog ref="CreateApplicationDialogRef" />

View File

@ -1,6 +1,8 @@
<template> <template>
<LayoutContainer :header="$t('views.chatLog.title')"> <div class="p-16-24">
<div class="p-24"> <h2 class="mb-16">{{ $t('views.chatLog.title') }}</h2>
<el-card style="--el-card-padding: 24px">
<div class="mb-16"> <div class="mb-16">
<el-select <el-select
v-model="history_day" v-model="history_day"
@ -24,6 +26,8 @@
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
@change="changeDayRangeHandle" @change="changeDayRangeHandle"
style="width: 240px;"
class="mr-12"
/> />
<el-input <el-input
v-model="search" v-model="search"
@ -153,7 +157,7 @@
</template> </template>
</el-table-column> </el-table-column>
</app-table> </app-table>
</div> </el-card>
<ChatRecordDrawer <ChatRecordDrawer
:next="nextChatRecord" :next="nextChatRecord"
:pre="preChatRecord" :pre="preChatRecord"
@ -223,31 +227,7 @@
:value="item.id" :value="item.id"
> >
<span class="flex align-center"> <span class="flex align-center">
<AppAvatar <KnowledgeIcon :type="item.type" v-if="!item.knowledge_id" />
v-if="!item.knowledge_id && item.type === '1'"
class="mr-12 avatar-purple"
shape="square"
:size="24"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar
v-else-if="!item.knowledge_id && item.type === '2'"
class="mr-12 avatar-purple"
shape="square"
:size="24"
style="background: none"
>
<img src="@/assets/logo_lark.svg" style="width: 100%" alt="" />
</AppAvatar>
<AppAvatar
v-else-if="!item.knowledge_id && item.type === '0'"
class="mr-12 avatar-blue"
shape="square"
:size="24"
>
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
{{ item.name }} {{ item.name }}
</span> </span>
</el-option> </el-option>
@ -283,12 +263,13 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</LayoutContainer> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, type Ref, onMounted, reactive, computed } from 'vue' import { ref, type Ref, onMounted, reactive, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import KnowledgeIcon from '@/views/knowledge/component/KnowledgeIcon.vue'
import ChatRecordDrawer from './component/ChatRecordDrawer.vue' import ChatRecordDrawer from './component/ChatRecordDrawer.vue'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import chatLogApi from '@/api/application/chat-log' import chatLogApi from '@/api/application/chat-log'
@ -542,7 +523,13 @@ const exportLog = () => {
obj = { ...obj, abstract: search.value } obj = { ...obj, abstract: search.value }
} }
chatLogApi.postExportChatLog(detail.value.id, detail.value.name, obj, { select_ids: arr }, loading) chatLogApi.postExportChatLog(
detail.value.id,
detail.value.name,
obj,
{ select_ids: arr },
loading,
)
} }
} }

View File

@ -134,7 +134,7 @@ import { set } from 'lodash'
import { app } from '@/main' import { app } from '@/main'
import NodeContainer from '@/workflow/common/NodeContainer.vue' import NodeContainer from '@/workflow/common/NodeContainer.vue'
import NodeCascader from '@/workflow/common/NodeCascader.vue' import NodeCascader from '@/workflow/common/NodeCascader.vue'
import AddDatasetDialog from '@/views/application/component/AddDatasetDialog.vue' import AddDatasetDialog from '@/views/application/component/AddKnowledgeDialog.vue'
import ParamSettingDialog from '@/views/application/component/ParamSettingDialog.vue' import ParamSettingDialog from '@/views/application/component/ParamSettingDialog.vue'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { ref, computed, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'