123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <template>
- <div class="card-list" ref="tabsRef" @scroll="handleTabsScroll">
- <el-card class="card" body-class="card-body" v-for="role in roleList" :key="role.id">
- <!-- 更多 -->
- <div class="more-container">
- <el-dropdown @command="handleMoreClick">
- <span class="el-dropdown-link">
- <el-button type="text" >
- <el-icon><More /></el-icon>
- </el-button>
- </span>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item :command="['edit', role]" >
- <el-icon><EditPen /></el-icon>编辑
- </el-dropdown-item>
- <el-dropdown-item :command="['delete', role]" style="color: red;" >
- <el-icon><Delete /></el-icon>
- <span>删除</span>
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- <!-- 头像 -->
- <div>
- <img class="avatar" :src="role.avatar"/>
- </div>
- <div class="right-container">
- <div class="content-container">
- <div class="title">{{ role.name }}</div>
- <div class="description">{{ role.description }}</div>
- </div>
- <div class="btn-container">
- <el-button type="primary" size="small" @click="handleUseClick(role)">使用</el-button>
- </div>
- </div>
- </el-card>
- </div>
- </template>
- <script setup lang="ts">
- import {ChatRoleVO} from '@/api/ai/model/chatRole'
- import {PropType, ref} from "vue";
- import {Delete, EditPen, More} from "@element-plus/icons-vue";
- const tabsRef = ref<any>() // tabs ref
- // 定义属性
- const props = defineProps({
- loading: {
- type: Boolean,
- required: true
- },
- roleList: {
- type: Array as PropType<ChatRoleVO[]>,
- required: true
- }
- })
- // 定义钩子
- const emits = defineEmits(['onDelete', 'onEdit', 'onUse', 'onPage'])
- // more 点击
- const handleMoreClick = async (data) => {
- const type = data[0]
- const role = data[1]
- if (type === 'delete') {
- emits('onDelete', role)
- } else {
- emits('onEdit', role)
- }
- }
- // 使用
- const handleUseClick = (role) => {
- emits('onUse', role)
- }
- const handleTabsScroll = async () => {
- if (tabsRef.value) {
- const { scrollTop, scrollHeight, clientHeight } = tabsRef.value;
- console.log('scrollTop', scrollTop)
- if (scrollTop + clientHeight >= scrollHeight - 20 && !props.loading) {
- console.log('分页')
- // page.value++;
- // fetchData(page.value);
- await emits('onPage')
- }
- }
- }
- onMounted(() => {
- console.log('props', props.roleList)
- })
- </script>
- <style lang="scss">
- // 重写 card 组件 body 样式
- .card-body {
- max-width: 300px;
- width: 300px;
- padding: 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;
- .card {
- margin-right: 20px;
- border-radius: 10px;
- margin-bottom: 30px;
- position: relative;
- .more-container {
- position: absolute;
- right: 12px;
- top: 0px;
- }
- .avatar {
- width: 40px;
- height: 40px;
- border-radius: 10px;
- overflow: hidden;
- }
- .right-container {
- margin-left: 10px;
- width: 100%;
- //height: 100px;
- .content-container {
- height: 85px;
- overflow: hidden;
- .title {
- font-size: 18px;
- font-weight: bold;
- color: #3e3e3e;
- }
- .description {
- margin-top: 10px;
- font-size: 14px;
- color: #6a6a6a;
- }
- }
- .btn-container {
- display: flex;
- flex-direction: row-reverse;
- margin-top: 15px;
- }
- }
- }
- }
- </style>
|