首次提交

This commit is contained in:
zeronline
2026-06-25 08:39:47 +08:00
parent 20a93c703a
commit c5cccd346b
169 changed files with 24720 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
const api = require('../../../services/api')
Page({
data: { posts: [], page: 1, loading: true, showCreate: false, content: '' },
onShow() { this.loadFeed() },
onPullDownRefresh() { this.setData({ page: 1 }); this.loadFeed().then(() => wx.stopPullDownRefresh()) },
async loadFeed() {
try {
const data = await api.get('/api/social/feed?page=' + this.data.page + '&pageSize=20')
if (this.data.page === 1) this.setData({ posts: data.list || [] })
else this.setData({ posts: [...this.data.posts, ...(data.list || [])] })
} catch(e) {}
this.setData({ loading: false })
},
openCreate() { this.setData({ showCreate: true, content: '' }) },
closeCreate() { this.setData({ showCreate: false }) },
onContentInput(e) { this.setData({ content: e.detail.value }) },
async submitPost() {
if (!this.data.content.trim()) return
try { await api.post('/api/social/posts', { content: this.data.content.trim(), privacy: 1 }); this.closeCreate(); this.onPullDownRefresh() }
catch(e) { wx.showToast({ title: e.message || '发布失败', icon: 'none' }) }
},
async onLike(e) {
const id = e.currentTarget.dataset.id; const posts = this.data.posts
try { await api.post('/api/social/posts/' + id + '/like'); const idx = posts.findIndex(p => p.id === id); if (idx > -1) { posts[idx].likes++; this.setData({ posts }) } }
catch(e) { wx.showToast({ title: '操作失败', icon: 'none' }) }
},
loadMore() { this.setData({ page: this.data.page + 1 }); this.loadFeed() },
})
+1
View File
@@ -0,0 +1 @@
{ "navigationBarTitleText": "广场", "enablePullDownRefresh": true, "usingComponents": {} }
+29
View File
@@ -0,0 +1,29 @@
<button class="create-post-btn" bindtap="openCreate">+ 分享动态</button>
<view wx:for="{{posts}}" wx:key="id" class="post-card" wx:for-item="p">
<view class="post-header">
<view class="post-avatar">{{p.user?.nickname?.[0] || '?'}}</view>
<view><text class="post-user">{{p.user?.nickname || '用户'}}</text><text class="post-time">{{p.createdAt?.slice(0,10)}}</text></view>
</view>
<text class="post-content" wx:if="{{p.content}}">{{p.content}}</text>
<view class="post-actions">
<text class="action-btn" data-id="{{p.id}}" bindtap="onLike">{{p.likes > 0 ? '❤️' : '🤍'}} {{p.likes}}</text>
<text class="action-btn">💬 {{p.comments}}</text>
</view>
</view>
<view class="load-more" wx:if="{{posts.length>0}}" bindtap="loadMore">加载更多</view>
<view class="empty" wx:if="{{!loading && posts.length===0}}"><text>🌊</text><text class="empty-text">还没有动态</text></view>
<view wx:if="{{loading}}" class="loading">加载中...</view>
<!-- 发布弹层 -->
<view class="modal-mask" wx:if="{{showCreate}}" bindtap="closeCreate">
<view class="modal-content" catchtap="">
<text class="modal-title">发布动态</text>
<textarea class="modal-textarea" value="{{content}}" bindinput="onContentInput" placeholder="分享你的打卡故事..." maxlength="500" />
<view class="modal-actions">
<button class="cancel-btn" bindtap="closeCreate">取消</button>
<button class="submit-btn" disabled="{{!content.trim()}}" bindtap="submitPost">发布</button>
</view>
</view>
</view>
+22
View File
@@ -0,0 +1,22 @@
.create-post-btn { display: block; margin: 12px 16px; background: white; border-radius: 12px; padding: 16px; color: #86868B; font-size: 15px; text-align: left; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.post-card { background: white; border-radius: 12px; margin: 8px 16px; padding: 14px 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.post-header { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.post-avatar { width: 36px; height: 36px; border-radius: 18px; background: linear-gradient(135deg,#FF6B35,#FF4D6D); display: flex; align-items: center; justify-content: center; color: white; font-size: 14px; font-weight: 600; }
.post-user { font-size: 14px; font-weight: 600; display: block; }
.post-time { font-size: 12px; color: #86868B; }
.post-content { font-size: 15px; line-height: 1.5; display: block; }
.post-actions { display: flex; gap: 20px; padding-top: 8px; margin-top: 8px; border-top: 0.5px solid #F0F0F0; }
.action-btn { font-size: 13px; color: #86868B; }
.load-more { text-align: center; padding: 16px; color: #86868B; font-size: 14px; }
.empty { text-align: center; padding: 60px 16px; font-size: 40px; }
.empty-text { font-size: 15px; color: #86868B; display: block; margin-top: 8px; }
.loading { text-align: center; padding: 40px; color: #86868B; }
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: flex-end; z-index: 100; }
.modal-content { background: white; border-radius: 16px 16px 0 0; width: 100%; padding: 20px 16px; }
.modal-title { font-size: 17px; font-weight: 600; text-align: center; display: block; margin-bottom: 12px; }
.modal-textarea { width: 100%; border: 1px solid #E5E5EA; border-radius: 10px; padding: 12px; font-size: 15px; min-height: 120px; box-sizing: border-box; }
.modal-actions { display: flex; gap: 12px; margin-top: 12px; }
.cancel-btn { flex: 1; padding: 12px; background: #f8f8fa; border: 1px solid #E5E5EA; border-radius: 10px; font-size: 15px; text-align: center; }
.submit-btn { flex: 1; padding: 12px; background: linear-gradient(135deg,#FF6B35,#FF4D6D); color: white; border: none; border-radius: 10px; font-size: 15px; font-weight: 600; text-align: center; }
.submit-btn[disabled] { opacity: 0.5; }