265 lines
5.0 KiB
Vue
265 lines
5.0 KiB
Vue
<template>
|
|
<view class="user-card" @click="handleCardClick">
|
|
<!-- 照片区域 -->
|
|
<view class="photo-wrapper">
|
|
<image
|
|
v-if="isPhotoPublic && firstPhoto"
|
|
class="user-photo"
|
|
:src="firstPhoto"
|
|
mode="aspectFill"
|
|
/>
|
|
<view v-else class="photo-placeholder">
|
|
<view class="blur-overlay"></view>
|
|
<text class="private-text">私密照片</text>
|
|
</view>
|
|
|
|
<!-- 徽章区域 -->
|
|
<view class="badges">
|
|
<view v-if="isMember" class="badge member-badge">会员</view>
|
|
<view v-if="isRealName" class="badge realname-badge">已实名</view>
|
|
</view>
|
|
|
|
<!-- 今天看过标识 -->
|
|
<view v-if="viewedToday" class="viewed-today">
|
|
<text>今天看过</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 用户信息区域 -->
|
|
<view class="user-info">
|
|
<view class="info-row">
|
|
<text class="nickname">{{ nickname }}</text>
|
|
<text class="age">{{ age }}岁</text>
|
|
</view>
|
|
<view class="info-row secondary">
|
|
<text class="location">{{ workCity }}</text>
|
|
<text class="divider">|</text>
|
|
<text class="height">{{ height }}cm</text>
|
|
</view>
|
|
<view class="info-row secondary">
|
|
<text class="education">{{ educationName }}</text>
|
|
<text class="divider">|</text>
|
|
<text class="occupation">{{ occupation }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 操作按钮区域 -->
|
|
<view class="action-buttons" @click.stop>
|
|
<button class="btn-contact" @click="handleContact">联系TA</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'UserCard',
|
|
props: {
|
|
userId: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
nickname: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
avatar: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
age: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
workCity: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
height: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
education: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
educationName: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
occupation: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
isMember: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isRealName: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isPhotoPublic: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
firstPhoto: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
viewedToday: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
emits: ['click', 'contact'],
|
|
methods: {
|
|
handleCardClick() {
|
|
this.$emit('click', this.userId)
|
|
},
|
|
handleContact() {
|
|
this.$emit('contact', this.userId)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.user-card {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
overflow: hidden;
|
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.photo-wrapper {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 400rpx;
|
|
|
|
.user-photo {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.photo-placeholder {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(135deg, #e0e0e0 0%, #c0c0c0 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
|
|
.blur-overlay {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(255, 255, 255, 0.3);
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
|
|
.private-text {
|
|
position: relative;
|
|
z-index: 1;
|
|
color: #666;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
.badges {
|
|
position: absolute;
|
|
top: 16rpx;
|
|
left: 16rpx;
|
|
display: flex;
|
|
gap: 8rpx;
|
|
|
|
.badge {
|
|
padding: 4rpx 12rpx;
|
|
border-radius: 8rpx;
|
|
font-size: 22rpx;
|
|
color: #fff;
|
|
}
|
|
|
|
.member-badge {
|
|
background: linear-gradient(135deg, #ffd700 0%, #ffb800 100%);
|
|
}
|
|
|
|
.realname-badge {
|
|
background: linear-gradient(135deg, #4cd964 0%, #34c759 100%);
|
|
}
|
|
}
|
|
|
|
.viewed-today {
|
|
position: absolute;
|
|
bottom: 16rpx;
|
|
right: 16rpx;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
padding: 4rpx 12rpx;
|
|
border-radius: 8rpx;
|
|
|
|
text {
|
|
color: #fff;
|
|
font-size: 22rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.user-info {
|
|
padding: 20rpx;
|
|
|
|
.info-row {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 8rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
&.secondary {
|
|
color: #999;
|
|
font-size: 26rpx;
|
|
}
|
|
|
|
.nickname {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-right: 12rpx;
|
|
}
|
|
|
|
.age {
|
|
font-size: 28rpx;
|
|
color: #ff6b6b;
|
|
}
|
|
|
|
.divider {
|
|
margin: 0 8rpx;
|
|
color: #ddd;
|
|
}
|
|
}
|
|
}
|
|
|
|
.action-buttons {
|
|
padding: 0 20rpx 20rpx;
|
|
|
|
.btn-contact {
|
|
width: 100%;
|
|
height: 72rpx;
|
|
line-height: 72rpx;
|
|
background: linear-gradient(135deg, #ff6b6b 0%, #ff5252 100%);
|
|
color: #fff;
|
|
font-size: 28rpx;
|
|
border-radius: 36rpx;
|
|
border: none;
|
|
|
|
&::after {
|
|
border: none;
|
|
}
|
|
}
|
|
}
|
|
</style>
|