与牧同行-小程序用户端
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.

304 lines
8.0 KiB

  1. // pages/forum/forum.js
  2. Page({
  3. data: {
  4. // 帖子列表数据
  5. posts: [],
  6. // 是否显示发帖弹窗
  7. showPostModal: false,
  8. // 发帖标题
  9. postTitle: '',
  10. // 发帖内容
  11. postContent: '',
  12. // 标签输入
  13. tagInput: '',
  14. // 已选标签
  15. selectedTags: [],
  16. // 当前回复的帖子索引
  17. activeReplyIndex: -1,
  18. // 回复内容
  19. replyContent: '',
  20. // 加载状态
  21. loading: false,
  22. },
  23. onLoad: function() {
  24. // 页面加载时获取帖子数据
  25. this.loadPosts();
  26. },
  27. onPullDownRefresh: function() {
  28. // 下拉刷新
  29. this.loadPosts();
  30. wx.stopPullDownRefresh();
  31. },
  32. // 加载帖子数据
  33. loadPosts: function() {
  34. this.setData({ loading: true });
  35. // 模拟网络请求
  36. setTimeout(() => {
  37. // 模拟数据
  38. const mockPosts = [
  39. {
  40. id: 1,
  41. username: '技术爱好者',
  42. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  43. time: '2小时前',
  44. title: '微信小程序如何实现图片上传和预览功能?',
  45. content: '我正在开发一个微信小程序,需要实现图片上传功能,并且能够在上传前预览图片。请问有什么好的实现方案吗?上传的图片大小限制和格式有什么建议?',
  46. tags: ['微信小程序', '图片上传', '前端开发'],
  47. likeCount: 12,
  48. replyCount: 5,
  49. viewCount: 156,
  50. liked: false,
  51. solved: false,
  52. showAllReplies: false,
  53. replies: [
  54. {
  55. username: '前端开发工程师',
  56. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  57. time: '1小时前',
  58. content: '可以使用wx.chooseImage选择图片,然后使用wx.uploadFile上传到服务器。预览功能可以使用wx.previewImage实现。'
  59. },
  60. {
  61. username: '小程序开发者',
  62. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  63. time: '45分钟前',
  64. content: '建议将图片大小限制在2MB以内,支持JPG、PNG格式。可以使用云开发存储功能简化上传流程。'
  65. }
  66. ]
  67. },
  68. {
  69. id: 2,
  70. username: '产品经理小王',
  71. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  72. time: '昨天 14:30',
  73. title: '如何设计一个用户友好的注册流程?',
  74. content: '我们正在设计一个新产品的注册流程,希望既保证安全性又尽量简化步骤。大家有什么好的设计建议或参考案例吗?',
  75. tags: ['产品设计', '用户体验', '注册流程'],
  76. likeCount: 8,
  77. replyCount: 3,
  78. viewCount: 89,
  79. liked: true,
  80. solved: true,
  81. showAllReplies: false,
  82. replies: [
  83. {
  84. username: 'UX设计师',
  85. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  86. time: '昨天 16:45',
  87. content: '建议采用手机号验证码注册,配合第三方登录选项。关键是将必填信息减到最少,其他信息可以后续引导补充。'
  88. }
  89. ]
  90. },
  91. {
  92. id: 3,
  93. username: '后端开发',
  94. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  95. time: '3天前',
  96. title: 'RESTful API设计的最佳实践有哪些?',
  97. content: '我正在设计一组RESTful API,想了解一些最佳实践,比如URL命名规范、状态码使用、版本控制等方面有什么推荐的做法?',
  98. tags: ['后端开发', 'API设计', 'RESTful'],
  99. likeCount: 15,
  100. replyCount: 7,
  101. viewCount: 234,
  102. liked: false,
  103. solved: false,
  104. showAllReplies: false,
  105. replies: [
  106. {
  107. username: '架构师',
  108. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  109. time: '2天前',
  110. content: '建议使用名词复数形式作为资源端点,合理使用HTTP状态码,API版本可以通过URL路径或请求头来管理。'
  111. },
  112. {
  113. username: '全栈工程师',
  114. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  115. time: '1天前',
  116. content: '不要忘记实现合适的错误处理机制,返回清晰的错误信息。同时考虑API限流和身份验证机制。'
  117. },
  118. {
  119. username: '资深开发者',
  120. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  121. time: '1天前',
  122. content: '推荐使用Swagger或OpenAPI规范来文档化你的API,这对前后端协作非常有帮助。'
  123. }
  124. ]
  125. }
  126. ];
  127. this.setData({
  128. posts: mockPosts,
  129. loading: false
  130. });
  131. }, 800);
  132. },
  133. // 显示发帖弹窗
  134. showPostModal: function() {
  135. this.setData({
  136. showPostModal: true
  137. });
  138. },
  139. // 隐藏发帖弹窗
  140. hidePostModal: function() {
  141. this.setData({
  142. showPostModal: false,
  143. postTitle: '',
  144. postContent: '',
  145. selectedTags: [],
  146. tagInput: ''
  147. });
  148. },
  149. // 防止弹窗内点击事件冒泡
  150. preventTap: function() {
  151. // 阻止事件冒泡
  152. },
  153. // 发帖标题输入
  154. onPostTitleInput: function(e) {
  155. this.setData({
  156. postTitle: e.detail.value
  157. });
  158. },
  159. // 发帖内容输入
  160. onPostContentInput: function(e) {
  161. this.setData({
  162. postContent: e.detail.value
  163. });
  164. },
  165. // 提交帖子
  166. submitPost: function() {
  167. const { postTitle, postContent, selectedTags } = this.data;
  168. if (!postTitle.trim()) {
  169. wx.showToast({
  170. title: '请输入标题',
  171. icon: 'none'
  172. });
  173. return;
  174. }
  175. if (!postContent.trim()) {
  176. wx.showToast({
  177. title: '请输入内容',
  178. icon: 'none'
  179. });
  180. return;
  181. }
  182. // 创建新帖子
  183. const newPost = {
  184. id: Date.now(),
  185. username: '当前用户',
  186. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  187. time: '刚刚',
  188. title: postTitle,
  189. content: postContent,
  190. tags: selectedTags,
  191. likeCount: 0,
  192. replyCount: 0,
  193. viewCount: 0,
  194. liked: false,
  195. solved: false,
  196. showAllReplies: false,
  197. replies: []
  198. };
  199. // 添加到帖子列表顶部
  200. const posts = this.data.posts;
  201. posts.unshift(newPost);
  202. this.setData({
  203. posts: posts,
  204. showPostModal: false,
  205. postTitle: '',
  206. postContent: '',
  207. selectedTags: [],
  208. tagInput: ''
  209. });
  210. wx.showToast({
  211. title: '发布成功',
  212. icon: 'success'
  213. });
  214. },
  215. // 显示回复输入框
  216. showReplyInput: function(e) {
  217. const index = e.currentTarget.dataset.index;
  218. this.setData({
  219. activeReplyIndex: index,
  220. replyContent: ''
  221. });
  222. },
  223. // 回复内容输入
  224. onReplyInput: function(e) {
  225. this.setData({
  226. replyContent: e.detail.value
  227. });
  228. },
  229. // 提交回复
  230. submitReply: function(e) {
  231. const index = e.currentTarget.dataset.index;
  232. const replyContent = this.data.replyContent.trim();
  233. if (!replyContent) {
  234. wx.showToast({
  235. title: '请输入回复内容',
  236. icon: 'none'
  237. });
  238. return;
  239. }
  240. const posts = this.data.posts;
  241. const post = posts[index];
  242. // 创建新回复
  243. const newReply = {
  244. username: '当前用户',
  245. avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
  246. time: '刚刚',
  247. content: replyContent
  248. };
  249. post.replies.push(newReply);
  250. post.replyCount += 1;
  251. this.setData({
  252. posts: posts,
  253. activeReplyIndex: -1,
  254. replyContent: ''
  255. });
  256. wx.showToast({
  257. title: '回复成功',
  258. icon: 'success'
  259. });
  260. },
  261. // 切换显示全部回复
  262. toggleReplies: function(e) {
  263. const index = e.currentTarget.dataset.index;
  264. const posts = this.data.posts;
  265. const post = posts[index];
  266. post.showAllReplies = !post.showAllReplies;
  267. this.setData({
  268. posts: posts
  269. });
  270. }
  271. });