feat: 应用

This commit is contained in:
wangdan-fit2cloud 2023-11-23 17:20:19 +08:00
parent 394a6a7ee6
commit de643d368d
13 changed files with 270 additions and 135 deletions

View File

@ -1,5 +1,22 @@
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'
const prefix = '/application' const prefix = '/application'
export default {} /**
*
* @param {
"current_page": "string",
"page_size": "string",
"name": "string",
}
*/
const getApplication: (param: pageRequest) => Promise<Result<any>> = (param) => {
return get(
`${prefix}/${param.current_page}/${param.page_size}`,
param.name && { name: param.name }
)
}
export default {
getApplication
}

View File

@ -1,6 +1,7 @@
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 { datasetListRequest, datasetData } from '@/api/type/dataset' import type { datasetData } from '@/api/type/dataset'
import type { pageRequest } from '@/api/type/common'
const prefix = '/dataset' const prefix = '/dataset'
/** /**
@ -11,7 +12,7 @@ const prefix = '/dataset'
"name": "string", "name": "string",
} }
*/ */
const getDateset: (param: datasetListRequest) => Promise<Result<any>> = (param) => { const getDateset: (param: pageRequest) => Promise<Result<any>> = (param) => {
return get( return get(
`${prefix}/${param.current_page}/${param.page_size}`, `${prefix}/${param.current_page}/${param.page_size}`,
param.name && { name: param.name } param.name && { name: param.name }

View File

@ -11,7 +11,14 @@ const prefix_provider = '/provider'
const getModel: (data?: modelRequest) => Promise<Result<any>> = (data) => { const getModel: (data?: modelRequest) => Promise<Result<any>> = (data) => {
return get(`${prefix}`, data) return get(`${prefix}`, data)
} }
/**
*
*/
const getProvider: () => Promise<Result<any>> = () => {
return get(`${prefix_provider}`)
}
export default { export default {
getModel getModel,
getProvider
} }

View File

@ -6,4 +6,10 @@ interface Dict<V> {
[propName: string]: V [propName: string]: V
} }
export type { KeyValue, Dict } interface pageRequest {
current_page: number
page_size: number
name: string
}
export type { KeyValue, Dict, pageRequest }

View File

@ -1,13 +1,7 @@
interface datasetListRequest {
current_page: number
page_size: number
name: string
}
interface datasetData { interface datasetData {
name: String name: String
desc: String desc: String
documents?: Array<any> documents?: Array<any>
} }
export type { datasetListRequest, datasetData } export type { datasetData }

View File

@ -197,5 +197,29 @@ export const iconMap: any = {
) )
]) ])
} }
},
'app-view': {
iconReader: () => {
return h('i', [
h(
'svg',
{
viewBox: '0 0 16 12',
version: '1.1',
xmlns: 'http://www.w3.org/2000/svg'
},
[
h('path', {
d: 'M6.9649 8.5176L10.8075 6.59629C10.9365 6.53178 11.0412 6.42717 11.1057 6.29815C11.2703 5.96883 11.1368 5.56838 10.8075 5.40372L6.9649 3.48241C6.87233 3.43612 6.77025 3.41203 6.66675 3.41203C6.29856 3.41203 6.00009 3.71051 6.00009 4.07869V7.92132C6.00009 8.02481 6.02418 8.12689 6.07047 8.21946C6.23513 8.54878 6.63558 8.68226 6.9649 8.5176Z',
fill: 'currentColor'
}),
h('path', {
d: 'M15.3334 0.75C15.3334 0.335786 15.0349 0 14.6667 0H1.33341C0.965225 0 0.666748 0.335786 0.666748 0.75V11.25C0.666748 11.6642 0.965225 12 1.33341 12H14.6667C15.0349 12 15.3334 11.6642 15.3334 11.25V0.75ZM2.00008 1.5H14.0001V10.5H2.00008V1.5Z',
fill: 'currentColor'
})
]
)
])
}
} }
} }

View File

@ -16,6 +16,18 @@ const useModelStore = defineStore({
reject(error) reject(error)
}) })
}) })
},
async asyncGetProvider() {
return new Promise((resolve, reject) => {
modelApi
.getProvider()
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
})
} }
} }
}) })

View File

@ -270,6 +270,17 @@ h4 {
.default-tag { .default-tag {
background: var(--tag-deflaut-bg); background: var(--tag-deflaut-bg);
color: var(--tag-deflaut-color); color: var(--tag-deflaut-color);
border: none;
}
.success-tag {
background: var(--tag-success-bg);
color: var(--el-color-success);
border: none;
}
.warning-tag {
background: var(--tag-warning-bg);
color: var(--el-color-warning);
border: none;
} }
/* /*

View File

@ -99,6 +99,11 @@
.el-dropdown { .el-dropdown {
color: var(--app-text-color); color: var(--app-text-color);
} }
.el-dropdown-menu__item {
color: var(--app-text-color);
font-weight: 400;
padding: 5px 11px;
}
.el-tag { .el-tag {
--el-tag-border-radius: 2px; --el-tag-border-radius: 2px;
@ -179,3 +184,5 @@
.el-textarea__inner { .el-textarea__inner {
font-size: 13px; font-size: 13px;
} }

View File

@ -25,6 +25,11 @@
/** tag */ /** tag */
--tag-deflaut-bg: rgba(51, 112, 255, 0.2); --tag-deflaut-bg: rgba(51, 112, 255, 0.2);
--tag-deflaut-color: #2b5fd9; --tag-deflaut-color: #2b5fd9;
--tag-success-bg: rgba(52, 199, 36, 0.20);
--tag-success-color: #2CA91F;
--tag-warning-bg: rgba(255, 136, 0, 0.20);
--tag-warning-color: #D97400;
/** card */ /** card */
--card-width: 330px; --card-width: 330px;
--card-min-height: 160px; --card-min-height: 160px;

View File

@ -35,14 +35,20 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="选择模型" prop="model_id"> <el-form-item label="选择模型" prop="model_id">
<el-select <!-- <el-select
v-model="applicationForm.model_id" v-model="applicationForm.model_id"
placeholder="请选择模型" placeholder="请选择模型"
style="width: 100%" style="width: 100%"
> >
<el-option label="Zone one" value="shanghai" /> <el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" /> <el-option label="Zone two" value="beijing" />
</el-select> </el-select> -->
<el-cascader
v-model="applicationForm.model_id"
:options="modelOptions"
:props="modelProps"
clearable
/>
</el-form-item> </el-form-item>
<el-form-item label="多轮对话"> <el-form-item label="多轮对话">
@ -120,7 +126,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, watch, onMounted } from 'vue' import { reactive, ref, watch, onMounted } from 'vue'
import AiDialog from '@/components/ai-dialog/index.vue' import AiDialog from '@/components/ai-dialog/index.vue'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules, CascaderProps } from 'element-plus'
import type { ApplicationFormType } from '@/api/type/application' import type { ApplicationFormType } from '@/api/type/application'
import useStore from '@/stores' import useStore from '@/stores'
const { model } = useStore() const { model } = useStore()
@ -149,14 +155,37 @@ const rules = reactive<FormRules<ApplicationFormType>>({
} }
] ]
}) })
const modelOptions = ref([])
watch(exampleList.value, () => { watch(exampleList.value, () => {
applicationForm.example = exampleList.value.filter((v) => v) applicationForm.example = exampleList.value.filter((v) => v)
}) })
let id = 0
const modelProps: CascaderProps = {
lazy: true,
async lazyLoad(node, resolve) {
console.log(node)
const { level } = node
if (level === 0) {
let res = await getProvider()
resolve(res)
}
// setTimeout(() => {
// const nodes = Array.from({ length: level + 1 }).map((item) => ({
// value: ++id,
// label: `Option - ${id}`,
// leaf: level >= 2
// }))
// resolve(nodes)
// }, 1000)
}
}
function getModel() { function getModel() {
loading.value = true loading.value = true
model.asyncGetModel() model
.asyncGetModel()
.then((res) => { .then((res) => {
loading.value = false loading.value = false
}) })
@ -164,8 +193,20 @@ function getModel() {
loading.value = false loading.value = false
}) })
} }
function getProvider() {
loading.value = true
model
.asyncGetProvider()
.then((res) => {
modelOptions.value = res?.data
loading.value = false
})
.catch(() => {
loading.value = false
})
}
onMounted(() => { onMounted(() => {
getModel() // getProvider()
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,94 +1,103 @@
<template> <template>
<div class="application-list-container p-24"> <div class="application-list-container p-24">
<div class="flex-between"> <div class="flex-between">
<h3>应用</h3> <h3>应用</h3>
<el-input <el-input
v-model="pageConfig.name" v-model="pageConfig.name"
@change="search" @change="search"
placeholder="按 名称 搜索" placeholder="按 名称 搜索"
prefix-icon="Search" prefix-icon="Search"
class="w-240" class="w-240"
/> />
</div> </div>
<div v-loading.fullscreen.lock="loading"> <div v-loading.fullscreen.lock="loading">
<el-row <el-row
:gutter="15" :gutter="15"
v-infinite-scroll="loadDataset" v-infinite-scroll="loadDataset"
:infinite-scroll-disabled="disabledScroll" :infinite-scroll-disabled="disabledScroll"
class="app-list-row" class="app-list-row"
> >
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mt-8"> <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mt-8">
<CardAdd title="创建应用" @click="router.push({ path: '/application/create' })" /> <CardAdd title="创建应用" @click="router.push({ path: '/application/create' })" />
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mt-8"> <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mt-8">
<CardBox title="应用" @click="router.push({ path: '/application/1/overview' })" /> <CardBox
</el-col> title="应用"
<!-- <el-col description="XXXXXX"
:xs="24" class="application-card cursor"
:sm="12" @click="router.push({ path: '/application/1/overview' })"
:md="8"
:lg="6"
:xl="4"
v-for="(item, index) in applicationList"
:key="index"
class="mt-8"
> >
<CardBox <div class="status-tag">
:title="item.name" <el-tag class="warning-tag">已停用</el-tag>
:description="item.desc" <el-tag class="success-tag">运行中</el-tag>
class="cursor" </div>
@click="router.push({ path: `/dataset/${item.id}/document` })"
> <template #footer>
<template #mouseEnter> <div class="footer-content">
<el-tooltip effect="dark" content="删除" placement="top"> <el-tooltip effect="dark" content="演示" placement="top">
<el-button text @click.stop="deleteDateset(item)" class="delete-button"> <el-button text @click.stop>
<el-icon><Delete /></el-icon> <AppIcon iconName="app-view"></AppIcon>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
</template> <el-divider direction="vertical" />
<el-tooltip effect="dark" content="设置" placement="top">
<template #footer> <el-button text @click.stop>
<div class="footer-content"> <AppIcon iconName="Setting"></AppIcon>
<span class="bold">{{ item?.document_count || 0 }}</span> </el-button>
文档<el-divider direction="vertical" /> </el-tooltip>
<span class="bold">{{ numberFormat(item?.char_length) || 0 }}</span> <el-divider direction="vertical" />
字符<el-divider direction="vertical" /> <span @click.stop>
<span class="bold">{{ item?.char_length || 0 }}</span> <el-dropdown trigger="click" placement="bottom-start">
关联应用 <span class="el-dropdown-link">
</div> <el-button text>
</template> <AppIcon iconName="MoreFilled"></AppIcon>
</CardBox> </el-button>
</el-col> --> </span>
</el-row> <template #dropdown>
</div> <el-dropdown-menu>
<div class="dropdown-custom-switch">
<span>运行中</span><el-switch v-model="state" />
</div>
<el-dropdown-item divided>删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</span>
</div>
</template>
</CardBox>
</el-col>
</el-row>
</div> </div>
</template> </div>
<script setup lang="ts"> </template>
import { ref, onMounted, reactive } from 'vue' <script setup lang="ts">
import datasetApi from '@/api/dataset' import { ref, onMounted, reactive } from 'vue'
import type { datasetListRequest } from '@/api/type/dataset' import applicationApi from '@/api/application'
import type { pageRequest } from '@/api/type/common'
// import { MsgSuccess, MsgConfirm } from '@/utils/message' // import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
// import { numberFormat } from '@/utils/utils' // import { numberFormat } from '@/utils/utils'
const router = useRouter() const router = useRouter()
const loading = ref(false) const loading = ref(false)
const disabledScroll = ref(false) const disabledScroll = ref(false)
const pageConfig = reactive<datasetListRequest>({ const pageConfig = reactive<pageRequest>({
current_page: 1, current_page: 1,
page_size: 20, page_size: 20,
name: '' name: ''
}) })
const applicationList = ref<any[]>([])
const state = ref(false)
function loadDataset() {}
function search() {
pageConfig.current_page = 1
getList()
}
const applicationList = ref<any[]>([])
function loadDataset() {}
function search() {
pageConfig.current_page = 1
getList()
}
// function deleteDateset(row: any) { // function deleteDateset(row: any) {
// MsgConfirm( // MsgConfirm(
// `${row.name} ?`, // `${row.name} ?`,
@ -112,37 +121,38 @@
// }) // })
// .catch(() => {}) // .catch(() => {})
// } // }
function getList() { function getList() {
loading.value = true loading.value = true
datasetApi applicationApi
.getDateset(pageConfig) .getApplication(pageConfig)
.then((res) => { .then((res) => {
applicationList.value = res.data?.records applicationList.value = res.data?.records
loading.value = false loading.value = false
}) })
.catch(() => { .catch(() => {
loading.value = false loading.value = false
}) })
}
onMounted(() => {
getList()
})
</script>
<style lang="scss" scoped>
.application-card {
.status-tag {
position: absolute;
right: 16px;
top: 20px;
} }
}
onMounted(() => { .dropdown-custom-switch {
// getList() padding: 5px 11px;
}) font-size: 14px;
</script> font-weight: 400;
<style lang="scss" scoped> span {
// .dataset-list-container { margin-right: 26px;
// .delete-button { }
// position: absolute; }
// right: 12px; </style>
// top: 18px;
// height: auto;
// }
// .footer-content {
// .bold {
// color: var(--app-text-color);
// }
// }
// }
</style>

View File

@ -63,7 +63,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, reactive } from 'vue' import { ref, onMounted, reactive } from 'vue'
import datasetApi from '@/api/dataset' import datasetApi from '@/api/dataset'
import type { datasetListRequest } from '@/api/type/dataset' import type { pageRequest } from '@/api/type/common'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { numberFormat } from '@/utils/utils' import { numberFormat } from '@/utils/utils'
@ -72,7 +72,7 @@ const router = useRouter()
const loading = ref(false) const loading = ref(false)
const datasetList = ref<any[]>([]) const datasetList = ref<any[]>([])
const disabledScroll = ref(false) const disabledScroll = ref(false)
const pageConfig = reactive<datasetListRequest>({ const pageConfig = reactive<pageRequest>({
current_page: 1, current_page: 1,
page_size: 20, page_size: 20,
name: '' name: ''