之前已经完成了使用本地的 Storage 存储信息。
但是Storage存在一个问题,如果用户删除了小程序,那么之前存储的信息也就不复存在了。
使用云函数
创建文件夹 cloudfunctions\
修改
project.config.json 添加
"cloudfunctionRoot": "cloudfunctions/",
在小程序编辑器中右键单击 cloudfunctions=>新建Node.js 云函数
创建rouder 函数
修改cloudfunctionsrouterpackage.json 添加需要的插件
{
"name": "index",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.1.2",
"tcb-router": "^1.1.2"
}
}
修改 cloudfunctionsrouterindex.js
// 云函数入口文件 cloudfunctions\router\index.js
// 微信sdk
const cloud = require('wx-server-sdk');
// 上古项目 给小程序云函数加个路由
const TcbRouter = require('tcb-router');
// 登录方法
const login = require('./controller/login');
// 保存用户信息方法
const saveUserInfo = require('./controller/saveUserInfo');
// 日志中间件
const log = require('./unit/log');
cloud.init();
// 云函数入口函数
exports.main = async (event, context) => {
const app = new TcbRouter({ event });
// app.use 表示该中间件会适用于所有的路由
app.use(log);
// 登录路由
app.router('login', login);
// 保存用户信息
app.router('saveUserInfo', saveUserInfo);
return app.serve();
};
新建 unit 下文件
// cloudfunctions\router\unit\db.js
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
/**
* 连接数据库 如果没有则创建
* @param {string} collect 集合名称(表明)
*/
const connect = async collect => {
return new Promise(async (resolve, reject) => {
let _db;
try {
await db.createCollection(collect);
_db = await db.collection(collect);
} catch (error) {
console.log(collect, '已存在');
}
_db = await db.collection(collect).add({ data: { msg: 'creat OK' } });
resolve(_db);
});
};
/**
* 添加数据
* @param {string} collect 需要更新的集合名称
* @param {object} data 存储的数据
*/
const add = async ({ collect, data }) => {
try {
await db.createCollection(collect);
} catch (error) {
console.log(collect, '已存在');
}
data.createTime = db.serverDate();
data.updataTime = db.serverDate();
let res = await db.collection(collect).add({ data });
return res;
};
/**
* 查找数据
* @param {string} collect 需要更新的集合名称
* @param {object} filter 过滤条件
*/
const orderBy = async ({
collect,
orderKey = 'updataTime',
order = 'desc',
field
}) => {
try {
await db.createCollection(collect);
} catch (error) {
console.log(collect, '已存在');
}
let res = await db
.collection(collect)
.orderBy(orderKey, order)
.field(field)
.get();
return res;
};
/**
* 查找数据
* @param {string} collect 需要更新的集合名称
* @param {object} filter 过滤条件
*/
const find = async ({ collect, filter, field }) => {
try {
await db.createCollection(collect);
} catch (error) {
console.log(collect, '已存在');
}
let res = await db
.collection(collect)
.where(filter)
.field(field)
.get();
return res;
};
/**
* 更新数据,如果没有则创建
* @param {string} collect 需要更新的集合名称
* @param {object} filter 过滤条件
* @param {object} data 新数据
*/
const update = async ({ collect, filter, data }) => {
try {
await db.createCollection(collect);
} catch (error) {
console.log(collect, '已存在');
}
data.updataTime = db.serverDate();
let res = await db
.collection(collect)
.where(filter)
.get();
if (res.data.length) {
res = await db
.collection(collect)
.where(filter)
.update({
data
});
} else {
data.createTime = db.serverDate();
res = await db.collection(collect).add({
data
});
}
return res;
};
module.exports = {
connect,
add,
find,
orderBy,
update
};
// cloudfunctions\router\unit\log.js
const cloud = require('wx-server-sdk');
const log = async (ctx, next) => {
ctx.data = {};
ctx.body = {
code: 200
};
ctx.wxContext = cloud.getWXContext();
// 请求的url
const url = ctx._req.url;
// 启动处理时间
const start = new Date();
console.log(`${start} =>[${url}]`);
await next();
// 结速处理时间
const endT = new Date();
const ms = endT - start;
// 输出日志 ctx.method 请求方式 ctx.url 请求地址
console.log(`${endT} <=[${url}] [${ms}ms] \n`);
};
module.exports = log;
新建 controller
// cloudfunctions\router\controller\login.js
const { find } = require('../unit/db');
const login = async (ctx, next) => {
let res = await find({
collect: 'userInfo',
filter: {
OPENID: ctx.wxContext.OPENID
},
field: {
_id: false,
country: true,
province: true,
city: true,
gender: true,
language: true,
avatarUrl: true,
nickName: true
}
});
if (res.data[0]) {
ctx.body.data = res.data[0];
}
await next(); // 执行下一中间件
};
module.exports = login;
// cloudfunctions\router\controller\login.js
const { update } = require('../unit/db');
const saveUserInfo = async (ctx, next) => {
let userInfo = Object.assign({}, ctx.wxContext, ctx._req.event.data);
let res = await update({
collect: 'userInfo',
data: userInfo,
filter: {
OPENID: ctx.wxContext.OPENID
}
});
ctx.body.data = res;
await next(); // 执行下一中间件
};
module.exports = saveUserInfo;
编辑完成之后
上传云函数
可以执行下测试以验证云函数是没有问题~
然后云函数添加完成
在小程序端调用云函数
首先 在 app.tsx 中添加
// 初始化云函数
Taro.cloud.init();
修改 srcstoreuserInfo.ts
// src\store\userInfo.ts
// 引入observable;
import { observable } from 'mobx';
import { getStorageSync, cloud } from '@tarojs/taro';
const userInfoStore = observable({
// 存储用户基本信息的对象
userInfo: {},
// 写入信息的方法
saveInfo(userInfo: userinfo) {
if (this!.userInfo) {
this.userInfo = Object.assign({}, this.userInfo, userInfo);
cloud.callFunction({
name: 'router',
data: {
$url: 'saveUserInfo',
data: this.userInfo
}
});
}
},
// 从本地读取用户信息
readInfo() {
const userInfo = getStorageSync('userInfo');
this.userInfo = Object.assign({}, this.userInfo, userInfo);
},
getCloudInfo() {
cloud
.callFunction({
name: 'router',
data: {
$url: 'login'
}
})
.then((res: any) => {
console.log({ res });
this.userInfo = res.result.data || {};
});
}
});
export default userInfoStore;
然后修改 src\pages\index\index.tsx
import { ComponentType } from 'react';
import Taro, { Component, Config } from '@tarojs/taro';
import { View, Button } from '@tarojs/components';
import { AtAvatar } from 'taro-ui';
// 引入mobx的修饰器
import { observer, inject } from '@tarojs/mobx';
import './index.scss';
// 编辑 src\pages\index\index.tsx 下的props接口类型
type PageStateProps = {
// 添加 userInfoStore
userInfoStore: {
userInfo: userinfo;
saveInfo: Function;
getCloudInfo: Function;
};
};
interface Index {
props: PageStateProps;
}
// 注入 userInfoStore
@inject('userInfoStore')
@observer
class Index extends Component {
config: Config = {
navigationBarTitleText: '首页'
};
/**
* @description: 获取用户信息
* @param {Object} detail onGetUserInfo 所返回的用户基本信息
* @return null
*/
getUserInfo({ detail }) {
const { userInfoStore } = this.props;
userInfoStore.saveInfo(detail.userInfo);
}
// 添加 didshow钩子,在每次页面显示的时候执行
componentDidShow() {
const { userInfoStore } = this.props;
// 在页面显示的时候读取用户信息
userInfoStore.getCloudInfo();
}
render() {
const { userInfo } = this.props.userInfoStore;
return (
<View className='index'>
{/* button使用 getUserInfo 可以在小程序中获取用户基本信息 */}
<Button
openType='getUserInfo'
onGetUserInfo={this.getUserInfo.bind(this)}
className='index-avatarUrl-btn nobtn-style'
>
<View className='avatar-box'>
<AtAvatar
image={userInfo.avatarUrl}
size='large'
circle
text={userInfo.avatarUrl ? '' : '空'}
></AtAvatar>
</View>
<View className='nickName-box'>
{userInfo.nickName || '点击登录'}
</View>
</Button>
</View>
);
}
}
export default Index as ComponentType;
这样,在点击用户授权头像之后,获取到的信息会存储在userInfo库中。
每次启动的时候,会从userInfo读取当前用户的信息
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。