31 changed files with 577 additions and 9 deletions
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 372 KiB |
After Width: | Height: | Size: 270 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0"><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
||||||
|
<svg t="1705480968419" class="icon" viewBox="0 0 1024 1024" version="1.1" |
||||||
|
xmlns="http://www.w3.org/2000/svg" p-id="2401" |
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" width="50" height="50"> |
||||||
|
<path d="M512 750.2c-10.6 0-20.8-4.2-28.3-11.7L75.6 330.3c-15.6-15.6-15.6-40.9 0-56.6 15.6-15.6 40.9-15.6 56.6 0L512 653.6l379.8-379.9c15.6-15.6 40.9-15.6 56.6 0 15.6 15.6 15.6 40.9 0 56.6L540.3 738.5c-7.5 7.5-17.7 11.7-28.3 11.7z" p-id="2402"></path> |
||||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||||
|
import AppContentDefaultBox from './index.vue' |
||||||
|
|
||||||
|
export { AppContentDefaultBox } |
@ -0,0 +1,15 @@ |
|||||||
|
<!-- 内容默认容器组件 --> |
||||||
|
<script setup lang="ts"> |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="app-content-default-box w-full"> |
||||||
|
<slot></slot> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
@include app('content-default-box') { |
||||||
|
padding: 0 100px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,3 @@ |
|||||||
|
import AppConversationDefault from './index.vue' |
||||||
|
|
||||||
|
export { AppConversationDefault } |
@ -0,0 +1,169 @@ |
|||||||
|
<!-- 会话默认对话组件 --> |
||||||
|
<script setup lang="ts"> |
||||||
|
import { ref } from 'vue' |
||||||
|
import DefaultImage from '@/assets/images/conversation/default_img.png' |
||||||
|
import TestImg from '@/assets/images/a1.png' |
||||||
|
import { SvgIcon } from '@/components/SvgIcon' |
||||||
|
import { AppContentDefaultBox } from '@/components/AppContentDefaultBox' |
||||||
|
import { AppDefaultLead } from '@/components/AppDefaultLead' |
||||||
|
import { AppModelSelect } from '@/components/AppModelSelect' |
||||||
|
import { AppTopPicks } from '@/components/AppTopPicks' |
||||||
|
import type { TopPickItem } from '@/components/AppTopPicks/index.d' |
||||||
|
import { AppPicture } from '@/components/AppPicture' |
||||||
|
import type { PictureType } from '@/components/AppPicture/index.d' |
||||||
|
|
||||||
|
const leadData = { |
||||||
|
title: '你好,我是青鸟语言大模型-同聪~', |
||||||
|
subTitles: [ |
||||||
|
'我可以自由的跟你对话~陪你聊天~帮你想方案~答疑解惑。', |
||||||
|
'你可以试着问我', |
||||||
|
], |
||||||
|
image: DefaultImage, |
||||||
|
} |
||||||
|
|
||||||
|
const topPickList = ref<TopPickItem[]>([ |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
label: '啦啦啦啦啦啦', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '2', |
||||||
|
label: '啦啦啦啦啦啦', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '3', |
||||||
|
label: '啦啦啦啦啦啦啦啦啦啦啦啦', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '4', |
||||||
|
label: '啦啦啦啦啦啦', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '5', |
||||||
|
label: '啦啦啦啦啦啦', |
||||||
|
}, |
||||||
|
]) |
||||||
|
|
||||||
|
const roleList = ref<PictureType[]>([ |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
image: TestImg, |
||||||
|
name: '法律顾问', |
||||||
|
type: '2', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
image: TestImg, |
||||||
|
name: '法律顾问', |
||||||
|
type: '2', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
image: TestImg, |
||||||
|
name: '法律顾问', |
||||||
|
type: '2', |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
image: TestImg, |
||||||
|
name: '法律顾问', |
||||||
|
type: '2', |
||||||
|
}, |
||||||
|
]) |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<AppContentDefaultBox> |
||||||
|
<AppModelSelect></AppModelSelect> |
||||||
|
<AppDefaultLead |
||||||
|
class="mt-10" |
||||||
|
:title="leadData.title" |
||||||
|
:sub-titles="leadData.subTitles" |
||||||
|
:image="leadData.image" |
||||||
|
></AppDefaultLead> |
||||||
|
<AppTopPicks class="pl-20 mt-10" :list="topPickList"></AppTopPicks> |
||||||
|
|
||||||
|
<div class="pl-20 mt-10 flex justify-between items-end"> |
||||||
|
<div class="category-box"> |
||||||
|
<div class="top flex items-center"> |
||||||
|
<p class="title"> |
||||||
|
常用角色 |
||||||
|
</p> |
||||||
|
<p class="sub-title truncate"> |
||||||
|
我会转换为不同的角色跟你对话 |
||||||
|
</p> |
||||||
|
<SvgIcon class="icon" name="more"></SvgIcon> |
||||||
|
</div> |
||||||
|
<div class="picture-box flex"> |
||||||
|
<AppPicture |
||||||
|
v-for="(item, index) in roleList" |
||||||
|
:key="index" |
||||||
|
class="picture-item-role" |
||||||
|
:name="item.name" |
||||||
|
:image="item.image" |
||||||
|
></AppPicture> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="category-box"> |
||||||
|
<div class="top flex items-center"> |
||||||
|
<p class="title"> |
||||||
|
热门应用 |
||||||
|
</p> |
||||||
|
<p class="sub-title truncate"> |
||||||
|
这里或许有你想要的好东西 |
||||||
|
</p> |
||||||
|
<SvgIcon class="icon" name="more"></SvgIcon> |
||||||
|
</div> |
||||||
|
<div class="picture-box flex"> |
||||||
|
<AppPicture |
||||||
|
v-for="(item, index) in roleList" |
||||||
|
:key="index" |
||||||
|
class="picture-item" |
||||||
|
:name="item.name" |
||||||
|
:image="item.image" |
||||||
|
type="entire" |
||||||
|
></AppPicture> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</AppContentDefaultBox> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.category-box { |
||||||
|
width: calc(50% - 10px); |
||||||
|
padding: 15px 20px; |
||||||
|
background-color: #edf3ff; |
||||||
|
border-radius: 8px; |
||||||
|
.top { |
||||||
|
position: relative; |
||||||
|
.title { |
||||||
|
font-size: 18px; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.sub-title { |
||||||
|
color: #6d7278; |
||||||
|
margin-left: 30px; |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.icon { |
||||||
|
width: 45px; |
||||||
|
height: 18px; |
||||||
|
cursor: pointer; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 6px; |
||||||
|
} |
||||||
|
} |
||||||
|
.picture-box { |
||||||
|
margin-top: 20px; |
||||||
|
.picture-item-role { |
||||||
|
margin-left: -10px; |
||||||
|
} |
||||||
|
.picture-item + .picture-item { |
||||||
|
margin-left: 15px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,3 @@ |
|||||||
|
import AppDefaultLead from './index.vue' |
||||||
|
|
||||||
|
export { AppDefaultLead } |
@ -0,0 +1,77 @@ |
|||||||
|
<!-- 默认导读组件 --> |
||||||
|
<script setup lang="ts"> |
||||||
|
defineProps({ |
||||||
|
title: { |
||||||
|
type: String, |
||||||
|
default: '你好啊', |
||||||
|
}, |
||||||
|
subTitles: { |
||||||
|
type: Array, |
||||||
|
default: () => [], |
||||||
|
}, |
||||||
|
image: { |
||||||
|
type: String, |
||||||
|
default: '', |
||||||
|
}, |
||||||
|
}) |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="app-default-lead flex justify-between"> |
||||||
|
<img class="profile" src="~@/assets/images/conversation/logo.png" alt=""> |
||||||
|
<div class="right"> |
||||||
|
<div class="banner flex justify-between"> |
||||||
|
<div class="content"> |
||||||
|
<p class="title"> |
||||||
|
{{ title }} |
||||||
|
</p> |
||||||
|
<p v-for="(subTitle, index) of subTitles" :key="index" class="sub-title"> |
||||||
|
{{ subTitle }} |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
<img v-if="image" class="banner-img" :src="image" alt=""> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
@include app('default-lead') { |
||||||
|
.profile { |
||||||
|
width: 50px; |
||||||
|
height: 40px; |
||||||
|
} |
||||||
|
.right { |
||||||
|
width: calc(100% - 50px); |
||||||
|
padding-left: 30px; |
||||||
|
.banner { |
||||||
|
padding: 30px; |
||||||
|
border-radius: 22px; |
||||||
|
background-image: url(../../assets/images/conversation/default_bg.png); |
||||||
|
background-size: cover; |
||||||
|
position: relative; |
||||||
|
box-shadow: 5px 5px 15px #2260e8; |
||||||
|
.content { |
||||||
|
color: #fff; |
||||||
|
.title { |
||||||
|
font-size: 26px; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 20px; |
||||||
|
line-height: 40px; |
||||||
|
} |
||||||
|
.sub-title { |
||||||
|
line-height: 32px; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
.banner-img { |
||||||
|
width: 50%; |
||||||
|
max-width: 500px; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,4 @@ |
|||||||
|
export interface ModelSelect { |
||||||
|
label: string |
||||||
|
value: string |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
import AppModelSelect from './index.vue' |
||||||
|
|
||||||
|
export { AppModelSelect } |
@ -0,0 +1,64 @@ |
|||||||
|
<!-- 3.5和4.0模型切换组件 --> |
||||||
|
<script setup lang="ts"> |
||||||
|
import { ref } from 'vue' |
||||||
|
import { Dropdown, Menu, MenuItem } from 'ant-design-vue' |
||||||
|
import type { ModelSelect } from './index.d' |
||||||
|
import { SvgIcon } from '@/components/SvgIcon' |
||||||
|
|
||||||
|
const emit = defineEmits(['change']) |
||||||
|
const optionActive = ref(0) |
||||||
|
const options: ModelSelect[] = [ |
||||||
|
{ |
||||||
|
label: '同聪3.5', |
||||||
|
value: '1', |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '同聪4.0', |
||||||
|
value: '2', |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
function handelChange(index: number, item: ModelSelect) { |
||||||
|
optionActive.value = index |
||||||
|
emit('change', index, item) |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<Dropdown :trigger="['click']"> |
||||||
|
<div class="app-model-select flex justify-between items-center" @click.prevent> |
||||||
|
<SvgIcon class="icon icon-robot" name="robot" /> |
||||||
|
{{ options[optionActive].label }} |
||||||
|
<SvgIcon class="icon icon-down" name="down" /> |
||||||
|
</div> |
||||||
|
|
||||||
|
<template #overlay> |
||||||
|
<Menu> |
||||||
|
<MenuItem v-for="(item, index) in options" :key="item.value" @click="handelChange(index, item)"> |
||||||
|
{{ item.label }} |
||||||
|
</MenuItem> |
||||||
|
</Menu> |
||||||
|
</template> |
||||||
|
</Dropdown> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
@include app('model-select') { |
||||||
|
width: 200px; |
||||||
|
height: 40px; |
||||||
|
padding: 0 20px; |
||||||
|
margin: 0 auto; |
||||||
|
color: #4670e3; |
||||||
|
background-color: #edf3ff; |
||||||
|
border-radius: 20px; |
||||||
|
cursor: pointer; |
||||||
|
.icon { |
||||||
|
width: 24px; |
||||||
|
height: 24px; |
||||||
|
} |
||||||
|
.icon-down { |
||||||
|
width: 18px; |
||||||
|
height: 18px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,6 @@ |
|||||||
|
export interface PictureType { |
||||||
|
id: string |
||||||
|
image: string |
||||||
|
name: string |
||||||
|
type: string |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
import AppPicture from './index.vue' |
||||||
|
|
||||||
|
export { AppPicture } |
@ -0,0 +1,71 @@ |
|||||||
|
<script setup lang="ts"> |
||||||
|
import { computed } from 'vue' |
||||||
|
|
||||||
|
interface Props { |
||||||
|
widthStyle?: number |
||||||
|
heightStyle?: number |
||||||
|
type?: 'separate' | 'entire' |
||||||
|
name: string |
||||||
|
image: string |
||||||
|
} |
||||||
|
const props = withDefaults(defineProps<Props>(), { |
||||||
|
widthStyle: 80, |
||||||
|
heightStyle: 80, |
||||||
|
type: 'separate', |
||||||
|
name: '', |
||||||
|
image: '', |
||||||
|
}) |
||||||
|
const w = computed(() => `${props.widthStyle}px`) |
||||||
|
const h = computed(() => `${props.heightStyle}px`) |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="app-picture" :style="{ width: w, height: h }"> |
||||||
|
<div v-if="props.type === 'separate'" class="separate-box w-full h-full"> |
||||||
|
<img class="img" :src="image" alt=""> |
||||||
|
<p class="name w-full"> |
||||||
|
{{ name }} |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
<div v-else class="entire-box w-full h-full"> |
||||||
|
<img class="img w-full h-full" :src="image" alt=""> |
||||||
|
|
||||||
|
<p class="name w-full"> |
||||||
|
{{ name }} |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
@include app('picture') { |
||||||
|
cursor: pointer; |
||||||
|
.separate-box { |
||||||
|
.img { |
||||||
|
width: calc(100% - 25px); |
||||||
|
height: calc(100% - 25px); |
||||||
|
margin: 0 auto; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
.name { |
||||||
|
text-align: center; |
||||||
|
margin-top: 3px; |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
.entire-box { |
||||||
|
position: relative; |
||||||
|
border-radius: 8px; |
||||||
|
overflow: hidden; |
||||||
|
.name { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
color: #fff; |
||||||
|
background-color: rgba($color: #000000, $alpha: 0.5); |
||||||
|
margin: 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,4 @@ |
|||||||
|
export interface TopPickItem { |
||||||
|
id: string |
||||||
|
label: string |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
import AppTopPicks from './index.vue' |
||||||
|
|
||||||
|
export { AppTopPicks } |
@ -0,0 +1,53 @@ |
|||||||
|
<!-- 精选推荐组件 --> |
||||||
|
<script setup lang="ts"> |
||||||
|
import type { TopPickItem } from './index.d' |
||||||
|
import { SvgIcon } from '@/components/SvgIcon' |
||||||
|
|
||||||
|
defineProps<{ |
||||||
|
list: TopPickItem[] |
||||||
|
}>() |
||||||
|
|
||||||
|
const emit = defineEmits(['change', 'refresh']) |
||||||
|
|
||||||
|
function handelChange(index: number, item: TopPickItem) { |
||||||
|
emit('change', index, item) |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="app-top-picks flex items-center"> |
||||||
|
<div |
||||||
|
v-for="(item, index) in list" |
||||||
|
:key="index" |
||||||
|
class="item truncate" |
||||||
|
@click="handelChange(index, item)" |
||||||
|
> |
||||||
|
{{ item.label }} |
||||||
|
</div> |
||||||
|
<SvgIcon class="icon" name="refresh" @click="emit('refresh')" /> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
@include app('top-picks') { |
||||||
|
.item { |
||||||
|
height: 40px; |
||||||
|
line-height: 40px; |
||||||
|
padding: 0 20px; |
||||||
|
color: #4670e3; |
||||||
|
background-color: #edf3ff; |
||||||
|
border-radius: 8px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.item + .item { |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.icon { |
||||||
|
width: 20px; |
||||||
|
height: 20px; |
||||||
|
color: #4670e3; |
||||||
|
margin-left: 20px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue