• Day12-微信小程序实战-交友小程序-搭建服务器与上传文件到后端并控制云开发数据库-项目总结与github代码发布流程(附上项目全部完整代码学习使用)


    要搞一个小型的cms内容发布系统

    因为小程序上线之后,直接对数据库进行操作的话,慧出问题的,所以一般都会做一个管理系统,让工作人员通过这个管理系统来对这个数据库进行增删改查

    微信小程序其实给我们提供了这样的能力了

     (也就是可以在自己已有的服务器来进行云操作,所以就可以通过这个CMS内容管理系统来对云数据库进行修改)

    我们就要建立自己的web服务器--》搭建一个简易的服务器

    https://koa.bootcss.com/

    这个是要node版本是7以上,可以在node官网去搭建,我这边之前按照过了,直接cmd打开,通过 node -v查看版本

    然后还要下载一个 cnpm,这个主要是下载第三方模块用的

     https://www.cnblogs.com/biglovevolcaner/p/6707746.html

    打开cmd,直接输入这位大佬博客里面的语句进行安装即可了

    这些都准备好了之后,就可以开始koa2的服务器搭建了

    我们选择koa的脚手架 koa-generator

    https://blog.csdn.net/sinat_39049092/article/details/104575018

    (跟这个博客到第三步就行)

    然后我们就可以到想要搭建系统的文件中(我在d盘新建了一个weapp文件)

    在cmd中输入 D:weapp 之后输入 d:即可跳转

    输入 koa2 miaomiao-cms -e

    (后面的-e表示的是选择ejs模板)

    然后安装提示,我们进入到这个建立的东西 cd miaomiao-cms

    然后安装一些初始的模块

     输入 cnpm i

     

    创立完之后,就可以去启动了,我们通过 npm start  

     启动好之后,我们在网页中 输入 localhost:3000

     如果看到了这个界面的话,说明web服务器就已经搭建好了,就可以在这个web服务器下做一个简易的cms系统了

    之后就可以在d盘找到这个文件了

     其中的public主要是放一些静态资源的

    在vscode里面打开我们的文件

    这个index其实就是类似于可以在前端显示的

    实现引入 axios.min.js 可以通过npm安装,也可以使用网上开源的

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    通过设置:

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
      </head>
      <body>
        <h1><%= title %></h1>
        <p>EJS Welcome to <%= title %></p>
        <label for="">
          上传图片 : <input type="file" id="uploadBtn">
        </label>
      </body>
    </html>

    我们可以看到

     注意:假如网页打不开,或者是没更新出现的html结构的话,就重新的在这个miaomiao.cms下面 npm start重新打开

    随便选一张图片,onchange就是只要选择了图片的话,就会触发这个事件了,file就是拿到的我们上传的文件了

    拿到这个图片要怎么传输给后台呢,这个时候就要进行文件操作了FormData这个对象来实现了

    通过append 给这个param对象添加一个key为file value为 。也就是通过这个append来产生一个键值对

    然后把这个对象通过axios来传输到后端

    这就是axios中传输给后端文件的代码 

    在传输之前,先对 config 配置文件 进行设置,告诉我们后端这个是一个文件数据流

     配置好了之后,就可以通过post把图片传输给后台的接口 uploadBannerImg

    通过下面的代码

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
      </head>
      <body>
        <h1>与你相遇-CMS管理系统</h1>
        <label for="">
          上传图片 : <input type="file" id="uploadBtn">
        </label>
    
        <script>
          var uploadBtn = document.getElementById('uploadBtn');
          uploadBtn.onchange = function(ev){
            var file = ev.target.files[0];
            var param = new FormData();
            param.append('file' , file);
    
            var config = {
              headers : {
                'Content-Type' : 'multipart/form-data'
              }
            };
    
            axios.post('/uploadBannerImg' , param , config).then((res)=>{
              console.log( res.data );
            });
          };
        </script>
      </body>
    </html>

    然后就是开始搞 定义 uploadBannerImg 这个接口了

    在routes-》index.js里面,添加上这个代码

    router.post('/uploadBannerImg' , async(ctx , next)=>{
      var files = ctx.request.files;
      console.log( files );
    
    })

     我们添加一个图片,然后可以看到在后端中

     会发现404了,我们再通过 npm start来开启

    先要结束上面的操作,通过 ctrl+c 弹出

     然后输入y之后,通过npm start,然后再次上传图片

     打印出来了这个,说明file为undefined 也就是没拿到这个图片了

    这个是因为koa默认是得不到我们上传文件的东西的,还需要下载一个第三方的模块来辅助完成这个功能才行

    通过在miaomiao-cms目录下的cmd 输入  cnpm i -S koa-body

    下载好了之后,在app.js里面,引入koa-body

    const koaBody = require('koa-body')

    然后在app.js里面做一个简单的配置

    app.use(koaBody({
      multipart : true,//指定是否可以上传多张
      formidable : {
        maxFileSize : 200*1024*1024   //设置上传文件大小最大限制,默认2M
      }
    }))

    (不配置这个,用默认的也是可以的)

    搞好之后,再把项目 npm start启动一下

    上传图片之后,还是显示 undefined

     原因就是index.js里面的files少了一个s

     二、把拿到的文件上传到云开发中

    c

     这里的use多了一个r

     把这两个代码书写错误改好了之后,再上传就可以看到结果了

    所以就实现了把图片传给后台了,然后我们就要把这个信息传给云平台了(以上完成了前台的文件传输到了后台)

     https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html

    通过:

    POST https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN

    通过这个代码其实是进行身份验证拿到一个通行证Token,才可以使用这样的功能

    https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html

    通过:

    GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

    可见它需要的是APP 的id还有密钥,这两个都可以在

    https://mp.weixin.qq.com/wxamp/wxaalarm/get_jserr?token=590850009&lang=zh_CN 

    开发-》开发设置(就可以拿到id和密钥了)

    两个都拿到的话,就可以通过get来获得Token了,然后再用post即可了

    首先在

    在外层写一个配置文件,因为这个id和密钥都是比较隐私的,为了不让其他人看到的话,最好就是写一个配置文件了

    把用户名和密钥都写到这个配置文件中去,然后开始打码

    先在config.js里面提供一个对外接口

    (里面的数据写入自己的即可) 

    module.exports = {
        appid : '',
        secret : ''
    };

    然后在index.js里面引入这个配置文件

    const config = require('./config.js');

    然后在koa2中,我们用的是request和request-promise,这样的一些第三方的模块,如果要安装的话,可以在github里面看看

    https://github.com/request/request-promise

    然后我们把后台关掉,开始下载一下这些东西

    输入 cnpm i -S request request-promise 

     就可以安装这两个东西了

     就可以看到已经下载成功,我们就可以开始使用了

    const request = require('request-promise');

    还有一个内置的fs用来操作文件的模块,我们可以直接引入,就不用下载了

    const fs = require('fs');

    然后在路由的index.js文件中的router.post里面添加:

      try{
        let options = {
          uri: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' +
          config.appid + '&secret=' + config.secret + '',
          json : true
        }
        let {access_token} = await request(options)
        console.log( access_token );
      } catch(err){
        console.log(err.stack)
      }

    但是出现了报错

     少了一个点,要。。/才行

     

     这样的话我们就拿到了access_token了(注意 哪个密匙的话最好用最新的,重新更新一下不然可能调用失败的)

    得到这个access_token之后我们就可以用post请求了来得到我们要用到的信息

     这个env就是指定了云环境id ,我们这里通过一个date设置时间戳的文件地址给filepath ,然后我们就把options拿去请求了,请求成功的话就返回赋值给res

    这个res包括什么,可以在微信开发文档里面看到的

     拿到这些数据之后,就要调用下一个接口了,来返回最新的数据

    注意有些参数 是 uri 而不是url的

    然后把我们res拿到的值映射到,下面这些参数中去

    const router = require('koa-router')()
    const config = require('../config.js');
    const request = require('request-promise');
    const fs = require('fs');
    router.get('/', async (ctx, next) => {
      await ctx.render('index', {
        title: 'Hello Koa 2!'
      })
    })
    
    router.get('/string', async (ctx, next) => {
      ctx.body = 'koa2 string'
    })
    
    router.get('/json', async (ctx, next) => {
      ctx.body = {
        title: 'koa2 json'
      }
    })
    
    router.post('/uploadBannerImg' , async(ctx , next)=>{
      // console.log( ctx.request )
      var files = ctx.request.files;
    
      // console.log( files );
    
      try{
        let options = {
          uri: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+config.appid + '&secret=' + config.secret + '',
          json : true
        }
        let {access_token} = await request(options);
        // console.log( access_token );
        let fileName = `${Date.now()}.jpg`;
        let filePath = `banner/${fileName}`;
        options = {
          method : 'POST',
          uri : 'https://api.weixin.qq.com/tcb/uploadfile?access_token=' + access_token + '',
          body : {
            "env" : 'gogocj-6skcv',
            "path" : filePath,
          },
          json : true
        }
        let res = await request(options);
        options =  {
          method : 'POST',
          uri : res.url,
          formData : {
            "Signature" : res.authorization ,
            "key" : filePath,
            "x-cos-security-token" : res.token,
            "x-cos-meta-fileid" : res.cos_file_id,
            "file" : {
              value : fs.createReadStream(file.path),
              options : {
                filename : fileName,
                contentType : file.type
              }
            }
          }
        }
        await request(options);
        ctx.body = res;
      } catch(err){
        console.log(err.stack)
      }
    
    })
    
    module.exports = router

    综上所述其实我们要调用三个接口,先用get来拿到我们的token,然后通过post来拿到我们其他上传的具体信息,然后通过这些res的具体信息来调用另外一个接口赖完成最终上传的任务

     但是我们在云开发中 查看存储的时候,并没有看到我们上传过来的东西(最后就是在前端也加上一些提示)就不用来看数据库了

    在数据库的存储中没有生成 banner

    上面黑图中,后面其实都是一些报错的

     这里少了一句对file进行定义的语句了,写上之后,全部的报错都消失了

     然后在云开发的存储中:

     就上传成功了

    POST https://api.weixin.qq.com/tcb/databaseadd?access_token=ACCESS_TOKEN

    这样也是通过传入access_token 来传入

     所以以上就实现了在web服务器端把图片上传到云开发的存储中,但是我们的目的是要在前端在banner中把这个图片放在轮播图上的,但是无法直接从存储中读取出来,要把存储文件的这个id写入到数据库中(表单中)

    我们在云开发的数据库中新建一个叫做 banner 的集合

    也就是说不仅要上传到云开发的存储中,还要上传到这个banner集合中

    查看开发文档:

    https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAdd.html

    const router = require('koa-router')()
    const config = require('../config.js');
    const request = require('request-promise');
    const fs = require('fs');
    router.get('/', async (ctx, next) => {
      await ctx.render('index', {
        title: 'Hello Koa 2!'
      })
    })
    
    router.get('/string', async (ctx, next) => {
      ctx.body = 'koa2 string'
    })
    
    router.get('/json', async (ctx, next) => {
      ctx.body = {
        title: 'koa2 json'
      }
    })
    
    router.post('/uploadBannerImg' , async(ctx , next)=>{
      // console.log( ctx.request )
      var files = ctx.request.files;
      var file = files.file;//这个file就是文件的一个二进制的数据了
      // console.log( files );
    
      try{
        let options = {
          uri: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+config.appid + '&secret=' + config.secret + '',
          json : true
        }
        let {access_token} = await request(options);
        // console.log( access_token );
        let fileName = `${Date.now()}.jpg`;
        let filePath = `banner/${fileName}`;
        options = {
          method : 'POST',
          uri : 'https://api.weixin.qq.com/tcb/uploadfile?access_token=' + access_token + '',
          body : {
            "env" : 'gogocj-6skcv',
            "path" : filePath,
          },
          json : true
        }
        let res = await request(options);
        let file_id = res.file_id;
        options = {
          method : 'POST',
          uri : 'https://api.weixin.qq.com/tcb/databaseadd?access_token=' + access_token + '',
          body : {
            "env" : 'gogocj-6skcv',
            "query" : "db.collection("banner").add({data:{fileId:""+ file_id+""}})"
          },
          json : true
    
        }
    
        await request(options)
    
        options =  {
          method : 'POST',
          uri : res.url,
          formData : {
            "Signature" : res.authorization ,
            "key" : filePath,
            "x-cos-security-token" : res.token,
            "x-cos-meta-fileid" : res.cos_file_id,
            "file" : {
              value : fs.createReadStream(file.path),
              options : {
                filename : fileName,
                contentType : file.type
              }
            }
          }
        }
        await request(options);
        ctx.body = res;
      } catch(err){
        console.log(err.stack)
      }
    
    })
    
    module.exports = router
    router/index.js

    我们再次上传的时候,就发现语句写入到banner这个集合里面了

    然后我们再上传第二张图片试试

     可以看到也是上传成功的了,这两条数据都是比较简单的,保存的就只是一个fileId的

    然后就可以回到微信开发者工具去打代码了,就可以直接读取banner这个集合里面的图片了

    在index.js里面对那个imgurl进行操作

    其实可以在getBannerList函数里面定义我们从集合中限制拿几张图片的

    (注意记得给这个banner数据库集合设置 好权限,不然可能就访问不到了

    在index.js里面的onready中触发这个函数

      getBannerList(){
        db.collection('banner').get().then((res)=>{
          console.log( res.data );
        });
      }

    通过这个,我们打印出东西来看看

    然后我们就可以把得到的数组映射到data里面的imgUrl即可了

    然后还要在wxml中,把src变成是item.fileId才行

     所以通过代码:

      getBannerList(){
        db.collection('banner').get().then((res)=>{
          // console.log( res.data );
          this.setData({
            imgUrls : res.data
          });
        });
      }
    <block wx:for="{{imgUrls}}" wx:key="{{index}}">
              <swiper-item>
                <image  src="{{item.fileId}}"  ></image>
              </swiper-item>
            </block>

    得到的效果就是:

     这两个图片就是我们通过cms内容管理系统上传的图片了

    其实虽然这个系统实现的功能就一个,但是是可以扩展的,比如用来管理用户,就是用户的头像如果是违规的话

    或者是发布一些系统的消息或者是公告的东西了(就是好友消息和系统消息都是可以有的,然后做一个好友消息和系统消息切换的分支即可)

     以上就完成了这个项目的初始内容了,下面就是通过预览,或者是通过真机调试(实时监听用户的操作)所以在调试完了之后,就是发布了,发布就是点击上传按钮

    上传代码完成之后,就可以在微信公众平台,打开版本管理,可以先不用上传审核,而是变成是一个体验的版本,就可以得到一个二维码了

    这个体验的权限就是通过(成员管理-》体验成员设置,

    当体验的感觉没问题之后,就可以提交审核了(如果审核不通过,就可能使banner中的图片和我们饿内容使不符合的,就使要把这个小程序改成和实际差不多的再进行提交审核才行的

    审核通过之后就会生成一个线上版本,这样的话如何的用户都可以进行访问了

    以上就是小程序发布的流程了的

    下面就是把代码上传到github中进行共享,我们把cms的文件和这个小程序的代码文件放一起

    文件放一起之后,就可以打开gitbub进行上传了

    如何我们通过git插件来上传的,可以下载一个git插件

    https://git-scm.com/downloads

    如然后在要上传的文件里面,右键点击git bash

    可以在这个页面中查看我们如何通过git插件来实现代码的上传的了

    https://github.com/gogocj/wxproject-miaomiao

     也就是点开git工具,然后输入 git init

    然后查看状态 git status

    然后就是 git add .  (注意后面是一个空格然后一个点)

    然后就是 git commit -m "up 1"

    上传好了之后,就可以通过git status 来看看我们是否已经上传成功了

    之后就可以设置一下远端了(remote)

    输入:git remote add origin https://github.com/gogocj/wxproject-miaomiao.git

    上传完毕之后,刷新一下就可以看到上传的东西了

     

     可以看到我们上传的东西都在这里了,但是虾米那的这个README.md其实是小程序中默认的,我们可以修改一下的

    可以直接在github里面对这个文件在线的编辑

     https://github.com/gogocj/wxproject-miaomiao

    这就是我上传到github上面的代码了

     感谢大家!

     

  • 相关阅读:
    记一次JVM Full GC (Metadata GC Threshold)调优经历
    非root用户启动nginx
    springboot项目报错解决:ERROR StatusLogger No Log4j 2 configuration file found
    分布式锁的常见实现思路
    虚拟机安装redis及宿主机连接测试
    使用console.log打印的内容不一定可信
    《数据库系统概论》第九章笔记
    《数据库系统概论》第六章笔记
    英文论文里的缩写:e.g. etc. et al. i.e.
    英文论文里的缩写:e.g. etc. et al. i.e.
  • 原文地址:https://www.cnblogs.com/SCAU-gogocj/p/13199942.html
Copyright © 2020-2023  润新知