Browse Source

修复eggbar提交功能,解决服务器启动问题并添加eggbar页面

pull/18/head
徐飞洋 1 month ago
parent
commit
18ee4d2a12
  1. 6
      app.json
  2. 4
      custom-tab-bar/index.js
  3. 4
      custom-tab-bar/index.wxml
  4. 174
      pages/eggbar/create-post.js
  5. 9
      pages/eggbar/create-post.json
  6. 68
      pages/eggbar/create-post.wxml
  7. 281
      pages/eggbar/create-post.wxss
  8. 148
      pages/eggbar/eggbar.js
  9. 12
      pages/eggbar/eggbar.json
  10. 79
      pages/eggbar/eggbar.wxml
  11. 270
      pages/eggbar/eggbar.wxss
  12. 120
      server-example/server-mysql.js
  13. 60
      utils/api.js

6
app.json

@ -9,6 +9,8 @@
"pages/evaluate2/one",
"pages/evaluate2/product-list",
"pages/evaluate2/spec-detail",
"pages/eggbar/eggbar",
"pages/eggbar/create-post",
"pages/settlement/index",
"pages/publish/index",
"pages/buyer/index",
@ -85,8 +87,8 @@
"text": "估"
},
{
"pagePath": "pages/settlement/index",
"text": "入驻"
"pagePath": "pages/eggbar/eggbar",
"text": "蛋吧"
},
{
"pagePath": "pages/favorites/index",

4
custom-tab-bar/index.js

@ -16,7 +16,7 @@ Component({
{ key: 'index', route: 'pages/index/index' },
{ key: 'chat', route: 'pages/chat/index', badgeKey: 'chat' },
{ key: 'evaluate', route: 'pages/evaluate2/one' },
{ key: 'settlement', route: 'pages/settlement/index' },
{ key: 'settlement', route: 'pages/eggbar/eggbar' },
{ key: 'favorites', route: 'pages/favorites/index' },
{ key: 'profile', route: 'pages/profile/index' }
]
@ -95,7 +95,7 @@ Component({
'pages/index/index',
'pages/chat/index',
'pages/evaluate2/one',
'pages/settlement/index',
'pages/eggbar/eggbar',
'pages/favorites/index',
'pages/profile/index'
];

4
custom-tab-bar/index.wxml

@ -33,13 +33,13 @@
<!-- 右侧按钮组 -->
<view class="tab-bar-right">
<view class="tab-bar-item {{selected === 'settlement' ? 'active' : ''}}"
data-path="pages/settlement/index"
data-path="pages/eggbar/eggbar"
data-key="settlement"
bindtap="switchTab">
<view class="tab-bar-icon">
<view class="tab-bar-badge" wx:if="{{badges['settlement']}}">{{badges['settlement']}}</view>
</view>
<view class="tab-bar-text">入驻</view>
<view class="tab-bar-text">蛋吧</view>
</view>

174
pages/eggbar/create-post.js

@ -0,0 +1,174 @@
const API = require('../../utils/api.js');
Page({
data: {
content: '',
images: [],
selectedTopic: null,
showTopicModal: false,
hotTopics: []
},
onLoad() {
this.loadHotTopics();
},
loadHotTopics() {
API.getHotTopics().then(res => {
this.setData({
hotTopics: res.data || []
});
}).catch(err => {
console.error('加载热门话题失败:', err);
});
},
onContentChange(e) {
this.setData({
content: e.detail.value
});
},
chooseImage() {
if (this.data.images.length >= 9) {
wx.showToast({
title: '最多只能上传9张图片',
icon: 'none'
});
return;
}
wx.chooseImage({
count: 9 - this.data.images.length,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.setData({
images: [...this.data.images, ...res.tempFilePaths]
});
}
});
},
deleteImage(e) {
const index = e.currentTarget.dataset.index;
const images = this.data.images.filter((_, i) => i !== index);
this.setData({
images
});
},
showTopicPicker() {
this.setData({
showTopicModal: true
});
},
hideTopicPicker() {
this.setData({
showTopicModal: false
});
},
selectTopic(e) {
const topic = e.currentTarget.dataset.topic;
this.setData({
selectedTopic: topic,
showTopicModal: false
});
},
stopPropagation() {
// 阻止事件冒泡
},
cancel() {
wx.navigateBack();
},
submit() {
if (!this.data.content.trim()) {
return;
}
wx.showLoading({
title: '发布中...'
});
// 先上传图片,获取永久 URL
this.uploadImages(this.data.images)
.then(uploadedImages => {
const postData = {
content: this.data.content,
images: uploadedImages,
topic: this.data.selectedTopic
};
return API.createPost(postData);
})
.then(res => {
wx.hideLoading();
wx.showToast({
title: '发布成功',
icon: 'success'
});
setTimeout(() => {
wx.navigateBack();
}, 1000);
})
.catch(err => {
wx.hideLoading();
wx.showToast({
title: '发布失败,请重试',
icon: 'none'
});
console.error('发布动态失败:', err);
});
},
// 上传图片获取永久 URL
uploadImages(tempImagePaths) {
return new Promise((resolve, reject) => {
if (!tempImagePaths || tempImagePaths.length === 0) {
resolve([]);
return;
}
const uploadedImages = [];
let uploadedCount = 0;
tempImagePaths.forEach((tempPath, index) => {
wx.uploadFile({
url: API.BASE_URL + '/api/eggbar/upload',
filePath: tempPath,
name: 'image',
formData: {
index: index,
total: tempImagePaths.length
},
success: (res) => {
if (res.statusCode === 200) {
try {
const data = JSON.parse(res.data);
if (data.success && data.imageUrl) {
uploadedImages.push(data.imageUrl);
}
} catch (e) {
console.error('解析上传响应失败:', e);
}
}
},
fail: (err) => {
console.error('上传图片失败:', err);
},
complete: () => {
uploadedCount++;
if (uploadedCount === tempImagePaths.length) {
resolve(uploadedImages);
}
}
});
});
});
}
});

9
pages/eggbar/create-post.json

@ -0,0 +1,9 @@
{
"usingComponents": {},
"enablePullDownRefresh": false,
"backgroundTextStyle": "dark",
"backgroundColor": "#f8f8f8",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "发布动态",
"navigationBarTextStyle": "black"
}

68
pages/eggbar/create-post.wxml

@ -0,0 +1,68 @@
<view>
<view class="header">
<text class="title">发布动态</text>
</view>
<view class="form">
<view class="form-item">
<textarea
class="textarea"
placeholder="分享你的想法..."
placeholder-class="placeholder"
value="{{content}}"
bindinput="onContentChange"
maxlength="500"
></textarea>
<text class="counter">{{content.length}}/500</text>
</view>
<view class="form-item">
<view class="label">添加图片</view>
<view class="image-uploader">
<view class="upload-area" bindtap="chooseImage">
<text class="upload-icon">+</text>
<text class="upload-text">选择图片</text>
</view>
<view class="image-list">
<view class="image-item" wx:for="{{images}}" wx:key="index">
<image class="image" src="{{item}}" mode="aspectFill"></image>
<view class="image-delete" bindtap="deleteImage" data-index="{{index}}">
<text>×</text>
</view>
</view>
</view>
</view>
</view>
<view class="form-item">
<view class="label">选择话题</view>
<view class="topic-picker" bindtap="showTopicPicker">
<text class="topic-text">{{selectedTopic ? '#' + selectedTopic : '选择话题'}}</text>
<text class="topic-arrow">▼</text>
</view>
</view>
</view>
<view class="footer">
<button class="cancel-btn" bindtap="cancel">取消</button>
<button class="submit-btn" bindtap="submit" disabled="{{!content.trim()}}">
发布
</button>
</view>
<!-- 话题选择器弹窗 -->
<view wx:if="{{showTopicModal}}" class="modal-overlay" bindtap="hideTopicPicker">
<view class="modal-container" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">选择话题</text>
<text class="modal-close" bindtap="hideTopicPicker">×</text>
</view>
<view class="modal-content">
<view class="topic-item" wx:for="{{hotTopics}}" wx:key="id" bindtap="selectTopic" data-topic="{{item.name}}">
<text class="topic-name">#{{item.name}}</text>
<text class="topic-count">{{item.count}}人讨论</text>
</view>
</view>
</view>
</view>
</view>

281
pages/eggbar/create-post.wxss

@ -0,0 +1,281 @@
page {
background-color: #f5f5f5;
height: 100vh;
}
.container {
min-height: 100vh;
padding: 20rpx;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.3);
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #ffffff;
}
.form {
background: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
.form-item {
margin-bottom: 30rpx;
}
.label {
font-size: 28rpx;
font-weight: 600;
color: #333333;
margin-bottom: 15rpx;
}
.textarea {
width: 100%;
min-height: 200rpx;
font-size: 28rpx;
color: #333333;
border: 2rpx solid #f0f0f0;
border-radius: 12rpx;
padding: 20rpx;
box-sizing: border-box;
resize: none;
line-height: 1.6;
}
.placeholder {
color: #999999;
}
.counter {
display: block;
text-align: right;
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
.image-uploader {
margin-top: 10rpx;
}
.upload-area {
width: 120rpx;
height: 120rpx;
border: 2rpx dashed #e0e0e0;
border-radius: 12rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #fafafa;
margin-bottom: 15rpx;
transition: all 0.3s ease;
}
.upload-area:active {
background: #f0f0f0;
transform: scale(0.98);
}
.upload-icon {
font-size: 48rpx;
color: #999999;
margin-bottom: 10rpx;
}
.upload-text {
font-size: 24rpx;
color: #999999;
}
.image-list {
display: flex;
gap: 15rpx;
flex-wrap: wrap;
margin-top: 15rpx;
}
.image-item {
position: relative;
width: 150rpx;
height: 150rpx;
border-radius: 12rpx;
overflow: hidden;
}
.image {
width: 100%;
height: 100%;
background: #f0f0f0;
}
.image-delete {
position: absolute;
top: 5rpx;
right: 5rpx;
width: 40rpx;
height: 40rpx;
background: rgba(0, 0, 0, 0.6);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 32rpx;
font-weight: bold;
transition: all 0.3s ease;
}
.image-delete:active {
background: rgba(0, 0, 0, 0.8);
transform: scale(0.9);
}
.topic-picker {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
border: 2rpx solid #f0f0f0;
border-radius: 12rpx;
background: #fafafa;
transition: all 0.3s ease;
}
.topic-picker:active {
background: #f0f0f0;
}
.topic-text {
font-size: 28rpx;
color: #333333;
}
.topic-arrow {
font-size: 20rpx;
color: #999999;
}
.footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
padding: 20rpx;
background: #ffffff;
border-top: 1rpx solid #f0f0f0;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
box-sizing: border-box;
}
.cancel-btn {
flex: 1;
height: 80rpx;
margin-right: 15rpx;
background: #f5f5f5;
color: #333333;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
font-weight: 600;
}
.submit-btn {
flex: 1;
height: 80rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
font-weight: 600;
}
.submit-btn:disabled {
background: #e0e0e0;
color: #999999;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.modal-container {
width: 80%;
max-height: 70vh;
background: #ffffff;
border-radius: 20rpx;
overflow: hidden;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.modal-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.modal-close {
font-size: 36rpx;
color: #999999;
padding: 10rpx;
}
.modal-content {
padding: 20rpx;
max-height: 50vh;
overflow-y: auto;
}
.topic-item {
padding: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
transition: all 0.3s ease;
}
.topic-item:active {
background: #f0f7ff;
}
.topic-name {
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.topic-count {
font-size: 24rpx;
color: #999999;
}

148
pages/eggbar/eggbar.js

@ -0,0 +1,148 @@
const API = require('../../utils/api.js');
Page({
data: {
hotTopics: [],
posts: [],
loading: false,
hasMore: true,
page: 1,
pageSize: 10
},
onLoad() {
this.loadHotTopics();
this.loadPosts();
},
onShow() {
this.setData({
page: 1,
hasMore: true,
posts: []
});
this.loadPosts();
},
onReachBottom() {
if (this.data.hasMore && !this.data.loading) {
this.loadPosts();
}
},
onPullDownRefresh() {
this.setData({
page: 1,
hasMore: true,
posts: []
});
this.loadHotTopics();
this.loadPosts();
wx.stopPullDownRefresh();
},
loadHotTopics() {
API.getHotTopics().then(res => {
this.setData({
hotTopics: res.data || []
});
}).catch(err => {
console.error('加载热门话题失败:', err);
});
},
loadPosts() {
if (this.data.loading) {
return;
}
this.setData({
loading: true
});
API.getPosts({
page: this.data.page,
pageSize: this.data.pageSize
}).then(res => {
const newPosts = res.data || [];
this.setData({
posts: this.data.page === 1 ? newPosts : [...this.data.posts, ...newPosts],
loading: false,
hasMore: newPosts.length >= this.data.pageSize,
page: this.data.page + 1
});
}).catch(err => {
console.error('加载动态失败:', err);
this.setData({
loading: false
});
});
},
viewTopic(e) {
const topic = e.currentTarget.dataset.topic;
wx.navigateTo({
url: `/pages/eggbar/topic-detail?id=${topic.id}`
});
},
viewPost(e) {
const post = e.currentTarget.dataset.post;
wx.navigateTo({
url: `/pages/eggbar/post-detail?id=${post.id}`
});
},
likePost(e) {
const postId = e.currentTarget.dataset.id;
const posts = this.data.posts.map(post => {
if (post.id === postId) {
return {
...post,
liked: !post.liked,
likes: post.liked ? post.likes - 1 : post.likes + 1
};
}
return post;
});
this.setData({ posts });
API.likePost(postId).then(res => {
console.log('点赞成功');
}).catch(err => {
console.error('点赞失败:', err);
});
},
commentPost(e) {
const postId = e.currentTarget.dataset.id;
wx.navigateTo({
url: `/pages/eggbar/post-detail?id=${postId}&focusComment=true`
});
},
sharePost(e) {
const postId = e.currentTarget.dataset.id;
wx.showShareMenu({
withShareTicket: true,
success: () => {
console.log('分享成功');
}
});
},
createPost() {
wx.navigateTo({
url: '/pages/eggbar/create-post'
});
},
onShareAppMessage() {
return {
title: '蛋吧 - 鸡蛋行业交流社区',
path: '/pages/eggbar/eggbar',
imageUrl: '/images/eggbar-share.jpg'
};
}
});

12
pages/eggbar/eggbar.json

@ -0,0 +1,12 @@
{
"usingComponents": {
"navigation-bar": "/components/navigation-bar/navigation-bar"
},
"enablePullDownRefresh": false,
"backgroundTextStyle": "dark",
"backgroundColor": "#f8f8f8",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "蛋吧",
"navigationBarTextStyle": "black",
"navigationStyle": "custom"
}

79
pages/eggbar/eggbar.wxml

@ -0,0 +1,79 @@
<view>
<view class="content">
<view class="header">
<text class="title">蛋吧</text>
<text class="subtitle">欢迎来到蛋吧社区</text>
</view>
<view class="section">
<view class="section-title">
<text class="title-text">热门话题</text>
</view>
<view class="topic-list">
<view class="topic-item" wx:for="{{hotTopics}}" wx:key="id" bindtap="viewTopic" data-topic="{{item}}">
<view class="topic-rank">{{index + 1}}</view>
<view class="topic-info">
<text class="topic-name">{{item.name}}</text>
<text class="topic-count">{{item.count}}人讨论</text>
</view>
</view>
</view>
</view>
<view class="section">
<view class="section-title">
<text class="title-text">最新动态</text>
</view>
<view class="post-list">
<view class="post-item" wx:for="{{posts}}" wx:key="id" bindtap="viewPost" data-post="{{item}}">
<view class="post-header">
<image class="post-avatar" src="{{item.avatar}}" mode="aspectFill"></image>
<view class="post-user">
<text class="post-username">{{item.username}}</text>
<text class="post-time">{{item.time}}</text>
</view>
</view>
<view class="post-content">
<text class="post-text">{{item.content}}</text>
<view class="post-images" wx:if="{{item.images && item.images.length > 0}}">
<image class="post-image" wx:for="{{item.images}}" wx:for-item="img" wx:key="index" src="{{img}}" mode="aspectFill"></image>
</view>
</view>
<view class="post-footer">
<view class="post-action" bindtap="likePost" data-id="{{item.id}}" catchtap="true">
<text class="action-icon">{{item.liked ? '❤️' : '🤍'}}</text>
<text class="action-text">{{item.likes}}</text>
</view>
<view class="post-action" bindtap="commentPost" data-id="{{item.id}}" catchtap="true">
<text class="action-icon">💬</text>
<text class="action-text">{{item.comments}}</text>
</view>
<view class="post-action" bindtap="sharePost" data-id="{{item.id}}" catchtap="true">
<text class="action-icon">📤</text>
<text class="action-text">分享</text>
</view>
</view>
</view>
</view>
<view class="loading" wx:if="{{loading}}">
<text>加载中...</text>
</view>
<view class="no-more" wx:if="{{!hasMore && posts.length > 0}}">
<text>没有更多内容了</text>
</view>
<view class="empty" wx:if="{{posts.length === 0 && !loading}}">
<text class="empty-icon">📭</text>
<text class="empty-text">暂无动态</text>
</view>
</view>
</view>
<view class="fab-button" bindtap="createPost">
<text class="fab-icon">✏️</text>
</view>
</view>

270
pages/eggbar/eggbar.wxss

@ -0,0 +1,270 @@
page {
background-color: #f5f5f5;
height: 100vh;
}
.container {
min-height: 100vh;
padding-bottom: 120rpx;
}
.content {
padding: 20rpx;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 20rpx;
padding: 40rpx 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.3);
}
.title {
display: block;
font-size: 48rpx;
font-weight: bold;
color: #ffffff;
margin-bottom: 10rpx;
}
.subtitle {
display: block;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.9);
}
.section {
background: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
.section-title {
margin-bottom: 20rpx;
padding-bottom: 15rpx;
border-bottom: 2rpx solid #f0f0f0;
}
.title-text {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.topic-list {
display: flex;
flex-direction: column;
gap: 15rpx;
}
.topic-item {
display: flex;
align-items: center;
padding: 20rpx;
background: #f8f9fa;
border-radius: 12rpx;
transition: all 0.3s ease;
}
.topic-item:active {
transform: scale(0.98);
background: #e9ecef;
}
.topic-rank {
width: 50rpx;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;
font-size: 24rpx;
font-weight: bold;
color: #ffffff;
margin-right: 20rpx;
}
.topic-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 5rpx;
}
.topic-name {
font-size: 28rpx;
font-weight: 600;
color: #333333;
}
.topic-count {
font-size: 24rpx;
color: #999999;
}
.post-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.post-item {
background: #ffffff;
border-radius: 16rpx;
padding: 25rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.post-item:active {
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.post-header {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.post-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 15rpx;
background: #f0f0f0;
}
.post-user {
flex: 1;
display: flex;
flex-direction: column;
gap: 5rpx;
}
.post-username {
font-size: 28rpx;
font-weight: 600;
color: #333333;
}
.post-time {
font-size: 24rpx;
color: #999999;
}
.post-content {
margin-bottom: 15rpx;
}
.post-text {
display: block;
font-size: 28rpx;
color: #333333;
line-height: 1.6;
margin-bottom: 15rpx;
}
.post-images {
display: flex;
gap: 10rpx;
flex-wrap: wrap;
}
.post-image {
width: 200rpx;
height: 200rpx;
border-radius: 12rpx;
background: #f0f0f0;
}
.post-footer {
display: flex;
justify-content: space-around;
padding-top: 15rpx;
border-top: 1rpx solid #f0f0f0;
}
.post-action {
display: flex;
align-items: center;
gap: 8rpx;
padding: 10rpx 20rpx;
border-radius: 20rpx;
transition: all 0.3s ease;
}
.post-action:active {
background: #f5f5f5;
}
.action-icon {
font-size: 32rpx;
}
.action-text {
font-size: 24rpx;
color: #666666;
}
.loading {
text-align: center;
padding: 40rpx;
color: #999999;
font-size: 28rpx;
}
.no-more {
text-align: center;
padding: 40rpx;
color: #999999;
font-size: 28rpx;
}
.empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 20rpx;
}
.empty-icon {
font-size: 120rpx;
margin-bottom: 20rpx;
opacity: 0.5;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
.fab-button {
position: fixed;
right: 30rpx;
bottom: 150rpx;
width: 120rpx;
height: 120rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6rpx 20rpx rgba(102, 126, 234, 0.4);
z-index: 1000;
transition: all 0.3s ease;
}
.fab-button:active {
transform: scale(0.95);
box-shadow: 0 4rpx 15rpx rgba(102, 126, 234, 0.3);
}
.fab-icon {
font-size: 48rpx;
}

120
server-example/server-mysql.js

@ -125,6 +125,57 @@ app.post('/api/test/post', (req, res) => {
});
});
// Eggbar 帖子创建接口
app.post('/api/eggbar/posts', async (req, res) => {
try {
console.log('===== 收到帖子创建请求 =====');
console.log('1. 收到请求体:', JSON.stringify(req.body, null, 2));
const { content, images, topic } = req.body;
// 数据验证
if (!content || content.trim() === '') {
return res.status(400).json({
success: false,
code: 400,
message: '帖子内容不能为空'
});
}
// 处理图片数据,确保是JSON格式
let imagesJson = null;
if (images && Array.isArray(images) && images.length > 0) {
imagesJson = JSON.stringify(images);
}
// 创建帖子记录
const newPost = await EggbarPost.create({
content: content.trim(),
images: imagesJson,
topic: topic || null
});
console.log('2. 帖子创建成功,ID:', newPost.id);
res.json({
success: true,
code: 200,
message: '帖子发布成功',
data: {
postId: newPost.id
}
});
} catch (error) {
console.error('创建帖子失败:', error);
res.status(500).json({
success: false,
code: 500,
message: '创建帖子失败: ' + error.message
});
}
});
// 获取封面图片列表接口
app.get('/api/cover', async (req, res) => {
try {
@ -219,6 +270,39 @@ const upload = multer({
fileFilter: fileFilter
});
// Eggbar 图片上传接口
app.post('/api/eggbar/upload', upload.single('image'), async (req, res) => {
try {
console.log('===== 收到图片上传请求 =====');
console.log('1. 文件信息:', req.file);
console.log('2. 表单数据:', req.body);
if (!req.file) {
return res.status(400).json({
success: false,
message: '没有收到文件'
});
}
// 使用OSS上传图片
const imageUrl = await OssUploader.uploadFile(req.file.path, 'eggbar', 'image');
console.log('3. 图片上传成功,URL:', imageUrl);
res.json({
success: true,
message: '图片上传成功',
imageUrl: imageUrl
});
} catch (error) {
console.error('上传图片失败:', error);
res.status(500).json({
success: false,
message: '上传图片失败: ' + error.message
});
}
});
// 添加请求日志中间件,捕获所有到达服务器的请求(必须放在bodyParser之后)
app.use((req, res, next) => {
// 使用统一的时间处理函数获取当前时间
@ -1306,6 +1390,42 @@ Cover.init({
timestamps: false
});
// Eggbar 帖子模型 - 用于存储用户发布的动态
class EggbarPost extends Model { }
EggbarPost.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
comment: '帖子ID'
},
content: {
type: DataTypes.TEXT,
allowNull: false,
comment: '帖子内容'
},
images: {
type: DataTypes.TEXT,
allowNull: true,
comment: '图片URL,JSON格式存储'
},
topic: {
type: DataTypes.STRING(255),
allowNull: true,
comment: '话题'
},
created_at: {
type: DataTypes.DATE,
defaultValue: Sequelize.NOW,
comment: '创建时间'
}
}, {
sequelize,
modelName: 'EggbarPost',
tableName: 'eggbar_posts',
timestamps: false
});
// 定义模型之间的关联关系
// 用户和商品的一对多关系 (卖家发布商品)

60
utils/api.js

@ -4500,5 +4500,65 @@ module.exports = {
resolve({ exists: false, error: error.message });
});
});
},
// 获取热门话题
getHotTopics: function() {
return new Promise((resolve, reject) => {
request('/api/eggbar/hot-topics', 'GET')
.then(response => {
console.log('获取热门话题成功:', response);
resolve(response);
})
.catch(error => {
console.error('获取热门话题失败:', error);
reject(error);
});
});
},
// 获取动态列表
getPosts: function(params) {
return new Promise((resolve, reject) => {
request('/api/eggbar/posts', 'GET', params)
.then(response => {
console.log('获取动态列表成功:', response);
resolve(response);
})
.catch(error => {
console.error('获取动态列表失败:', error);
reject(error);
});
});
},
// 点赞动态
likePost: function(postId) {
return new Promise((resolve, reject) => {
request(`/api/eggbar/posts/${postId}/like`, 'POST')
.then(response => {
console.log('点赞成功:', response);
resolve(response);
})
.catch(error => {
console.error('点赞失败:', error);
reject(error);
});
});
},
// 创建动态
createPost: function(postData) {
return new Promise((resolve, reject) => {
request('/api/eggbar/posts', 'POST', postData)
.then(response => {
console.log('创建动态成功:', response);
resolve(response);
})
.catch(error => {
console.error('创建动态失败:', error);
reject(error);
});
});
}
};
Loading…
Cancel
Save