Files
t/pages2/follow/follow.vue
T

430 lines
10 KiB
Vue
Raw 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>
<view>
<unicloud-db ref='udb' v-slot:default="{ pagination, hasMore, loading, error, options }"
orderby="last_view_time desc"
@error="onqueryerror" :page-size="10"
@onPullDownRefresh="onPullDownRefresh" @load="listLoad"
:collection="colList" >
<!-- #ifdef APP-NVUE -->
<list class="uni-list" :border="false" :style="{ height: listHeight }">
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<scroll-view
scroll-y
class="uni-list"
refresher-enabled
:refresher-triggered="loadType=== 'refresh'"
:style="{ height: listHeight }"
@refresherrefresh="refresh"
@scrolltolower="loadMore"
>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<refresh-box :loading="loading" @refresh="refresh"></refresh-box>
<!-- #endif -->
<!-- 列表渲染 -->
<template v-for="(item, index) in followLst">
<view class="follow-item">
<view class="avatar-container" @click="toPersonalpage(item)">
<cloud-image
:src="(item.fid[0].avatar_file && item.fid[0].avatar_file.url) || 'https://qnycdn.mymoyu.top/static/avatar.jpg'"
mode="aspectFill" border-radius="50%"
height="80rpx" width="80rpx"></cloud-image>
</view>
<view class="info-container" @click="toPersonalpage(item)">
{{ item.fid[0].nickname }}
</view>
<view
class="btn-container"
:class="{ 'followed': item.fid[0].isFollow }"
>
<view @click="toggleFollow(item, index)">{{ item.fid[0].isFollow ? '已关注' : '关注' }}</view>
</view>
</view>
</template>
<!-- 加载状态:上拉加载更多,加载中,没有更多数据了,加载错误 -->
<!-- #ifdef APP-PLUS -->
<uni-list-item>
<template v-slot:body>
<!-- #endif -->
<uni-load-state @networkResume="refresh"
:state="{ data: listData, pagination, hasMore, loading, error }"
@loadMore="loadMore">
</uni-load-state>
<!-- #ifdef APP-PLUS -->
</template>
</uni-list-item>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
</scroll-view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</list>
<!-- #endif -->
</unicloud-db>
</view>
</template>
<script>
import { ref, computed, onReady } from 'vue'
import statusBar from "@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar"
import refreshBox from "@/uni_modules/uni-cms-article/components/refresh-box/refreshBox.nvue"
import cloudImage from "../../components/cloud-image.vue"
const db = uniCloud.database()
import { store } from '@/pages3/uni_modules/uni-id-pages/common/store.js'
export default {
components: {
statusBar,
refreshBox,
cloudImage
},
setup() {
const udbRef = ref(null)
const showRefresh = ref(false)
const listHeight = ref(0)
const mpButtonLeftPlaceholderSize = ref(0)
const mpButtonPlaceholderSize = ref(87)
const navBarHeight = ref(44)
const listData = ref([])
const loadType = ref(null)
const followLst = ref([])
const userInfo = computed(() => store.userInfo)
const realNameStatus = computed(() => {
if (!userInfo.value.realNameAuth) return 0
return userInfo.value.realNameAuth.authStatus
})
const colList = computed(() => {
return [
db.collection("follow")
.where(followWhere.value)
.field("_id,fid,create_time")
.getTemp(),
db.collection("uni-id-users")
.field('_id,nickname,avatar_file')
.getTemp()
]
})
const followWhere = computed(() => {
return userInfo.value && userInfo.value._id
? { uid: userInfo.value._id }
: { uid: '__empty__' }
})
function toPersonalpage(item) {
uni.navigateTo({
url: "/uni_modules/zetank-personalpage/pages/personalpage/personalpage?uid=" + item.fid[0]._id
})
}
async function toggleFollow(item, index) {
try {
if (item.fid[0].isFollow === false) {
const res = await uniCloud.importObject("follow").follow({
uid: userInfo.value._id,
fid: item.fid[0]._id
})
if (res.code === 200) {
followLst.value[index].fid[0].isFollow = true
} else {
console.log(res.msg)
}
} else if (item.fid[0].isFollow === true) {
const res = await uniCloud.importObject("follow").reFollow({
uid: userInfo.value._id,
fid: item.fid[0]._id
})
if (res.code === 200) {
followLst.value[index].fid[0].isFollow = false
} else {
console.log(res.msg)
}
}
} catch (e) {
console.log(e.message)
}
}
async function listLoad(data) {
if (!data || data.length === 0) {
loadType.value = null
return 0
}
let tempFollowLst = []
data.forEach(item => {
if (item.fid && item.fid[0]) {
let newItem = {
_id: item._id,
create_time: item.create_time,
fid: [{
_id: item.fid[0]._id,
nickname: item.fid[0].nickname || '未知用户',
avatar_file: item.fid[0].avatar_file || {},
isFollow: true
}]
}
tempFollowLst.push(newItem)
}
})
followLst.value = loadType.value === 'loadMore' ? followLst.value.concat(tempFollowLst) : tempFollowLst
listData.value = followLst.value
loadType.value = null
}
function initNavBarSize() {
// #ifdef MP-TOUTIAO
let menuButtonInfo = tt.getCustomButtonBoundingClientRect()
menuButtonInfo.width = menuButtonInfo.capsule.width
mpButtonLeftPlaceholderSize.value = menuButtonInfo.leftIcon.width + 10
// #endif
// #ifndef MP-TOUTIAO
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
// #endif
mpButtonPlaceholderSize.value = menuButtonInfo.width + 10
navBarHeight.value = uni.getSystemInfoSync().system.toLowerCase().includes('ios') ? 44 : 48
}
function refresh() {
loadType.value = 'refresh'
udbRef.value.loadData({ clear: true }, () => {
uni.stopPullDownRefresh()
// #ifdef APP-NVUE
showRefresh.value = false
// #endif
})
}
function loadMore() {
loadType.value = 'loadMore'
udbRef.value.loadMore()
}
function onqueryerror(e) {
console.error(e)
}
onReady(() => {
// #ifdef MP
initNavBarSize()
// #endif
listHeight.value = uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - navBarHeight.value + 'px'
udbRef.value.loadData()
})
return {
udbRef,
showRefresh,
listHeight,
mpButtonLeftPlaceholderSize,
mpButtonPlaceholderSize,
navBarHeight,
listData,
loadType,
followLst,
userInfo,
realNameStatus,
colList,
followWhere,
toPersonalpage,
toggleFollow,
listLoad,
initNavBarSize,
refresh,
loadMore,
onqueryerror
}
}
}
</script>
<style lang="scss" scoped>
/* #ifndef APP-NVUE */
.pages view {
display: flex;
box-sizing: border-box;
flex-direction: column;
}
/* #endif */
.pages {
background-color: #FFFFFF;
}
.refresh {
text-align: center;
}
.nav-box {
background-color: #FFFFFF;
position: fixed;
top: 0;
left: 0;
right: 0;
/* #ifndef APP-PLUS */
z-index: 9;
/* #endif */
}
.pages .nav {
display: flex;
align-items: center;
flex-direction: row;
}
.uni-search-box {
flex: 1;
padding: 0 10px;
}
.uni-search-box ::v-deep .uni-searchbar {
padding: 0;
}
.uni-search-box ::v-deep .uni-searchbar__box {
height: 32px;
flex-direction: row;
}
.cover-search-bar {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
.pages .uni-list ::v-deep .uni-list-item__container {
flex-direction: row;
width: 100%;
}
.pages .uni-list ::v-deep .uni-list-item {
align-items: flex-start;
}
.pages .uni-list ::v-deep .uni-load-more {
display: flex;
}
.pages .uni-list ::v-deep .uni-list--border:after {
background-color: #f5f5f5;
}
.main {
display: flex;
justify-content: space-between;
flex-direction: column;
flex: 1;
padding-left: 30rpx;
padding-right: 30rpx;
padding-top: 24rpx;
padding-bottom: 24rpx;
.title {
font-size: 30rpx;
color: #bbb;
}
.thumbnails {
margin: 20rpx 0;
display: flex;
align-items: center;
flex-direction: row;
.img {
flex: 1;
/* #ifndef APP-NVUE */
width: auto;
/* #endif */
height: 200rpx;
border-radius: 8rpx;
margin: 0 10rpx;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
}
}
.info {
display: flex;
flex-direction: row;
margin-top: 20rpx;
}
.author,
.publish_date {
font-size: 24rpx;
color: #bbbbbb;
}
.publish_date {
margin-left: 14rpx;
}
}
/* 父容器设置 */
.follow-item {
will-change: transform;
display: flex;
align-items: center;
padding: 24rpx;
margin: 20rpx;
background: #FFFFFF;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}
/* 头像区块 (占1份) */
.avatar-container {
flex: 1;
min-width: 0;
margin-right: 20rpx;
}
/* 信息区块 (占3份) */
.info-container {
flex: 3;
min-width: 0;
overflow: hidden;
}
.name {
font-size: 32rpx;
color: #333;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
/* 按钮区块 (占2份) */
.btn-container {
flex:1.5;
text-align: center;
padding: 12rpx 24rpx;
border: 1rpx solid #07C160;
border-radius: 40rpx;
color: #07C160;
transition: all 0.3s;
}
.btn-container.followed {
border-color: #CCCCCC;
color: #666666;
background: #F8F8F8;
}
</style>