与牧同行-小程序用户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

407 lines
10 KiB

Page({
data: {
post: null,
replyContent: '',
replyTarget: {
type: '',
username: '',
replyId: '',
replyIndex: null,
commentId: '',
commentIndex: null
},
replyPlaceholder: '输入您的回复...',
isInputFocused: false,
inputTransformY: '0',
isSubmitting: false,
showPreview: false,
previewImages: [],
previewIndex: 0,
loading: false,
scrollToId: '',
currentUser: '当前用户',
keyboardHeight: 0
},
onLoad: function(options) {
const postId = options.id || '1';
this.loadPostDetail(postId);
// 监听键盘高度变化
wx.onKeyboardHeightChange(res => {
if (res.height > 0) {
this.setData({ keyboardHeight: res.height });
}
});
},
// 加载帖子详情
loadPostDetail: function(postId) {
this.setData({ loading: true });
// 模拟API请求
setTimeout(() => {
const mockPost = {
id: 1,
username: '技术爱好者',
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
time: '2小时前',
title: '微信小程序如何实现图片上传和预览功能?',
content: '我正在开发一个微信小程序,需要实现图片上传功能,并且能够在上传前预览图片。请问有什么好的实现方案吗?上传的图片大小限制和格式有什么建议?',
images: [
'https://img.yzcdn.cn/vant/cat.jpeg',
'https://img.yzcdn.cn/vant/cat.jpeg'
],
tags: ['微信小程序', '图片上传', '前端开发'],
likeCount: 12,
replyCount: 5,
viewCount: 156,
liked: false,
solved: false,
replies: [
{
replyId: 'r1_1',
username: '前端开发工程师',
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
time: '1小时前',
content: '可以使用wx.chooseImage选择图片,然后使用wx.uploadFile上传到服务器。预览功能可以使用wx.previewImage实现。',
likeCount: 3,
liked: false,
comments: [
{
commentId: 'c1_1',
username: '学习者',
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
toUsername: '前端开发工程师',
time: '30分钟前',
content: '感谢分享,请问有具体的代码示例吗?'
}
]
},
{
replyId: 'r1_2',
username: '小程序开发者',
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
time: '45分钟前',
content: '建议将图片大小限制在2MB以内,支持JPG、PNG格式。可以使用云开发存储功能简化上传流程。',
likeCount: 2,
liked: true,
comments: []
}
]
};
this.setData({
post: mockPost,
loading: false
});
}, 500);
},
// 滚动监听
onScroll: function(e) {
// 可以在这里实现滚动相关逻辑
},
// 输入框获取焦点
onInputFocus: function(e) {
this.setData({
isInputFocused: true,
inputTransformY: `-${e.detail.height}px`
});
},
// 输入框失去焦点
onInputBlur: function() {
this.setData({
isInputFocused: false,
inputTransformY: '0'
});
},
// 回复输入
onReplyInput: function(e) {
this.setData({
replyContent: e.detail.value
});
},
// 聚焦到输入框
focusReplyInput: function() {
this.setData({
replyTarget: {
type: 'post',
username: this.data.post.username
},
replyPlaceholder: `回复 ${this.data.post.username}...`,
replyContent: '',
isInputFocused: true
});
},
// 回复用户
replyToUser: function(e) {
const { type, index, replyIndex, commentIndex, username } = e.currentTarget.dataset;
const replyTarget = {
type: type,
username: username
};
if (type === 'reply') {
replyTarget.replyIndex = parseInt(index);
replyTarget.replyId = this.data.post.replies[index].replyId;
} else if (type === 'comment') {
replyTarget.replyIndex = parseInt(replyIndex);
replyTarget.commentIndex = parseInt(commentIndex);
replyTarget.commentId = this.data.post.replies[replyIndex].comments[commentIndex].commentId;
replyTarget.replyId = this.data.post.replies[replyIndex].replyId;
}
this.setData({
replyTarget: replyTarget,
replyPlaceholder: `回复 @${username}...`,
replyContent: '',
isInputFocused: true
});
// 滚动到输入框位置
setTimeout(() => {
this.setData({
scrollToId: type === 'reply' ? `reply-${replyTarget.replyId}` : ''
});
}, 100);
},
// 清除回复目标
clearReplyTarget: function() {
this.setData({
replyTarget: {
type: '',
username: '',
replyId: '',
replyIndex: null,
commentId: '',
commentIndex: null
},
replyPlaceholder: '输入您的回复...',
replyContent: ''
});
},
// 提交回复
submitReply: function() {
const { replyContent, replyTarget, post } = this.data;
const content = replyContent.trim();
if (!content) {
wx.showToast({ title: '请输入内容', icon: 'none' });
return;
}
if (content.length > 500) {
wx.showToast({ title: '回复内容不能超过500字', icon: 'none' });
return;
}
this.setData({ isSubmitting: true });
// 模拟网络请求
setTimeout(() => {
if (replyTarget.type === 'post') {
// 回复帖子
this.replyToPost(content);
} else if (replyTarget.type === 'reply') {
// 回复评论
this.replyToComment(content, replyTarget);
} else if (replyTarget.type === 'comment') {
// 回复评论的回复
this.replyToCommentReply(content, replyTarget);
} else {
// 普通回复(直接回复帖子)
this.replyToPost(content);
}
this.setData({ isSubmitting: false });
}, 500);
},
// 回复帖子
replyToPost: function(content) {
const post = this.data.post;
const replyId = `r${post.id}_${Date.now()}`;
const newReply = {
replyId: replyId,
username: this.data.currentUser,
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
time: '刚刚',
content: content,
likeCount: 0,
liked: false,
comments: []
};
post.replies.push(newReply);
post.replyCount += 1;
this.setData({
post: post,
replyContent: '',
replyTarget: {
type: '',
username: '',
replyId: '',
replyIndex: null,
commentId: '',
commentIndex: null
},
replyPlaceholder: '输入您的回复...',
isInputFocused: false
});
wx.showToast({
title: '回复成功',
icon: 'success',
duration: 1500
});
// 滚动到最新回复
setTimeout(() => {
this.setData({
scrollToId: `reply-${replyId}`
});
}, 800);
},
// 回复评论
replyToComment: function(content, target) {
const post = this.data.post;
const replyIndex = target.replyIndex;
const reply = post.replies[replyIndex];
const commentId = `c${reply.replyId}_${Date.now()}`;
const newComment = {
commentId: commentId,
username: this.data.currentUser,
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
toUsername: target.username,
time: '刚刚',
content: content
};
if (!reply.comments) {
reply.comments = [];
}
reply.comments.push(newComment);
this.setData({
post: post,
replyContent: '',
replyTarget: {
type: '',
username: '',
replyId: '',
replyIndex: null,
commentId: '',
commentIndex: null
},
replyPlaceholder: '输入您的回复...',
isInputFocused: false
});
wx.showToast({
title: '回复成功',
icon: 'success',
duration: 1500
});
},
// 回复评论的回复
replyToCommentReply: function(content, target) {
const post = this.data.post;
const reply = post.replies[target.replyIndex];
const originalComment = reply.comments[target.commentIndex];
const commentId = `cc${originalComment.commentId}_${Date.now()}`;
const newComment = {
commentId: commentId,
username: this.data.currentUser,
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
toUsername: target.username,
time: '刚刚',
content: content
};
reply.comments.push(newComment);
this.setData({
post: post,
replyContent: '',
replyTarget: {
type: '',
username: '',
replyId: '',
replyIndex: null,
commentId: '',
commentIndex: null
},
replyPlaceholder: '输入您的回复...',
isInputFocused: false
});
wx.showToast({
title: '回复成功',
icon: 'success',
duration: 1500
});
},
// 图片预览
previewImage: function(e) {
const imgIndex = e.currentTarget.dataset.imgIndex;
const images = this.data.post.images;
this.setData({
showPreview: true,
previewImages: images,
previewIndex: imgIndex
});
},
// 图片预览滑动
onSwiperChange: function(e) {
this.setData({
previewIndex: e.detail.current
});
},
// 隐藏预览
hidePreview: function() {
this.setData({ showPreview: false });
},
// 下拉刷新
onPullDownRefresh: function() {
if (this.data.post) {
this.loadPostDetail(this.data.post.id);
}
wx.stopPullDownRefresh();
},
// 页面上拉触底
onReachBottom: function() {
// 这里可以实现加载更多回复的逻辑
console.log('加载更多回复');
},
// 页面卸载
onUnload: function() {
// 移除键盘高度监听
wx.offKeyboardHeightChange();
}
});