feat: 应用

This commit is contained in:
wangdan-fit2cloud 2023-11-24 19:02:52 +08:00
parent 11f29317c8
commit 5fb86a8f15
26 changed files with 497 additions and 95 deletions

View File

@ -1,8 +1,17 @@
import { Result } from '@/request/Result' import { Result } from '@/request/Result'
import { get, post, del, put } from '@/request/index' import { get, post, del, put } from '@/request/index'
import type { pageRequest } from '@/api/type/common' import type { pageRequest } from '@/api/type/common'
import type { ApplicationFormType } from '@/api/type/application'
const prefix = '/application' const prefix = '/application'
/**
*
* @param
*/
const getAllAppilcation: () => Promise<Result<any[]>> = () => {
return get(`${prefix}`)
}
/** /**
* *
* @param { * @param {
@ -17,6 +26,62 @@ const getApplication: (param: pageRequest) => Promise<Result<any>> = (param) =>
param.name && { name: param.name } param.name && { name: param.name }
) )
} }
export default {
getApplication /**
*
* @param
* {
"name": "string",
"desc": "string",
"model_id": "string",
"multiple_rounds_dialogue": true,
"prologue": "string",
"example": [
"string"
],
"dataset_id_list": [
"string"
]
}
*/
const postApplication: (data: ApplicationFormType) => Promise<Result<any>> = (data) => {
return post(`${prefix}`, data)
}
// 临时对话open
/**
*
* @param
* {
"model_id": "string",
"multiple_rounds_dialogue": true,
"dataset_id_list": [
"string"
]
}
*/
const postChatOpen: (data: ApplicationFormType) => Promise<Result<any>> = (data) => {
return post(`${prefix}/chat/open`, data)
}
// 临时对话open
/**
*
* @param
* chat_id: string
* {
"message": "string",
}
*/
const postChatMessage: (chat_id: string, message: string) => Promise<Result<any>> = (
chat_id,
message
) => {
return post(`${prefix}/chat_message/${chat_id}`, { message })
}
export default {
getAllAppilcation,
getApplication,
postApplication,
postChatOpen,
postChatMessage
} }

View File

@ -21,10 +21,10 @@ const getDateset: (param: pageRequest) => Promise<Result<any>> = (param) => {
/** /**
* *
* @param name * @param
*/ */
const getAllDateset: (param?: string) => Promise<Result<any[]>> = (param) => { const getAllDateset: () => Promise<Result<any[]>> = () => {
return get(`${prefix}`, param && { name: param }) return get(`${prefix}`)
} }
/** /**

View File

@ -1,10 +1,10 @@
interface ApplicationFormType { interface ApplicationFormType {
name: string name?: string
desc: string desc?: string
model_id: string model_id: string
multiple_rounds_dialogue: boolean multiple_rounds_dialogue: boolean
prologue: string prologue?: string
example: string[] example?: string[]
dataset_id_list: string[] dataset_id_list: string[]
} }
export type { ApplicationFormType } export type { ApplicationFormType }

View File

@ -0,0 +1,4 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.1716 0.688342C19.6753 0.532733 20.0458 1.16193 19.6652 1.52691L11.2658 9.58356C10.0058 10.7921 8.32754 11.4668 6.5817 11.4668C4.68044 11.4668 2.8669 10.667 1.58487 9.26303L0.45879 8.02985C0.332247 7.90313 0.241372 7.74527 0.195339 7.5722C0.149305 7.39913 0.149742 7.21698 0.196605 7.04413C0.243468 6.87129 0.335099 6.71386 0.462248 6.58775C0.589398 6.46164 0.747567 6.3713 0.92079 6.32585L19.1716 0.688342Z" fill="#BBBFC4"/>
<path d="M11 15.1851C11 13.2766 11.7377 11.4419 13.0588 10.0646L20.4664 2.34177C20.8268 1.96601 21.4499 2.32266 21.3084 2.82374L16.143 21.1182C16.0971 21.291 16.0064 21.4487 15.8801 21.5754C15.7538 21.7021 15.5964 21.7932 15.4237 21.8397C15.251 21.8862 15.0691 21.8864 14.8964 21.8402C14.7236 21.794 14.566 21.7031 14.4395 21.5767L13.4439 20.6791C11.8881 19.2764 11 17.2799 11 15.1851Z" fill="#BBBFC4"/>
</svg>

After

Width:  |  Height:  |  Size: 945 B

View File

@ -0,0 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.1716 1.68834C20.6753 1.53273 21.0458 2.16193 20.6652 2.52691L12.2658 10.5836C11.0058 11.7921 9.32754 12.4668 7.5817 12.4668C5.68044 12.4668 3.8669 11.667 2.58487 10.263L1.45879 9.02985C1.33225 8.90313 1.24137 8.74527 1.19534 8.5722C1.14931 8.39913 1.14974 8.21698 1.19661 8.04413C1.24347 7.87129 1.3351 7.71386 1.46225 7.58775C1.5894 7.46164 1.74757 7.3713 1.92079 7.32585L20.1716 1.68834Z" fill="url(#paint0_linear_987_5140)"/>
<path d="M12 16.1851C12 14.2766 12.7377 12.4419 14.0588 11.0646L21.4664 3.34177C21.8268 2.96601 22.4499 3.32266 22.3084 3.82374L17.143 22.1182C17.0971 22.291 17.0064 22.4487 16.8801 22.5754C16.7538 22.7021 16.5964 22.7932 16.4237 22.8397C16.251 22.8862 16.0691 22.8864 15.8964 22.8402C15.7236 22.794 15.566 22.7031 15.4395 22.5767L14.4439 21.6791C12.8881 20.2764 12 18.2799 12 16.1851Z" fill="url(#paint1_linear_987_5140)"/>
<defs>
<linearGradient id="paint0_linear_987_5140" x1="22.3289" y1="13.1532" x2="1.16113" y2="13.1532" gradientUnits="userSpaceOnUse">
<stop stop-color="#9258F7"/>
<stop offset="1" stop-color="#3370FF"/>
</linearGradient>
<linearGradient id="paint1_linear_987_5140" x1="22.3289" y1="13.1532" x2="1.16113" y2="13.1532" gradientUnits="userSpaceOnUse">
<stop stop-color="#9258F7"/>
<stop offset="1" stop-color="#3370FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -23,7 +23,11 @@
<h4 class="mb-8">您可以尝试输入以下问题</h4> <h4 class="mb-8">您可以尝试输入以下问题</h4>
<el-space wrap> <el-space wrap>
<template v-for="(item, index) in data?.example" :key="index"> <template v-for="(item, index) in data?.example" :key="index">
<div class="problem-button cursor ellipsis-2" v-if="item"> <div
@click="quickProblemHandel(item)"
class="problem-button cursor ellipsis-2"
v-if="item"
>
<el-icon><EditPen /></el-icon> <el-icon><EditPen /></el-icon>
{{ item }} {{ item }}
</div> </div>
@ -64,9 +68,24 @@
placeholder="请输入" placeholder="请输入"
:autosize="{ minRows: 1, maxRows: 8 }" :autosize="{ minRows: 1, maxRows: 8 }"
/> />
<div class="operate"> <div class="operate" v-loading="loading">
<el-button text class="sent-button" disabled> <el-button
<AppIcon iconName="app-send"></AppIcon> text
class="sent-button"
:disabled="!(inputValue && data?.name && data?.model_id)"
@click="chatHandle"
>
<img
v-show="!(inputValue && data?.name && data?.model_id)"
src="@/assets/icon_send.svg"
alt=""
/>
<img
v-show="inputValue && data?.name && data?.model_id"
src="@/assets/icon_send_colorful.svg"
alt=""
/>
<!-- <AppIcon iconName="app-send"></AppIcon> -->
</el-button> </el-button>
</div> </div>
</div> </div>
@ -75,13 +94,39 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import applicationApi from '@/api/application'
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
default: () => {} default: () => {}
} }
}) })
const loading = ref(false)
const inputValue = ref('') const inputValue = ref('')
function quickProblemHandel(val: string) {
inputValue.value = val
}
function chatHandle() {
loading.value = true
const obj = {
model_id: props.data.model_id,
dataset_id_list: props.data.dataset_id_list,
multiple_rounds_dialogue: props.data.multiple_rounds_dialogue,
}
applicationApi
.postChatOpen(obj)
.then((res) => {
loading.value = false
})
.catch(() => {
loading.value = false
})
}
// funcion chatMessage(chatId) {
// postChatMessage
// }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ai-dialog { .ai-dialog {
@ -162,12 +207,20 @@ const inputValue = ref('')
padding: 12px 16px; padding: 12px 16px;
} }
.operate { .operate {
padding: 10px 12px; padding: 6px 10px;
.sent-button { .sent-button {
max-height: none;
.el-icon { .el-icon {
font-size: 24px; font-size: 24px;
} }
} }
:deep(.el-loading-spinner) {
margin-top: -15px;
.circular {
width: 31px;
height: 31px;
}
}
} }
} }
} }

View File

@ -1,7 +1,9 @@
<template> <template>
<el-icon class="back-button cursor mr-8" @click="jump"> <el-button class="back-button cursor mr-4" text @click="jump">
<Back /> <el-icon>
</el-icon> <Back />
</el-icon>
</el-button>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -25,6 +27,6 @@ function jump() {
<style lang="scss"> <style lang="scss">
.back-button { .back-button {
font-size:20px; font-size: 20px;
} }
</style> </style>

View File

@ -174,30 +174,31 @@ export const iconMap: any = {
]) ])
} }
}, },
'app-send': { // 'app-send': {
iconReader: () => { // iconReader: () => {
return h('i', [ // return h('i', [
h( // h(
'svg', // 'svg',
{ // {
viewBox: '0 0 24 24', // viewBox: '0 0 24 24',
version: '1.1', // version: '1.1',
xmlns: 'http://www.w3.org/2000/svg' // xmlns: 'http://www.w3.org/2000/svg'
}, // },
[ // [
h('path', { // h('path', {
d: 'M20.1716 1.68834C20.6753 1.53273 21.0458 2.16193 20.6652 2.52691L12.2658 10.5836C11.0058 11.7921 9.32754 12.4668 7.5817 12.4668C5.68044 12.4668 3.8669 11.667 2.58487 10.263L1.45879 9.02985C1.33225 8.90313 1.24137 8.74527 1.19534 8.5722C1.14931 8.39913 1.14974 8.21698 1.19661 8.04413C1.24347 7.87129 1.3351 7.71386 1.46225 7.58775C1.5894 7.46164 1.74757 7.3713 1.92079 7.32585L20.1716 1.68834Z', // d: 'M20.1716 1.68834C20.6753 1.53273 21.0458 2.16193 20.6652 2.52691L12.2658 10.5836C11.0058 11.7921 9.32754 12.4668 7.5817 12.4668C5.68044 12.4668 3.8669 11.667 2.58487 10.263L1.45879 9.02985C1.33225 8.90313 1.24137 8.74527 1.19534 8.5722C1.14931 8.39913 1.14974 8.21698 1.19661 8.04413C1.24347 7.87129 1.3351 7.71386 1.46225 7.58775C1.5894 7.46164 1.74757 7.3713 1.92079 7.32585L20.1716 1.68834Z',
fill: 'currentColor' // fill: 'currentColor'
}), // }),
h('path', { // h('path', {
d: 'M12 16.1851C12 14.2766 12.7377 12.4419 14.0588 11.0646L21.4664 3.34177C21.8268 2.96601 22.4499 3.32266 22.3084 3.82374L17.143 22.1182C17.0971 22.291 17.0064 22.4487 16.8801 22.5754C16.7538 22.7021 16.5964 22.7932 16.4237 22.8397C16.251 22.8862 16.0691 22.8864 15.8964 22.8402C15.7236 22.794 15.566 22.7031 15.4395 22.5767L14.4439 21.6791C12.8881 20.2764 12 18.2799 12 16.1851Z', // d: 'M12 16.1851C12 14.2766 12.7377 12.4419 14.0588 11.0646L21.4664 3.34177C21.8268 2.96601 22.4499 3.32266 22.3084 3.82374L17.143 22.1182C17.0971 22.291 17.0064 22.4487 16.8801 22.5754C16.7538 22.7021 16.5964 22.7932 16.4237 22.8397C16.251 22.8862 16.0691 22.8864 15.8964 22.8402C15.7236 22.794 15.566 22.7031 15.4395 22.5767L14.4439 21.6791C12.8881 20.2764 12 18.2799 12 16.1851Z',
fill: 'currentColor' // fill: 'currentColor'
}) // })
] // ]
) // )
]) // ])
} // }
}, // },
'app-view': { 'app-view': {
iconReader: () => { iconReader: () => {
return h('i', [ return h('i', [

View File

@ -2,7 +2,7 @@
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition appear name="fade-transform" mode="out-in"> <transition appear name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews"> <keep-alive :include="cachedViews">
<component :is="Component" /> <component :is="Component" :key="route.fullPath" />
</keep-alive> </keep-alive>
</transition> </transition>
</router-view> </router-view>

View File

@ -0,0 +1,131 @@
<template>
<div class="flex align-center ml-8 mt-8 mb-16">
<back-button :to="activeMenu"></back-button>
<el-dropdown placement="bottom-start" trigger="click" @command="changeMenu">
<span class="el-dropdown-link flex">
<span class="ellipsis-1"> {{ currentName }}</span>
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<template v-for="(item, index) in list" :key="index">
<div :class="item.id === id ? 'dropdown-active' : ''">
<el-dropdown-item :command="item.id">
<div class="flex">
<AppAvatar class="mr-12" shape="square" :size="24">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<span class="ellipsis-1"> {{ item?.name }}</span>
</div>
</el-dropdown-item>
</div>
</template>
</el-dropdown-menu>
<div class="border-t" style="padding: 8px 11px; min-width: 200px">
<template v-if="isApplication">
<el-button link @click="router.push({ path: '/application/create' })">
<el-icon class="mr-4"><Plus /></el-icon>
</el-button>
</template>
<template v-else-if="isDataset">
<el-button link @click="router.push({ path: '/dataset/create' })">
<el-icon class="mr-4"><Plus /></el-icon>
</el-button>
</template>
</div>
</template>
</el-dropdown>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router'
import useStore from '@/stores'
const { common, dataset, application } = useStore()
const route = useRoute()
const router = useRouter()
const {
meta: { activeMenu },
params: { id }
} = route
onBeforeRouteLeave((to, from) => {
common.saveBreadcrumb(null)
})
const list = ref<any[]>([])
const loading = ref(false)
const breadcrumbData = computed(() => common.breadcrumb)
const currentName = computed(() => {
const {
params: { id }
} = route
return list.value?.filter((v) => v.id === id)?.[0]?.name
})
const isApplication = computed(() => {
const { meta } = route as any
return meta?.activeMenu.includes('application')
})
const isDataset = computed(() => {
const { meta } = route as any
return meta?.activeMenu.includes('dataset')
})
function changeMenu(id: string) {
if (isApplication.value) {
router.push({ path: `/application/${id}/overview` })
} else if (isDataset.value) {
router.push({ path: `/dataset/${id}/document` })
}
}
function getDataset() {
loading.value = true
dataset
.asyncGetAllDateset()
.then((res: any) => {
list.value = res.data
common.saveBreadcrumb(list.value)
loading.value = false
})
.catch(() => {
loading.value = false
})
}
function getApplication() {
loading.value = true
application
.asyncGetAllApplication()
.then((res: any) => {
list.value = res.data
common.saveBreadcrumb(list.value)
loading.value = false
})
.catch(() => {
loading.value = false
})
}
onMounted(() => {
if (!breadcrumbData.value) {
if (isDataset.value) {
getDataset()
} else if (isApplication.value) {
getApplication()
}
} else {
list.value = breadcrumbData.value
}
})
</script>
<style scoped lang="scss">
:deep(.dropdown-active) {
background-color: var(--el-dropdown-menuItem-hover-fill);
.el-dropdown-menu__item {
color: var(--el-dropdown-menuItem-hover-color);
}
}
</style>

View File

@ -1,5 +1,8 @@
<template> <template>
<div class="sidebar p-8"> <div class="sidebar p-8">
<div v-if="showBreadcrumb">
<AppBreadcrumb />
</div>
<el-scrollbar wrap-class="scrollbar-wrapper"> <el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu :default-active="activeMenu" router> <el-menu :default-active="activeMenu" router>
<sidebar-item <sidebar-item
@ -19,9 +22,18 @@ import { computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { getChildRouteListByPathAndName } from '@/router/index' import { getChildRouteListByPathAndName } from '@/router/index'
import SidebarItem from './SidebarItem.vue' import SidebarItem from './SidebarItem.vue'
import AppBreadcrumb from './AppBreadcrumb.vue'
const route = useRoute() const route = useRoute()
const showBreadcrumb = computed(() => {
const { meta } = route as any
return (
meta?.activeMenu &&
(meta?.activeMenu.includes('dataset') || meta?.activeMenu.includes('application'))
)
})
const subMenuList = computed(() => { const subMenuList = computed(() => {
const { meta } = route const { meta } = route
return getChildRouteListByPathAndName(meta.parentPath, meta.parentName) return getChildRouteListByPathAndName(meta.parentPath, meta.parentName)

View File

@ -18,7 +18,7 @@ const applicationRouter = {
hidden: true hidden: true
}, },
{ {
path: '/application/:appId', path: '/application/:id',
name: 'ApplicationDetail', name: 'ApplicationDetail',
meta: { title: '应用详情', activeMenu: '/application' }, meta: { title: '应用详情', activeMenu: '/application' },
component: Layout, component: Layout,
@ -31,7 +31,7 @@ const applicationRouter = {
icon: 'Document', icon: 'Document',
title: '概览', title: '概览',
active: 'overview', active: 'overview',
parentPath: '/application/:appId', parentPath: '/application/:id',
parentName: 'ApplicationDetail' parentName: 'ApplicationDetail'
}, },
component: () => import('@/views/application/AppOverview.vue') component: () => import('@/views/application/AppOverview.vue')
@ -43,7 +43,7 @@ const applicationRouter = {
icon: 'Setting', icon: 'Setting',
title: '设置', title: '设置',
active: 'setting', active: 'setting',
parentPath: '/application/:appId', parentPath: '/application/:id',
parentName: 'ApplicationDetail' parentName: 'ApplicationDetail'
}, },
component: () => import('@/views/application/CreateAndSetting.vue') component: () => import('@/views/application/CreateAndSetting.vue')
@ -55,7 +55,7 @@ const applicationRouter = {
icon: 'Setting', icon: 'Setting',
title: '对话日志', title: '对话日志',
active: 'dialog', active: 'dialog',
parentPath: '/application/:appId', parentPath: '/application/:id',
parentName: 'ApplicationDetail' parentName: 'ApplicationDetail'
}, },
component: () => import('@/views/application/DialogLog.vue') component: () => import('@/views/application/DialogLog.vue')

View File

@ -18,7 +18,7 @@ const datasetRouter = {
hidden: true hidden: true
}, },
{ {
path: '/dataset/:datasetId', path: '/dataset/:id',
name: 'DatasetDetail', name: 'DatasetDetail',
meta: { title: '文档', activeMenu: '/dataset' }, meta: { title: '文档', activeMenu: '/dataset' },
component: Layout, component: Layout,
@ -31,7 +31,7 @@ const datasetRouter = {
icon: 'Document', icon: 'Document',
title: '文档', title: '文档',
active: 'document', active: 'document',
parentPath: '/dataset/:datasetId', parentPath: '/dataset/:id',
parentName: 'DatasetDetail' parentName: 'DatasetDetail'
}, },
component: () => import('@/views/document/index.vue') component: () => import('@/views/document/index.vue')
@ -43,7 +43,7 @@ const datasetRouter = {
icon: 'Setting', icon: 'Setting',
title: '设置', title: '设置',
active: 'setting', active: 'setting',
parentPath: '/dataset/:datasetId', parentPath: '/dataset/:id',
parentName: 'DatasetDetail' parentName: 'DatasetDetail'
}, },
component: () => import('@/views/document/DatasetSetting.vue') component: () => import('@/views/document/DatasetSetting.vue')
@ -51,7 +51,7 @@ const datasetRouter = {
] ]
}, },
{ {
path: '/dataset/:datasetId/:documentId', // 分段详情 path: '/dataset/:id/:documentId', // 分段详情
name: 'Paragraph', name: 'Paragraph',
meta: { activeMenu: '/dataset' }, meta: { activeMenu: '/dataset' },
component: () => import('@/views/paragraph/index.vue'), component: () => import('@/views/paragraph/index.vue'),

View File

@ -1,16 +1,20 @@
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
const store = createPinia() const store = createPinia()
export { store } export { store }
import useCommonStore from './modules/common'
import useUserStore from './modules/user' import useUserStore from './modules/user'
import useDatasetStore from './modules/dataset' import useDatasetStore from './modules/dataset'
import useParagraphStore from './modules/paragraph' import useParagraphStore from './modules/paragraph'
import useModelStore from './modules/model' import useModelStore from './modules/model'
import useApplicationStore from './modules/application'
const useStore = () => ({ const useStore = () => ({
common: useCommonStore(),
user: useUserStore(), user: useUserStore(),
dataset: useDatasetStore(), dataset: useDatasetStore(),
paragraph: useParagraphStore(), paragraph: useParagraphStore(),
model: useModelStore(), model: useModelStore(),
application: useApplicationStore()
}) })
export default useStore export default useStore

View File

@ -0,0 +1,23 @@
import { defineStore } from 'pinia'
import applicationApi from '@/api/application'
const useApplicationStore = defineStore({
id: 'application',
state: () => ({}),
actions: {
async asyncGetAllApplication() {
return new Promise((resolve, reject) => {
applicationApi
.getAllAppilcation()
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
}
}
})
export default useApplicationStore

View File

@ -0,0 +1,17 @@
import { defineStore } from 'pinia'
import type { User } from '@/api/type/user'
import UserApi from '@/api/user'
const useCommonStore = defineStore({
id: 'common',
state: () => ({
breadcrumb: null
}),
actions: {
saveBreadcrumb(data) {
this.breadcrumb = data
}
}
})
export default useCommonStore

View File

@ -1,6 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { datasetData } from '@/api/type/dataset' import type { datasetData } from '@/api/type/dataset'
import type { UploadUserFile } from 'element-plus' import type { UploadUserFile } from 'element-plus'
import datasetApi from '@/api/dataset'
export interface datasetStateTypes { export interface datasetStateTypes {
baseInfo: datasetData | null baseInfo: datasetData | null
@ -19,6 +20,18 @@ const useDatasetStore = defineStore({
}, },
saveDocumentsFile(file: UploadUserFile[]) { saveDocumentsFile(file: UploadUserFile[]) {
this.documentsFiles = file this.documentsFiles = file
},
async asyncGetAllDateset() {
return new Promise((resolve, reject) => {
datasetApi
.getAllDateset()
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
} }
} }
}) })

View File

@ -326,6 +326,14 @@ h4 {
} }
} }
// checkbox-group 文字在左 input在右
.app-custom-checkbox-group {
line-height: normal;
.el-checkbox__label {
display: none;
}
}
/* /*
头像渐变背景 头像渐变背景
*/ */

View File

@ -102,6 +102,10 @@
color: var(--app-text-color); color: var(--app-text-color);
font-weight: 400; font-weight: 400;
padding: 5px 11px; padding: 5px 11px;
&:not(.is-disabled):focus {
background-color: var(--app-text-color-light-1);
color: var(--app-text-color);
}
} }
.el-tag { .el-tag {

View File

@ -1,5 +1,5 @@
<template> <template>
<LayoutContainer :header="appId ? '设置' : '创建应用'" back-to="-1" class="create-application"> <LayoutContainer :header="id ? '设置' : '创建应用'" back-to="-1" class="create-application">
<el-row> <el-row>
<el-col :span="10"> <el-col :span="10">
<div class="p-24 mb-16" style="padding-bottom: 0"> <div class="p-24 mb-16" style="padding-bottom: 0">
@ -79,7 +79,7 @@
<template #label> <template #label>
<div class="flex-between"> <div class="flex-between">
<span>关联数据集</span> <span>关联数据集</span>
<el-button type="primary" link> <el-button type="primary" link @click="openDatasetDialog">
<el-icon class="mr-4"><Plus /></el-icon> <el-icon class="mr-4"><Plus /></el-icon>
</el-button> </el-button>
</div> </div>
@ -87,7 +87,7 @@
<div> <div>
<el-text type="info">关联的数据集展示在这里</el-text> <el-text type="info">关联的数据集展示在这里</el-text>
</div> </div>
<div class="w-full"> <!-- <div class="w-full">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="mb-8"> <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="mb-8">
<el-card class="relate-dataset-card" shadow="never"> <el-card class="relate-dataset-card" shadow="never">
@ -105,14 +105,14 @@
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
</div> </div> -->
</el-form-item> </el-form-item>
<el-form-item label="开场白"> <el-form-item label="开场白">
<el-input <el-input
v-model="applicationForm.prologue" v-model="applicationForm.prologue"
type="textarea" type="textarea"
placeholder="开始对话的欢迎语。您可以这样写:您好,我是 MaxKB 智能小助手,您可以向我提出 MaxKB 产品使用中遇到的任何问题。" placeholder="开始对话的欢迎语。您可以这样写:您好,我是 MaxKB 智能小助手,您可以向我提出 MaxKB 产品使用中遇到的任何问题。"
:rows="3" :rows="4"
/> />
</el-form-item> </el-form-item>
<el-form-item label="示例"> <el-form-item label="示例">
@ -128,8 +128,8 @@
</el-scrollbar> </el-scrollbar>
</div> </div>
<div class="text-right border-t p-16"> <div class="text-right border-t p-16">
<el-button> 取消 </el-button> <el-button @click="router.push({ path: `/application` })"> 取消 </el-button>
<el-button type="primary" :disabled="loading"> 创建 </el-button> <el-button type="primary" @click="submit" :disabled="loading"> 创建 </el-button>
</div> </div>
</el-col> </el-col>
<el-col :span="14" class="p-24 border-l"> <el-col :span="14" class="p-24 border-l">
@ -142,6 +142,7 @@
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<AddDatasetDialog ref="AddDatasetDialogRef" />
</LayoutContainer> </LayoutContainer>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -149,6 +150,7 @@ import { reactive, ref, watch, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { groupBy } from 'lodash' import { groupBy } from 'lodash'
import AiDialog from '@/components/ai-dialog/index.vue' import AiDialog from '@/components/ai-dialog/index.vue'
import AddDatasetDialog from './components/AddDatasetDialog.vue'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import type { ApplicationFormType } from '@/api/type/application' import type { ApplicationFormType } from '@/api/type/application'
import type { Provider } from '@/api/type/model' import type { Provider } from '@/api/type/model'
@ -158,10 +160,11 @@ const { model } = useStore()
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const { const {
params: { appId } params: { id }
} = route as any } = route as any
const applicationFormRef = ref<FormInstance>() const applicationFormRef = ref<FormInstance>()
const AddDatasetDialogRef = ref()
const loading = ref(false) const loading = ref(false)
const exampleList = ref(['', '']) const exampleList = ref(['', ''])
@ -192,6 +195,46 @@ watch(exampleList.value, () => {
applicationForm.example = exampleList.value.filter((v) => v) applicationForm.example = exampleList.value.filter((v) => v)
}) })
function submit() {
loading.value = true
// const documents = [] as any[]
// StepSecondRef.value.paragraphList.map((item: any) => {
// documents.push({
// name: item.name,
// paragraphs: item.content
// })
// })
// const obj = { ...baseInfo.value, documents } as datasetData
// if (id) {
// documentApi
// .postDocument(id, documents)
// .then((res) => {
// MsgSuccess('')
// clearStore()
// router.push({ path: `/dataset/${id}/document` })
// })
// .catch(() => {
// loading.value = false
// })
// } else {
// datasetApi
// .postDateset(obj)
// .then((res) => {
// successInfo.value = res.data
// active.value = 2
// clearStore()
// loading.value = false
// })
// .catch(() => {
// loading.value = false
// })
// }
}
function openDatasetDialog() {
AddDatasetDialogRef.value.open()
}
function getModel() { function getModel() {
loading.value = true loading.value = true
model model

View File

@ -1,17 +1,26 @@
<template> <template>
<el-dialog title="添加关联数据集" v-model="dialogVisible" width="600"> <el-dialog title="添加关联数据集" v-model="dialogVisible" width="600">
<el-row :gutter="12"> <el-checkbox-group v-model="checkList" class="app-custom-checkbox-group">
<el-col :span="12"> <el-row :gutter="12">
<el-card shadow="hover"> Hover </el-card> <el-col :span="12">
</el-col> <el-card shadow="hover">
<el-col :span="12"> <div class="title flex-between">
<el-card shadow="hover"> Hover </el-card> <div class="flex align-center">
</el-col> <AppAvatar class="mr-12" shape="square" :size="32">
</el-row> <img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<h4 class="ellipsis-1">数据集</h4>
</div>
<el-checkbox label="Option A" />
</div>
</el-card>
</el-col>
</el-row>
</el-checkbox-group>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> 取消 </el-button> <el-button @click.prevent="dialogVisible = false"> 取消 </el-button>
<el-button type="primary" @click="submitHandle"> 保存 </el-button> <el-button type="primary" @click="submitHandle"> 确认 </el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -22,14 +31,13 @@ import { ref, watch } from 'vue'
const emit = defineEmits(['updateContent']) const emit = defineEmits(['updateContent'])
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
const checkList = ref([])
const detail = ref({})
const paragraphFormRef = ref() const paragraphFormRef = ref()
watch(dialogVisible, (bool) => { watch(dialogVisible, (bool) => {
if (!bool) { if (!bool) {
detail.value = {} checkList.value = []
} }
}) })

View File

@ -18,7 +18,7 @@ import datasetApi from '@/api/dataset'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
const route = useRoute() const route = useRoute()
const { const {
params: { datasetId } params: { id }
} = route as any } = route as any
const BaseFormRef = ref() const BaseFormRef = ref()
@ -29,7 +29,7 @@ async function submit() {
if (await BaseFormRef.value?.validate()) { if (await BaseFormRef.value?.validate()) {
loading.value = true loading.value = true
datasetApi datasetApi
.putDateset(datasetId, BaseFormRef.value.form) .putDateset(id, BaseFormRef.value.form)
.then((res) => { .then((res) => {
MsgSuccess('保存成功') MsgSuccess('保存成功')
loading.value = false loading.value = false
@ -43,7 +43,7 @@ async function submit() {
function getDetail() { function getDetail() {
loading.value = true loading.value = true
datasetApi datasetApi
.getDatesetDetail(datasetId) .getDatesetDetail(id)
.then((res) => { .then((res) => {
detail.value = res.data detail.value = res.data
loading.value = false loading.value = false

View File

@ -5,7 +5,7 @@
<div class="flex-between"> <div class="flex-between">
<el-button <el-button
type="primary" type="primary"
@click="router.push({ path: '/dataset/upload', query: { id: datasetId } })" @click="router.push({ path: '/dataset/upload', query: { id: id } })"
>上传文档</el-button >上传文档</el-button
> >
<el-input <el-input
@ -108,7 +108,7 @@ import { MsgSuccess, MsgConfirm } from '@/utils/message'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const { const {
params: { datasetId } params: { id }
} = route as any } = route as any
const loading = ref(false) const loading = ref(false)
@ -124,7 +124,7 @@ const paginationConfig = reactive({
}) })
function rowClickHandle(row: any) { function rowClickHandle(row: any) {
router.push({ path: `/dataset/${datasetId}/${row.id}` }) router.push({ path: `/dataset/${id}/${row.id}` })
} }
/* /*
@ -134,7 +134,7 @@ function creatQuickHandle(val: string) {
loading.value = true loading.value = true
const obj = { name: val } const obj = { name: val }
documentApi documentApi
.postDocument(datasetId, obj) .postDocument(id, obj)
.then((res) => { .then((res) => {
getList() getList()
MsgSuccess('创建成功') MsgSuccess('创建成功')
@ -156,7 +156,7 @@ function deleteDocument(row: any) {
.then(() => { .then(() => {
loading.value = true loading.value = true
documentApi documentApi
.delDocument(datasetId, row.id) .delDocument(id, row.id)
.then(() => { .then(() => {
MsgSuccess('删除成功') MsgSuccess('删除成功')
getList() getList()
@ -174,7 +174,7 @@ function deleteDocument(row: any) {
function updateData(documentId: string, data: any) { function updateData(documentId: string, data: any) {
loading.value = true loading.value = true
documentApi documentApi
.putDocument(datasetId, documentId, data) .putDocument(id, documentId, data)
.then((res) => { .then((res) => {
const index = documentData.value.findIndex((v) => v.id === documentId) const index = documentData.value.findIndex((v) => v.id === documentId)
documentData.value.splice(index, 1, res.data) documentData.value.splice(index, 1, res.data)
@ -217,7 +217,7 @@ function handleCurrentChange(val: number) {
function getList() { function getList() {
loading.value = true loading.value = true
documentApi documentApi
.getDocument(datasetId as string, filterText.value) .getDocument(id as string, filterText.value)
.then((res) => { .then((res) => {
documentData.value = res.data documentData.value = res.data
paginationConfig.total = res.data.length paginationConfig.total = res.data.length

View File

@ -55,7 +55,7 @@ const { paragraph } = useStore()
const route = useRoute() const route = useRoute()
const { const {
params: { datasetId, documentId } params: { id, documentId }
} = route as any } = route as any
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
@ -93,7 +93,7 @@ const submitHandle = async () => {
loading.value = true loading.value = true
if (problemId.value) { if (problemId.value) {
paragraph paragraph
.asyncPutParagraph(datasetId, documentId, problemId.value, paragraphFormRef.value?.form) .asyncPutParagraph(id, documentId, problemId.value, paragraphFormRef.value?.form)
.then(() => { .then(() => {
emit('refresh') emit('refresh')
loading.value = false loading.value = false
@ -111,7 +111,7 @@ const submitHandle = async () => {
} }
: paragraphFormRef.value?.form : paragraphFormRef.value?.form
paragraphApi paragraphApi
.postParagraph(datasetId, documentId, obj) .postParagraph(id, documentId, obj)
.then((res) => { .then((res) => {
emit('refresh') emit('refresh')
loading.value = false loading.value = false

View File

@ -42,7 +42,7 @@ const props = defineProps({
const route = useRoute() const route = useRoute()
const { const {
params: { datasetId, documentId } params: { id, documentId }
} = route as any } = route as any
const inputRef = ref() const inputRef = ref()
@ -68,7 +68,7 @@ function delProblemHandle(item: any, index: number) {
loading.value = true loading.value = true
if (item.id) { if (item.id) {
paragraphApi paragraphApi
.delProblem(datasetId, documentId, props.problemId || '', item.id) .delProblem(id, documentId, props.problemId || '', item.id)
.then((res) => { .then((res) => {
getProblemList() getProblemList()
}) })
@ -84,7 +84,7 @@ function delProblemHandle(item: any, index: number) {
function getProblemList() { function getProblemList() {
loading.value = true loading.value = true
paragraphApi paragraphApi
.getProblem(datasetId, documentId, props.problemId || '') .getProblem(id, documentId, props.problemId || '')
.then((res) => { .then((res) => {
problemList.value = res.data problemList.value = res.data
loading.value = false loading.value = false
@ -108,7 +108,7 @@ function addProblemHandle(val: string) {
loading.value = true loading.value = true
if (props.problemId) { if (props.problemId) {
paragraphApi paragraphApi
.postProblem(datasetId, documentId, props.problemId, obj) .postProblem(id, documentId, props.problemId, obj)
.then((res) => { .then((res) => {
getProblemList() getProblemList()
problemValue.value = '' problemValue.value = ''

View File

@ -79,7 +79,7 @@ import useStore from '@/stores'
const { paragraph } = useStore() const { paragraph } = useStore()
const route = useRoute() const route = useRoute()
const { const {
params: { datasetId, documentId } params: { id, documentId }
} = route as any } = route as any
const ParagraphDialogRef = ref() const ParagraphDialogRef = ref()
@ -96,7 +96,7 @@ function changeState(bool: Boolean, row: any) {
} }
loading.value = true loading.value = true
paragraph paragraph
.asyncPutParagraph(datasetId, documentId, row.id, obj) .asyncPutParagraph(id, documentId, row.id, obj)
.then((res) => { .then((res) => {
loading.value = false loading.value = false
}) })
@ -113,7 +113,7 @@ function deleteParagraph(row: any) {
.then(() => { .then(() => {
loading.value = true loading.value = true
paragraphApi paragraphApi
.delParagraph(datasetId, documentId, row.id) .delParagraph(id, documentId, row.id)
.then(() => { .then(() => {
MsgSuccess('删除成功') MsgSuccess('删除成功')
getParagraphDetail() getParagraphDetail()
@ -137,7 +137,7 @@ function editParagraph(row: any) {
function getDetail() { function getDetail() {
loading.value = true loading.value = true
documentApi documentApi
.getDocumentDetail(datasetId, documentId) .getDocumentDetail(id, documentId)
.then((res) => { .then((res) => {
documentDetail.value = res.data documentDetail.value = res.data
loading.value = false loading.value = false
@ -150,7 +150,7 @@ function getDetail() {
function getParagraphDetail() { function getParagraphDetail() {
loading.value = true loading.value = true
paragraphApi paragraphApi
.getParagraph(datasetId, documentId) .getParagraph(id, documentId)
.then((res) => { .then((res) => {
paragraphDetail.value = res.data paragraphDetail.value = res.data
loading.value = false loading.value = false