uniapp+node.js前后端做帖子模块:发布帖子(社区管理平台的小程序)

@TOC


👍 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富!


0前提

温馨提示:我做的思路可能是复杂化了或者说代码写的不规范,如果你觉得可以更加简便的话欢迎分享到评论区或者自己改写一下我的代码,我的后端是写的很简单的没有什么路由分发是直接写的,你可以自由优化 小程序的其他部分你可以看看我往期的文章

1.一些准备

1.1表

帖子表 post

字段名称 类型(长度) 允许空 主键 外键 自增 唯一 说明
id int 帖子id
title varchar(20) 标题
content varchar(20) 内容
images varchar(200) 详情表
classification varchar(20) 帖子分类
likes int 点赞数
comments int 评论数
shares int 分享数
userId int 用户id
communityId int 小区id
creatTime timestamp 创建时间
updateTime timestamp 数据改变时的时间

1.2总体思路

用户可以在首页或者是在帖子详情的页面去点击一个按钮然后跳转到发布帖子的页面,填写完信息之后点击发布,后端接受信息保存到数据库中,点击发布后自动返回上一页,并且如果返回的是首页还需要重新获取一遍帖子列表的数据

2.前端

前端:当进入发帖页时还需要去阻拦一下用户,查看一下用户有没有登陆,如果登录之后才可以进入到这个发帖页(我这里是没有写的是直接默认根据用户登陆了,写的话思路就是查询本地存储是否有token和用户信息)。当进入发帖页之后用户需要去填写这个帖子的标题、内容、上传图片(我这里是没有去限制最多上传多少个图片的),选择帖子的分类(我把帖子的分类写死了的,你们可以写活)填写完这些信息之后点击发布就开始调用发帖的方法了。因为我的这个小程序是平台多个小区,所以就有设置用户在当前哪一个小区发帖,这个帖子就归属到那个小区去。 如果信息没有完整就需要去提示一下用户需要讲信息填写完整 所以总计传入后端的信息有:帖子标题、内容、图片字符串、分类名字、用户id、小区id

xml 复制代码
<template>
  <view>
    <view class="container">
      <view class="input-container">
        <view class="input-item">
          <text class="input-label">帖子标题:</text>
          <input type="text" v-model="post.title" class="input-field" placeholder="请输入帖子标题" />
        </view>
        <view class="input-item">
          <text class="input-label">帖子内容:</text>
          <textarea v-model="post.content" class="input-field" placeholder="请输入帖子内容"></textarea>
        </view>
        <view class="input-item">
          <text class="input-label">选择图片:</text>
          <button @click="chooseImage">上传图片</button>
          <!--          <image v-if="post.image" :src="post.image" class="post-image" mode="aspectFill" /> -->
        </view>
        <view class="image-container">
          <view v-for="(image, index) in images" :key="index" class="image-item">
            <image :src="image" mode="aspectFit" class="image-src"></image>
          </view>
        </view>
        <view class="input-item">
          <text class="input-label">选择分类:</text>
          <picker mode="selector" :range="classification" v-model="selectedCategoryIndex" @change="categoryChange">
            <view class="picker">当前选择:{{ classification[selectedCategoryIndex] }}</view>
          </picker>
        </view>
      </view>
      <view class="button-container">
        <button @click="publishPost">发布帖子</button>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      images: [], // 存储已上传图片的数组
      post: {
        title: '',
        content: '',
        images: '', // 存储已上传图片的数组
        classification: ''
      },
      classification: ['分类1', '分类2', '分类3', '分类4'],
      selectedCategoryIndex: 0
    };
  },
  methods: {
    //选择图片进行上传
    chooseImage() {
      uni.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success: (res) => {
          const tempFilePaths = res.tempFilePaths;
          this.images.push(tempFilePaths[0]);
        }
      });
    },
    //选择分类
    categoryChange(e) {
      this.selectedCategoryIndex = e.detail.value;
    },
    //发布帖子
    async publishPost() {
      this.post.classification = this.classification[this.selectedCategoryIndex];
      this.post.images = this.images.join(',');
      console.log(this.post.categorie);
      if (!this.post.title || !this.post.content || !this.post.images || !this.post.classification) {
        uni.showToast({
          title: '请填写完整信息',
          icon: 'none'
        });
        return;
      }
      const res = await this.$myRequest({
        method: 'post',
        url: '/fatie',
        data: {
          title: this.post.title,
          content: this.post.content,
          images: this.post.images,
          classification: this.post.classification,
          userId: this.$store.state.user.id,
          communityId: this.$store.state.communityId
        }
      });
      uni.showToast({
        title: '发布成功',
        icon: 'success'
      });
    }
  }
};
</script>

3.后端

后端:当接受到前端传来的信息之后到数据库里面去新增这一条帖子信息,这里也是需要验证用户信息的就是验证前端传来的token解析之后是否和传来的用户id是一致的(不过我没加😊,这个验证可以自己搞搞加

xml 复制代码
<template>
  <view>
    <view class="container">
      <view class="input-container">
        <view class="input-item">
          <text class="input-label">帖子标题:</text>
          <input type="text" v-model="post.title" class="input-field" placeholder="请输入帖子标题" />
        </view>
        <view class="input-item">
          <text class="input-label">帖子内容:</text>
          <textarea v-model="post.content" class="input-field" placeholder="请输入帖子内容"></textarea>
        </view>
        <view class="input-item">
          <text class="input-label">选择图片:</text>
          <button @click="chooseImage">上传图片</button>
          <!--          <image v-if="post.image" :src="post.image" class="post-image" mode="aspectFill" /> -->
        </view>
        <view class="image-container">
          <view v-for="(image, index) in images" :key="index" class="image-item">
            <image :src="image" mode="aspectFit" class="image-src"></image>
          </view>
        </view>
        <view class="input-item">
          <text class="input-label">选择分类:</text>
          <picker mode="selector" :range="classification" v-model="selectedCategoryIndex" @change="categoryChange">
            <view class="picker">当前选择:{{ classification[selectedCategoryIndex] }}</view>
          </picker>
        </view>
      </view>
      <view class="button-container">
        <button @click="publishPost">发布帖子</button>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      images: [], // 存储已上传图片的数组
      post: {
        title: '',
        content: '',
        images: '', // 存储已上传图片的数组
        classification: ''
      },
      classification: ['分类1', '分类2', '分类3', '分类4'],
      selectedCategoryIndex: 0
    };
  },
  methods: {
    //选择图片进行上传
    chooseImage() {
      uni.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success: (res) => {
          const tempFilePaths = res.tempFilePaths;
          this.images.push(tempFilePaths[0]);
        }
      });
    },
    //选择分类
    categoryChange(e) {
      this.selectedCategoryIndex = e.detail.value;
    },
    //发布帖子
    async publishPost() {
      this.post.classification = this.classification[this.selectedCategoryIndex];
      this.post.images = this.images.join(',');
      console.log(this.post.categorie);
      if (!this.post.title || !this.post.content || !this.post.images || !this.post.classification) {
        uni.showToast({
          title: '请填写完整信息',
          icon: 'none'
        });
        return;
      }
      const res = await this.$myRequest({
        method: 'post',
        url: '/fatie',
        data: {
          title: this.post.title,
          content: this.post.content,
          images: this.post.images,
          classification: this.post.classification,
          userId: this.$store.state.user.id,
          communityId: this.$store.state.communityId
        }
      });
      uni.showToast({
        title: '发布成功',
        icon: 'success'
      });
    }
  }
};
</script>
相关推荐
brzhang9 分钟前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室16 分钟前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
广州华水科技24 分钟前
北斗形变监测传感器在水库安全中的应用及技术优势分析
前端
开发者如是说1 小时前
Compose 开发桌面程序的一些问题
前端·架构
旺代1 小时前
Token 存储与安全防护
前端
洋不写bug2 小时前
html实现简历信息填写界面
前端·html
三十_A2 小时前
【无标题】
前端·后端·node.js
excel2 小时前
Vue 编译器源码解读:transformVBindShorthand 的设计与原理
前端
时间的情敌3 小时前
Vue3的异步DOM更新:nextTick的正确使用方法
前端·javascript·vue.js
风语者日志3 小时前
[LitCTF 2023]作业管理系统
前端·网络·安全·web安全·ctf