多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
上篇文章我们利用wx.login方法获取了用户的唯一标识openid,有了这个标识我们就可以针对每一位用户进行数据上的功能制作。 首先,我们将用户的openid存到数据库,完成用户注册的第一步。 1.添加数据 (1)后端,以php的thinkphp6框架为例。 第一步 ,我们在数据库创建一个user表,因为种种原因我想为表加一个后缀,所以我将表命名为user_green。 ![](https://img.kancloud.cn/0d/55/0d551bae991178128c2c3e29eca9831d_690x242.png) 其中id和用户的openid都为该字段的主键,依靠强大的主键功能强制避免用户进行多次注册。 第二步 ,在tp6框架中创建一个模型,模型名需要与数据库表名对应,所以根据命名规则设置模型名为UserGreen。 ![](https://img.kancloud.cn/34/8b/348bcea7a0d96eb26d8ce2d4b4a1bffb_210x88.png) ``` <?php 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]); ``` ![](https://img.kancloud.cn/3b/a2/3ba2929b195902e186999f5fcb395150_799x431.png) 编辑add方法,接收前端传来的数据添加到数据库。 ``` 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 '新增数据成功'; } } ``` ![](https://img.kancloud.cn/a3/8b/a38b0e4a9615cec90c110606a553081c_763x508.png) 注意 ,我们的方法中要使用之前创建的模型UserGreen,所以最上方就需要引入这个模型: ![](https://img.kancloud.cn/b9/54/b954682d5dad43ad20834e8973cc4f52_356x238.png) 此时后端就位。 (2)前端,完成用户登录后将openid发送到后端 修改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) } } }) } ``` 点击授权按钮进行测试,发现总是会报错: ![](https://img.kancloud.cn/ac/d1/acd16fee5cedb378b23be42c8d21ce14_511x45.png) 报错500一般就是后端的问题,于是我开始以为自己哪里复制错了,经过一系列查找,发现去掉跨域的中间件就正常了: ![](https://img.kancloud.cn/60/1f/601f47a9eafa6077ef281410357f10ec_635x504.png) 猜想可能我在本地localhost可能与微信小程序不存在跨域问题,这也是微信小程序发送请求必须在https而却能在http://localhost正常运行的原因吧。 之后后端上线时再加上跨域就行。 改动之后测试: ![](https://img.kancloud.cn/53/81/53810050abf7c2a32482282456d52143_472x168.png) 没问题,再看数据库是否有了数据: ![](https://img.kancloud.cn/34/7e/347e246c2fd945441894174891b25588_610x181.png) 没问题,再看本地缓存是否正常: ![](https://img.kancloud.cn/1d/28/1d285aec6398beb0345049c866863e98_416x156.png) OK,完成添加数据。 2.完成注册 大家多测试几次就会注意到两个问题,一是数据中 update_time 和 create_time 并没有数据填入,第二就是设置openid主键后依然会有新数据产生: ![](https://img.kancloud.cn/a9/20/a920ac1bb42af1d0f155c2e18ba39566_542x71.png) (1)先解决时间戳问题: 进入user模型中,添加这两个字段,属性为datetime: ![](https://img.kancloud.cn/36/fd/36fd16f4fcb3dc003eb11b6f81efde70_443x436.png) 我错啦各位大哥,我记错了,这里并不是不用写,是不用设置传入的数据。前边的有太多地方截图了,我实在懒得改了!!! 然后授权测试: ![](https://img.kancloud.cn/ca/52/ca52faabc9a67caee4853edd955bf8ef_621x190.png) 没问题。 (2)避免重复注册: 避免重复注册的方法就是提前在数据库查一下这个用户是否注册过,也就是查一下数据库中是否有该openid。 第一步 ,为了避免代码混乱,将注册过程封装成方法 register() : ![](https://img.kancloud.cn/27/57/27570375e6eabc63d10c4fd18db061ac_824x805.png) ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ![](https://img.kancloud.cn/7c/b5/7cb5b4ae87ee9d045a91fe1b3f518cff_687x446.png) 第二步 ,后端封装一个查询是否注册的方法: 路由: ``` // 查询是否注册 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) } }) } ``` 感觉比较复杂,但主要逻辑自己考虑一下就能明白,主要就两个判断, 是否有之前登陆的缓存 ,没有的话查一下 是否注册 。 而且形式上我为了逻辑通顺多出了很多步骤,大家可以根据自己的需求进行设计。主要的前后端方法和接口就是上边那些了。