487 lines
10 KiB
Vue
487 lines
10 KiB
Vue
<template>
|
|
<view class="user-card" @click="handleCardClick">
|
|
<!-- 今天看过标识 -->
|
|
<view v-if="viewedToday" class="viewed-tag">
|
|
<text>今天看过</text>
|
|
</view>
|
|
|
|
<!-- 不公开照片样式:两列信息布局 -->
|
|
<view v-if="!isPhotoPublic || !firstPhoto" class="card-no-photo">
|
|
<!-- 标题行 -->
|
|
<view class="title-row">
|
|
<text class="gender-year">{{ genderText }} · {{ birthYear }}年</text>
|
|
<view class="title-tags">
|
|
<image v-if="isMember && memberIconUrl" class="member-icon" :src="memberIconUrl" mode="heightFix" />
|
|
<text v-else-if="isMember" class="tag tag-member">会员</text>
|
|
<text v-if="isRealName" class="tag tag-realname">已实名</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 信息区域:两列布局 -->
|
|
<view class="info-grid">
|
|
<view class="info-item">
|
|
<text class="label">年龄</text>
|
|
<text class="value">{{ age }}岁</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">身高</text>
|
|
<text class="value">{{ height }}cm</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">学历</text>
|
|
<text class="value">{{ educationName }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">体重</text>
|
|
<text class="value">{{ weight ? weight + 'kg' : '未填写' }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">收入</text>
|
|
<text class="value">{{ incomeText }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">职业</text>
|
|
<text class="value">{{ occupation || '未填写' }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">现居</text>
|
|
<text class="value">{{ workCity || '未填写' }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">家乡</text>
|
|
<text class="value">{{ hometown || '未填写' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 简介 -->
|
|
<view class="intro-section" v-if="intro">
|
|
<text class="intro-text">{{ intro }}</text>
|
|
</view>
|
|
|
|
<!-- 操作按钮 -->
|
|
<view class="action-buttons" @click.stop>
|
|
<button class="btn-detail" @click="handleCardClick">查看详细资料</button>
|
|
<button class="btn-contact" @click="handleContact">联系对方</button>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 公开照片样式:左信息右照片 -->
|
|
<view v-else class="card-with-photo">
|
|
<!-- 标题行 -->
|
|
<view class="title-row">
|
|
<text class="gender-year">{{ genderText }} · {{ birthYear }}年</text>
|
|
<view class="title-tags">
|
|
<image v-if="isMember && memberIconUrl" class="member-icon" :src="memberIconUrl" mode="heightFix" />
|
|
<text v-else-if="isMember" class="tag tag-member">会员</text>
|
|
<text v-if="isRealName" class="tag tag-realname">已实名</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 内容区域 -->
|
|
<view class="content-row">
|
|
<!-- 左侧信息 -->
|
|
<view class="info-left">
|
|
<view class="info-item">
|
|
<text class="label">现居</text>
|
|
<text class="value">{{ workCity || '未填写' }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">学历</text>
|
|
<text class="value">{{ educationName }}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">身高</text>
|
|
<text class="value">{{ height }}cm</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="label">职业</text>
|
|
<text class="value">{{ occupation || '未填写' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 右侧照片 -->
|
|
<view class="photo-right">
|
|
<image class="user-photo" :src="fullPhotoUrl" mode="aspectFill" />
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 简介 -->
|
|
<view class="intro-section" v-if="intro">
|
|
<text class="intro-text">{{ intro }}</text>
|
|
</view>
|
|
|
|
<!-- 操作按钮 -->
|
|
<view class="action-buttons" @click.stop>
|
|
<button class="btn-detail" @click="handleCardClick">查看详细资料</button>
|
|
<button class="btn-contact" @click="handleContact">联系对方</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
getFullImageUrl
|
|
} from '@/utils/image.js'
|
|
import {
|
|
useConfigStore
|
|
} from '@/store/config.js'
|
|
|
|
export default {
|
|
name: 'UserCard',
|
|
props: {
|
|
userId: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
nickname: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
avatar: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
gender: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
age: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
birthYear: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
workCity: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
hometown: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
height: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
weight: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
education: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
educationName: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
occupation: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
monthlyIncome: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
intro: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
isMember: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
memberLevel: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
isRealName: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isPhotoPublic: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
firstPhoto: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
viewedToday: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
emits: ['click', 'contact'],
|
|
computed: {
|
|
genderText() {
|
|
return this.gender === 1 ? '男' : '女'
|
|
},
|
|
fullPhotoUrl() {
|
|
return getFullImageUrl(this.firstPhoto)
|
|
},
|
|
incomeText() {
|
|
if (!this.monthlyIncome) return '未填写'
|
|
if (this.monthlyIncome < 5000) return '5千以下'
|
|
if (this.monthlyIncome < 8000) return '5千~8千/月'
|
|
if (this.monthlyIncome < 10000) return '8千~1万/月'
|
|
if (this.monthlyIncome < 15000) return '1万~1.5万/月'
|
|
if (this.monthlyIncome < 20000) return '1.5万~2万/月'
|
|
if (this.monthlyIncome < 30000) return '2万~3万/月'
|
|
return '3万以上/月'
|
|
},
|
|
memberIconUrl() {
|
|
if (!this.isMember || !this.memberLevel) return ''
|
|
const configStore = useConfigStore()
|
|
const iconUrl = configStore.getMemberIcon(this.memberLevel)
|
|
return iconUrl ? getFullImageUrl(iconUrl) : ''
|
|
}
|
|
},
|
|
methods: {
|
|
handleCardClick() {
|
|
this.$emit('click', this.userId)
|
|
},
|
|
handleContact() {
|
|
this.$emit('contact', this.userId)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.user-card {
|
|
background: linear-gradient(to bottom, #FFEBEA 0%, #FFFFFF 100%);
|
|
border-radius: 24rpx;
|
|
overflow: hidden;
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
|
|
margin-bottom: 24rpx;
|
|
position: relative;
|
|
padding: 32rpx;
|
|
}
|
|
|
|
// 今天看过标签
|
|
.viewed-tag {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
background: rgba(255, 180, 180, 0.65);
|
|
padding: 15rpx 24rpx;
|
|
border-radius: 0 24rpx 0 24rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
text {
|
|
color: #fff;
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
line-height: 1;
|
|
}
|
|
}
|
|
|
|
// 标题行
|
|
.title-row {
|
|
margin-bottom: 24rpx;
|
|
display: flex;
|
|
flex-direction: row;
|
|
|
|
.gender-year {
|
|
font-size: 42rpx;
|
|
font-weight: 600;
|
|
color: #ff6b6b;
|
|
display: inline;
|
|
margin-right: 16rpx;
|
|
}
|
|
|
|
.title-tags {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 8rpx;
|
|
vertical-align: middle;
|
|
|
|
.member-icon {
|
|
width: auto;
|
|
height: 42rpx;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.tag {
|
|
display: inline-block;
|
|
font-size: 26rpx;
|
|
padding: 6rpx 16rpx;
|
|
border-radius: 8rpx;
|
|
height: 36rpx;
|
|
line-height: 24rpx;
|
|
box-sizing: border-box;
|
|
vertical-align: middle;
|
|
|
|
&.tag-realname {
|
|
background: #3d4a4a;
|
|
color: #fff;
|
|
}
|
|
|
|
&.tag-member {
|
|
background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
|
|
color: #ff9800;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 不公开照片样式
|
|
.card-no-photo {
|
|
.info-grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
|
|
.info-item {
|
|
width: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
|
|
.label {
|
|
font-size: 32rpx;
|
|
color: #999;
|
|
width: 80rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.value {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
margin-left: 16rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 公开照片样式
|
|
.card-with-photo {
|
|
.content-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
.info-left {
|
|
flex: 1;
|
|
|
|
.info-item {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.label {
|
|
font-size: 32rpx;
|
|
color: #999;
|
|
width: 80rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.value {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
margin-left: 16rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.photo-right {
|
|
width: 200rpx;
|
|
height: 200rpx;
|
|
margin-left: 24rpx;
|
|
flex-shrink: 0;
|
|
|
|
.user-photo {
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 简介区域
|
|
.intro-section {
|
|
margin-top: 24rpx;
|
|
padding-top: 24rpx;
|
|
border-top: 1rpx solid #f5f5f5;
|
|
|
|
.intro-text {
|
|
font-size: 30rpx;
|
|
color: #333;
|
|
line-height: 1.6;
|
|
font-weight: 600;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
// 操作按钮
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 24rpx;
|
|
margin-top: 32rpx;
|
|
|
|
button {
|
|
flex: 1;
|
|
height: 80rpx;
|
|
line-height: 80rpx;
|
|
font-size: 32rpx;
|
|
border-radius: 40rpx;
|
|
border: none;
|
|
|
|
&::after {
|
|
border: none;
|
|
}
|
|
}
|
|
|
|
.btn-detail {
|
|
background: #fff;
|
|
color: #333;
|
|
border: 2rpx solid #FFCBCB;
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: -2rpx;
|
|
left: -2rpx;
|
|
right: -2rpx;
|
|
bottom: -2rpx;
|
|
background: linear-gradient(to right, #FFCBCB, #FF7B7B);
|
|
z-index: -1;
|
|
border-radius: 40rpx;
|
|
}
|
|
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: #fff;
|
|
z-index: -1;
|
|
border-radius: 38rpx;
|
|
}
|
|
}
|
|
|
|
.btn-contact {
|
|
background: linear-gradient(to right, #FFBDC2, #FF8A93);
|
|
color: #fff;
|
|
}
|
|
}
|
|
</style> |