|
|
@@ -0,0 +1,704 @@
|
|
|
+<template>
|
|
|
+ <view class="user-detail-page">
|
|
|
+ <!-- 自定义导航栏 -->
|
|
|
+ <view class="custom-navbar">
|
|
|
+ <view class="navbar-left" @click="goBack">
|
|
|
+ <text class="back-icon">←</text>
|
|
|
+ </view>
|
|
|
+ <view class="navbar-title">用户详情</view>
|
|
|
+ <view class="navbar-right"></view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <scroll-view scroll-y class="page-content" v-if="userInfo">
|
|
|
+ <!-- 用户头像和基本信息 -->
|
|
|
+ <view class="user-header">
|
|
|
+ <image
|
|
|
+ :src="userInfo.avatar || userInfo.avatarUrl || '/static/close.png'"
|
|
|
+ class="user-avatar"
|
|
|
+ mode="aspectFill"
|
|
|
+ @error="onAvatarError"
|
|
|
+ />
|
|
|
+ <view class="user-basic">
|
|
|
+ <view class="user-name-row">
|
|
|
+ <text class="user-name">{{ userInfo.nickname || '未设置' }}</text>
|
|
|
+ <view class="score-badge" v-if="compatibilityScore">
|
|
|
+ <text>匹配度 {{ fmtScore(compatibilityScore) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="user-meta">
|
|
|
+ <text v-if="userInfo.genderText">{{ userInfo.genderText }}</text>
|
|
|
+ <text v-if="userInfo.age">{{ userInfo.age }}岁</text>
|
|
|
+ <text v-if="userInfo.height">{{ userInfo.height }}cm</text>
|
|
|
+ <text v-if="userInfo.educationText">{{ userInfo.educationText }}</text>
|
|
|
+ <text v-if="userInfo.salaryText">{{ userInfo.salaryText }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="user-tags" v-if="hasTags">
|
|
|
+ <text v-if="userInfo.star" class="tag">{{ userInfo.star }}</text>
|
|
|
+ <text v-if="userInfo.animal" class="tag">{{ userInfo.animal }}</text>
|
|
|
+ <text v-if="userInfo.jobTitle" class="tag">{{ userInfo.jobTitle }}</text>
|
|
|
+ <text v-for="t in parseHobby(userInfo.hobby)" :key="t" class="tag">{{ t }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 详细信息 -->
|
|
|
+ <view class="detail-section">
|
|
|
+ <view class="section-title">详细信息</view>
|
|
|
+ <view class="detail-grid">
|
|
|
+ <view class="detail-item" v-if="userInfo.schoolName">
|
|
|
+ <text class="detail-label">毕业院校</text>
|
|
|
+ <text class="detail-value">{{ userInfo.schoolName }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item" v-if="userInfo.company">
|
|
|
+ <text class="detail-label">工作单位</text>
|
|
|
+ <text class="detail-value">{{ userInfo.company }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item" v-if="userInfo.maritalText">
|
|
|
+ <text class="detail-label">婚姻状况</text>
|
|
|
+ <text class="detail-value">{{ userInfo.maritalText }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item" v-if="userInfo.houseText">
|
|
|
+ <text class="detail-label">房产</text>
|
|
|
+ <text class="detail-value">{{ userInfo.houseText }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item" v-if="userInfo.carText">
|
|
|
+ <text class="detail-label">车产</text>
|
|
|
+ <text class="detail-value">{{ userInfo.carText }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item" v-if="userInfo.weight">
|
|
|
+ <text class="detail-label">体重</text>
|
|
|
+ <text class="detail-value">{{ userInfo.weight }}kg</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 自我简介 -->
|
|
|
+ <view class="detail-section" v-if="userInfo.introduction">
|
|
|
+ <view class="section-title">自我简介</view>
|
|
|
+ <view class="introduction-content">
|
|
|
+ <text>{{ userInfo.introduction }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 动态区域 -->
|
|
|
+ <view class="dynamic-section">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">动态</text>
|
|
|
+ <text class="section-more" @click="viewAllDynamics" v-if="dynamicList.length > 0">
|
|
|
+ 查看全部({{ totalDynamics }}) >
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 动态列表 -->
|
|
|
+ <view v-if="loadingDynamics" class="loading-tip">
|
|
|
+ <text>加载动态中...</text>
|
|
|
+ </view>
|
|
|
+ <view v-else-if="dynamicList.length === 0" class="empty-dynamics">
|
|
|
+ <text class="empty-icon">📝</text>
|
|
|
+ <text class="empty-text">该用户还没有发布动态</text>
|
|
|
+ </view>
|
|
|
+ <view v-else class="dynamic-list">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in dynamicList"
|
|
|
+ :key="item.dynamicId || index"
|
|
|
+ class="dynamic-item"
|
|
|
+ @click="viewDynamicDetail(item)"
|
|
|
+ >
|
|
|
+ <!-- 动态内容 -->
|
|
|
+ <view class="dynamic-content" v-if="item.content">
|
|
|
+ <text class="dynamic-text">{{ item.content }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 动态媒体(照片/视频) -->
|
|
|
+ <view class="dynamic-media" v-if="item.mediaUrls && item.mediaUrls.length > 0">
|
|
|
+ <view :class="['media-grid', getGridClass(item)]">
|
|
|
+ <image
|
|
|
+ v-for="(url, idx) in item.mediaUrls.slice(0, 9)"
|
|
|
+ :key="idx"
|
|
|
+ :src="url"
|
|
|
+ class="media-image"
|
|
|
+ mode="aspectFill"
|
|
|
+ @click.stop="previewMedia(item.mediaUrls, idx)"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 动态信息 -->
|
|
|
+ <view class="dynamic-info">
|
|
|
+ <text class="dynamic-time">{{ formatTime(item.createdAt) }}</text>
|
|
|
+ <view class="dynamic-stats">
|
|
|
+ <text class="stat-item">❤️ {{ item.likeCount || 0 }}</text>
|
|
|
+ <text class="stat-item comment-stat" @click.stop="viewDynamicComments(item)">💬 {{ item.commentCount || 0 }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 加载中 -->
|
|
|
+ <view v-else class="loading-container">
|
|
|
+ <text>加载中...</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import api from '@/utils/api.js'
|
|
|
+
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ userId: null,
|
|
|
+ userInfo: null,
|
|
|
+ compatibilityScore: null,
|
|
|
+ dynamicList: [],
|
|
|
+ loadingDynamics: false,
|
|
|
+ totalDynamics: 0,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 6
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ computed: {
|
|
|
+ hasTags() {
|
|
|
+ return this.userInfo && (
|
|
|
+ this.userInfo.star ||
|
|
|
+ this.userInfo.animal ||
|
|
|
+ this.userInfo.jobTitle ||
|
|
|
+ this.userInfo.hobby
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ onLoad(options) {
|
|
|
+ if (options.userId) {
|
|
|
+ this.userId = parseInt(options.userId)
|
|
|
+ if (options.score) {
|
|
|
+ this.compatibilityScore = parseFloat(options.score)
|
|
|
+ }
|
|
|
+ this.loadUserInfo()
|
|
|
+ this.loadUserDynamics()
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '用户ID无效',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 1500)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ // 加载用户信息
|
|
|
+ async loadUserInfo() {
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: '加载中...' })
|
|
|
+ const detail = await api.user.getDetailInfo(this.userId)
|
|
|
+ if (detail) {
|
|
|
+ // 确保photos是数组
|
|
|
+ if (!detail.photos || !Array.isArray(detail.photos)) {
|
|
|
+ detail.photos = []
|
|
|
+ if (detail.avatar) {
|
|
|
+ detail.photos.push(detail.avatar)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.userInfo = detail
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '用户信息不存在',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 1500)
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('获取用户信息失败:', e)
|
|
|
+ uni.showToast({
|
|
|
+ title: '获取用户信息失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加载用户动态
|
|
|
+ async loadUserDynamics() {
|
|
|
+ if (!this.userId) return
|
|
|
+
|
|
|
+ this.loadingDynamics = true
|
|
|
+ try {
|
|
|
+ const currentUserId = uni.getStorageSync('userId')
|
|
|
+ const params = {
|
|
|
+ pageNum: this.pageNum,
|
|
|
+ pageSize: this.pageSize,
|
|
|
+ currentUserId: currentUserId ? parseInt(currentUserId) : null
|
|
|
+ }
|
|
|
+ const result = await api.dynamic.getUserDynamics(this.userId, params)
|
|
|
+ console.log('用户动态API返回:', result)
|
|
|
+
|
|
|
+ // 处理PageResult格式:{ records: [], total: 0, current: 1, size: 10 }
|
|
|
+ let list = []
|
|
|
+ let total = 0
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ // PageResult格式:{ records: [], total: 0 }
|
|
|
+ if (result.records && Array.isArray(result.records)) {
|
|
|
+ list = result.records
|
|
|
+ total = result.total || 0
|
|
|
+ }
|
|
|
+ // 兼容格式:{ list: [], total: 0 }
|
|
|
+ else if (result.list && Array.isArray(result.list)) {
|
|
|
+ list = result.list
|
|
|
+ total = result.total || result.list.length
|
|
|
+ }
|
|
|
+ // 直接是数组
|
|
|
+ else if (Array.isArray(result)) {
|
|
|
+ list = result
|
|
|
+ total = result.length
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理mediaUrls字段(可能是字符串需要解析)
|
|
|
+ list = list.map(item => {
|
|
|
+ if (item.mediaUrls && typeof item.mediaUrls === 'string') {
|
|
|
+ try {
|
|
|
+ item.mediaUrls = JSON.parse(item.mediaUrls)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析mediaUrls失败:', e)
|
|
|
+ item.mediaUrls = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!item.mediaUrls || !Array.isArray(item.mediaUrls)) {
|
|
|
+ item.mediaUrls = []
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
+
|
|
|
+ this.dynamicList = list
|
|
|
+ this.totalDynamics = total
|
|
|
+ console.log('处理后的动态列表:', this.dynamicList)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('获取用户动态失败:', e)
|
|
|
+ uni.showToast({
|
|
|
+ title: '加载动态失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ } finally {
|
|
|
+ this.loadingDynamics = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查看全部动态
|
|
|
+ viewAllDynamics() {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/recommend/user-dynamics?userId=${this.userId}`
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查看动态详情
|
|
|
+ viewDynamicDetail(item) {
|
|
|
+ if (!item || !item.dynamicId) {
|
|
|
+ console.error('动态项无效:', item)
|
|
|
+ uni.showToast({
|
|
|
+ title: '动态信息无效',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/plaza/detail?dynamicId=${item.dynamicId}`
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查看动态评论
|
|
|
+ viewDynamicComments(item) {
|
|
|
+ if (!item || !item.dynamicId) {
|
|
|
+ console.error('动态项无效:', item)
|
|
|
+ uni.showToast({
|
|
|
+ title: '动态信息无效',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/plaza/detail?dynamicId=${item.dynamicId}&scrollToComment=true`
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 预览媒体
|
|
|
+ previewMedia(urls, index) {
|
|
|
+ if (!urls || urls.length === 0) return
|
|
|
+ uni.previewImage({
|
|
|
+ urls: urls,
|
|
|
+ current: index
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取网格类名
|
|
|
+ getGridClass(item) {
|
|
|
+ const count = item.mediaUrls ? item.mediaUrls.length : 0
|
|
|
+ if (count === 1) return 'grid-1'
|
|
|
+ if (count === 2 || count === 4) return 'grid-2'
|
|
|
+ return 'grid-3'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 格式化时间
|
|
|
+ formatTime(timeStr) {
|
|
|
+ if (!timeStr) return ''
|
|
|
+ const date = new Date(timeStr)
|
|
|
+ const now = new Date()
|
|
|
+ const diff = now - date
|
|
|
+ const minutes = Math.floor(diff / 60000)
|
|
|
+ const hours = Math.floor(diff / 3600000)
|
|
|
+ const days = Math.floor(diff / 86400000)
|
|
|
+
|
|
|
+ if (minutes < 1) return '刚刚'
|
|
|
+ if (minutes < 60) return `${minutes}分钟前`
|
|
|
+ if (hours < 24) return `${hours}小时前`
|
|
|
+ if (days < 7) return `${days}天前`
|
|
|
+ return date.toLocaleDateString()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 格式化匹配度
|
|
|
+ fmtScore(s) {
|
|
|
+ return s ? Number(s).toFixed(1) : '0.0'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 解析兴趣爱好
|
|
|
+ parseHobby(h) {
|
|
|
+ try {
|
|
|
+ const arr = typeof h === 'string' ? JSON.parse(h) : h
|
|
|
+ return Array.isArray(arr) ? arr.slice(0, 6) : []
|
|
|
+ } catch {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 头像加载错误
|
|
|
+ onAvatarError() {
|
|
|
+ if (this.userInfo) {
|
|
|
+ this.userInfo.avatar = '/static/close.png'
|
|
|
+ this.userInfo.avatarUrl = '/static/close.png'
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 返回
|
|
|
+ goBack() {
|
|
|
+ uni.navigateBack()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.user-detail-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #F5F5F5;
|
|
|
+ padding-top: 90rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 自定义导航栏 */
|
|
|
+.custom-navbar {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ height: 90rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-bottom: 2rpx solid #E0E0E0;
|
|
|
+ z-index: 999;
|
|
|
+}
|
|
|
+
|
|
|
+.navbar-left,
|
|
|
+.navbar-right {
|
|
|
+ width: 80rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.back-icon {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.navbar-title {
|
|
|
+ flex: 1;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+/* 页面内容 */
|
|
|
+.page-content {
|
|
|
+ height: calc(100vh - 90rpx);
|
|
|
+ padding: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 用户头部 */
|
|
|
+.user-header {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ border: 2rpx solid #E0E0E0;
|
|
|
+}
|
|
|
+
|
|
|
+.user-avatar {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ border-radius: 80rpx;
|
|
|
+ margin-right: 24rpx;
|
|
|
+ border: 4rpx solid #FFE5F1;
|
|
|
+ background: #F5F5F5;
|
|
|
+}
|
|
|
+
|
|
|
+.user-basic {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.user-name-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.user-name {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.score-badge {
|
|
|
+ background: #FFE5F1;
|
|
|
+ color: #E91E63;
|
|
|
+ padding: 6rpx 16rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.user-meta {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 16rpx;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.user-tags {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.tag {
|
|
|
+ background: #F5F5F5;
|
|
|
+ color: #666;
|
|
|
+ padding: 8rpx 16rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ border: 1rpx solid #E0E0E0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 详细信息区域 */
|
|
|
+.detail-section {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ border: 2rpx solid #E0E0E0;
|
|
|
+}
|
|
|
+
|
|
|
+.section-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding-bottom: 12rpx;
|
|
|
+ border-bottom: 2rpx solid #F0F0F0;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(2, 1fr);
|
|
|
+ gap: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-label {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.introduction-content {
|
|
|
+ background: #F8F9FA;
|
|
|
+ padding: 20rpx;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ border-left: 4rpx solid #E91E63;
|
|
|
+ line-height: 1.8;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+/* 动态区域 */
|
|
|
+.dynamic-section {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ border: 2rpx solid #E0E0E0;
|
|
|
+}
|
|
|
+
|
|
|
+.section-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding-bottom: 12rpx;
|
|
|
+ border-bottom: 2rpx solid #F0F0F0;
|
|
|
+}
|
|
|
+
|
|
|
+.section-more {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #E91E63;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-item {
|
|
|
+ padding: 20rpx;
|
|
|
+ background: #F8F9FA;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ border: 1rpx solid #E0E0E0;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-content {
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 1.6;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ -webkit-line-clamp: 3;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-media {
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.media-grid {
|
|
|
+ display: grid;
|
|
|
+ gap: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.grid-1 {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+}
|
|
|
+
|
|
|
+.grid-2 {
|
|
|
+ grid-template-columns: repeat(2, 1fr);
|
|
|
+}
|
|
|
+
|
|
|
+.grid-3 {
|
|
|
+ grid-template-columns: repeat(3, 1fr);
|
|
|
+}
|
|
|
+
|
|
|
+.media-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 200rpx;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ background: #F5F5F5;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-info {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-stats {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-item {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-stat {
|
|
|
+ cursor: pointer;
|
|
|
+ transition: opacity 0.2s;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-stat:active {
|
|
|
+ opacity: 0.6;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-dynamics {
|
|
|
+ text-align: center;
|
|
|
+ padding: 60rpx 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-icon {
|
|
|
+ font-size: 80rpx;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.loading-tip {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40rpx;
|
|
|
+ color: #999;
|
|
|
+ font-size: 26rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.loading-container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 100vh;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|