|
|
@@ -68,28 +68,34 @@
|
|
|
<view class="empty-tip" v-if="dynamicList.length === 0">
|
|
|
<text>暂无动态</text>
|
|
|
</view>
|
|
|
- <view class="dynamic-item" v-for="item in dynamicList" :key="item.dynamicId" @click="goToDetail(item.dynamicId)">
|
|
|
- <!-- 动态内容 -->
|
|
|
- <view class="dynamic-content">
|
|
|
- <text class="dynamic-text">{{ item.content }}</text>
|
|
|
+ <view class="dynamic-item" v-for="item in dynamicList" :key="item.dynamicId">
|
|
|
+ <!-- 操作菜单按钮 -->
|
|
|
+ <view class="dynamic-menu" @click.stop="showActionMenu(item)">
|
|
|
+ <text class="menu-icon">⋯</text>
|
|
|
</view>
|
|
|
- <!-- 动态图片 -->
|
|
|
- <view class="dynamic-images" v-if="item.mediaUrls">
|
|
|
- <image
|
|
|
- class="dynamic-image"
|
|
|
- v-for="(img, index) in getMediaUrls(item.mediaUrls)"
|
|
|
- :key="index"
|
|
|
- :src="img"
|
|
|
- mode="aspectFill"
|
|
|
- @click.stop="previewImage(getMediaUrls(item.mediaUrls), index)"
|
|
|
- ></image>
|
|
|
- </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">{{ item.commentCount || 0 }} 评论</text>
|
|
|
+ <view @click="goToDetail(item.dynamicId)">
|
|
|
+ <!-- 动态内容 -->
|
|
|
+ <view class="dynamic-content">
|
|
|
+ <text class="dynamic-text">{{ item.content }}</text>
|
|
|
+ </view>
|
|
|
+ <!-- 动态图片 -->
|
|
|
+ <view class="dynamic-images" v-if="item.mediaUrls">
|
|
|
+ <image
|
|
|
+ class="dynamic-image"
|
|
|
+ v-for="(img, index) in getMediaUrls(item.mediaUrls)"
|
|
|
+ :key="index"
|
|
|
+ :src="img"
|
|
|
+ mode="aspectFill"
|
|
|
+ @click.stop="previewImage(getMediaUrls(item.mediaUrls), index)"
|
|
|
+ ></image>
|
|
|
+ </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">{{ item.commentCount || 0 }} 评论</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -100,35 +106,41 @@
|
|
|
<view class="empty-tip" v-if="interactionList.length === 0">
|
|
|
<text>暂无互动</text>
|
|
|
</view>
|
|
|
- <view class="interaction-item" v-for="item in interactionList" :key="item.dynamicId" @click="goToDetail(item.dynamicId)">
|
|
|
- <!-- 用户信息 -->
|
|
|
- <view class="user-info">
|
|
|
- <image class="avatar" :src="getAvatar(item)" mode="aspectFill"></image>
|
|
|
- <view class="user-details">
|
|
|
- <text class="nickname">{{ getNickname(item) }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <!-- 互动内容 -->
|
|
|
- <view class="interaction-content">
|
|
|
- <text class="interaction-text">{{ item.content }}</text>
|
|
|
- </view>
|
|
|
- <!-- 互动图片 -->
|
|
|
- <view class="interaction-images" v-if="item.mediaUrls">
|
|
|
- <image
|
|
|
- class="interaction-image"
|
|
|
- v-for="(img, index) in getMediaUrls(item.mediaUrls)"
|
|
|
- :key="index"
|
|
|
- :src="img"
|
|
|
- mode="aspectFill"
|
|
|
- @click.stop="previewImage(getMediaUrls(item.mediaUrls), index)"
|
|
|
- ></image>
|
|
|
+ <view class="interaction-item" v-for="item in interactionList" :key="item.dynamicId">
|
|
|
+ <!-- 操作菜单按钮 -->
|
|
|
+ <view class="interaction-menu" @click.stop="showInteractionMenu(item)">
|
|
|
+ <text class="menu-icon">⋯</text>
|
|
|
</view>
|
|
|
- <!-- 互动信息 -->
|
|
|
- <view class="interaction-info">
|
|
|
- <text class="interaction-time">{{ formatTime(item.createdAt) }}</text>
|
|
|
- <view class="interaction-stats">
|
|
|
- <text class="stat-item">{{ item.likeCount || 0 }} 赞</text>
|
|
|
- <text class="stat-item">{{ item.commentCount || 0 }} 评论</text>
|
|
|
+ <view @click="goToDetail(item.dynamicId)">
|
|
|
+ <!-- 用户信息 -->
|
|
|
+ <view class="user-info">
|
|
|
+ <image class="avatar" :src="getAvatar(item)" mode="aspectFill"></image>
|
|
|
+ <view class="user-details">
|
|
|
+ <text class="nickname">{{ getNickname(item) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 互动内容 -->
|
|
|
+ <view class="interaction-content">
|
|
|
+ <text class="interaction-text">{{ item.content }}</text>
|
|
|
+ </view>
|
|
|
+ <!-- 互动图片 -->
|
|
|
+ <view class="interaction-images" v-if="item.mediaUrls">
|
|
|
+ <image
|
|
|
+ class="interaction-image"
|
|
|
+ v-for="(img, index) in getMediaUrls(item.mediaUrls)"
|
|
|
+ :key="index"
|
|
|
+ :src="img"
|
|
|
+ mode="aspectFill"
|
|
|
+ @click.stop="previewImage(getMediaUrls(item.mediaUrls), index)"
|
|
|
+ ></image>
|
|
|
+ </view>
|
|
|
+ <!-- 互动信息 -->
|
|
|
+ <view class="interaction-info">
|
|
|
+ <text class="interaction-time">{{ formatTime(item.createdAt) }}</text>
|
|
|
+ <view class="interaction-stats">
|
|
|
+ <text class="stat-item">{{ item.likeCount || 0 }} 赞</text>
|
|
|
+ <text class="stat-item">{{ item.commentCount || 0 }} 评论</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -245,7 +257,12 @@ export default {
|
|
|
},
|
|
|
// 切换互动子标签
|
|
|
switchSubTab(subTab) {
|
|
|
+ if (this.activeSubTab === subTab) {
|
|
|
+ return; // 如果点击的是当前标签,不重复加载
|
|
|
+ }
|
|
|
this.activeSubTab = subTab;
|
|
|
+ // 先清空列表
|
|
|
+ this.interactionList = [];
|
|
|
// 根据子标签加载对应数据
|
|
|
this.loadInteractionData();
|
|
|
},
|
|
|
@@ -297,26 +314,59 @@ export default {
|
|
|
// 加载互动数据
|
|
|
loadInteractionData() {
|
|
|
const userInfo = uni.getStorageSync('userInfo');
|
|
|
- if (userInfo && userInfo.userId) {
|
|
|
- if (this.activeSubTab === 'like') {
|
|
|
- // 获取用户点赞的动态列表
|
|
|
- api.dynamic.getLikedList(userInfo.userId, 1, 10).then(res => {
|
|
|
- if (res && res.records) {
|
|
|
- this.interactionList = res.records;
|
|
|
- }
|
|
|
- }).catch(err => {
|
|
|
- console.error('获取用户点赞列表失败:', err);
|
|
|
+ if (!userInfo || !userInfo.userId) {
|
|
|
+ console.warn('用户信息不存在,无法加载互动数据');
|
|
|
+ this.interactionList = [];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先清空列表,避免显示旧数据
|
|
|
+ this.interactionList = [];
|
|
|
+
|
|
|
+ if (this.activeSubTab === 'like') {
|
|
|
+ // 获取用户点赞的动态列表
|
|
|
+ console.log('开始加载点赞列表,userId:', userInfo.userId);
|
|
|
+ api.dynamic.getLikedList(userInfo.userId, 1, 10).then(res => {
|
|
|
+ console.log('点赞列表API返回数据:', res);
|
|
|
+ if (res) {
|
|
|
+ // 处理返回数据,支持多种可能的数据结构
|
|
|
+ const records = res.records || res.list || (Array.isArray(res) ? res : []);
|
|
|
+ this.interactionList = records || [];
|
|
|
+ console.log('设置点赞列表,数量:', this.interactionList.length);
|
|
|
+ } else {
|
|
|
+ this.interactionList = [];
|
|
|
+ console.log('点赞列表返回数据为空');
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ console.error('获取用户点赞列表失败:', err);
|
|
|
+ this.interactionList = [];
|
|
|
+ uni.showToast({
|
|
|
+ title: '加载点赞列表失败',
|
|
|
+ icon: 'none'
|
|
|
});
|
|
|
- } else if (this.activeSubTab === 'collect') {
|
|
|
- // 获取用户收藏的动态列表
|
|
|
- api.dynamic.getFavoritesList(userInfo.userId, 1, 10).then(res => {
|
|
|
- if (res && res.records) {
|
|
|
- this.interactionList = res.records;
|
|
|
- }
|
|
|
- }).catch(err => {
|
|
|
- console.error('获取用户收藏列表失败:', err);
|
|
|
+ });
|
|
|
+ } else if (this.activeSubTab === 'collect') {
|
|
|
+ // 获取用户收藏的动态列表
|
|
|
+ console.log('开始加载收藏列表,userId:', userInfo.userId);
|
|
|
+ api.dynamic.getFavoritesList(userInfo.userId, 1, 10).then(res => {
|
|
|
+ console.log('收藏列表API返回数据:', res);
|
|
|
+ if (res) {
|
|
|
+ // 处理返回数据,支持多种可能的数据结构
|
|
|
+ const records = res.records || res.list || (Array.isArray(res) ? res : []);
|
|
|
+ this.interactionList = records || [];
|
|
|
+ console.log('设置收藏列表,数量:', this.interactionList.length);
|
|
|
+ } else {
|
|
|
+ this.interactionList = [];
|
|
|
+ console.log('收藏列表返回数据为空');
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ console.error('获取用户收藏列表失败:', err);
|
|
|
+ this.interactionList = [];
|
|
|
+ uni.showToast({
|
|
|
+ title: '加载收藏列表失败',
|
|
|
+ icon: 'none'
|
|
|
});
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
},
|
|
|
// 加载浏览记录数据
|
|
|
@@ -420,6 +470,187 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
+ },
|
|
|
+ // 显示操作菜单
|
|
|
+ showActionMenu(item) {
|
|
|
+ uni.showActionSheet({
|
|
|
+ itemList: ['编辑动态', '删除动态'],
|
|
|
+ success: (res) => {
|
|
|
+ if (res.tapIndex === 0) {
|
|
|
+ // 编辑动态
|
|
|
+ this.editDynamic(item);
|
|
|
+ } else if (res.tapIndex === 1) {
|
|
|
+ // 删除动态
|
|
|
+ this.deleteDynamic(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 编辑动态
|
|
|
+ editDynamic(item) {
|
|
|
+ // 跳转到编辑页面,传递动态信息
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/plaza/publish?edit=true&dynamicId=${item.dynamicId}&content=${encodeURIComponent(item.content || '')}&mediaUrls=${encodeURIComponent(JSON.stringify(item.mediaUrls || []))}&mediaType=${item.mediaType || 0}&visibility=${item.visibility || 1}`
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 删除动态
|
|
|
+ deleteDynamic(item) {
|
|
|
+ uni.showModal({
|
|
|
+ title: '确认删除',
|
|
|
+ content: '确定要删除这条动态吗?删除后无法恢复。',
|
|
|
+ confirmText: '删除',
|
|
|
+ confirmColor: '#E91E63',
|
|
|
+ success: async (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ try {
|
|
|
+ const userInfo = uni.getStorageSync('userInfo');
|
|
|
+ if (!userInfo || !userInfo.userId) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请先登录',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '删除中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ await api.dynamic.deleteUserDynamic(item.dynamicId, userInfo.userId);
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: '删除成功',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 重新加载动态列表
|
|
|
+ this.loadDynamicData();
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('删除动态失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: error.message || '删除失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 显示互动操作菜单
|
|
|
+ showInteractionMenu(item) {
|
|
|
+ const menuItems = [];
|
|
|
+ if (this.activeSubTab === 'like') {
|
|
|
+ menuItems.push('取消点赞');
|
|
|
+ } else if (this.activeSubTab === 'collect') {
|
|
|
+ menuItems.push('取消收藏');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (menuItems.length === 0) return;
|
|
|
+
|
|
|
+ uni.showActionSheet({
|
|
|
+ itemList: menuItems,
|
|
|
+ success: (res) => {
|
|
|
+ if (res.tapIndex === 0) {
|
|
|
+ if (this.activeSubTab === 'like') {
|
|
|
+ this.cancelLike(item);
|
|
|
+ } else if (this.activeSubTab === 'collect') {
|
|
|
+ this.cancelFavorite(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 取消点赞
|
|
|
+ async cancelLike(item) {
|
|
|
+ try {
|
|
|
+ const userInfo = uni.getStorageSync('userInfo');
|
|
|
+ if (!userInfo || !userInfo.userId) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请先登录',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '处理中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ await api.dynamic.unlike(item.dynamicId, userInfo.userId);
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: '已取消点赞',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 通知其他页面更新状态(如首页、详情页)
|
|
|
+ uni.$emit('dynamic-updated', {
|
|
|
+ dynamicId: item.dynamicId,
|
|
|
+ isLiked: false,
|
|
|
+ likeCount: Math.max(0, (item.likeCount || 0) - 1)
|
|
|
+ });
|
|
|
+
|
|
|
+ // 从列表中移除该项
|
|
|
+ const index = this.interactionList.findIndex(i => i.dynamicId === item.dynamicId);
|
|
|
+ if (index !== -1) {
|
|
|
+ this.interactionList.splice(index, 1);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('取消点赞失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: error.message || '操作失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 取消收藏
|
|
|
+ async cancelFavorite(item) {
|
|
|
+ try {
|
|
|
+ const userInfo = uni.getStorageSync('userInfo');
|
|
|
+ if (!userInfo || !userInfo.userId) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请先登录',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '处理中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ await api.dynamic.unfavorite(item.dynamicId, userInfo.userId);
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: '已取消收藏',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 通知其他页面更新状态(如首页、详情页)
|
|
|
+ uni.$emit('dynamic-updated', {
|
|
|
+ dynamicId: item.dynamicId,
|
|
|
+ isFavorited: false,
|
|
|
+ favoriteCount: Math.max(0, (item.favoriteCount || 0) - 1)
|
|
|
+ });
|
|
|
+
|
|
|
+ // 从列表中移除该项
|
|
|
+ const index = this.interactionList.findIndex(i => i.dynamicId === item.dynamicId);
|
|
|
+ if (index !== -1) {
|
|
|
+ this.interactionList.splice(index, 1);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('取消收藏失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: error.message || '操作失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -585,12 +816,53 @@ export default {
|
|
|
.browse-item {
|
|
|
padding: 30rpx;
|
|
|
border-bottom: 2rpx solid #F5F5F5;
|
|
|
+ position: relative;
|
|
|
|
|
|
&:last-child {
|
|
|
border-bottom: none;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* 动态操作菜单 */
|
|
|
+.dynamic-menu {
|
|
|
+ position: absolute;
|
|
|
+ top: 30rpx;
|
|
|
+ right: 30rpx;
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 10;
|
|
|
+
|
|
|
+ .menu-icon {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #999999;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 互动操作菜单 */
|
|
|
+.interaction-menu {
|
|
|
+ position: absolute;
|
|
|
+ top: 30rpx;
|
|
|
+ right: 30rpx;
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 10;
|
|
|
+
|
|
|
+ .menu-icon {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #999999;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* 用户信息 */
|
|
|
.user-info {
|
|
|
display: flex;
|