Initial commit

This commit is contained in:
2026-06-05 17:46:51 +08:00
commit c04c890186
96 changed files with 6477 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
import { Post } from '../../types/index'
import { api } from '../../utils/api'
import { getAvatarGradient, getPetEmoji } from '../../utils/format'
import { PAGE_SIZE } from '../../utils/constants'
interface FeedTab { key: 'feed' | 'nearby' | 'hot'; label: string }
const app = getApp<{ userInfo: any; currentLocation: any }>()
Page({
data: {
statusBarHeight: 0,
tabBarHeight: 56,
posts: [] as Post[],
stories: [] as any[],
activeTab: 'feed' as 'feed' | 'nearby' | 'hot',
feedTabs: [
{ key: 'feed', label: '关注' },
{ key: 'nearby', label: '附近' },
{ key: 'hot', label: '热门' },
] as FeedTab[],
loading: false,
loadingMore: false,
refreshing: false,
hasMore: true,
page: 0,
hasUnread: false,
myAvatarGradient: 'linear-gradient(135deg, #ffd6e8, #fff1a6)',
myEmoji: '🐶',
},
onLoad() {
const info = wx.getSystemInfoSync()
this.setData({
statusBarHeight: info.statusBarHeight,
tabBarHeight: info.windowHeight - info.safeArea.bottom + 56,
})
this.loadFeed(true)
this.loadStories()
this.syncMyInfo()
},
onShow() {
const tabBar = this.getTabBar() as any
tabBar?.setSelected?.(0)
},
onPullDownRefresh() {
this.onRefresh()
},
async onRefresh() {
this.setData({ refreshing: true, page: 0, hasMore: true })
await this.loadFeed(true)
this.setData({ refreshing: false })
},
async loadFeed(reset = false) {
if (!reset && !this.data.hasMore) return
if (this.data.loading && !reset) return
const page = reset ? 0 : this.data.page
this.setData(reset ? { loading: true } : { loadingMore: true })
try {
const loc = app.globalData?.currentLocation
const res = await api.getPosts({
page,
type: this.data.activeTab,
latitude: loc?.latitude,
longitude: loc?.longitude,
})
const posts = reset ? res.list : [...this.data.posts, ...res.list]
this.setData({
posts,
page: page + 1,
hasMore: res.hasMore,
})
} catch (e) {
wx.showToast({ title: '加载失败,下拉重试', icon: 'none' })
} finally {
this.setData({ loading: false, loadingMore: false })
}
},
async loadStories() {
try {
const res = await wx.cloud.callFunction({
name: 'getStories',
data: {},
}) as any
if (res.result?.code === 0) {
this.setData({ stories: res.result.data || [] })
}
} catch {}
},
syncMyInfo() {
const user = app.globalData?.userInfo
if (!user) return
const pet = user.pets?.[0]
this.setData({
myAvatarGradient: getAvatarGradient(user.openid || ''),
myEmoji: pet ? getPetEmoji(pet.species, pet.breed) : '🐶',
})
},
onSwitchTab(e: WechatMiniprogram.CustomEvent) {
const key = e.currentTarget.dataset.key as 'feed' | 'nearby' | 'hot'
if (key === this.data.activeTab) return
this.setData({ activeTab: key })
this.loadFeed(true)
},
onLoadMore() {
this.loadFeed(false)
},
onLikeChange(e: WechatMiniprogram.CustomEvent) {
const { postId, liked, count } = e.detail
const posts = this.data.posts.map(p =>
p._id === postId ? { ...p, isLiked: liked, likeCount: count } : p
)
this.setData({ posts })
},
onSearch() {
wx.navigateTo({ url: '/pages/search/search' })
},
onNotify() {
wx.navigateTo({ url: '/pages/notifications/notifications' })
},
onMyStory() {
wx.navigateTo({ url: '/pages/post/post?type=story' })
},
onStoryTap(e: WechatMiniprogram.CustomEvent) {
const id = e.currentTarget.dataset.id
wx.navigateTo({ url: `/pages/story/story?id=${id}` })
},
onGoPost() {
wx.navigateTo({ url: '/pages/post/post' })
},
onShareAppMessage() {
return {
title: '汪圈 — 宠物社区',
path: '/pages/feed/feed',
}
},
})