reactor:【AI 大模型】chat/role 简化成 unocss

This commit is contained in:
YunaiV
2025-07-27 20:07:22 +08:00
parent 9a209a8249
commit 9a16b2b34d
3 changed files with 53 additions and 170 deletions

View File

@ -31,7 +31,9 @@
class="conversation-item classify-title" class="conversation-item classify-title"
v-if="conversationMap[conversationKey].length" v-if="conversationMap[conversationKey].length"
> >
<el-text class="mx-1" size="small" tag="b">{{ conversationKey }}</el-text> <el-text class="mx-1" size="small" tag="b">
{{ conversationKey }}
</el-text>
</div> </div>
<div <div
class="conversation-item" class="conversation-item"
@ -193,12 +195,12 @@ const getConversationGroupByCreateTime = async (list: ChatConversationVO[]) => {
// 排序、指定、时间分组(今天、一天前、三天前、七天前、30天前) // 排序、指定、时间分组(今天、一天前、三天前、七天前、30天前)
// noinspection NonAsciiCharacters // noinspection NonAsciiCharacters
const groupMap = { const groupMap = {
置顶: [], 置顶: [] as ChatConversationVO[],
今天: [], 今天: [] as ChatConversationVO[],
一天前: [], 一天前: [] as ChatConversationVO[],
三天前: [], 三天前: [] as ChatConversationVO[],
七天前: [], 七天前: [] as ChatConversationVO[],
三十天前: [] 三十天前: [] as ChatConversationVO[]
} }
// 当前时间的时间戳 // 当前时间的时间戳
const now = Date.now() const now = Date.now()

View File

@ -1,9 +1,16 @@
<template> <template>
<div class="card-list" ref="tabsRef" @scroll="handleTabsScroll"> <div
<div class="card-item" v-for="role in roleList" :key="role.id"> class="flex flex-row flex-wrap relative h-full overflow-auto px-25px pb-140px items-start content-start justify-start"
<el-card class="card" body-class="card-body"> ref="tabsRef"
@scroll="handleTabsScroll"
>
<div v-for="role in roleList" :key="role.id">
<el-card
class="inline-block mr-20px rounded-10px mb-20px relative"
body-class="max-w-240px w-240px pt-15px px-15px pb-10px flex flex-row justify-start relative"
>
<!-- 更多操作 --> <!-- 更多操作 -->
<div class="more-container" v-if="showMore"> <div class="absolute top-0 right-12px" v-if="showMore">
<el-dropdown @command="handleMoreClick"> <el-dropdown @command="handleMoreClick">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
<el-button type="text"> <el-button type="text">
@ -24,14 +31,18 @@
</div> </div>
<!-- 角色信息 --> <!-- 角色信息 -->
<div> <div>
<img class="avatar" :src="role.avatar" /> <img class="w-40px h-40px rounded-10px overflow-hidden" :src="role.avatar" />
</div> </div>
<div class="right-container"> <div class="ml-10px w-full">
<div class="content-container"> <div class="h-85px">
<div class="title">{{ role.name }}</div> <div class="text-18px font-bold" style="color: var(--el-text-color-primary)">
<div class="description">{{ role.description }}</div> {{ role.name }}
</div>
<div class="mt-10px text-14px" style="color: var(--el-text-color-regular)">
{{ role.description }}
</div>
</div> </div>
<div class="btn-container"> <div class="flex flex-row-reverse mt-2px">
<el-button type="primary" size="small" @click="handleUseClick(role)">使用</el-button> <el-button type="primary" size="small" @click="handleUseClick(role)">使用</el-button>
</div> </div>
</div> </div>
@ -79,7 +90,7 @@ const handleMoreClick = async (data) => {
} }
/** 选中 */ /** 选中 */
const handleUseClick = (role) => { const handleUseClick = (role: any) => {
emits('onUse', role) emits('onUse', role)
} }
@ -88,87 +99,8 @@ const handleTabsScroll = async () => {
if (tabsRef.value) { if (tabsRef.value) {
const { scrollTop, scrollHeight, clientHeight } = tabsRef.value const { scrollTop, scrollHeight, clientHeight } = tabsRef.value
if (scrollTop + clientHeight >= scrollHeight - 20 && !props.loading) { if (scrollTop + clientHeight >= scrollHeight - 20 && !props.loading) {
await emits('onPage') emits('onPage')
} }
} }
} }
</script> </script>
<style lang="scss">
// 重写 card 组件 body 样式
.card-body {
max-width: 240px;
width: 240px;
padding: 15px 15px 10px 15px;
display: flex;
flex-direction: row;
justify-content: flex-start;
position: relative;
}
</style>
<style scoped lang="scss">
// 卡片列表
.card-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
position: relative;
height: 100%;
overflow: auto;
padding: 0px 25px;
padding-bottom: 140px;
align-items: start;
align-content: flex-start;
justify-content: start;
.card {
display: inline-block;
margin-right: 20px;
border-radius: 10px;
margin-bottom: 20px;
position: relative;
.more-container {
position: absolute;
top: 0;
right: 12px;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 10px;
overflow: hidden;
}
.right-container {
margin-left: 10px;
width: 100%;
//height: 100px;
.content-container {
height: 85px;
.title {
font-size: 18px;
font-weight: bold;
color: var(--el-text-color-primary);
}
.description {
margin-top: 10px;
font-size: 14px;
color: var(--el-text-color-regular);
}
}
.btn-container {
display: flex;
flex-direction: row-reverse;
margin-top: 2px;
}
}
}
}
</style>

View File

@ -1,17 +1,19 @@
<!-- chat 角色仓库 --> <!-- chat 角色仓库 -->
<template> <template>
<el-container class="role-container"> <el-container
class="role-container absolute w-full h-full m-0 p-0 left-0 right-0 top-0 bottom-0 bg-[var(--el-bg-color)] overflow-hidden flex !flex-col"
>
<ChatRoleForm ref="formRef" @success="handlerAddRoleSuccess" /> <ChatRoleForm ref="formRef" @success="handlerAddRoleSuccess" />
<!-- header --> <!-- header -->
<RoleHeader title="角色仓库" class="relative" /> <RoleHeader title="角色仓库" class="relative" />
<!-- main --> <!-- main -->
<el-main class="role-main"> <el-main class="flex-1 overflow-hidden m-0 !p-0 relative">
<div class="search-container"> <div class="mx-5 mt-5 mb-0 absolute right-0 -top-1.25 z-100">
<!-- 搜索按钮 --> <!-- 搜索按钮 -->
<el-input <el-input
:loading="loading" :loading="loading"
v-model="search" v-model="search"
class="search-input" class="!w-60"
size="default" size="default"
placeholder="请输入搜索的内容" placeholder="请输入搜索的内容"
:suffix-icon="Search" :suffix-icon="Search"
@ -23,13 +25,21 @@
@click="handlerAddRole" @click="handlerAddRole"
class="ml-20px" class="ml-20px"
> >
<Icon icon="ep:user" style="margin-right: 5px" /> <Icon icon="ep:user" class="mr-1.25" />
添加角色 添加角色
</el-button> </el-button>
</div> </div>
<!-- tabs --> <!-- tabs -->
<el-tabs v-model="activeTab" class="tabs" @tab-click="handleTabsClick"> <el-tabs
<el-tab-pane class="role-pane" label="我的角色" name="my-role"> v-model="activeTab"
@tab-click="handleTabsClick"
class="relative h-full [&_.el-tabs__nav-scroll]:my-2.5 [&_.el-tabs__nav-scroll]:mx-5"
>
<el-tab-pane
label="我的角色"
name="my-role"
class="flex flex-col h-full overflow-y-auto relative"
>
<RoleList <RoleList
:loading="loading" :loading="loading"
:role-list="myRoleList" :role-list="myRoleList"
@ -43,7 +53,7 @@
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="公共角色" name="public-role"> <el-tab-pane label="公共角色" name="public-role">
<RoleCategoryList <RoleCategoryList
class="role-category-list" class="mx-6.75"
:category-list="categoryList" :category-list="categoryList"
:active="activeCategory" :active="activeCategory"
@on-category-click="handlerCategoryClick" @on-category-click="handlerCategoryClick"
@ -220,70 +230,9 @@ onMounted(async () => {
await getActiveTabsRole() await getActiveTabsRole()
}) })
</script> </script>
<!-- 覆盖 element ui css --> <!-- 覆盖 element plus css -->
<style lang="scss"> <style lang="scss">
.el-tabs__content {
position: relative;
height: 100%;
overflow: hidden;
}
.el-tabs__nav-scroll { .el-tabs__nav-scroll {
margin: 10px 20px; margin: 10px 20px;
} }
</style> </style>
<!-- 样式 -->
<style scoped lang="scss">
// 跟容器
.role-container {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: var(--el-bg-color);
overflow: hidden;
display: flex;
flex-direction: column;
.role-main {
flex: 1;
overflow: hidden;
margin: 0;
padding: 0;
position: relative;
.search-container {
margin: 20px 20px 0px 20px;
position: absolute;
right: 0;
top: -5px;
z-index: 100;
}
.search-input {
width: 240px;
}
.tabs {
position: relative;
height: 100%;
.role-category-list {
margin: 0 27px;
}
}
.role-pane {
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
position: relative;
}
}
}
</style>