mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
merge
This commit is contained in:
commit
9af53c8821
|
|
@ -32,6 +32,7 @@
|
|||
"pinia": "^2.1.6",
|
||||
"pinyin-pro": "^3.18.2",
|
||||
"vue": "^3.3.4",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-router": "^4.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -29,32 +29,6 @@ const getApplication: (param: pageRequest) => Promise<Result<any>> = (param) =>
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得临时回话Id
|
||||
* @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)
|
||||
}
|
||||
/**
|
||||
* 对话
|
||||
* @param 参数
|
||||
* chat_id: string
|
||||
* {
|
||||
"message": "string",
|
||||
}
|
||||
*/
|
||||
const postChatMessage: (chat_id: string, message: string) => Promise<any> = (chat_id, message) => {
|
||||
return postStream(`/api/${prefix}/chat_message/${chat_id}`, { message })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建应用
|
||||
* @param 参数
|
||||
|
|
@ -156,16 +130,85 @@ const getAccessToken: (applicaiton_id: string, loading?: Ref<boolean>) => Promis
|
|||
return get(`${prefix}/${applicaiton_id}/access_token`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用认证
|
||||
* @param 参数
|
||||
{
|
||||
"access_token": "string"
|
||||
}
|
||||
*/
|
||||
const postAppAuthentication: (access_token: string, loading?: Ref<boolean>) => Promise<any> = (
|
||||
access_token,
|
||||
loading
|
||||
) => {
|
||||
return post(`${prefix}/authentication`, { access_token }, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话获取应用相关信息
|
||||
* @param 参数
|
||||
{
|
||||
"access_token": "string"
|
||||
}
|
||||
*/
|
||||
const getProfile: (loading?: Ref<boolean>) => Promise<any> = (loading) => {
|
||||
return get(`${prefix}/profile`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得临时回话Id
|
||||
* @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)
|
||||
}
|
||||
|
||||
/**
|
||||
* 正式回话Id
|
||||
* @param 参数
|
||||
* {
|
||||
"model_id": "string",
|
||||
"multiple_rounds_dialogue": true,
|
||||
"dataset_id_list": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
*/
|
||||
const getChatOpen: (applicaiton_id: String) => Promise<Result<any>> = (applicaiton_id) => {
|
||||
return get(`${prefix}/${applicaiton_id}/chat/open`)
|
||||
}
|
||||
/**
|
||||
* 对话
|
||||
* @param 参数
|
||||
* chat_id: string
|
||||
* {
|
||||
"message": "string",
|
||||
}
|
||||
*/
|
||||
const postChatMessage: (chat_id: string, message: string) => Promise<any> = (chat_id, message) => {
|
||||
return postStream(`/api/${prefix}/chat_message/${chat_id}`, { message })
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllAppilcation,
|
||||
getApplication,
|
||||
postApplication,
|
||||
putApplication,
|
||||
postChatOpen,
|
||||
getChatOpen,
|
||||
postChatMessage,
|
||||
delApplication,
|
||||
getApplicationDetail,
|
||||
getApplicationDataset,
|
||||
getAPIKey,
|
||||
getAccessToken
|
||||
getAccessToken,
|
||||
postAppAuthentication,
|
||||
getProfile
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-tooltip effect="dark" content="重新生成" placement="top">
|
||||
<el-button text @click.stop>
|
||||
<AppIcon iconName="VideoPlay"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" content="复制" placement="top">
|
||||
<el-button text @click="copyClick(item?.answer_text)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" content="赞同" placement="top">
|
||||
<el-button text>
|
||||
<AppIcon iconName="app-like"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" content="取消赞同" placement="top">
|
||||
<el-button text>
|
||||
<AppIcon iconName="app-like-color"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" content="反对" placement="top">
|
||||
<el-button text>
|
||||
<AppIcon iconName="app-oppose"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" content="取消反对" placement="top">
|
||||
<el-button text>
|
||||
<AppIcon iconName="app-oppose-color"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
|
||||
defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:data'])
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -64,22 +64,24 @@
|
|||
:inner_suffix="false"
|
||||
></MarkdownRenderer>
|
||||
</el-card>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="item.is_stop && !item.write_ed"
|
||||
@click="startChat(item)"
|
||||
link
|
||||
class="mt-8"
|
||||
>继续</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-else-if="!item.write_ed"
|
||||
@click="stopChat(item)"
|
||||
link
|
||||
class="mt-8"
|
||||
>停止回答</el-button
|
||||
>
|
||||
<div class="flex-between mt-8">
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="item.is_stop && !item.write_ed"
|
||||
@click="startChat(item)"
|
||||
link
|
||||
>继续</el-button
|
||||
>
|
||||
<el-button type="primary" v-else-if="!item.write_ed" @click="stopChat(item)" link
|
||||
>停止回答</el-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- <div v-if="item.write_ed && props.appId">
|
||||
<OperationButton :data="item" />
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -107,6 +109,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, onUpdated, computed } from 'vue'
|
||||
import OperationButton from './OperationButton.vue'
|
||||
import applicationApi from '@/api/application'
|
||||
import { ChatManagement, type chatType } from '@/api/type/application'
|
||||
import { randomId } from '@/utils/utils'
|
||||
|
|
@ -114,7 +117,8 @@ const props = defineProps({
|
|||
data: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
appId: String
|
||||
})
|
||||
|
||||
const scrollDiv = ref()
|
||||
|
|
@ -125,7 +129,7 @@ const chartOpenId = ref('')
|
|||
const chatList = ref<chatType[]>([])
|
||||
|
||||
const isDisabledChart = computed(
|
||||
() => !(inputValue.value && props.data?.name && props.data?.model_id)
|
||||
() => !(inputValue.value && (props.appId || (props.data?.name && props.data?.model_id)))
|
||||
)
|
||||
|
||||
function quickProblemHandel(val: string) {
|
||||
|
|
@ -160,15 +164,27 @@ function getChartOpenId() {
|
|||
dataset_id_list: props.data.dataset_id_list,
|
||||
multiple_rounds_dialogue: props.data.multiple_rounds_dialogue
|
||||
}
|
||||
applicationApi
|
||||
.postChatOpen(obj)
|
||||
.then((res) => {
|
||||
chartOpenId.value = res.data
|
||||
chatMessage()
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
if (props.appId) {
|
||||
applicationApi
|
||||
.getChatOpen(props.appId)
|
||||
.then((res) => {
|
||||
chartOpenId.value = res.data
|
||||
chatMessage()
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
} else {
|
||||
applicationApi
|
||||
.postChatOpen(obj)
|
||||
.then((res) => {
|
||||
chartOpenId.value = res.data
|
||||
chatMessage()
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
function chatMessage() {
|
||||
loading.value = true
|
||||
|
|
@ -188,10 +204,12 @@ function chatMessage() {
|
|||
applicationApi.postChatMessage(chartOpenId.value, problem_text).then(async (response) => {
|
||||
inputValue.value = ''
|
||||
const row = chatList.value.find((item) => item.id === id)
|
||||
|
||||
if (row) {
|
||||
ChatManagement.addChatRecord(row, 50, loading)
|
||||
ChatManagement.write(id)
|
||||
const reader = response.body.getReader()
|
||||
/*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
if (done) {
|
||||
|
|
@ -203,11 +221,14 @@ function chatMessage() {
|
|||
const str = decoder.decode(value, { stream: true })
|
||||
if (str && str.startsWith('data:')) {
|
||||
const content = JSON?.parse(str.replace('data:', ''))?.content
|
||||
|
||||
if (content) {
|
||||
ChatManagement.append(id, content)
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// console
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</el-avatar>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { pinyin } from 'pinyin-pro';
|
||||
import { pinyin } from 'pinyin-pro'
|
||||
import { computed } from 'vue'
|
||||
defineOptions({ name: 'AppAvatar' })
|
||||
const props = defineProps({
|
||||
|
|
@ -26,37 +26,31 @@ const firstUserName = computed(() => {
|
|||
return props.name?.substring(0, 1)
|
||||
})
|
||||
|
||||
function getAvatarColour(name: string) {
|
||||
const charIndex = pinyin.getFullChars(name).charAt(0).toUpperCase().charCodeAt(0) - 65
|
||||
const getAvatarColour = (name: string) => {
|
||||
const colours = [
|
||||
'#ACA9E5',
|
||||
'#BCC934',
|
||||
'#B3CFE8',
|
||||
'#DCDEB5',
|
||||
'#D65A4A',
|
||||
'#E0C78B',
|
||||
'#E59191',
|
||||
'#E99334',
|
||||
'#FF6632',
|
||||
'#F4B7EF',
|
||||
'#F7D407',
|
||||
'#F8BB98',
|
||||
'#2BCBB1',
|
||||
'#3594F1',
|
||||
'#486660',
|
||||
'#4B689F',
|
||||
'#5976F6',
|
||||
'#72B1B2',
|
||||
'#778293',
|
||||
'#7D6624',
|
||||
'#82CBB5',
|
||||
'#837F6A',
|
||||
'#87B087',
|
||||
'#9AC0C4',
|
||||
'#958E55',
|
||||
'#99E4F2'
|
||||
'#3370FF',
|
||||
'#4954E6',
|
||||
'#F54A45',
|
||||
'#00B69D',
|
||||
'#2CA91F',
|
||||
'#98B600',
|
||||
'#F80F80',
|
||||
'#D136D1',
|
||||
'#F01D94',
|
||||
'#7F3BF5',
|
||||
'#8F959E'
|
||||
]
|
||||
return colours[charIndex]
|
||||
let charIndex = name ? pinyin(name).charAt(0).toUpperCase().charCodeAt(0) - 65 : 0
|
||||
|
||||
function getColor() {
|
||||
if (!colours[charIndex]) {
|
||||
charIndex -= 10
|
||||
getColor()
|
||||
}
|
||||
return colours[charIndex]
|
||||
}
|
||||
|
||||
return getColor()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
<div class="card-header">
|
||||
<slot name="header">
|
||||
<div class="title flex align-center">
|
||||
<AppAvatar v-if="!slots.icon && showIcon" class="mr-12" shape="square" :size="32">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
<slot v-else name="icon"> </slot>
|
||||
<slot name="icon">
|
||||
<AppAvatar v-if="showIcon" class="mr-12" shape="square" :size="32">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
</slot>
|
||||
<h4 class="ellipsis-1" style="width: 100%">{{ title }}</h4>
|
||||
</div>
|
||||
</slot>
|
||||
|
|
|
|||
|
|
@ -2,18 +2,10 @@
|
|||
<div class="common-list">
|
||||
<el-scrollbar>
|
||||
<ul v-if="data.length > 0">
|
||||
<li
|
||||
v-if="slots.prefix"
|
||||
@click="clickHandle()"
|
||||
:class="modelValue === undefined || modelValue === null ? 'active' : ''"
|
||||
class="cursor"
|
||||
>
|
||||
<slot name="prefix"> </slot>
|
||||
</li>
|
||||
<template v-for="(item, index) in data" :key="index">
|
||||
<li
|
||||
@click.prevent="clickHandle(item)"
|
||||
:class="modelValue === item ? 'active' : ''"
|
||||
@click.prevent="clickHandle(item, index)"
|
||||
:class="current === index ? 'active' : ''"
|
||||
class="cursor"
|
||||
>
|
||||
<slot :row="item" :index="index"> </slot>
|
||||
|
|
@ -32,8 +24,6 @@ defineOptions({ name: 'CommonList' })
|
|||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
|
||||
data: Array<any>
|
||||
}>(),
|
||||
{
|
||||
|
|
@ -41,11 +31,13 @@ withDefaults(
|
|||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits(['click', 'update:modelValue'])
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
function clickHandle(row?: any) {
|
||||
const current = ref(0)
|
||||
|
||||
function clickHandle(row: any, index: number) {
|
||||
current.value = index
|
||||
emit('click', row)
|
||||
emit('update:modelValue', row)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -308,5 +308,139 @@ export const iconMap: any = {
|
|||
)
|
||||
])
|
||||
}
|
||||
}
|
||||
},
|
||||
'app-restore': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M3.33333 5.3335V13.3335H10V5.3335H3.33333ZM11.3333 4.66683V14.0742C11.3333 14.4015 11.0548 14.6668 10.7111 14.6668H2.62222C2.27858 14.6668 2 14.4015 2 14.0742V4.59276C2 4.26548 2.27858 4.00016 2.62222 4.00016H10.6667C11.0349 4.00016 11.3333 4.29864 11.3333 4.66683ZM13.8047 1.52876C13.9254 1.6494 14 1.81607 14 2.00016V10.3335C14 10.5176 13.8508 10.6668 13.6667 10.6668H13C12.8159 10.6668 12.6667 10.5176 12.6667 10.3335V2.66683H6.33333C6.14924 2.66683 6 2.51759 6 2.3335V1.66683C6 1.48273 6.14924 1.3335 6.33333 1.3335H13.3333C13.5174 1.3335 13.6841 1.40812 13.8047 1.52876Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-copy': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M3.33333 5.3335V13.3335H10V5.3335H3.33333ZM11.3333 4.66683V14.0742C11.3333 14.4015 11.0548 14.6668 10.7111 14.6668H2.62222C2.27858 14.6668 2 14.4015 2 14.0742V4.59276C2 4.26548 2.27858 4.00016 2.62222 4.00016H10.6667C11.0349 4.00016 11.3333 4.29864 11.3333 4.66683ZM13.8047 1.52876C13.9254 1.6494 14 1.81607 14 2.00016V10.3335C14 10.5176 13.8508 10.6668 13.6667 10.6668H13C12.8159 10.6668 12.6667 10.5176 12.6667 10.3335V2.66683H6.33333C6.14924 2.66683 6 2.51759 6 2.3335V1.66683C6 1.48273 6.14924 1.3335 6.33333 1.3335H13.3333C13.5174 1.3335 13.6841 1.40812 13.8047 1.52876Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-like': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M2.00518 14.6608H0.666612C0.666097 14.6874 0.666707 5.33317 0.666612 5.29087H2.00518C2.00004 5.33317 1.98014 14.6874 2.00518 14.6608ZM9.70096 5.28984H12.5717C14.5687 5.28984 15.0274 7.05264 14.5687 8.37353L12.5717 13.6308C12.4029 14.2423 11.8409 14.6665 11.1995 14.6665H3.33882C3.154 14.6665 3.00418 14.5167 3.00418 14.3319V5.62448C3.00418 5.43966 3.154 5.28984 3.33882 5.28984H4.02656C4.24449 5.28984 4.44877 5.18374 4.5741 5.00545L7.35254 1.05296C7.5406 0.753754 8.04824 0.52438 8.5893 0.770777C9.40089 1.14037 10.3724 1.94718 10.3724 3.28394C10.3724 3.78809 10.1486 4.45673 9.70096 5.28984ZM12.5717 6.62841H7.46215L8.52183 4.65626C8.87422 4.00045 9.03388 3.52351 9.03388 3.28394C9.03388 2.89556 8.9524 2.45627 8.25544 2.09612L5.26934 6.34402C5.14401 6.5223 4.93973 6.62841 4.72181 6.62841H4.34275V13.3279H11.1995C11.2411 13.3279 11.2734 13.3035 11.2813 13.2747L11.298 13.2142L13.3098 7.91815C13.5743 7.13902 13.3105 6.62841 12.5717 6.62841Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-like-color': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
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: '#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: '#FFC60A'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-oppose': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M2.00518 1.28008H0.666616C0.666616 1.33341 0.666504 10.6667 0.666616 10.65H2.00518C1.99984 10.6667 1.99984 1.33341 2.00518 1.28008ZM9.70097 10.6511H12.5717C14.5687 10.6511 15.0274 8.88828 14.5687 7.56739L12.5717 2.3101C12.4029 1.69862 11.8409 1.27441 11.1996 1.27441H3.33883C3.15401 1.27441 3.00418 1.42424 3.00418 1.60906V10.3164C3.00418 10.5013 3.15401 10.6511 3.33883 10.6511H4.02656C4.24449 10.6511 4.44877 10.7572 4.5741 10.9355L7.35254 14.888C7.5406 15.1872 8.04825 15.4165 8.58931 15.1701C9.40089 14.8005 10.3724 13.9937 10.3724 12.657C10.3724 12.1528 10.1486 11.4842 9.70097 10.6511ZM12.5717 9.31251H7.46216L8.52184 11.2847C8.87422 11.9405 9.03388 12.4174 9.03388 12.657C9.03388 13.0454 8.95241 13.4846 8.25545 13.8448L5.26935 9.5969C5.14402 9.41861 4.93974 9.31251 4.72181 9.31251H4.34275V2.61298H11.1996C11.2411 2.61298 11.2734 2.63737 11.2813 2.6662L11.298 2.72673L13.3098 8.02277C13.5743 8.8019 13.3105 9.31251 12.5717 9.31251Z',
|
||||
fill: 'currentColor'
|
||||
}),
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
'app-oppose-color': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 16 16',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M9.70106 10.7102H12.5718C14.5688 10.7102 15.0275 8.94736 14.5688 7.62647L12.5718 2.36918C12.403 1.7577 11.841 1.3335 11.1996 1.3335H3.33891C3.1541 1.3335 3.00427 1.48332 3.00427 1.66814V10.3755C3.00427 10.5603 3.1541 10.7102 3.33891 10.7102H4.02665C4.24458 10.7102 4.44886 10.8163 4.57419 10.9945L7.35263 14.947C7.54069 15.2462 8.04834 15.4756 8.58939 15.2292C9.40098 14.8596 10.3725 14.0528 10.3725 12.7161C10.3725 12.2119 10.1487 11.5433 9.70106 10.7102Z',
|
||||
fill: '#F54A45'
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M2.00004 1.3335H0.661473C0.661473 1.3335 0.660982 10.7764 0.661473 10.7035H2.00001C1.99469 10.6868 1.9947 1.38674 2.00004 1.3335Z',
|
||||
fill: '#F54A45'
|
||||
})
|
||||
]
|
||||
)
|
||||
])
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,19 @@
|
|||
<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">
|
||||
<div class="flex align-center">
|
||||
<AppAvatar
|
||||
v-if="isApplication"
|
||||
:name="item.name"
|
||||
pinyinColor
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
:size="24"
|
||||
/>
|
||||
<AppAvatar v-else-if="isDataset" 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>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@
|
|||
<div v-if="!menu.meta || !menu.meta.hidden" class="sidebar-item">
|
||||
<el-menu-item ref="subMenu" :index="menu.path" popper-class="sidebar-popper">
|
||||
<template #title>
|
||||
<AppIcon
|
||||
v-if="menu.meta && menu.meta.icon"
|
||||
:iconName="menu.meta.icon"
|
||||
class="sidebar-icon"
|
||||
/>
|
||||
<AppIcon v-if="menu.meta && menu.meta.icon" :iconName="menuIcon" class="sidebar-icon" />
|
||||
<span v-if="menu.meta && menu.meta.title">{{ menu.meta.title }}</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
|
@ -14,11 +10,20 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { type RouteRecordRaw } from 'vue-router'
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
menu: RouteRecordRaw
|
||||
activeMenu: any
|
||||
}>()
|
||||
const menuIcon = computed(() => {
|
||||
if (props.activeMenu === props.menu.path) {
|
||||
return props.menu.meta?.iconActive || props.menu?.meta?.icon
|
||||
} else {
|
||||
return props.menu?.meta?.icon
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
v-for="(menu, index) in subMenuList"
|
||||
:key="index"
|
||||
:menu="menu"
|
||||
:activeMenu="activeMenu"
|
||||
>
|
||||
</sidebar-item>
|
||||
</el-menu>
|
||||
|
|
|
|||
|
|
@ -7,14 +7,13 @@ import {
|
|||
type RouteRecordRaw,
|
||||
type RouteRecordName
|
||||
} from 'vue-router'
|
||||
import useStore from '@/stores';
|
||||
import useStore from '@/stores'
|
||||
import { routes } from '@/router/routes'
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: routes
|
||||
})
|
||||
|
||||
|
||||
// 路由前置拦截器
|
||||
router.beforeEach(
|
||||
async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||
|
|
@ -22,8 +21,8 @@ router.beforeEach(
|
|||
next()
|
||||
return
|
||||
}
|
||||
const { user } = useStore();
|
||||
const notAuthRouteNameList = ['register', 'login', 'forgot_password', 'reset_password']
|
||||
const { user } = useStore()
|
||||
const notAuthRouteNameList = ['register', 'login', 'forgot_password', 'reset_password', 'Chat']
|
||||
|
||||
if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
|
||||
const token = user.getToken()
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ const applicationRouter = {
|
|||
path: 'overview',
|
||||
name: 'AppOverview',
|
||||
meta: {
|
||||
icon: 'Document',
|
||||
icon: 'app-all-menu',
|
||||
iconActive: 'app-all-menu-active',
|
||||
title: '概览',
|
||||
active: 'overview',
|
||||
parentPath: '/application/:id',
|
||||
|
|
|
|||
|
|
@ -45,6 +45,20 @@ const useApplicationStore = defineStore({
|
|||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
async asyncAppAuthentication(token: string, loading?: Ref<boolean>) {
|
||||
return new Promise((resolve, reject) => {
|
||||
applicationApi
|
||||
.postAppAuthentication(token, loading)
|
||||
.then((res) => {
|
||||
localStorage.setItem('accessToken', res.data)
|
||||
resolve(res)
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import type { User } from '@/api/type/user'
|
|||
import UserApi from '@/api/user'
|
||||
|
||||
export interface userStateTypes {
|
||||
userType: number // 1 系统操作者 2 对话用户
|
||||
userInfo: User | null
|
||||
token: any
|
||||
}
|
||||
|
|
@ -10,6 +11,7 @@ export interface userStateTypes {
|
|||
const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
state: (): userStateTypes => ({
|
||||
userType: 1,
|
||||
userInfo: null,
|
||||
token: ''
|
||||
}),
|
||||
|
|
@ -18,7 +20,9 @@ const useUserStore = defineStore({
|
|||
if (this.token) {
|
||||
return this.token
|
||||
}
|
||||
return localStorage.getItem('token')
|
||||
return this.userType === 1
|
||||
? localStorage.getItem('token')
|
||||
: localStorage.getItem('accessToken')
|
||||
},
|
||||
|
||||
getPermissions() {
|
||||
|
|
@ -35,7 +39,9 @@ const useUserStore = defineStore({
|
|||
return ''
|
||||
}
|
||||
},
|
||||
|
||||
changeUserType(num: number) {
|
||||
this.userType = num
|
||||
},
|
||||
async profile() {
|
||||
return UserApi.profile().then((ok) => {
|
||||
this.userInfo = ok.data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import Clipboard from 'vue-clipboard3'
|
||||
import { MsgSuccess, MsgError } from '@/utils/message'
|
||||
/*
|
||||
复制粘贴
|
||||
*/
|
||||
export async function copyClick(info: string) {
|
||||
const { toClipboard } = Clipboard()
|
||||
try {
|
||||
await toClipboard(info)
|
||||
MsgSuccess('复制成功')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
MsgError('复制失败')
|
||||
}
|
||||
}
|
||||
|
|
@ -49,3 +49,4 @@ export function realatedObject(list: any, val: string | number, attr: string) {
|
|||
const filterData: any = list.filter((item: any) => item[attr] === val)?.[0]
|
||||
return filterData || null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,14 @@
|
|||
<h4 class="title-decoration-1 mb-16">应用信息</h4>
|
||||
<el-card shadow="never" class="overview-card">
|
||||
<div class="title flex align-center">
|
||||
<AppAvatar class="mr-12" shape="square" :size="32">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
<AppAvatar
|
||||
v-if="detail?.name"
|
||||
:name="detail?.name"
|
||||
pinyinColor
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
:size="32"
|
||||
/>
|
||||
<h4 class="ellipsis-1">{{ detail?.name }}</h4>
|
||||
<div class="ml-8" v-if="detail">
|
||||
<el-tag v-if="detail?.status" class="success-tag">运行中</el-tag>
|
||||
|
|
@ -24,8 +29,8 @@
|
|||
{{ shareUrl }}
|
||||
</span>
|
||||
|
||||
<el-button type="primary" text>
|
||||
<el-icon style="font-size: 13px"><CopyDocument /></el-icon>
|
||||
<el-button type="primary" text @click="copyClick(shareUrl)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
|
|
@ -37,14 +42,14 @@
|
|||
</span>
|
||||
|
||||
<el-button type="primary" text>
|
||||
<el-icon style="font-size: 13px"><CopyDocument /></el-icon>
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<span class="vertical-middle lighter"> API Secret: ************** </span>
|
||||
<span>
|
||||
<el-button type="primary" text>
|
||||
<el-icon style="font-size: 13px"><CopyDocument /></el-icon>
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</span>
|
||||
<span>
|
||||
|
|
@ -56,12 +61,12 @@
|
|||
</el-col> -->
|
||||
</el-row>
|
||||
<div class="mt-16">
|
||||
<el-button type="primary"> 演示 </el-button>
|
||||
<el-button type="primary"><a :href="shareUrl" target="_blank">演示</a></el-button>
|
||||
<el-button @click="openDialog"> 嵌入第三方 </el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<EmbedDialog ref="EmbedDialogRef" />
|
||||
<EmbedDialog ref="EmbedDialogRef"/>
|
||||
</LayoutContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
@ -69,6 +74,7 @@ import { reactive, ref, watch, onMounted } from 'vue'
|
|||
import { useRouter, useRoute } from 'vue-router'
|
||||
import applicationApi from '@/api/application'
|
||||
import EmbedDialog from './components/EmbedDialog.vue'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import useStore from '@/stores'
|
||||
const { application } = useStore()
|
||||
const router = useRouter()
|
||||
|
|
@ -76,6 +82,7 @@ const route = useRoute()
|
|||
|
||||
const EmbedDialogRef = ref()
|
||||
const shareUrl = ref('')
|
||||
const accessToken = ref('')
|
||||
const detail = ref<any>(null)
|
||||
const apiKey = ref<any>(null)
|
||||
const {
|
||||
|
|
@ -85,10 +92,11 @@ const {
|
|||
const loading = ref(false)
|
||||
|
||||
function openDialog() {
|
||||
EmbedDialogRef.value.open()
|
||||
EmbedDialogRef.value.open(accessToken.value)
|
||||
}
|
||||
function getAccessToken() {
|
||||
application.asyncGetAccessToken(id, loading).then((res) => {
|
||||
accessToken.value = res?.data?.access_token
|
||||
shareUrl.value = application.location + res?.data?.access_token
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-dialog title="添加关联数据集" v-model="dialogVisible" width="600">
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div class="my-header flex">
|
||||
<h4 :id="titleId" :class="titleClass">添加关联数据集</h4>
|
||||
<el-button link class="ml-16" @click="refresh">
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
<div class="code border-t p-16">
|
||||
<div class="flex-between">
|
||||
<span class="bold">复制以下代码进行嵌入</span>
|
||||
<el-button text>
|
||||
<el-icon style="font-size: 13px"><CopyDocument /></el-icon>
|
||||
<el-button text @click="copyClick(source1)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-8">
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
<div class="code border-t p-16">
|
||||
<div class="flex-between">
|
||||
<span class="bold">复制以下代码进行嵌入</span>
|
||||
<el-button text>
|
||||
<el-icon style="font-size: 13px"><CopyDocument /></el-icon>
|
||||
<el-button text @click="copyClick(source2)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-8">
|
||||
|
|
@ -38,48 +38,45 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import useStore from '@/stores'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array<any>,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
const { application } = useStore()
|
||||
|
||||
const emit = defineEmits(['addData'])
|
||||
|
||||
const loading = ref(false)
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
const source1 = ref(`<iframe
|
||||
src="https://udify.app/chatbot/ASkyzvhN5Z1h6k7g"
|
||||
|
||||
const source1 = ref('')
|
||||
|
||||
const source2 = ref('')
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
source1.value = ''
|
||||
source2.value = ''
|
||||
}
|
||||
})
|
||||
|
||||
const open = (val: string) => {
|
||||
source1.value = `<iframe
|
||||
src="${application.location + val}"
|
||||
style="width: 100%; height: 100%;"
|
||||
frameborder="0"
|
||||
allow="microphone">
|
||||
</iframe>
|
||||
`)
|
||||
|
||||
const source2 = ref(`<script> window.difyChatbotConfig = {
|
||||
token: '85FfbbzTpXzzr40X'
|
||||
`
|
||||
source2.value = `<script> window.difyChatbotConfig = {
|
||||
token: "${val}"
|
||||
}
|
||||
<\/script>
|
||||
<script src="https://udify.app/embed.min.js"
|
||||
id="85FfbbzTpXzzr40X"
|
||||
id="${val}"
|
||||
defer>
|
||||
<\/script>
|
||||
`)
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const open = (checked: any) => {
|
||||
`
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const submitHandle = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@
|
|||
class="application-card cursor"
|
||||
@click="router.push({ path: `/application/${item.id}/overview` })"
|
||||
>
|
||||
<template #icon>
|
||||
<AppAvatar
|
||||
v-if="item.name"
|
||||
:name="item.name"
|
||||
pinyinColor
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
:size="32"
|
||||
/>
|
||||
</template>
|
||||
<div class="status-tag">
|
||||
<el-tag v-if="item.status" class="success-tag">运行中</el-tag>
|
||||
<el-tag v-else class="warning-tag">已停用</el-tag>
|
||||
|
|
@ -44,7 +54,7 @@
|
|||
<template #footer>
|
||||
<div class="footer-content">
|
||||
<el-tooltip effect="dark" content="演示" placement="top">
|
||||
<el-button text @click.stop>
|
||||
<el-button text @click.stop @click="getAccessToken(item.id)">
|
||||
<AppIcon iconName="app-view"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
|
|
@ -71,7 +81,9 @@
|
|||
<span>运行中</span>
|
||||
<!-- <el-switch v-model="item.status" @change="changeState($event, item)" /> -->
|
||||
</div>
|
||||
<el-dropdown-item divided @click="deleteApplication(item)">删除</el-dropdown-item>
|
||||
<el-dropdown-item divided @click="deleteApplication(item)"
|
||||
>删除</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
|
@ -88,8 +100,10 @@
|
|||
import { ref, onMounted, reactive } from 'vue'
|
||||
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 useStore from '@/stores'
|
||||
const { application } = useStore()
|
||||
const router = useRouter()
|
||||
|
||||
const loading = ref(false)
|
||||
|
|
@ -109,29 +123,31 @@ function search() {
|
|||
getList()
|
||||
}
|
||||
|
||||
function deleteApplication(row: any) {
|
||||
MsgConfirm(
|
||||
`是否删除应用:${row.name} ?`,
|
||||
`删除后该应用将不再提供服务,请谨慎操作。`,
|
||||
{
|
||||
confirmButtonText: '删除',
|
||||
confirmButtonClass: 'danger'
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
loading.value = true
|
||||
applicationApi
|
||||
.delApplication(row.id)
|
||||
.then(() => {
|
||||
MsgSuccess('删除成功')
|
||||
getList()
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
function getAccessToken(id: string) {
|
||||
application.asyncGetAccessToken(id, loading).then((res) => {
|
||||
window.open(application.location + res?.data?.access_token)
|
||||
})
|
||||
}
|
||||
|
||||
function deleteApplication(row: any) {
|
||||
MsgConfirm(`是否删除应用:${row.name} ?`, `删除后该应用将不再提供服务,请谨慎操作。`, {
|
||||
confirmButtonText: '删除',
|
||||
confirmButtonClass: 'danger'
|
||||
})
|
||||
.then(() => {
|
||||
loading.value = true
|
||||
applicationApi
|
||||
.delApplication(row.id)
|
||||
.then(() => {
|
||||
MsgSuccess('删除成功')
|
||||
getList()
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// function changeState(bool: Boolean, row: any) {
|
||||
// const obj = {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,45 @@
|
|||
<template>
|
||||
<div class="chat">
|
||||
<div class="chat__header">
|
||||
<div class="chat-width"><h2 class="ml-24">111</h2></div>
|
||||
<div class="chat-width">
|
||||
<h2 class="ml-24">{{ applicationDetail?.name }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat__main chat-width" v-loading="loading">
|
||||
<AiDialog :data="applicationDetail" :appId="applicationDetail?.id"></AiDialog>
|
||||
</div>
|
||||
<div class="chat__main chat-width"><AiDialog></AiDialog></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import AiDialog from '@/components/ai-dialog/index.vue'
|
||||
import applicationApi from '@/api/application'
|
||||
import useStore from '@/stores'
|
||||
const route = useRoute()
|
||||
const {
|
||||
params: { accessToken }
|
||||
} = route as any
|
||||
|
||||
const { application, user } = useStore()
|
||||
|
||||
const loading = ref(false)
|
||||
const applicationDetail = ref<any>({})
|
||||
|
||||
function getAccessToken(token: string) {
|
||||
application.asyncAppAuthentication(token, loading).then((res) => {
|
||||
getProfile()
|
||||
})
|
||||
}
|
||||
function getProfile() {
|
||||
applicationApi.getProfile(loading).then((res) => {
|
||||
applicationDetail.value = res.data
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
user.changeUserType(2)
|
||||
getAccessToken(accessToken)
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.chat {
|
||||
|
|
|
|||
|
|
@ -3,33 +3,31 @@
|
|||
<div class="template-manage flex main-calc-height">
|
||||
<div class="template-manage__left p-8 border-r">
|
||||
<h4 class="p-16">供应商</h4>
|
||||
|
||||
<common-list
|
||||
v-model="active_provider"
|
||||
:data="provider_list"
|
||||
class="mt-8"
|
||||
v-loading="loading"
|
||||
@click="clickListHandle"
|
||||
>
|
||||
<template #prefix>
|
||||
<div class="flex">
|
||||
<template #default="{ row, index }">
|
||||
<div class="flex" v-if="index === 0">
|
||||
<AppIcon
|
||||
style="height: 24px; width: 24px"
|
||||
class="mr-8"
|
||||
:iconName="active_provider ? 'app-all-menu' : 'app-all-menu-active'"
|
||||
style="height: 20px; width: 20px"
|
||||
:iconName="active_provider === row ? 'app-all-menu-active' : 'app-all-menu'"
|
||||
></AppIcon>
|
||||
<span>全部模型</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<div class="flex">
|
||||
<span :innerHTML="row.icon" alt="" style="height: 24px; width: 24px" class="mr-8" />
|
||||
<div class="flex" v-else>
|
||||
<span :innerHTML="row.icon" alt="" style="height: 20px; width: 20px" class="mr-8" />
|
||||
<span>{{ row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</common-list>
|
||||
</div>
|
||||
<div class="template-manage__right p-24" v-loading="list_model_loading">
|
||||
<h3 v-if="active_provider">{{ active_provider.name }}</h3>
|
||||
<h3 v-else>全部模型</h3>
|
||||
<h3>{{ active_provider?.name }}</h3>
|
||||
<div class="flex-between mt-8">
|
||||
<el-button type="primary" @click="openCreateModel(active_provider)">创建模型</el-button>
|
||||
<el-input
|
||||
|
|
@ -66,6 +64,12 @@ import { splitArray } from '@/utils/common'
|
|||
import CreateModel from '@/views/template/component/CreateModel.vue'
|
||||
import SelectProvider from '@/views/template/component/SelectProvider.vue'
|
||||
|
||||
const allObj = {
|
||||
icon: '',
|
||||
provider: '',
|
||||
name: '全部模型'
|
||||
}
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const active_provider = ref<Provider>()
|
||||
|
|
@ -81,8 +85,13 @@ const model_split_list = computed(() => {
|
|||
const createModelRef = ref<InstanceType<typeof CreateModel>>()
|
||||
const selectProviderRef = ref<InstanceType<typeof SelectProvider>>()
|
||||
|
||||
const clickListHandle = (item: Provider) => {
|
||||
active_provider.value = item
|
||||
list_model()
|
||||
}
|
||||
|
||||
const openCreateModel = (provider?: Provider) => {
|
||||
if (provider) {
|
||||
if (provider && provider.provider) {
|
||||
createModelRef.value?.open(provider)
|
||||
} else {
|
||||
selectProviderRef.value?.open()
|
||||
|
|
@ -90,19 +99,17 @@ const openCreateModel = (provider?: Provider) => {
|
|||
}
|
||||
|
||||
const list_model = () => {
|
||||
const params = active_provider.value ? { provider: active_provider.value.provider } : {}
|
||||
const params = active_provider.value?.provider ? { provider: active_provider.value.provider } : {}
|
||||
ModelApi.getModel({ ...model_search_form.value, ...params }, list_model_loading).then((ok) => {
|
||||
model_list.value = ok.data
|
||||
})
|
||||
}
|
||||
|
||||
watch(active_provider, list_model, {
|
||||
immediate: true
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
ModelApi.getProvider(loading).then((ok) => {
|
||||
provider_list.value = [...ok.data]
|
||||
active_provider.value = allObj
|
||||
provider_list.value = [allObj, ...ok.data]
|
||||
list_model()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue