500 lines
10 KiB
Vue
500 lines
10 KiB
Vue
<template>
|
||
<s-layout title="社区种草" :bgStyle="{ color: '#fff' }">
|
||
<!-- 导航栏切换 -->
|
||
<view class="top-nav">
|
||
<view :class="{ active: currentTab === 0 }" @click="switchTab(0)">关注</view>
|
||
<view :class="{ active: currentTab === 1 }" @click="switchTab(1)">发现</view>
|
||
</view>
|
||
|
||
<!-- 新增的二级导航栏 -->
|
||
<view class="second-nav">
|
||
<view v-for="(item, index) in secondNavList" :key="index" :class="{ active: secondNavIndex === index }"
|
||
@click="switchSecondNav(index)">
|
||
{{ item }}
|
||
</view>
|
||
</view>
|
||
|
||
<view class="container">
|
||
<scroll-view scroll-y :style="{ height: windowHeight + 'px' }" @scrolltolower="loadMore">
|
||
<!-- 两列容器 -->
|
||
<view class="waterfall">
|
||
<!-- 左列 -->
|
||
<view class="column">
|
||
<view v-for="(item, index) in leftList" :key="'left-' + index" class="item"
|
||
@click="goDetail(item.id)">
|
||
<image :src="item.picUrl" mode="widthFix"></image>
|
||
<view class="item-content">
|
||
<text>{{ item.content }}</text>
|
||
<view class="item-actions">
|
||
<view class="action-like" @click.stop="likeItem(item.id, index, 'left')">
|
||
<image
|
||
:src="item.isLiked ? '/static/images/like-active.png' : '/static/images/like.png'"
|
||
mode="aspectFit"></image>
|
||
<text>{{ item.likeCount !== null ? item.likeCount : 0 }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 右列 -->
|
||
<view class="column">
|
||
<view v-for="(item, index) in rightList" :key="'right-' + index" class="item"
|
||
@click="goDetail(item.id)">
|
||
<image :src="item.picUrl" mode="widthFix"></image>
|
||
<view class="item-content">
|
||
<text>{{ item.content }}</text>
|
||
<view class="item-actions">
|
||
<view class="action-like" @click.stop="likeItem(item.id, index, 'right')">
|
||
<image
|
||
:src="item.isLiked ? '/static/images/like-active.png' : '/static/images/like.png'"
|
||
mode="aspectFit"></image>
|
||
<text>{{ item.likeCount !== null ? item.likeCount : 0 }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 加载提示 -->
|
||
<view class="loading">{{ loadingText }}</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<!-- 发布 -->
|
||
<view class="publish" @click="publish" :class="bottomNavigationIsCustom ? 'bottom' : ''">发布</view>
|
||
</s-layout>
|
||
</template>
|
||
|
||
<script setup>
|
||
import request from '@/sheep/request';
|
||
import SeedApi from '@/sheep/api/seedComm/seedComm.js';
|
||
import sheep from '@/sheep';
|
||
import {
|
||
baseUrl,
|
||
apiPath
|
||
} from '@/sheep/config';
|
||
import {
|
||
computed,
|
||
reactive,
|
||
nextTick,
|
||
onMounted,
|
||
ref
|
||
} from 'vue';
|
||
import {
|
||
onShow,
|
||
onReachBottom
|
||
} from '@dcloudio/uni-app';
|
||
|
||
// 响应式数据
|
||
const windowHeight = ref(0);
|
||
const allData = ref([]);
|
||
const leftList = ref([]);
|
||
const rightList = ref([]);
|
||
const page = ref(1);
|
||
const loadingText = ref('加载中...');
|
||
const currentTab = ref(1); // 0 表示关注,1 表示发现
|
||
const secondNavList = ref(['推荐', '视频', '短剧', '旅游', '美食', '游戏', '钓鱼', '服饰', '信息发布', '创业']);
|
||
const secondNavIndex = ref(0);
|
||
const isShow = ref(false);
|
||
|
||
// 点赞功能
|
||
const likeItem = async (id, index, column) => {
|
||
try {
|
||
// 先获取当前点赞状态
|
||
const {
|
||
code,
|
||
data
|
||
} = await SeedApi.getLike(id);
|
||
if (code !== 0) {
|
||
uni.showToast({
|
||
title: '获取点赞状态失败',
|
||
icon: 'fail'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 判断用户是否已点赞
|
||
const isLiked = data === true;
|
||
|
||
// 调用点赞API
|
||
const {
|
||
code: likeCode,
|
||
data: likeData
|
||
} = await SeedApi.doLike(id);
|
||
if (likeCode === 0) {
|
||
// 获取当前列表
|
||
const list = column === 'left' ? leftList.value : rightList.value;
|
||
const item = list[index];
|
||
|
||
// 更新点赞状态
|
||
item.isLiked = !isLiked; // 切换点赞状态
|
||
// 如果已点赞,likeCount+1,否则likeCount-1
|
||
item.likeCount = isLiked ? item.likeCount - 1 : item.likeCount + 1;
|
||
|
||
// 更新列表
|
||
if (column === 'left') {
|
||
leftList.value = [...leftList.value.slice(0, index), item, ...leftList.value.slice(index + 1)];
|
||
} else {
|
||
rightList.value = [...rightList.value.slice(0, index), item, ...rightList.value.slice(index +
|
||
1)];
|
||
}
|
||
|
||
// 提示用户
|
||
uni.showToast({
|
||
title: item.isLiked ? '点赞成功' : '取消点赞',
|
||
icon: 'success'
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: likeData || '点赞失败',
|
||
icon: 'fail'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('点赞请求失败:', error);
|
||
uni.showToast({
|
||
title: '网络错误,请稍后再试',
|
||
icon: 'fail'
|
||
});
|
||
}
|
||
}
|
||
// 生命周期
|
||
onMounted(() => {
|
||
windowHeight.value = uni.getSystemInfoSync().windowHeight
|
||
// loadData()
|
||
})
|
||
onShow(() => {
|
||
// 重置数据
|
||
page.value = 1
|
||
allData.value = []
|
||
leftList.value = []
|
||
rightList.value = []
|
||
loadingText.value = '加载中...'
|
||
|
||
loadData()
|
||
})
|
||
const goDetail = (id) => {
|
||
uni.navigateTo({
|
||
url: `/pages/seeding/seeding_fabu/detail?id=${id}`
|
||
});
|
||
}
|
||
// 获取数据
|
||
const loadData = async () => {
|
||
if (loadingText.value !== '加载中...') return;
|
||
try {
|
||
let newData = [];
|
||
if (currentTab.value === 0) {
|
||
newData = await getFollowList();
|
||
} else {
|
||
newData = await getlist();
|
||
}
|
||
// 获取每一项的点赞状态
|
||
for (let item of newData) {
|
||
const {
|
||
code,
|
||
data
|
||
} = await SeedApi.getLike(item.id); // 获取每条数据的点赞状态
|
||
if (code === 0) {
|
||
item.isLiked = data; // 根据返回的点赞状态设置
|
||
} else {
|
||
item.isLiked = false; // 如果获取失败,默认未点赞
|
||
}
|
||
}
|
||
allData.value = [...allData.value, ...newData];
|
||
|
||
// 简单交替分配数据
|
||
newData.forEach((item, index) => {
|
||
index % 2 === 0 ? leftList.value.push(item) : rightList.value.push(item);
|
||
});
|
||
|
||
loadingText.value = '加载完成';
|
||
} catch (error) {
|
||
console.error('加载数据失败:', error);
|
||
loadingText.value = '加载失败';
|
||
}
|
||
};
|
||
const loadMore = () => {
|
||
page.value++
|
||
loadingText.value = '加载中...'
|
||
loadData()
|
||
}
|
||
// 模拟接口请求
|
||
const mockApiRequest = () => {
|
||
return new Promise(resolve => {
|
||
setTimeout(() => {
|
||
const mockData = Array(10).fill().map((_, i) => ({
|
||
id: Date.now() + i,
|
||
title: `Item ${page.value * 10 + i}`,
|
||
image: `https://picsum.photos/300/${400 + Math.floor(Math.random() * 200)}`
|
||
}))
|
||
resolve(mockData)
|
||
}, 1000)
|
||
})
|
||
}
|
||
// 获取关注列表
|
||
async function getFollowList() {
|
||
const {
|
||
code,
|
||
data
|
||
} = await SeedApi.getSeedList({
|
||
pageNo: page.value,
|
||
});
|
||
if (code !== 0) {
|
||
return;
|
||
}
|
||
return data.list;
|
||
}
|
||
|
||
// 获取发现列表
|
||
async function getlist() {
|
||
const {
|
||
code,
|
||
data
|
||
} = await SeedApi.getSeedList({
|
||
pageNo: page.value,
|
||
});
|
||
if (code !== 0) {
|
||
return;
|
||
}
|
||
return data.list;
|
||
}
|
||
|
||
// 切换标签
|
||
const switchTab = (tabIndex) => {
|
||
currentTab.value = tabIndex;
|
||
page.value = 1;
|
||
allData.value = [];
|
||
leftList.value = [];
|
||
rightList.value = [];
|
||
loadingText.value = '加载中...';
|
||
loadData();
|
||
};
|
||
|
||
// 切换二级导航标签
|
||
const switchSecondNav = (index) => {
|
||
secondNavIndex.value = index;
|
||
page.value = 1;
|
||
allData.value = [];
|
||
leftList.value = [];
|
||
rightList.value = [];
|
||
loadingText.value = '加载中...';
|
||
loadData();
|
||
};
|
||
|
||
// 发布动态
|
||
function publish() {
|
||
uni.navigateTo({
|
||
url: '/pages/seeding/seeding_fabu/seeding_fabu', // 根据实际路径调整
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.top-nav {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 10px;
|
||
background-color: #f5f5f5;
|
||
|
||
view {
|
||
padding: 5px 20px;
|
||
cursor: pointer;
|
||
|
||
&.active {
|
||
color: #e93323;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
|
||
// .seeding {
|
||
// .list {
|
||
// background: white;
|
||
// margin: 10px;
|
||
// margin-bottom: 5px;
|
||
// padding: 10px;
|
||
|
||
// .top {
|
||
// display: flex;
|
||
// align-items: center;
|
||
|
||
// .l {
|
||
// margin-right: 10px;
|
||
|
||
// .img {
|
||
// width: 40px;
|
||
// height: 40px;
|
||
// }
|
||
// }
|
||
|
||
// .r {
|
||
// .name {
|
||
// font-weight: 700;
|
||
// }
|
||
|
||
// .time {
|
||
// font-size: 12px;
|
||
// color: rgba(163, 163, 163);
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// .content {
|
||
// margin-top: 10px;
|
||
// }
|
||
|
||
// .bottom {
|
||
// display: flex;
|
||
// justify-content: flex-end;
|
||
|
||
// .ck {
|
||
// display: flex;
|
||
// align-items: center;
|
||
// margin-right: 20px;
|
||
// color: rgba(163, 163, 163);
|
||
|
||
// .img {
|
||
// width: 20px;
|
||
// height: 20px;
|
||
// margin-right: 8px;
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// .btn {
|
||
// margin-top: 50px;
|
||
// background: white;
|
||
// display: flex;
|
||
// justify-content: center;
|
||
// flex-wrap: wrap;
|
||
|
||
// .content_cs {
|
||
// width: 100%;
|
||
// text-align: center;
|
||
// padding: 10px;
|
||
// margin: 20px 0;
|
||
// margin-bottom: 10px;
|
||
// background-color: rgba(246, 246, 246);
|
||
// }
|
||
|
||
// .pic {
|
||
// width: 100%;
|
||
// text-align: center;
|
||
// }
|
||
// }
|
||
|
||
// .dd {
|
||
// width: 100%;
|
||
// text-align: center;
|
||
// background: red;
|
||
// color: white;
|
||
// width: 50%;
|
||
// margin: 0 auto;
|
||
// padding: 10px;
|
||
// margin-bottom: 30px;
|
||
// border-radius: 15px;
|
||
// }
|
||
.second-nav {
|
||
display: flex;
|
||
justify-content: start;
|
||
padding: 10rpx;
|
||
background-color: #fff;
|
||
border-bottom: 1px solid #eaeaea;
|
||
overflow-x: auto;
|
||
white-space: nowrap;
|
||
|
||
view {
|
||
padding: 5px 10px;
|
||
cursor: pointer;
|
||
|
||
&.active {
|
||
color: #e93323;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
|
||
.waterfall {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 10rpx;
|
||
}
|
||
|
||
.column {
|
||
flex: 1;
|
||
max-width: 49%;
|
||
}
|
||
|
||
.item {
|
||
background: #fff;
|
||
margin-bottom: 20rpx;
|
||
border-radius: 10rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.item image {
|
||
width: 100%;
|
||
}
|
||
|
||
.loading {
|
||
text-align: center;
|
||
padding: 20rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.publish {
|
||
position: fixed;
|
||
z-index: 9999;
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
opacity: 1;
|
||
border-radius: 50%;
|
||
bottom: 142rpx;
|
||
right: 24rpx;
|
||
color: pink;
|
||
line-height: 100rpx;
|
||
text-align: center;
|
||
background-color: palevioletred;
|
||
// @include linear-gradient(theme);
|
||
|
||
.iconfont {
|
||
font-size: 50rpx;
|
||
}
|
||
}
|
||
|
||
.item-content {
|
||
padding: 12rpx;
|
||
|
||
.item-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 10rpx;
|
||
|
||
.action-like {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 24rpx;
|
||
|
||
image {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
margin-right: 4rpx;
|
||
}
|
||
|
||
text {
|
||
color: #999;
|
||
}
|
||
|
||
// 点赞激活状态样式
|
||
&.liked text {
|
||
color: #e93323;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |