发布时间:2025-12-10 11:30:04 浏览次数:6
后台采用的框架为Koa2框架,编程软件为vs code,node环境
获取小程序全局唯一后台接口调用凭据(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。
优化代码
由于后台大部分功能是调用云函数,所以说调用云函数的代码内容基本是一样的。可以将调用云函数的方法进行封装,下面是封装的代码
此时需要修改路由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配置以下代码
(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
(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'})}此时,如果前端要获取歌单信息,则需要向后端地址为http://localhost:8080/playlist/list发送请求
最后启动后端服务,在终端输入命令 node app.js(编译入口文件)
结束编译:ctrl+C即可