# 云音乐平台搭建
serverless 函数即服务
云函数:云端运行的代码,微信私有的协议天然鉴权
云数据库: JSON数据库
云存储:存储文件
云调用:基于云函数免鉴权使用小程序开放接口
HTTP API:和原有项目打通
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
//数据库连接操作
const db =cloud.database()
//从外界获取数据
const rp =require("request-promise")
//对接的具体数据库
const playlistCollection = db.collection("playlist")
const URL= "http://musicapi.xiecheng.live/personalized"
// 云函数入口函数
exports.main = async (event, context) => {
//数据库获取数据
const list = await playlistCollection.get()
console.log(list)
//第三方平台获取数据
const playlist=await rp(URL).then(res=>{
return JSON.parse(res).result
})
console.log(playlist)
const newData=[]
// if(list.data.length&list.data.length>0){
for (let i = 0, len1 = playlist.length; i < len1; i++) {
let flag = true
for (let j = 0, len2 = list.data.length; j < len2; j++) {
if (playlist[i].id === list.data[j].id) {
flag = false
break
}
}
if (flag) {
newData.push(playlist[i])
}
}
// }else{
// newData=playlist
// }
console.log(newData)
//填写数据到数据库,只支持一条条添加
for (let i=0,len=newData.length;i<len;i++){
await playlistCollection.add({
data:{
...newData[i],
createTime:db.serverDate()
}
}).then(res=>{
console.log("success")
}).catch(err=>{
console.log("fail")
})
}
console.log(playlist)
return newData.length
}
# 微信小程序数据库操作
# 增加和查询
const cloud = require('wx-server-sdk') //云函数入口文件
const db =cloud.database() //获取数据库的引用
const playlistCollection = db.collection("playlist")//连接数据库playlist
const list = await playlistCollection.get()//获取数据
//添加数据
playlistCollection.add({
data:{
...newData[i],
createTime:db.serverDate()
}
}).then(res=>{
console.log("success")
}).catch(err=>{
console.log("fail")
})
# 总条数
const MAX_LIMIT = 10
const countResult = await playlistCollection.count()
const total = countResult.total//获取数据库总条数
# 分页查询
const batchTimes = Math.ceil(total / MAX_LIMIT)
const tasks = []
for (let i = 0; i < batchTimes; i++) {
//分页查询
let promise = playlistCollection.skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
tasks.push(promise)
}
let list = {
data: []
}
if (tasks.length > 0) {
list = (await Promise.all(tasks)).reduce((acc, cur) => {
return {
data: acc.data.concat(cur.data)
}
})
}
# 排序方式
cloud.database().collection("playlist")
.skip(event.start)
.limit(event.count)
.orderBy("createTime","desc")//逆序
.get()
.then(res=>{
return res
})
# 云函数触发器config.json
{
"triggers": [
{
"name": "myTrigger",//名称
"type": "timer",//类型
"config": "0 0 10,14,16,23 * * * *"//时间
}
]
}
# 请求云函数 wx.cloud.callFunction
wx.showLoading({
title: '加载中',
})
wx.cloud.callFunction({
name:"music",
data:{
start:this.data.playlist.length,
count:MAX_LIMIT
}
}).then(res=>{
this.setData({
playlist:this.data.playlist.concat(res.result.data)
})
wx.stopPullDownRefresh()//当下拉刷新数据请求完成时取消最上方得三个加载点
wx.hideLoading()
})
# 云函数路由 tcb-router
云函数数量有限,可以把相似的放在同一个云函数进行处理 return app.serve()要记住加在末尾返回当前服务
// 云函数入口文件
const cloud = require('wx-server-sdk')
const TcbRouter = require('tcb-router')
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
const app = new TcbRouter({
event
})
app.use(async(ctx, next) => {
console.log('进入全局中间件')
ctx.data = {}
ctx.data.openId = event.userInfo.openId
await next()
console.log('退出全局中间件')
})
app.router('music', async(ctx, next) => {
console.log('进入音乐名称中间件')
ctx.data.musicName = '数鸭子'
await next()
console.log('退出音乐名称中间件')
}, async(ctx, next) => {
console.log('进入音乐类型中间件')
ctx.data.musicType = '儿歌'
ctx.body = {
data: ctx.data
}
console.log('退出音乐类型中间件')
})
app.router('movie', async(ctx, next) => {
console.log('进入电影名称中间件')
ctx.data.movieName = '千与千寻'
await next()
console.log('退出电影名称中间件')
}, async(ctx, next) => {
console.log('进入电影类型中间件')
ctx.data.movieType = '日本动画片'
ctx.body = {
data: ctx.data
}
console.log('退出电影类型中间件')
})
return app.serve()
}
//调用云函数部分
//$url是云函数内部走的路由名称
getMusicInfo() {
wx.cloud.callFunction({
name: 'tcbRouter',
data: {
$url: 'music'
},
}).then((res) => {
console.log(res)
})
},
getMovieInfo() {
wx.cloud.callFunction({
name: 'tcbRouter',
data: {
$url: 'movie'
}
}).then((res) => {
console.log(res)
})
}
# wx where条件查询
//小程序端
_loadBlogList(start = 0) {
wx.showLoading({
title: '拼命加载中',
})
wx.cloud.callFunction({
name: 'blog',
data: {
keyword,
start,
count: 10,
$url: 'list',
}
}).then((res) => {
console.log(res)
this.setData({
blogList: this.data.blogList.concat(res.result)
})
wx.hideLoading()
wx.stopPullDownRefresh()
})
},
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const TcbRouter = require('tcb-router')
const db = cloud.database()
const blogCollection = db.collection('blog')
const MAX_LIMIT = 100
// 云函数入口函数
exports.main = async(event, context) => {
const app = new TcbRouter({
event
})
app.router('list', async(ctx, next) => {
const keyword = event.keyword
let w = {}
if (keyword.trim() != '') {
w = {
content: new db.RegExp({
regexp: keyword,
options: 'i'
})
}
}
let blogList = await blogCollection.where(w).skip(event.start).limit(event.count)
.orderBy('createTime', 'desc').get().then((res) => {
return res.data
})
ctx.body = blogList
})
return app.serve()
}
小程序端 也可以直接访问数据库,需要注意,云函数端cloud.database()不需要加wx,小程序端需要加
const db = wx.cloud.database()
db.collection('blog').orderBy('createTime', 'desc').get().then((res)=>{
console.log(res)
const data = res.data
for (let i = 0, len = data.length; i<len; i++){
data[i].createTime = data[i].createTime.toString()
}
this.setData({
blogList: data
})
})
// 初始化
wx.cloud.init({
env: 'tianqi-xxx'
})
// 获取数据库实例
const db = wx.cloud.database()
// 增
db.collection('集合名称').add({
data: {} // 插入的数据
}).then(res => {
// 可以通过 res._id 获取创建的记录的 id
console.log(res._id)
})
// 删
db.collection('集合名称').doc('文档 ID').remove().then(res => {
console.log('removed')
})
// 改
db.collection('集合名称').doc('文档 ID').update({
data: {
title: '我的第 1 篇文章', // 只更新 title 字段,其他不更新
}
}).then(res => {
// 可以通过 res._id 获取创建的记录的 id
console.log(res._id)
})
// 查
db.collection('集合名称').doc('文档 ID').get().then(res => {
// 打印结果,res.data 即为记录的数据
console.log(res)
})
const _ = db.command // 取指令
db.collection('集合名称').where({
// 查找条件
category: 'computer',
properties: {
memory: _.gt(8), // 表示大于 8
}
})
# Cron 表达式
Cron 表达式有七个必需字段,按空格分隔。
| 第一位 | 第二位 | 第三位 | 第四位 | 第五位 | 第六位 | 第七位 |
|---|---|---|---|---|---|---|
| 秒 | 分钟 | 小时 | 日 | 月 | 星期 | 年 |
通配符 含义
, (逗号) 代表取用逗号隔开的字符的并集。例如:在“小时”字段中 1,2,3 表示1点、2点和3点
- (破折号) 包含指定范围的所有值。例如:在“日”字段中,1-15 包含指定月份的 1 号到 15 号
* (星号) 表示所有值。在“小时”字段中,* 表示每个小时
/ (正斜杠) 指定增量。在“分钟”字段中,输入 1/10 以指定从第一分钟开始的每隔十分钟重复。例如,第 11 分钟、第 21 分钟和第 31 分钟,依此类推
*/5 * * * * * * 表示每5秒触发一次
0 0 2 1 * * * 表示在每月的1日的凌晨2点触发
0 15 10 * * MON-FRI * 表示在周一到周五每天上午10:15触发
0 0 10,14,16 * * * * 表示在每天上午10点,下午2点,4点触发
0 */30 9-17 * * * * 表示在每天上午9点到下午5点内每半小时触发
0 0 12 * * WED * 表示在每个星期三中午12点触发
# 云调用
小程序端获取openid const { OPENID } = cloud.getWXContext()
# 模板消息(但是已经废除)
<form slot="modal-content" report-submit="true" bind:submit="onSend">
<textarea name="content" class="comment-content"
placeholder="写评论" value="{{content}}" fixed="true">
</textarea>
<button class="send" form-type="submit">发送</button>
</form>
// 推送模板消息
wx.cloud.callFunction({
name: 'sendMessage',
data: {
content,
formId,
blogId: this.properties.blogId
}
}).then((res) => {
console.log(res)
})
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
const {
OPENID
} = cloud.getWXContext()
const result = await cloud.openapi.templateMessage.send({
touser: OPENID,
page: `/pages/blog-comment/blog-comment?blogId=${event.blogId}`,
data: {
keyword1: {
value: '评价完成'
},
keyword2: {
value: event.content
}
},
templateId: 'PjUkFDsOsC3ktzUATsIVy0t1D4RlL-aKbuhGUb7TLS0',//配置好的模板ID
formId: event.formId
})
return result
}
# 微信小程序订阅功能
在微信小程序官网选择好订阅消息,新建一个模板,然后把模板ID复制.
<!-- bindsubmit会报错,可以改成tap -->
<x-bottom-modal modalShow="{{modalShow}}">
<form slot="modal-content" report-submit="true" bind:submit="onSend">
<textarea name="content" class="comment-content"
placeholder="写评论" value="{{content}}" fixed="true">
</textarea>
<button class="send" form-type="submit">发送</button>
</form>
</x-bottom-modal>
//onsend请求后端操作
//小程序端先询问是否需要订阅
wx.requestSubscribeMessage({
tmplIds: ['BSlLhaQ6Bm1USUtdFfwpuc3_xxxx'],
success (res) {
console.log(res)
},
fail(err){
console.log(err)
}
})
// 推送模板消息
wx.cloud.callFunction({
name: 'sendMessage',
data: {
content,
formId,
blogId: this.properties.blogId
}
}).then((res) => {
console.log(res)
}).catch(err=>{
console.log(err)
})
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
const {
OPENID
} = cloud.getWXContext()
console.log(OPENID)
const result = await cloud.openapi.subscribeMessage.send({
touser: OPENID,
page: `/pages/blog-comment/blog-comment?blogId=${event.blogId}`,
data: {
phrase1: {
value: '评价完成'
},
thing2: {
value: event.content
}
},
templateId: 'BSlLhaQ6Bm1USUtdFfwpuc3_xxxx',
formId: event.formId
})
return result
}
//config.json
{
"permissions": {
"openapi": [
"subscribeMessage.send"
]
}
}