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>
相关推荐
小林爱10 分钟前
【Compose multiplatform教程08】【组件】Text组件
android·java·前端·ui·前端框架·kotlin·android studio
跨境商城搭建开发20 分钟前
一个服务器可以搭建几个网站?搭建一个网站的流程介绍
运维·服务器·前端·vue.js·mysql·npm·php
hhzz22 分钟前
vue前端项目中实现电子签名功能(附完整源码)
前端·javascript·vue.js
秋雨凉人心25 分钟前
上传npm包加强
开发语言·前端·javascript·webpack·npm·node.js
NoneCoder1 小时前
CSS系列(37)-- Overscroll Behavior详解
前端·css
Nejosi_念旧1 小时前
使用Webpack构建NPM Library
前端·webpack·npm
前端切圖仔1 小时前
失业,仲裁,都赶上了(二)
前端·javascript·程序员
冰红茶-Tea1 小时前
typescript数据类型(二)
前端·typescript
slongzhang_1 小时前
elementPlus消息组件多按钮案例
前端·javascript·vue.js
会发光的猪。2 小时前
vue中el-select选择框带搜索和输入,根据用户输入的值显示下拉列表
前端·javascript·vue.js·elementui