ai助理
parent
e301b39ba0
commit
8b3035aae7
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -0,0 +1,9 @@
|
|||
<?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="1691821825409" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="5851" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M640 160 256 160C220.64 160 192 188.64 192 224L192 672 256 672 256 224 640 224 640 160 640 160ZM736 288 384 288C348.64 288 320 316.672 320 352L320 800C320 835.328 348.64 864 384 864L736 864C771.328 864 800 835.328 800 800L800 352C800 316.672 771.328 288 736 288L736 288ZM384 352 736 352 736 800 384 800 384 352Z"
|
||||
fill="currentColor" p-id="5852"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 709 B |
|
|
@ -14,14 +14,14 @@
|
|||
<SvgIcon class="text-white text-40px mb-46px" name="人工客服"></SvgIcon>
|
||||
<SvgIcon class="text-white text-40px mb-46px" name="疑问"></SvgIcon>
|
||||
</div>
|
||||
|
||||
<van-popup v-model:show="show" position="left" class="slider-class">
|
||||
<div class="w-479px h-full flex flex-col">
|
||||
<div class="h-100px"></div>
|
||||
<div
|
||||
class="bg-gradient-to-b to-[#101011] from-[#414548] flex-1 border-t-7px border-[#3662FE] flex flex-col items-center"
|
||||
>
|
||||
<!-- @click="openTemplateModal" -->
|
||||
<SilderBtn>
|
||||
<SilderBtn @click="openTemplateModal">
|
||||
<template #icon>
|
||||
<SvgIcon class="text-white text-35px" name="dp"></SvgIcon>
|
||||
</template>
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<SilderBtn>
|
||||
<SilderBtn @click="handleNewChat">
|
||||
<template #icon>
|
||||
<SvgIcon
|
||||
class="text-white text-35px transform rotate-45"
|
||||
|
|
@ -97,6 +97,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
|
||||
<TemplateModal v-model:show="open" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -106,7 +108,7 @@ import TemplateItem from './template-item.vue'
|
|||
import GroupItem from './group-item.vue'
|
||||
import ScrollContainer from '@/components/ScrollContainer/index.vue'
|
||||
|
||||
// import TemplateModal from './template-modal.vue'
|
||||
import TemplateModal from './template-modal.vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useChat } from '@/stores'
|
||||
import http from '@/io/request'
|
||||
|
|
|
|||
|
|
@ -1,25 +1,27 @@
|
|||
<template>
|
||||
<div class="py-3 px-4 bg-[#414548] w-79 h-122 rounded-4px">
|
||||
<div
|
||||
class="py-18px px-24px bg-[#414548] bg-opacity-40 w-431px h-665px rounded-2px flex-none box-content overflow-hidden flex flex-col"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<div class="flex-1 text-xl">{{ data.title }}</div>
|
||||
<div class="flex-1 text-27px">{{ data.title }}</div>
|
||||
<div
|
||||
class="bg-[#3662FE] w-7 h-7 rounded-4px flex items-center justify-center"
|
||||
class="bg-[#3662FE] w-40px h-40px rounded-4px flex items-center justify-center"
|
||||
>
|
||||
<SvgIcon
|
||||
@click="onCopy"
|
||||
class="text-white text-lg cursor-pointer"
|
||||
class="text-white text-20px cursor-pointer"
|
||||
name="ic_copy"
|
||||
></SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 text-base leading-24px">
|
||||
<div class="mt-56px text-22px leading-33px flex-1 overflow-y-auto">
|
||||
{{ data.content }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { copyToClip } from '@/utils/copy'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { showToast } from 'vant'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
|
@ -28,16 +30,16 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const onCopy = () => {
|
||||
copyToClip(props.data.content)
|
||||
.then((res) => {
|
||||
proxy.$mitt.emit('temp-copy', props.data.content);
|
||||
message.success('复制成功~')
|
||||
proxy.$mitt.emit('temp-copy', props.data.content)
|
||||
showToast('复制成功~')
|
||||
})
|
||||
.catch(() => {
|
||||
message.error('复制失败~')
|
||||
showToast('复制失败~')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,55 +1,78 @@
|
|||
<template>
|
||||
<a-modal
|
||||
<van-popup
|
||||
v-bind="getBindValue"
|
||||
centered
|
||||
:title="null"
|
||||
:footer="null"
|
||||
width="85.81rem"
|
||||
:style="{ background: '#16171890' }"
|
||||
wrapClassName="template-modal"
|
||||
>
|
||||
<div class="text-white">
|
||||
<div class="text-white py-48px w-680px border border-[#5E6369] rounded-6px relative">
|
||||
<div class="absolute right-30px top-30px">
|
||||
<SvgIcon
|
||||
@click="handleClose"
|
||||
class="text-white text-50px cursor-pointer text-30px"
|
||||
name="qx"
|
||||
></SvgIcon>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<img
|
||||
class="w-10.5"
|
||||
class="w-31px"
|
||||
src="@/assets/images/tip-icon-blue.png"
|
||||
alt=""
|
||||
srcset=""
|
||||
/>
|
||||
<div class="text-2xl">海兔AIGC提示模板大全</div>
|
||||
<div class="text-27px">海兔AIGC提示模板大全</div>
|
||||
</div>
|
||||
<div class="mt-2.25 opacity-40 text-center">
|
||||
<div class="mt-30px text-22px opacity-40 text-center">
|
||||
Haitu AIGC Writing Inspiration Complete Works
|
||||
</div>
|
||||
<div class="my-6 flex items-center justify-center">
|
||||
<a-cascader
|
||||
:allowClear="false"
|
||||
class="cu-cascader w-100"
|
||||
:fieldNames="{ label: 'title', value: 'id' }"
|
||||
v-model:value="value"
|
||||
:options="options"
|
||||
placeholder="请选择"
|
||||
@change="changeCategories"
|
||||
popupClassName="cu-cascader-popup"
|
||||
/>
|
||||
<div class="my-40px flex items-center justify-center">
|
||||
<van-popover v-model:show="popovershow" class="cu-popover" overlay>
|
||||
<div class="w-600px">
|
||||
<van-cascader
|
||||
@finish="onFinish"
|
||||
v-model="value"
|
||||
title=""
|
||||
@close="popovershow = false"
|
||||
:options="options"
|
||||
/>
|
||||
</div>
|
||||
<template #reference>
|
||||
<van-field
|
||||
readonly
|
||||
:border="false"
|
||||
class="h-72px cu-field-se !w-600px"
|
||||
v-model="fieldValue"
|
||||
placeholder="请选择"
|
||||
></van-field>
|
||||
</template>
|
||||
</van-popover>
|
||||
</div>
|
||||
<div
|
||||
ref="scrollbarRef"
|
||||
@scroll="handleScroll"
|
||||
class="max-h-36.5rem overflow-hidden overflow-y-auto"
|
||||
>
|
||||
<div
|
||||
class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4"
|
||||
>
|
||||
<TemplateCard
|
||||
class="mx-auto"
|
||||
v-for="(item, i) in templates"
|
||||
:key="i"
|
||||
:data="item"
|
||||
></TemplateCard>
|
||||
</div>
|
||||
<div class="overflow-x-scroll flex px-34px" ref="scrollbarRef">
|
||||
<TemplateCard
|
||||
class="mr-25px"
|
||||
v-for="(item, i) in templates"
|
||||
:key="i"
|
||||
:data="item"
|
||||
></TemplateCard>
|
||||
</div>
|
||||
<div class="flex justify-center mt-20px">
|
||||
<SvgIcon
|
||||
:class="{ 'opacity-40': pageNum <= 1 }"
|
||||
@click="handleP"
|
||||
class="text-white text-50px cursor-pointer mx-60px"
|
||||
name="right-arrow"
|
||||
></SvgIcon>
|
||||
<SvgIcon
|
||||
:class="{ 'opacity-40': !isMore }"
|
||||
@click="handleN"
|
||||
class="text-white text-50px cursor-pointer transform rotate-180 mx-60px"
|
||||
name="right-arrow"
|
||||
></SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</van-popup>
|
||||
</template>
|
||||
<script>
|
||||
import { ref, computed, unref, defineComponent, onMounted, nextTick } from 'vue'
|
||||
|
|
@ -61,18 +84,22 @@ export default defineComponent({
|
|||
ScrollContainer,
|
||||
TemplateCard,
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
setup(props, { attrs,emit }) {
|
||||
const pageNum = ref(1)
|
||||
|
||||
const scrollbarRef = ref(null)
|
||||
|
||||
const templates = ref([])
|
||||
|
||||
const popovershow = ref(false)
|
||||
|
||||
const options = ref([])
|
||||
|
||||
const value = ref([])
|
||||
const value = ref('')
|
||||
|
||||
const isLoading = ref(false)
|
||||
const fieldValue = ref('')
|
||||
|
||||
const isMore = ref(true)
|
||||
|
||||
const modelOpen = ref(false)
|
||||
|
||||
|
|
@ -87,56 +114,73 @@ export default defineComponent({
|
|||
return attr
|
||||
})
|
||||
|
||||
const handleClose = () => {
|
||||
emit('update:show', false)
|
||||
}
|
||||
|
||||
const getCategories = () => {
|
||||
http.get('/api/prompt-categories').then((res) => {
|
||||
changeId2(res, 'id', 'value')
|
||||
changeId2(res, 'title', 'text')
|
||||
options.value = res
|
||||
})
|
||||
}
|
||||
|
||||
const onFinish = ({ selectedOptions }) => {
|
||||
fieldValue.value = selectedOptions.map((option) => option.text).join('/')
|
||||
popovershow.value = false
|
||||
console.log(value.value);
|
||||
changeCategories()
|
||||
}
|
||||
|
||||
function changeId2(objAry, key, newkey) {
|
||||
if (objAry != null) {
|
||||
objAry.forEach((item) => {
|
||||
Object.assign(item, {
|
||||
[newkey]: item[key],
|
||||
})
|
||||
delete item[key]
|
||||
changeId2(item.children, key, newkey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const getTemplates = () => {
|
||||
http
|
||||
.get('/api/prompt-templates', {
|
||||
params: {
|
||||
per_page: 20,
|
||||
per_page: 10,
|
||||
page: pageNum.value,
|
||||
category_id: value.value[value.value.length - 1] ?? null,
|
||||
category_id: value.value,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
if (pageNum.value == 1) templates.value = []
|
||||
templates.value = templates.value.concat(res.data)
|
||||
pageNum.value++
|
||||
isLoading.value = false
|
||||
templates.value = res.data
|
||||
isMore.value = true
|
||||
scrollbarRef.value.scrollLeft = 0
|
||||
if (templates.value.length >= res.total) {
|
||||
isLoading.value = true
|
||||
isMore.value = false
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
isLoading.value = true
|
||||
})
|
||||
.catch((e) => {})
|
||||
}
|
||||
|
||||
const changeCategories = async (e) => {
|
||||
pageNum.value = 1
|
||||
isLoading.value = false
|
||||
getTemplates()
|
||||
await nextTick()
|
||||
scrollbarRef.value.scrollTop = 0
|
||||
}
|
||||
|
||||
const handleScroll = (e) => {
|
||||
if (isLoading.value) return
|
||||
const container = scrollbarRef.value
|
||||
const scrollHeight = container.scrollHeight
|
||||
const scrollTop = container.scrollTop
|
||||
const clientHeight = container.clientHeight
|
||||
const extra = 20
|
||||
if (scrollTop < 100) return
|
||||
const handleP = () => {
|
||||
if (pageNum.value == 1) return
|
||||
pageNum.value--
|
||||
getTemplates()
|
||||
}
|
||||
|
||||
if (scrollHeight - scrollTop - extra <= clientHeight) {
|
||||
isLoading.value = true
|
||||
// loadMore()
|
||||
}
|
||||
const handleN = () => {
|
||||
if (!isMore.value) return
|
||||
pageNum.value++
|
||||
getTemplates()
|
||||
}
|
||||
|
||||
const loadMore = () => {
|
||||
|
|
@ -149,13 +193,20 @@ export default defineComponent({
|
|||
})
|
||||
|
||||
return {
|
||||
popovershow,
|
||||
value,
|
||||
options,
|
||||
getBindValue,
|
||||
templates,
|
||||
scrollbarRef,
|
||||
handleScroll,
|
||||
handleN,
|
||||
handleP,
|
||||
isMore,
|
||||
pageNum,
|
||||
handleClose,
|
||||
changeCategories,
|
||||
fieldValue,
|
||||
onFinish,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
@ -219,4 +270,36 @@ export default defineComponent({
|
|||
color: white;
|
||||
}
|
||||
}
|
||||
.cu-field-se {
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #414548;
|
||||
input {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
.cu-popover {
|
||||
.van-popover__arrow {
|
||||
color: #27292b !important;
|
||||
}
|
||||
.van-cascader__options {
|
||||
height: 500px;
|
||||
}
|
||||
.van-popover__content {
|
||||
background: #27292b;
|
||||
}
|
||||
.van-tabs__nav {
|
||||
background: #27292b;
|
||||
}
|
||||
.van-cascader__option {
|
||||
color: white;
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
.van-cascader__tab {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue