2025-06-09 11:33:50 +08:00

500 lines
10 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>