mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 文档模块
This commit is contained in:
parent
98681964d7
commit
68c6d409be
|
|
@ -67,14 +67,26 @@ const postDateset: (data: any) => Promise<Result<any>> = (data) => {
|
|||
* @param 参数 file:file,limit:number,patterns:array,with_filter:boolean
|
||||
*/
|
||||
const postSplitDocument: (data: any) => Promise<Result<any>> = (data) => {
|
||||
console.log(data)
|
||||
return post(`${prefix}/document/split`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档列表
|
||||
* @param 参数 dataset_id, name
|
||||
*/
|
||||
|
||||
const getDocument: (dataset_id: string, name?: string) => Promise<Result<any>> = (
|
||||
dataset_id,
|
||||
name
|
||||
) => {
|
||||
return get(`${prefix}/${dataset_id}/document`, name && { name })
|
||||
}
|
||||
|
||||
export default {
|
||||
getDateset,
|
||||
getAllDateset,
|
||||
delDateset,
|
||||
postDateset,
|
||||
postSplitDocument
|
||||
postSplitDocument,
|
||||
getDocument
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ import { ref, onBeforeUpdate } from 'vue'
|
|||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const cachedViews: any = ref([])
|
||||
onBeforeUpdate(() => {
|
||||
let isCached = route.meta?.cache
|
||||
let name = route.name
|
||||
const { name, meta } = route
|
||||
let isCached = meta?.cache
|
||||
if (isCached && name && !cachedViews.value.includes(name)) {
|
||||
cachedViews.value.push(name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ import SidebarItem from './SidebarItem.vue'
|
|||
const route = useRoute()
|
||||
|
||||
const subMenuList = computed(() => {
|
||||
return getChildRouteListByPathAndName(route.meta.parentPath, route.meta.parentName)
|
||||
const { meta } = route
|
||||
return getChildRouteListByPathAndName(meta.parentPath, meta.parentName)
|
||||
})
|
||||
|
||||
const activeMenu = computed(() => {
|
||||
|
|
|
|||
|
|
@ -15,15 +15,14 @@ import { useRouter, useRoute, type RouteRecordRaw } from 'vue-router'
|
|||
import { computed } from 'vue'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const props = defineProps<{
|
||||
menu: RouteRecordRaw
|
||||
}>()
|
||||
|
||||
const isActive = computed(() => {
|
||||
return (
|
||||
(route.name == props.menu.name && route.path == props.menu.path) ||
|
||||
route?.meta?.activeMenu == props.menu.path
|
||||
)
|
||||
const { name, path, meta } = route
|
||||
return (name == props.menu.name && path == props.menu.path) || meta?.activeMenu == props.menu.path
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<div class="main-layout h-full flex">
|
||||
<div class="sidebar-container">
|
||||
<Sidebar /></div>
|
||||
<Sidebar />
|
||||
</div>
|
||||
<div class="view-container">
|
||||
<AppMain />
|
||||
</div>
|
||||
|
|
@ -20,6 +21,6 @@ import { Sidebar, AppMain } from '../components'
|
|||
background-color: var(--sidebar-bg-color);
|
||||
}
|
||||
.view-container {
|
||||
width: 100%;
|
||||
width: calc(100% - var(--sidebar-width));
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -18,23 +18,23 @@ const datasetRouter = {
|
|||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/dataset/:id',
|
||||
path: '/dataset/:datasetId',
|
||||
name: 'DatasetDetail',
|
||||
meta: { title: '文档', activeMenu: '/dataset' },
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'doc',
|
||||
name: 'DatasetDoc',
|
||||
path: 'document',
|
||||
name: 'DatasetDocument',
|
||||
meta: {
|
||||
icon: 'Document',
|
||||
title: '文档',
|
||||
active: 'doc',
|
||||
parentPath: '/dataset/:id',
|
||||
active: 'document',
|
||||
parentPath: '/dataset/:datasetId',
|
||||
parentName: 'DatasetDetail'
|
||||
},
|
||||
component: () => import('@/views/dataset/DatasetDoc.vue')
|
||||
component: () => import('@/views/dataset/DatasetDocument.vue')
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
|
|
@ -43,7 +43,7 @@ const datasetRouter = {
|
|||
icon: 'Setting',
|
||||
title: '设置',
|
||||
active: 'setting',
|
||||
parentPath: '/dataset/:id',
|
||||
parentPath: '/dataset/:datasetId',
|
||||
parentName: 'DatasetDetail'
|
||||
},
|
||||
component: () => import('@/views/dataset/DatasetSetting.vue')
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ h4 {
|
|||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
.w-240 {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.mt-8 {
|
||||
margin-top: 8px;
|
||||
|
|
@ -249,3 +252,24 @@ h4 {
|
|||
background: var(--app-layout-bg-color);
|
||||
border: none;
|
||||
}
|
||||
|
||||
// 表格第一行插入自定义行
|
||||
.table-custom-append {
|
||||
.el-table__append-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border-bottom: var(--el-table-border);
|
||||
width: 100%;
|
||||
height: 49px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: 0 12px;
|
||||
&:hover {
|
||||
background: var(--el-color-primary-light-9);
|
||||
}
|
||||
}
|
||||
.el-table__body {
|
||||
margin-top: 49px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@
|
|||
|
||||
.el-button {
|
||||
padding: 5px 12px;
|
||||
&.is-text {
|
||||
padding: 4px !important;
|
||||
font-size: 16px;
|
||||
max-height: 24px;
|
||||
&:not(.is-disabled):hover {
|
||||
background: var(--app-text-color-primary-light-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-avatar {
|
||||
--el-avatar-bg-color: var(--el-color-primary);
|
||||
|
|
@ -92,15 +100,24 @@
|
|||
}
|
||||
.el-table {
|
||||
--el-table-header-bg-color: var(--app-layout-bg-color);
|
||||
}
|
||||
.el-table {
|
||||
--el-table-text-color: var(--app-text-color-primary);
|
||||
font-weight: 400;
|
||||
thead {
|
||||
color: var(--app-text-color-secondary);
|
||||
th {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
th.el-table__cell {
|
||||
border-top: var(--el-table-border);
|
||||
}
|
||||
.el-table__cell {
|
||||
padding: 12px 0;
|
||||
}
|
||||
.el-checkbox {
|
||||
height: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
// el-steps
|
||||
|
|
@ -124,7 +141,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
overflow-x: hidden;
|
||||
|
||||
.el-switch {
|
||||
height: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
const getCheckDate = (timestamp: any) => {
|
||||
if (!timestamp) return false
|
||||
const dt = new Date(timestamp)
|
||||
if (isNaN(dt.getTime())) return false
|
||||
return dt
|
||||
}
|
||||
export const datetimeFormat = (timestamp: any) => {
|
||||
const dt = getCheckDate(timestamp)
|
||||
if (!dt) return timestamp
|
||||
|
||||
const y = dt.getFullYear()
|
||||
const m = (dt.getMonth() + 1 + '').padStart(2, '0')
|
||||
const d = (dt.getDate() + '').padStart(2, '0')
|
||||
const hh = (dt.getHours() + '').padStart(2, '0')
|
||||
const mm = (dt.getMinutes() + '').padStart(2, '0')
|
||||
const ss = (dt.getSeconds() + '').padStart(2, '0')
|
||||
|
||||
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
|
||||
}
|
||||
|
||||
export const dateFormat = (timestamp: any) => {
|
||||
const dt = getCheckDate(timestamp)
|
||||
if (!dt) return timestamp
|
||||
|
||||
const y = dt.getFullYear()
|
||||
const m = (dt.getMonth() + 1 + '').padStart(2, '0')
|
||||
const d = (dt.getDate() + '').padStart(2, '0')
|
||||
|
||||
return `${y}-${m}-${d}`
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
function toThousands(num: any) {
|
||||
export function toThousands(num: any) {
|
||||
return num.toString().replace(/\d+/, function (n: any) {
|
||||
return n.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
<template>
|
||||
<LayoutContainer header="文档">
|
||||
<div class="main-calc-height">
|
||||
<div class="p-24">
|
||||
1111
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</LayoutContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<template>
|
||||
<LayoutContainer header="文档">
|
||||
<div class="main-calc-height">
|
||||
<div class="p-24" v-loading="loading">
|
||||
<div class="flex-between">
|
||||
<el-button type="primary">上传文档</el-button>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="按 文档名称 搜索"
|
||||
prefix-icon="Search"
|
||||
class="w-240"
|
||||
/>
|
||||
</div>
|
||||
<el-table :data="documentData" class="table-custom-append mt-16">
|
||||
<template #append>
|
||||
<el-button type="primary" link>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<span class="ml-4">快速创建空白文档</span>
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table-column prop="name" label="文件名称" />
|
||||
<el-table-column prop="char_length" label="字符数" align="right">
|
||||
<template #default="{ row }">
|
||||
{{ toThousands(row.char_length) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="paragraph_count" label="分段" align="right" />
|
||||
<el-table-column prop="status" label="文件状态">
|
||||
<!-- <el-switch v-model="value1" /> -->
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="启动状态">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.is_active" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" label="创建时间" width="170">
|
||||
<template #default="{ row }">
|
||||
{{ datetimeFormat(row.create_time) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="update_time" label="更新时间" width="170">
|
||||
<template #default="{ row }">
|
||||
{{ datetimeFormat(row.update_time) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="操作" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
<el-tooltip effect="dark" content="刷新" placement="top">
|
||||
<el-button type="primary" text>
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
</el-button> </el-tooltip
|
||||
></span>
|
||||
<span class="ml-4">
|
||||
<el-tooltip effect="dark" content="删除" placement="top">
|
||||
<el-button type="primary" text>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import datasetApi from '@/api/dataset'
|
||||
import { toThousands } from '@/utils/utils'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { params } = route
|
||||
const { datasetId } = params
|
||||
|
||||
const loading = ref(false)
|
||||
const filterText = ref('')
|
||||
const documentData = ref<any[]>([])
|
||||
|
||||
function getList() {
|
||||
loading.value = true
|
||||
datasetApi
|
||||
.getDocument(datasetId as string, filterText.value)
|
||||
.then((res) => {
|
||||
documentData.value = res.data
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -2,12 +2,7 @@
|
|||
<div class="dataset-list-container p-24">
|
||||
<div class="flex-between">
|
||||
<h3>数据集</h3>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="搜索内容"
|
||||
prefix-icon="Search"
|
||||
style="width: 300px"
|
||||
/>
|
||||
<el-input v-model="filterText" placeholder="搜索内容" prefix-icon="Search" class="w-240" />
|
||||
</div>
|
||||
<div v-loading.fullscreen.lock="loading">
|
||||
<el-row
|
||||
|
|
@ -32,7 +27,7 @@
|
|||
:title="item.name"
|
||||
:description="item.desc"
|
||||
class="cursor"
|
||||
@click="router.push({ path: `/dataset/${item.id}/doc` })"
|
||||
@click="router.push({ path: `/dataset/${item.id}/document` })"
|
||||
>
|
||||
<template #mouseEnter>
|
||||
<el-tooltip effect="dark" content="删除" placement="top">
|
||||
|
|
@ -128,7 +123,6 @@ onMounted(() => {
|
|||
position: absolute;
|
||||
right: 12px;
|
||||
top: 18px;
|
||||
padding: 6px;
|
||||
height: auto;
|
||||
}
|
||||
.footer-content {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
<template>
|
||||
<div class="upload-document">
|
||||
<!-- 基本信息 -->
|
||||
<BaseForm ref="BaseFormRef" />
|
||||
<!-- 上传文档 -->
|
||||
<UploadComponent ref="UploadComponentRef" />
|
||||
</div>
|
||||
|
||||
<div class="upload-document">
|
||||
<!-- 基本信息 -->
|
||||
<BaseForm ref="BaseFormRef" />
|
||||
<!-- 上传文档 -->
|
||||
<UploadComponent ref="UploadComponentRef" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
|
|
@ -39,6 +38,5 @@ defineExpose({
|
|||
.upload-document {
|
||||
width: 70%;
|
||||
margin: 0 auto;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ import type { FormInstance, FormRules } from 'element-plus'
|
|||
import UserApi from '@/api/user'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { params } = route
|
||||
const { code, email } = params
|
||||
const resetPasswordForm = ref<ResetPasswordRequest>({
|
||||
password: '',
|
||||
re_password: '',
|
||||
|
|
@ -71,8 +73,6 @@ const resetPasswordForm = ref<ResetPasswordRequest>({
|
|||
})
|
||||
|
||||
onMounted(() => {
|
||||
const code = route.params.code
|
||||
const email = route.params.email
|
||||
if (code && email) {
|
||||
resetPasswordForm.value.code = code as string
|
||||
resetPasswordForm.value.email = email as string
|
||||
|
|
@ -133,4 +133,4 @@ const resetPassword = () => {
|
|||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import '../index.scss';
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ onMounted(() => {
|
|||
|
||||
.permission-setting {
|
||||
box-sizing: border-box;
|
||||
width: calc(100% - var(--team-manage-left-width) - 5px);
|
||||
width: calc(100% - var(--team-manage-left-width));
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue