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