上篇文章我们利用wx.login方法获取了用户的唯一标识openid,有了这个标识我们就可以针对每一位用户进行数据上的功能制作。
首先,我们将用户的openid存到数据库,完成用户注册的第一步。
第一步 ,我们在数据库创建一个user表,因为种种原因我想为表加一个后缀,所以我将表命名为user_green。
其中id和用户的openid都为该字段的主键,依靠强大的主键功能强制避免用户进行多次注册。
第二步 ,在tp6框架中创建一个模型,模型名需要与数据库表名对应,所以根据命名规则设置模型名为UserGreen。
namespace app\web\model;
use think\Model;
class UserGreen extends Model{
// // 定义json数据
protected $json = ['information'];
// // 定义json数据查询时返回数组
protected $jsonAssoc = true;
// 设置字段信息
protected $schema = [
'id' => 'int',
'openid' => 'string',
'information' => 'text'
];
}
此时查阅数据,id和openid没问题,而个人信息information字段中我打算以json格式直接存入取出,里面可以包含很多数据。
另外update_time和create_time字段可以利用tp6框架自动填充,无需在模型中设置。
第三步 ,创建后端接口,使用户注册。
复制之前讲过的restful路由,实现高复用路由接口设置,并使用tp6中间件完成跨域操作:
// 通用模型操作
Route::group('/api/rest/:model', function(){
// 新增数据到数据库
Route::post('/', 'index/add');
// 查询单个数据到数据库
Route::get('/:id', 'index/find');
// 查询所有数据到数据库
Route::get('/', 'index/findall');
// 修改单个数据到数据库
Route::put('/:id/', 'index/update');
// 删除单个数据到数据库
Route::delete('/:id', 'index/delete');
})->middleware([\app\admin\middleware\compareToken::class]);
public function add()
{
// 获取前端传值
$data = request() -> param();
// return $data;
if($data['model'] == "user"){
// 使用模型格式化传来的数据
$db_data = new UserGreen;
// 利用模型将数据传到数据库
$db_data->save([
'openid' => $data['openid'],
'information' => $data,
]);
// 返回结果
return '新增数据成功';
}
}
注意 ,我们的方法中要使用之前创建的模型UserGreen,所以最上方就需要引入这个模型:
此时后端就位。
修改login方法:
login() {
wx.login({
success(res) {
console.log('code', res)
if (res.code) {
// 获取到code后进行下一步操作,通过auth.code2Session获取openid
uni.request({
url: 'http://localhost:3000/web/openid/' + res.code,
success(res) {
console.log('openid', res)
// 将openid存储到缓存,减少资源消耗
wx.setStorage({
key: "openid",
data: res.data.openid
})
// 注册
uni.request({
url: 'http://localhost:3000/web/api/rest/user',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
data: {
openid: res.data.openid
},
success(res) {
console.log('注册成功', res)
}
})
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
点击授权按钮进行测试,发现总是会报错:
报错500一般就是后端的问题,于是我开始以为自己哪里复制错了,经过一系列查找,发现去掉跨域的中间件就正常了:
猜想可能我在本地localhost可能与微信小程序不存在跨域问题,这也是微信小程序发送请求必须在https而却能在http://localhost正常运行的原因吧。
之后后端上线时再加上跨域就行。
改动之后测试:
没问题,再看数据库是否有了数据:
没问题,再看本地缓存是否正常:
OK,完成添加数据。
大家多测试几次就会注意到两个问题,一是数据中 update_time 和 create_time 并没有数据填入,第二就是设置openid主键后依然会有新数据产生:
进入user模型中,添加这两个字段,属性为datetime:
我错啦各位大哥,我记错了,这里并不是不用写,是不用设置传入的数据。前边的有太多地方截图了,我实在懒得改了!!!
然后授权测试:
没问题。
避免重复注册的方法就是提前在数据库查一下这个用户是否注册过,也就是查一下数据库中是否有该openid。
第一步 ,为了避免代码混乱,将注册过程封装成方法 register() :
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
第二步 ,后端封装一个查询是否注册的方法:
路由:
// 查询是否注册
Route::get('/is_register/:openid', 'index/is_register');
方法:
// 查询是否注册
public function is_register() {
$data = request() -> param();
$db_data = UserGreen::where("openid", $data['openid']) -> select();
return json($db_data);
}
第三步 ,当用户进入页面时,检查用户本地缓存是否有openid,并获取openid:
created() {
var that = this
wx.getStorage({
key: 'openid',
success(res) {
// 如果本地缓存有openid,说明一定注册过,无需验证,直接使用openid即可
that.openid = res.data
},
fail() {
// 如果没有本地缓存的openid,可能有两个原因
// 第一,用户是第一次登录,没有进行过注册
// 第二,用户的本地缓存过期或清理,需要验证是否注册过
// 都跳转到login进行登录获取openid,获取到openid后使用下一步的isRegister()方法验证是否需要注册
this.login()
}
})
},
第四步 ,前端注册一个调用后端是否注册的方法 isRegister() ,并传值openid:
isRegister(openid) {
// 是否注册
uni.request({
url: 'http://localhost:3000/web/is_register/' + openid,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: 'GET',
success(res) {
console.log('是否注册', res)
if(!res.data[0]) {
// 如果没有注册过,则跳转register()方法进行注册
this.register(openid)
}
// 如果注册过,则到此为止
},
error(err){
console.log(err)
}
})
}
感觉比较复杂,但主要逻辑自己考虑一下就能明白,主要就两个判断, 是否有之前登陆的缓存 ,没有的话查一下 是否注册 。
而且形式上我为了逻辑通顺多出了很多步骤,大家可以根据自己的需求进行设计。主要的前后端方法和接口就是上边那些了。
这篇文章的知识点包括增加数据、查询数据。下篇文章进行数据完善,以头像、昵称、个人信息等功能为例学习修改数据。
更多设计、功能的学习经验,大家也可以去我的公众号查看!
————