import { api } from '../../utils/api' import { formatTime, getAvatarGradient } from '../../utils/format' import { AppGlobalData } from '../../types/index' const app = getApp<{ globalData: AppGlobalData }>() function normalizeAuthor(author: any, authorId = '') { return { ...(author || {}), nickName: author?.nickName || '匿名用户', avatarUrl: author?.avatarUrl || '', openid: author?.openid || authorId, } } function normalizePost(post: any) { return { authorId: '', ...(post || {}), author: normalizeAuthor(post?.author, post?.authorId), content: post?.content || '', images: Array.isArray(post?.images) ? post.images : [], hashtags: Array.isArray(post?.hashtags) ? post.hashtags : [], likeCount: typeof post?.likeCount === 'number' ? post.likeCount : 0, commentCount: typeof post?.commentCount === 'number' ? post.commentCount : 0, createdAt: post?.createdAt || '', } } function normalizeComment(comment: any) { return { authorId: '', ...(comment || {}), author: normalizeAuthor(comment?.author, comment?.authorId), content: comment?.content || '', createdAt: comment?.createdAt || '', gradient: getAvatarGradient(comment?.authorId || ''), timeText: comment?.createdAt ? formatTime(comment.createdAt) : '', } } Page({ data: { statusBarHeight: 0, postId: '', post: null as any, comments: [] as any[], avatarGradient: '', timeText: '', likeCount: 0, commentText: '', focusInput: false, pendingFocusComment: false, }, onLoad(query: { id?: string; focus?: string }) { const info = wx.getSystemInfoSync() this.setData({ statusBarHeight: info.statusBarHeight, postId: query.id || '', pendingFocusComment: query.focus === 'comment', }) this.loadPost(query.id || '') }, async loadPost(id: string) { if (!id) return try { const res = await wx.cloud.callFunction({ name: 'getPost', data: { postId: id }, }) as any const post = normalizePost(res.result?.data) if (!post?._id) return this.setData({ post, avatarGradient: getAvatarGradient(post.authorId || ''), timeText: post.createdAt ? formatTime(post.createdAt) : '', likeCount: post.likeCount, }) if (this.data.pendingFocusComment) { wx.nextTick(() => { this.setData({ focusInput: true, pendingFocusComment: false }) }) } this.loadComments(id) } catch {} }, async loadComments(postId: string) { try { const res = await api.getComments(postId) const comments = res.list.map(normalizeComment) this.setData({ comments }) } catch {} }, async onLike() { const post = this.data.post if (!post) return const was = post.isLiked this.setData({ 'post.isLiked': !was, likeCount: was ? this.data.likeCount - 1 : this.data.likeCount + 1 }) try { const res = await api.likePost(post._id) this.setData({ likeCount: res.count, 'post.isLiked': res.liked }) } catch { this.setData({ 'post.isLiked': was, likeCount: post.likeCount }) } }, onCommentInput(e: WechatMiniprogram.CustomEvent) { this.setData({ commentText: e.detail.value }) }, onCommentBlur() { this.setData({ focusInput: false }) }, async onSend() { const text = this.data.commentText.trim() if (!text || !this.data.postId) return this.setData({ commentText: '' }) try { await api.addComment(this.data.postId, text) const comments = await api.getComments(this.data.postId) this.setData({ comments: comments.list.map(normalizeComment), }) } catch { wx.showToast({ title: '发送失败', icon: 'none' }) } }, focusComment() { this.setData({ focusInput: true }) }, onAuthorTap() { const post = this.data.post if (post?.authorId) wx.navigateTo({ url: `/pages/pet-detail/pet-detail?userId=${post.authorId}` }) }, onImgTap(e: WechatMiniprogram.CustomEvent) { const post = this.data.post wx.previewImage({ current: post.images[e.currentTarget.dataset.idx], urls: post.images }) }, onMore() { wx.showActionSheet({ itemList: ['举报'], success: () => wx.showToast({ title: '已提交举报', icon: 'success' }), }) }, onBack() { wx.navigateBack() }, })