微信小程序后台管理系统(后端)笔记

发布时间:2025-12-10 11:30:04 浏览次数:6

一、前期框架的搭建

后台采用的框架为Koa2框架,编程软件为vs code,node环境

  • 步骤一:创建一个空文件
  • 步骤二:在vs code打开该文件,并按ctrl+`打开终端
  • 步骤三:输入命令npm init(初始化package.json),也可以用npm init -y(直接默认初始化package.json)
  • 步骤四:输入命令npm install koa(下载koa)

二、获取AcessToken(接口调用凭证)

获取小程序全局唯一后台接口调用凭据(access_token)。调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存。
由于,我是调用云函数,所以必须需要接口调用凭证。

注意:

中控服务器是自己搭建的后台

请求地址及参数
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

(3)下载第三请求库request-promise,由于前面部分已经下载了,所以直接导入即可。

代码实现

知识点一:调用云函数我这里是通过调用云函数实现从云数据库中获取歌单信息,下面是我部署的云函数(云函数名为music,路由名(地址)为playlist)app.router('playlist', async (ctx, next) => {ctx.body = await cloud.database().collection('playlist').skip(event.start).limit(event.count).orderBy('createTime', 'desc').get().then((res) => {return res})})

后台调用云函数

const Router=require('koa-router')const router=new Router()const getAccessToken=require('../utils/getAccessToken.js')const rp=require('request-promise')// /list是后台路由地址router.get('/list',async(ctx,next)=>{// 获取调用接口凭证const access_token= await getAccessToken()//云数据库运行环境const ENV='您的云开发环境ID'//调用云函数地址(参数name是您的云函数名字)const URL=`https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=${access_token}&env=${ENV}&name=music`//获取前端的发送过来的请求数据const query=ctx.request.query//调用云函数的请求参数(封装成对象)const option={method:'POST',//必须是POST请求url:URL,body:{$url:'playlist',//云函数的路由名(地址)start:parseInt(query.start),count:parseInt(query.count)},json:true//返回格式为JSON格式};//发送请求const data=await rp(option).then((res)=>{//console.log(res)return JSON.parse(res.resp_data).data}).catch((err)=>{console.log(err)})//返回数据给前端ctx.body={data,code:20000}})module.exports=router//将路由抛出

在返回数据中,一个数据code:20000 目的是:因为我前端采用的是vue-admin-template搭建的前端管理系统,必须返回code:20000。

优化代码
由于后台大部分功能是调用云函数,所以说调用云函数的代码内容基本是一样的。可以将调用云函数的方法进行封装,下面是封装的代码

const getAccessToken = require('./getAccessToken.js')const rp = require('request-promise')const callCloudFn = async (ctx, fnName, params) => {const ACCESS_TOKEN = await getAccessToken()const options = {method: 'POST',uri: `https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=${ACCESS_TOKEN}&env=${ctx.state.env}&name=${fnName}`,//ctx.state.env通过全局中间件获取云开发环境,在入口文件(app.js)有配置body: {...params},json: true }return await rp(options).then((res) => {return res//注:返回的格式是字符串}).catch(function (err) {})}module.exports = callCloudFn

此时需要修改路由list中的代码

const Router=require('koa-router')const router=new Router()const rp=require('request-promise')const callCloudFun=require('../utils/callCloudFn')router.get('/list',async(ctx,next)=>{//获取前端请求的数据const query=ctx.request.query//发送请求const res=await callCloudFun(ctx,'music',{$url:'playlist',start:parseInt(query.start),count:parseInt(query.count)})let data=[]if(res.resp_data){data=JSON.parse(res.resp_data).data}ctx.body={data,code:20000,}})module.exports=router

这样的好处就是减少代码的重复率,增加代码的利用率。

知识点二:API调用云数据库

前期准备
(1)下载koa-body,获取post请求数据

在app.js配置以下代码

//接收post参数解析app.use(koaBody({multipart: true,}))

(2)创建功能模块

const rp=require('request-promise')const getAccessToken = require('./getAccessToken.js')const callCloudDB=async(ctx,fnName,query={})=>{//fnName数据操作的类型 query数据操作语句const access_token=await getAccessToken()const options={method:'POST',uri:`https://api.weixin.qq.com/tcb/${fnName}?access_token=${access_token}`,body:{query,env:ctx.state.env,},json:true}return await rp(options).then((res)=>{return res}).catch((err)=>{console.log(err)})}module.exports=callCloudDB

(3)更新数据
因为前端提交更新数据的形式是post,所以后端代码应该为post

router.post('/updatePlaylist',async(ctx,next)=>{//获取请求体const params=ctx.request.body//更新语句const query=`db.collection('playlist').doc('${params._id}').update({data:{name:'${params.name}',copywriter:'${params.copywriter}'}})`const res= await callCloudDB(ctx,'databaseupdate',query)ctx.body={code:20000,data:res}})module.exports=router

(4)删除数据

router.get('/deletePlaylist',async(ctx,next)=>{const query=`db.collection('playlist').doc('${ctx.request.query.id}').remove()`const res=await callCloudDB(ctx,'databasedelete',query)ctx.body={code:20000,data:res}})

(5)增加数据

const query=`db.collection('swiper').add({data:{fileId:'${fileid}'}})`const res=await callCloudDB(ctx,'databaseadd',query)

(6)查询数据

router.get('/getById',async(ctx,next)=>{const query=`db.collection('playlist').doc('${ctx.request.query.id}').get()`const res=await callCloudDB(ctx,'databasequery',query)//console.log(res)ctx.body={code:20000,data:JSON.parse(res.data)}})知识点三:文件的上传、下载和删除

创建功能模块

const getAccessToken = require('./getAccessToken.js')const callCloudDB = require('./callCloudDB.js')const rp =require('request-promise')const fs=require('fs')const cloudStore={//下载图片async download(ctx,fileList){const ACCESSTOKEN=await getAccessToken()const options={method:'POST',uri:`https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=${ACCESSTOKEN}`,body:{env:ctx.state.env,file_list:fileList},json:true}return await rp(options).then((res)=>{return res}).catch((err)=>{console.log(err)})},//上传图片到云存储async uploadfile(ctx){//步骤一:发送上传文件的请求,获取相应信息const ACCESSTOKEN=await getAccessToken()const file=ctx.request.files.file//上传文件信息//文件路径(随机)const path=`swiper/${Date.now()}-${Math.random}-${file.name}`const options={method:'POST',uri:`https://api.weixin.qq.com/tcb/uploadfile?access_token=${ACCESSTOKEN}`,body:{env:ctx.state.env,path:path},json:true}const info= await rp(options).then((res)=>{return res}).catch((err)=>{console.log(err)})//console.log(info)//步骤二:上传图片const params={method:"POST",headers:{"content-type":'multipart/form-data', },uri:info.url,formData:{key:path,Signature:info.authorization,'x-cos-security-token':info.token,'x-cos-meta-fileid':info.cos_file_id,file:fs.createReadStream(file.path)//二进制文件},json:true}await rp(params)return info.file_id//返回文件id到调用方,将其存储在云数据库}//删除文件async delFile(ctx,fileid_list){const ACCESSTOKEN=await getAccessToken()const options={method:'POST',uri:` https://api.weixin.qq.com/tcb/batchdeletefile?access_token=${ACCESSTOKEN}`,body:{fileid_list,env:ctx.state.env,},json:true}return await rp(options).then((res)=>{return res}).catch((err)=>{console.log(err)})}}module.exports= cloudStore

(2)调用功能模板

//读取图片(获取歌曲链接)router.get('/list',async(ctx,next)=>{//读取数据库文件信息const query=`db.collection('swiper').get()`const res=await callCloudDB(ctx,'databasequery',query)//获取图片链接(http形式)let fileList=[]const data=res.data//遍历文件信息,封装请求对象for(let i=0,len=data.length;i<len;i++){fileList.push({fileid:JSON.parse(data[i]).fileId,max_age:7200})}//获取下载链接(http形式)const dlRes=await cloudStore.download(ctx,fileList)//封装对象,将所需要的信息返回到前端let returnData=[]for(let i=0,len=dlRes.file_list.length;i<len;i++){returnData.push({download_url:dlRes.file_list[i].download_url,//文件下载链接fileId : dlRes.file_list[i].fileid,_id:JSON.parse(data[i])._id})}ctx.body={code:20000,data:returnData}})//上传图片router.post('/upload',async(ctx,next)=>{//上传图片 返回文件idconst fileid=await cloudStore.uploadfile(ctx)//console.log(fileid)const query=`db.collection('swiper').add({data:{fileId:'${fileid}'}})`//写入数据库const res=await callCloudDB(ctx,'databaseadd',query)ctx.body={code:20000,id_list:res.id_list}})//删除文件export function del(params){return request({params,url:`${baseURL}/swiper/del`,method:'get'})}

四、配置入口文件(app.js)

const Koa=require('koa')const Router=require('koa-router')const cors=require('koa2-cors')const koaBody=require('koa-body')const ENV='haocloud-xagb6'const app=new Koa()const router=new Router()//解决跨域问题app.use(cors({//配置允许访问后台的URL地址origin:['http://localhost:9528'],credentials:true}))//接收post参数解析app.use(koaBody({multipart: true,}))//全局中间键app.use(async(ctx,next)=>{ctx.state.env=ENVawait next()})// http://localhost:3000/playlist/list(调用获取歌单的URL)const playlist=require('./controller/playlist.js')router.use('/playlist',playlist.routes())const swiperList=require('./controller/swiper.js')router.use('/swiper',swiperList.routes())const blogList=require('./controller/blog.js')router.use('/blog',blogList.routes())//声明routerapp.use(router.routes())//允许router下的所有方法app.use(router.allowedMethods())app.listen(8080,()=>{console.log('服务开启在端口为8080')})

此时,如果前端要获取歌单信息,则需要向后端地址为http://localhost:8080/playlist/list发送请求

  • playlist指的是 routers.use(’/playlist’,playlist.routes())中的playlist
  • list指的是router.get(’/list’,async(ctx,next)=>{}中的list(就是一个叫playlist的router的路由下的名为list的路由 个人理解)

最后启动后端服务,在终端输入命令 node app.js(编译入口文件)

结束编译:ctrl+C即可

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477