76 lines
2.8 KiB
Vue
76 lines
2.8 KiB
Vue
<template>
|
|
<view class="circle-detail">
|
|
<view class="header" v-if="circle.id">
|
|
<text class="name">#{{ circle.name }}</text>
|
|
<text class="desc">{{ circle.description }}</text>
|
|
<button class="btn-join" v-if="!isMember" @tap="joinCircle">加入圈子</button>
|
|
<button class="btn-leave" v-else @tap="leaveCircle">退出圈子</button>
|
|
</view>
|
|
<view class="post-list">
|
|
<view class="post-item" v-for="item in posts" :key="item.id" @tap="goPost(item.id)">
|
|
<text class="post-title">{{ item.title }}</text>
|
|
<text class="post-meta">{{ item.user?.nickname }} · ❤ {{ item.likeCount }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { api } from '../../api/index'
|
|
import { useUserStore } from '../../store/user'
|
|
|
|
const userStore = useUserStore()
|
|
const circle = ref<any>({})
|
|
const posts = ref<any[]>([])
|
|
const isMember = ref(false)
|
|
|
|
onMounted(async () => {
|
|
const id = Number((uni as any).getCurrentInstance()?.router?.params?.id || '')
|
|
try {
|
|
const [c, p]: any = await Promise.all([
|
|
api.circles.detail(id),
|
|
api.circles.posts(id, { pageSize: 20 }),
|
|
])
|
|
circle.value = c
|
|
posts.value = p.items || []
|
|
} catch (e) { console.error(e) }
|
|
})
|
|
|
|
async function joinCircle() {
|
|
if (!userStore.isLoggedIn) { uni.navigateTo({ url: '/pages/login/index' }); return }
|
|
try {
|
|
await api.circles.join(circle.value.id)
|
|
isMember.value = true
|
|
uni.showToast({ title: '已加入', icon: 'success' })
|
|
} catch (e: any) {
|
|
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
|
|
}
|
|
}
|
|
|
|
async function leaveCircle() {
|
|
try {
|
|
await api.circles.leave(circle.value.id)
|
|
isMember.value = false
|
|
uni.showToast({ title: '已退出', icon: 'success' })
|
|
} catch (e: any) {
|
|
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
|
|
}
|
|
}
|
|
|
|
const goPost = (id: number) => uni.navigateTo({ url: `/pages/post-detail/index?id=${id}` })
|
|
</script>
|
|
|
|
<style scoped>
|
|
.circle-detail { }
|
|
.header { padding: 40rpx 30rpx; background: #fff; border-bottom: 1rpx solid #f0f0f0; }
|
|
.name { font-size: 40rpx; font-weight: bold; color: #4f8cff; display: block; }
|
|
.desc { font-size: 26rpx; color: #666; margin-top: 16rpx; display: block; }
|
|
.btn-join { background: #4f8cff; color: #fff; border-radius: 10rpx; padding: 16rpx 40rpx; font-size: 26rpx; margin-top: 20rpx; border: none; }
|
|
.btn-leave { background: #fff; color: #ff4d4f; border-radius: 10rpx; padding: 16rpx 40rpx; font-size: 26rpx; margin-top: 20rpx; border: 1rpx solid #ff4d4f; }
|
|
.post-list { padding: 20rpx 30rpx; }
|
|
.post-item { background: #fff; border-radius: 12rpx; padding: 24rpx; margin-bottom: 16rpx; }
|
|
.post-title { font-size: 28rpx; font-weight: 500; display: block; }
|
|
.post-meta { font-size: 22rpx; color: #999; margin-top: 8rpx; display: block; }
|
|
</style>
|