Skip to content

Commit

Permalink
feat: ✨️开发添加好友,好友详情,详情修改功能
Browse files Browse the repository at this point in the history
  • Loading branch information
ZRMYDYCG committed Mar 5, 2025
1 parent e3ec547 commit 67d386b
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 63 deletions.
44 changes: 44 additions & 0 deletions src/view/contacts/components/add-contact-dialog.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
:deep(.gc-column__header) .search {
margin-bottom: 15px;
}

:deep(.el-scrollbar) .gc-list {
padding-bottom: 30px;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user {
display: flex;
align-items: center;
width: 100%;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user .avater {
flex-shrink: 0;
width: 45px;
height: 45px;
margin-right: 15px;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user .avater img {
border-radius: 50%;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user .info {
flex: 1;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user .info .info-top {
display: flex;
justify-content: space-between;
align-items: center;
}

:deep(.el-scrollbar) .gc-list .gc-list__item .contact-item .user .info .info-top .nickname {
flex: 1;
width: 0;
font-size: 15px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
136 changes: 132 additions & 4 deletions src/view/contacts/components/add-contact-dialog.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,135 @@
<script setup lang="ts"></script>

<template>
<div></div>
<el-dialog
v-model="dialogVisible"
title="添加好友"
width="500"
:modal="false"
:close-on-click-modal="true"
@closed="handleClosed"
>
<GCColumn ref="gcColumnRef" v-loading="loading" class="!h-[400px]">
<template #header>
<el-form ref="searchFormRef" :model="searchFormMdl" class="search" @submit.prevent="handleSearchFriend">
<el-form-item prop="keywords">
<el-input v-model="searchFormMdl.keywords" placeholder="搜索" clearable>
<template #prefix>
<i class="ri-search-line"></i>
</template>
</el-input>
</el-form-item>
</el-form>
</template>

<!-- S 搜素结果 -->
<GCList
ref="contactListRef"
:list="contactList"
:options="{
key: 'user_id',
}"
>
<template #default="{ item }">
<div class="contact-item flex w-[100%]">
<div class="user flex w-[100%] items-center">
<div class="avater">
<img :src="item.avatar" alt="" />
</div>
<div class="info">
<div class="info-top flex items-center justify-between">
<p class="nickname truncate">{{ item.nickname }}</p>
</div>
</div>
<div class="oprate">
<el-button size="small" @click="handleAdd(item)">加为好友</el-button>
</div>
</div>
</div>
</template>
</GCList>
<!-- E 搜素结果 -->
</GCColumn>
</el-dialog>
</template>

<style scoped></style>
<script setup lang="ts">
import GCColumn from '@/components/Column/index.vue'
import GCList from '@/components/List/index.vue'
import { useCurrentInstance, useLoadMore, usePageList } from '@/hooks'
import type { ElForm } from 'element-plus'
import { nextTick, onMounted, reactive, ref } from 'vue'
interface ContactItem {
user_id: string | number
avatar: string
nickname: string
}
const { proxy } = useCurrentInstance()
const $api = proxy.$api
const dialogVisible = ref(false)
const loading = ref(false)
const searchFormRef = ref<InstanceType<typeof ElForm>>()
const searchFormMdl = reactive({
keywords: '',
})
const {
list: contactList,
loading: listLoading,
getPageList,
initData,
handleRefresh,
} = usePageList<ContactItem>({
getPageListApi: $api.contact.getContactList,
searchParams: searchFormMdl,
})
const gcColumnRef = ref<InstanceType<typeof GCColumn>>()
// 加载更多逻辑
onMounted(() => {
nextTick(() => {
const scrollContainer = gcColumnRef.value?.$el?.querySelector('.el-scrollbar__wrap')
if (scrollContainer) {
useLoadMore({
type: 'bottom',
scrollBottomCallback: getPageList,
container: scrollContainer,
distance: 150,
})
}
})
})
const handleSearchFriend = () => {
handleRefresh()
}
const handleAdd = (contact: ContactItem) => {
// console.log('添加为好友', contact)
}
const handleClosed = () => {
searchFormRef.value?.resetFields()
initData()
}
const open = () => {
dialogVisible.value = true
}
const close = () => {
dialogVisible.value = false
}
defineExpose({
open,
close,
})
</script>

<style scoped>
@import './add-contact-dialog.css';
</style>
59 changes: 59 additions & 0 deletions src/view/contacts/components/contact-detail.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.contact-detail {
flex: 1;
height: 850px;
}

.contact-detail .contact-detail-wrapper {
width: 400px;
margin: 0 auto;
}

.contact-detail .contact-detail-wrapper .base-info {
padding: 100px 0 45px;
border-bottom: 1px solid #e7e7e7;
}

.contact-detail .contact-detail-wrapper .base-info .left {
margin-right: 30px;
}

.contact-detail .contact-detail-wrapper .base-info .left .nickname {
font-size: 18px;
}

.contact-detail .contact-detail-wrapper .base-info .left .nickname .sex {
width: 18px;
margin-left: 5px;
}

.contact-detail .contact-detail-wrapper .base-info .left .desc {
font-size: 14px;
color: #96a1b1;
word-break: break-all;
margin-top: 5px;
}

.contact-detail .contact-detail-wrapper .base-info .right .avater {
flex-shrink: 0;
width: 45px;
height: 45px;
}

.contact-detail .contact-detail-wrapper .base-info .right .avater img {
border-radius: 50%;
}

.contact-detail .contact-detail-wrapper .other-info {
padding: 40px 0 30px;
border-bottom: 1px solid #e7e7e7;
}

.contact-detail .contact-detail-wrapper .other-info .info-row .lable {
width: 5em;
color: #96a1b1;
margin-right: 30px;
}

.contact-detail .contact-detail-wrapper .oprate {
margin-top: 60px;
}
76 changes: 73 additions & 3 deletions src/view/contacts/components/contact-detail.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,77 @@
<script setup lang="ts"></script>
<script lang="ts" setup>
interface Contact {
remark: string
sex: number | string
desc: string
avatar: string
nickname: string
account: string
[key: string]: any
}
interface Props {
contact?: Contact
}
// 定义 props 和 emits
const emit = defineEmits(['set-contact-info'])
import { withDefaults } from 'vue'
withDefaults(defineProps<Props>(), {
contact: () => ({
remark: '',
sex: '',
desc: '',
avatar: '',
nickname: '',
account: '',
}),
})
</script>

<template>
<div></div>
<div class="contact-detail">
<div class="contact-detail-wrapper">
<div class="base-info flex items-center justify-between">
<div class="left">
<div class="nickname flex items-center">
<span>{{ contact.remark }}</span>
<img v-if="String(contact.sex) === '0'" class="sex" src="~@/assets/default_avatar.png" alt="" />
<img v-if="String(contact.sex) === '1'" class="sex" src="~@/assets/default_avatar.png" alt="" />
<el-button circle size="small" class="ml-[5px]" title="资料设置" @click="$emit('set-contact-info')">
<template #icon>
<i class="ri-edit-box-line"></i>
</template>
</el-button>
</div>
<div class="desc">{{ contact.desc }}</div>
</div>

<div class="right">
<div class="avater">
<img :src="contact.avater" alt="" />
</div>
</div>
</div>

<div class="other-info">
<div class="info-row flex items-center">
<div class="lable">名称</div>
<div class="value">{{ contact.nickname }}</div>
</div>
<div class="info-row flex items-center">
<div class="lable">账号</div>
<div class="value">{{ contact.account }}</div>
</div>
</div>

<div class="oprate">
<el-button type="primary" class="mx-auto !block w-[140px]">发消息</el-button>
</div>
</div>
</div>
</template>

<style scoped></style>
<style scoped>
@import './contact-detail.css';
</style>
52 changes: 52 additions & 0 deletions src/view/contacts/components/contact-list.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.contact-list {
width: 300px;
height: 100vh;
border-right: 1px solid #e0e4ea;
}

.contact-list .gc-column ::v-deep .gc-column__header {
display: flex;
align-items: center;
justify-content: space-between;
height: 70px;
padding: 15px;
border-bottom: 1px solid #e0e4ea;
}

.contact-list .gc-column .gc-column__header .oprate .el-button + .el-button {
margin-left: 5px;
}

.contact-list .gc-column .list-title {
font-size: 14px;
color: #96a1b1;
line-height: 45px;
padding-left: 15px;
margin-bottom: 5px;
}

.contact-list .gc-column ::v-deep .el-scrollbar .gc-list {
padding-bottom: 30px;
}

.contact-list .gc-column ::v-deep .el-scrollbar .gc-list .gc-list__item .contact-item .user .avater {
flex-shrink: 0;
width: 45px;
height: 45px;
margin-right: 15px;
}

.contact-list .gc-column ::v-deep .el-scrollbar .gc-list .gc-list__item .contact-item .user .avater img {
border-radius: 50%;
}

.contact-list .gc-column ::v-deep .el-scrollbar .gc-list .gc-list__item .contact-item .user .info {
flex: 1;
}

.contact-list .gc-column ::v-deep .el-scrollbar .gc-list .gc-list__item .contact-item .user .info-top .nickname {
flex: 1;
width: 0;
font-size: 15px;
font-weight: 600;
}
Loading

0 comments on commit 67d386b

Please sign in to comment.