master
ihzero 2023-08-17 13:56:16 +08:00
parent a747231358
commit 687fa6cffb
6 changed files with 163 additions and 64 deletions

View File

@ -11,6 +11,14 @@ body {
height: 100%;
width: 100%;
}
.van-button--primary{
background-color: #3662FE !important;
}
.van-floating-bubble{
background: transparent !important;
width: 140px !important;
height: 140px !important;
}
::-webkit-scrollbar {
width: 7px;

View File

@ -0,0 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1692247991456" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="7389" xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="200">
<path
d="M513 19.7c-272.9 0-495 222.1-495 495 0 86 22.4 170.6 64.7 244.9 8.6 15.1-4.4 43.8-18.3 74.2-17.9 39.5-25.1 59.9-17.7 68.5 2.2 2.9 7.3 4.4 15.5 4.4 14.5 0 35.7-4.7 56.3-9.2 21.6-4.8 42.1-9.3 56.9-9.3 8.7 0 14.5 1.5 18.3 4.8 89.1 75.2 202.5 116.7 319.3 116.7 272.9 0 495-222 495-495 0-272.9-222-495-495-495z m0 922.7c-100.9 0-198.9-35.8-275.8-100.8-16.1-13.6-37-20.6-61.8-20.6-10.8 0-22.1 1.3-33.7 3.2 11.9-32.1 17.8-65.8-0.5-97.9-36.6-64.1-55.9-137.3-55.9-211.6C85.3 278.9 277.2 87 513 87c235.9 0 427.8 191.9 427.8 427.7 0 235.8-191.9 427.7-427.8 427.7z"
fill="currentColor" p-id="7390"></path>
<path
d="M445.2 323.5c18.5 0 33.6 15.1 33.6 33.6v315.2c0 18.5-15.1 33.6-33.6 33.6s-33.6-15.1-33.6-33.6V357.1c-0.1-18.5 15.1-33.6 33.6-33.6zM580.9 373.6c18.5 0 33.6 15.1 33.6 33.6v215c0 18.5-15.1 33.6-33.6 33.6s-33.6-15.1-33.6-33.6v-215c0-18.5 15.2-33.6 33.6-33.6zM716.7 449.3c18.5 0 33.6 15.1 33.6 33.6v63.5c0 18.5-15.1 33.6-33.6 33.6s-33.6-15.1-33.6-33.6v-63.5c0-18.4 15.1-33.6 33.6-33.6zM309.4 449.3c18.5 0 33.6 15.1 33.6 33.6v63.5c0 18.5-15.1 33.6-33.6 33.6s-33.6-15.1-33.6-33.6v-63.5c-0.1-18.4 15.1-33.6 33.6-33.6z"
fill="currentColor" p-id="7391"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,79 @@
<template>
<div>
<van-floating-bubble
v-model:offset="offsetc"
axis="xy"
icon="chat"
magnetic="x"
:gap="0"
@click="onClick"
@offset-change="onOffsetChange"
>
<div ref="floatref" class="w-full h-full flex items-center justify-center">
<div class="ai-float-btn">
<SvgIcon class="text-white" name="生活助手"></SvgIcon>
</div>
</div>
</van-floating-bubble>
<van-popup teleport="body" v-model:show="show">
<div class="relative">
<div class="absolute right-20px top-30px">
<SvgIcon @click="show=false" class="text-white" name="close"></SvgIcon>
</div>
<AiAssistant :content="content"></AiAssistant>
</div>
</van-popup>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRect } from '@vant/use'
import AiAssistant from './ai-assistant.vue'
const floatref = ref(null)
const props = defineProps({
offset: {
type: Object,
default: null,
},
content: {
type: String,
default: '',
},
})
const offsetc = ref({ x: 0, y: 0 })
const show = ref(false)
const onOffsetChange = (offset) => {
console.log(offset)
}
const setOffset = () => {
const { offset } = props
const { width,height } = useRect(floatref.value)
offsetc.value = {
x: offset?.x ?? window.innerWidth - width,
y: offset?.y ?? height,
}
}
const onClick = () => {
show.value = true
}
onMounted(() => {
setOffset()
})
</script>
<style lang="scss">
.ai-float {
background: #3662fe;
box-shadow: 0px 12px 26px 0px rgba(32, 69, 201, 0.86);
}
.ai-float-btn {
width: 94px;
height: 94px;
background: #3662fe;
box-shadow: 0px 12px 26px 0px rgba(32, 69, 201, 0.86);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@ -1,28 +1,16 @@
<template>
<div class="fixed w-86 h-full z-999" :style="styleObj">
<!-- <vue-draggable-resizable
:x="0"
:y="0"
:z="999"
:resizable="true"
w="auto"
h="auto"
> -->
<div class="w-86 bg-[#161718] p-3" ref="floatWindow">
<div class="w-full z-999" :style="styleObj">
<div class="w-full bg-[#161718] p-28px" ref="floatWindow">
<div class="flex text-white items-center justify-between">
<div class="flex items-center">
<Avatar />
<span class="font-bold text-lg ml-4">海兔AI智慧助理</span>
<span class="font-bold text-27px ml-26px">海兔AI智慧助理</span>
</div>
<SvgIcon
class="text-white text-xl cursor-pointer"
name="close"
></SvgIcon>
</div>
<div class="border-2px border-[#A6A8AF] p-4 mt-4">
<div class="grid grid-cols-3 gap-x-2.5 options">
<div class="border-1px border-[#A6A8AF] p-32px mt-30px">
<div class="grid grid-cols-3 gap-x-21px options">
<div
class="border-2px border-[#414548] h-6.5 text-center text-sm leading-6.5 text-white cursor-pointer"
class="border-1px border-[#414548] h-52px text-center text-27px leading-52px text-white cursor-pointer"
:class="{ active: optionIndex === index }"
@click="changeOption(index)"
v-for="(item, index) in options"
@ -31,30 +19,32 @@
{{ item.name }}
</div>
</div>
<div class="w-full h-2px bg-[#3662FE] my-2.5"></div>
<div class="w-full h-4px bg-[#3662FE] my-20px"></div>
<div class="flex justify-end">
<SvgIcon
v-if="loading"
@click="handleStop"
class="text-white text-xl ml-2 cursor-pointer"
class="text-white text-44px ml-20px cursor-pointer"
name="pause"
></SvgIcon>
<SvgIcon class="text-white text-xl ml-2" name="right-arrow"></SvgIcon>
<SvgIcon
class="text-white text-44px ml-20px"
name="right-arrow"
></SvgIcon>
</div>
<div class="mt-5 h-97 -mx-4">
<ScrollContainer ref="scrollRefAi">
<div class="px-4">
<div class="text-base text-white opacity-40 leading-6">
<div class="mt-10px h-600px">
<ScrollContainer class="!h-full" ref="scrollRefAi">
<div class="px-0">
<div class="text-27px text-white opacity-40 leading-34px">
<div class="text-center" v-if="contentLoading">
<a-spin size="small" />
<van-loading type="spinner" size="24"/>
</div>
<div v-else>
{{ contenText }}
</div>
<!-- 大自然是人类赖以生存发展的基本条件尊重自然顺应自然保护自然是全面建设社会主义现代化国家的内在要求大自然是人类赖以生存发展的基本条件尊重自然顺应自然保护自然是全面建设社会主义现代化国家是全面建设社会主义现代化国家的内在要求 -->
</div>
<Message
class="my-4"
class="my-20px"
v-for="(item, index) in dataSources"
:key="index"
:text="item.text"
@ -64,31 +54,30 @@
</div>
</ScrollContainer>
</div>
<div class="flex">
<a-input
<div class="flex border-1px border-[#414548] h-88px mt-20px">
<van-field
@pressEnter="sendMessage"
v-model:value="prompt"
v-model="prompt"
size="small"
class="flex-1 text-sm rounded-r-none rounded-4px bg-[#414548] bg-opacity-40 text-white placeholder-[#FFFFFF40] border-[#414548]"
:border="false"
class="cu-field-ai"
placeholder="向我提问有关文本的任何问题"
></a-input>
<a-button
></van-field>
<van-button
@click="sendMessage"
type="primary"
class="rounded-r-4px rounded-l-none px-6 h-full !w-19"
class="!rounded-r-4px !rounded-l-none px-6 h-full !w-155px"
>
<template #icon>
<SvgIcon class="text-white text-xl" name="send"></SvgIcon>
<SvgIcon class="text-white text-34px" name="send"></SvgIcon>
</template>
</a-button>
</van-button>
</div>
<div class="opacity-40 text-sm text-center mt-4">
<div class="opacity-40 text-27px text-center mt-40px">
文案仅供参考使用前请核实风险自负
</div>
</div>
</div>
<!-- </vue-draggable-resizable> -->
</div>
</template>
@ -100,8 +89,6 @@ import { ref, computed, nextTick } from 'vue'
import http from '@/io/request'
import { v4 as uuidv4 } from 'uuid'
import { useAiChat } from '@/stores/aichat'
import VueDraggableResizable from 'vue-draggable-resizable/src/components/vue-draggable-resizable.vue'
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
const props = defineProps({
top: {
type: String,
@ -183,7 +170,7 @@ const changeOption = (index) => {
autoMessage()
}
const currentOption = computed(() => {
if(optionIndex.value === null) return null
if (optionIndex.value === null) return null
return options[optionIndex.value] ?? null
})
@ -193,11 +180,13 @@ const dataSources = computed(() => {
const prompt = ref('')
const autoMessage = async ()=>{
const message = replacePlaceholder(currentOption.value.value, truncateRichText(props.content, 4000))
const autoMessage = async () => {
const message = replacePlaceholder(
currentOption.value.value,
truncateRichText(props.content, 4000)
)
if(loading.value) return
if (loading.value) return
contentLoading.value = true
loading.value = true
try {
@ -233,26 +222,24 @@ const autoMessage = async ()=>{
}
const errorMessage = error?.errmsg ?? '好像出错了,请稍后再试。'
contenText.value = errorMessage
}finally{
} finally {
contentLoading.value = false
loading.value = false
}
}
function truncateRichText(richText, maxLength) {
//
const plainText = richText.replace(/<[^>]+>/g, '');
const plainText = richText.replace(/<[^>]+>/g, '')
// maxLength
const truncatedText = plainText.substring(0, maxLength);
const truncatedText = plainText.substring(0, maxLength)
return truncatedText;
return truncatedText
}
function replacePlaceholder(originalText, replacement) {
return originalText.replace('{0}', replacement);
return originalText.replace('{0}', replacement)
}
const sendMessage = async () => {
@ -290,8 +277,6 @@ const sendMessage = async () => {
const { responseText } = xhr
if (xhr.status == 200) {
const arr = parseEventMessages(responseText)
const { conversation_id, message_id } = arr[0]
const msg = arr.reduce((acc, item) => {
return acc + item.text
}, '')
@ -370,15 +355,26 @@ function scrollToBottomIfAtBottom() {
}
</script>
<style lang="scss" scoped>
:deep(.ant-input-group) {
.ant-input-group-addon {
height: 100%;
// display: inline-block;
&:last-child {
padding: 0;
<style lang="scss">
.cu-field-ai {
height: 100% !important;
background-color: #1e1f21;
color: #fff;
border: none;
border-radius: 4px;
height: 52px;
font-size: 27px;
line-height: 52px;
padding: 0 10px;
input {
color: white !important;
&::placeholder {
color: #ffffff41 !important;
}
}
.van-field__body {
height: 100% !important;
}
}
.options {
.active {

View File

@ -25,7 +25,10 @@
:data="item"
></CardItem>
</div>
<AiAssistant />
</div>
</div>
</template>
<script setup>
@ -34,6 +37,7 @@ import bg01 from '@/assets/images/insights_01.jpg'
import bg02 from '@/assets/images/insights_02.jpg'
import bg03 from '@/assets/images/insights_03.jpg'
import bg04 from '@/assets/images/insights_04.jpg'
import AiAssistant from '@/views/chat/components/ai-assistant-float.vue'
const list = [
{
icon: '法律法规',

View File

@ -81,7 +81,7 @@ import 'swiper/css/navigation'
const modules = [Mousewheel, Navigation, EffectCoverflow]
const pagetSize = 100
const pagetSize = 20
const weekNewsPage = ref(1)
const weekNewsList = ref([])