feat: 添加 Prompt 模板和 Prompt 商店支持 (#268)

* feat: 添加Prompt模板和Prompt商店支持

* feat: well done

---------

Co-authored-by: Redon <790348264@qq.com>
This commit is contained in:
Nothing1024
2023-03-11 16:09:52 +08:00
committed by GitHub
parent 514ab7e9e4
commit 00ade41a76
8 changed files with 525 additions and 11 deletions

View File

@@ -1,7 +1,8 @@
<script setup lang='ts'>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { NButton, NInput, useDialog, useMessage } from 'naive-ui'
import { storeToRefs } from 'pinia'
import { NAutoComplete, NButton, NInput, useDialog, useMessage } from 'naive-ui'
import html2canvas from 'html2canvas'
import { Message } from './components'
import { useScroll } from './hooks/useScroll'
@@ -11,7 +12,7 @@ import { useUsingContext } from './hooks/useUsingContext'
import HeaderComponent from './components/Header/index.vue'
import { HoverButton, SvgIcon } from '@/components/common'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { useChatStore } from '@/store'
import { useChatStore, usePromptStore } from '@/store'
import { fetchChatAPIProcess } from '@/api'
import { t } from '@/locales'
@@ -40,6 +41,11 @@ const conversationList = computed(() => dataSources.value.filter(item => (!item.
const prompt = ref<string>('')
const loading = ref<boolean>(false)
// 添加PromptStore
const promptStore = usePromptStore()
// 使用storeToRefs保证store修改后联想部分能够重新渲染
const { promptList: promptTemplate } = storeToRefs<any>(promptStore)
function handleSubmit() {
onConversation()
}
@@ -394,6 +400,31 @@ function handleStop() {
}
}
// 可优化部分
// 搜索选项计算这里使用value作为索引项所以当出现重复value时渲染异常(多项同时出现选中效果)
// 理想状态下其实应该是key作为索引项,但官方的renderOption会出现问题所以就需要value反renderLabel实现
const searchOptions = computed(() => {
if (prompt.value.startsWith('/')) {
return promptTemplate.value.filter((item: { key: string }) => item.key.toLowerCase().includes(prompt.value.substring(1).toLowerCase())).map((obj: { value: any }) => {
return {
label: obj.value,
value: obj.value,
}
})
}
else {
return []
}
})
// value反渲染key
const renderOption = (option: { label: string }) => {
for (const i of promptTemplate.value) {
if (i.value === option.label)
return [i.key]
}
return []
}
const placeholder = computed(() => {
if (isMobile.value)
return t('chat.placeholderMobile')
@@ -490,13 +521,14 @@ onUnmounted(() => {
<SvgIcon icon="ri:chat-history-line" />
</span>
</HoverButton>
<NInput
v-model:value="prompt"
type="textarea"
:autosize="{ minRows: 1, maxRows: 2 }"
:placeholder="placeholder"
@keypress="handleEnter"
/>
<NAutoComplete v-model:value="prompt" :options="searchOptions" :render-label="renderOption">
<template #default="{ handleInput, handleBlur, handleFocus }">
<NInput
v-model:value="prompt" type="textarea" :placeholder="placeholder"
:autosize="{ minRows: 1, maxRows: 2 }" @input="handleInput" @focus="handleFocus" @blur="handleBlur" @keypress="handleEnter"
/>
</template>
</NAutoComplete>
<NButton type="primary" :disabled="buttonDisabled" @click="handleSubmit">
<template #icon>
<span class="dark:text-black">

View File

@@ -1,16 +1,18 @@
<script setup lang='ts'>
import type { CSSProperties } from 'vue'
import { computed, watch } from 'vue'
import { computed, ref, watch } from 'vue'
import { NButton, NLayoutSider } from 'naive-ui'
import List from './List.vue'
import Footer from './Footer.vue'
import { useAppStore, useChatStore } from '@/store'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { PromptStore } from '@/components/common'
const appStore = useAppStore()
const chatStore = useChatStore()
const { isMobile } = useBasicLayout()
const show = ref(false)
const collapsed = computed(() => appStore.siderCollapsed)
@@ -75,6 +77,11 @@ watch(
<div class="flex-1 min-h-0 pb-4 overflow-hidden">
<List />
</div>
<div class="p-4">
<NButton block @click="show = true">
Prompt Store
</NButton>
</div>
</main>
<Footer />
</div>
@@ -82,4 +89,5 @@ watch(
<template v-if="isMobile">
<div v-show="!collapsed" class="fixed inset-0 z-40 bg-black/40" @click="handleUpdateCollapsed" />
</template>
<PromptStore v-model:visible="show" />
</template>