从无到有创建一个聊天App之三-绑定api实现

绑定api设计

  • 设计思想
    用户使用QQ登录,只需传入QQ返回的标识唯一用户的id,拿到此id后,需要在数据库中查找有无此用户,若没有,则走注册流程,若有,则走登录流程。注册流程即需要用户填写基本信息,这个App的主旨思想是聊天类的,我们需要手机用户的性别、年龄段、所在地这些信息,若用户提交完毕,即可返回token和user_id。若走登录流程,那么返回token和user_id即可。
  • 定义
    1.绑定
    访问url:
    users/account/qq/:openid post
    返回:
{
    "code": 0,
    "msg": "success",
    "result": {
        "register": 1,
        "token": "atoken",
        "user_id":"auserid"
    }
}

字段说明:
register:整形值 1-账号合法 2-尚未填写基本资料 3-尚未注册
token:字符串 用于后续请求接口访问授权
user_id:字符串 我们的系统中用于标识唯一的用户

2.基本资料提交
访问url:
users/account/basic/:userid post
body:

{
    "sex": 1,
    "age_range": 1,
    "live_province": 0
}

返回

{
    "code": 0,
    "msg": "success",
}

字段说明
sex:整形值 性别 1-男,2-女,3-保密
age_range:整形值 年龄段 1-10后 2-00后 3-90后 4-80后 5-70后 6-其它
live_province:整形值 居住省 取值1到34,咱就不精确到下面的地址了,数据挺多的,而且也用不着,大致范围就好了。

Server端实现

  • 运行MongoDB
    启动MongoDB很简单,首先去要创建一个空白文件夹,在数据库服务器运行时将会在其中写入一些所需使用的文件,然后再安装目录的bin文件夹下运行如下命令即可:mongod.exe -dbpath d:\db\mdb,如下图所示,表示运行成功。其中d:\db\mdb为刚刚创建的空白文件夹。
    MongoDB启动图
  • 使用原生js连接数据库
    a.在项目的根目录运行npm install mongodb安装驱动
    b.MongoDB版本2和版本3的连接方式是不一样的,我们这里因为没有指定版本,所以安装的是版本3,因此,使用如下语句连接,具体api可以参考官方文档。MongoDB 3 连接api
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017', function (err, client) {
    if (err) throw err;
    else {
        console.log("成功建立数据库连接")
    }
});
  • 和其它语言类似,原生的数据库操作方式总是显得很啰嗦,没必要重新造轮子,我们改为使用mongoose来操作数据库。
    a. 运行npm install mongoose安装
    b. 改为如下代码,重新运行,照样没毛病!
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/users');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    console.log("成功建立数据库连接")
});
  • 根据http请求提交的openid,就可以根据设计思想里面说的逻辑处理了。

    关于生成token,这里使用uuid,采用的开源库如下:uuid生成库

  • 至此,这两个api已经实现完毕,这里仅仅修改了users.js文件,贴上代码如下,写的不够优雅,第一次写node.js程序,却也很容易理解。不知道逻辑有没有说明错误以及遗漏,后续我会将代码放到GitHub上。当然这里没有对token做时效的限制,这个是有问题的,后面也会修复。

var express = require('express');
var router = express.Router();
const uuidv1 = require('uuid/v1');

let UNKONW_ERROR = 10080000;
let NO_USER = 10081001;
let PARAMETER_ERROR = 10081002;

var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/users');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
    console.log("成功建立数据库连接");
    //定义一个用户的数据结构
    let userSchema = mongoose.Schema({
        token: String,
        qqId: String,
        sex: Number,
        ageRange: Number,
        liveProvince: Number
    });
    let User = mongoose.model('user', userSchema);

    //绑定请求
    router.post('/account/qq/:openid', function (req, res) {
        let requestQQID = req.params.openid;
        console.log("get request openid:" + requestQQID);
        let person = {};
        let result = {};

        User.findOne({qqId: requestQQID}, function (err, user) {
            if (err) {
                person.code = UNKONW_ERROR;
                person.msg = err;
                res.send(person);
                return console.error(err);
            }
            console.log("by " + requestQQID + " find user:" + user);
            if (user) {
                //找到用户
                if (user.sex && user.ageRange && user.liveProvince) {
                    //登录成功
                    result.register = 1;
                } else {
                    //用户尚未填写基本资料
                    result.register = 2;
                }
                result.token = user.token;
                result.user_id = user._id;
                person.code = 0;
                person.msg = "success";
                person.result = result;
                res.send(person);
            } else {
                //没有找到用户
                person.code = NO_USER;
                person.msg = "no user found";
                result.register = 3;
                //生成token和qq id绑定
                let token = uuidv1();
                let newUser = new User({
                    token: token,
                    qqId: requestQQID
                });
                newUser.save(function (err, newUser) {
                    if (err) {
                        person.code = UNKONW_ERROR;
                        person.msg = err;
                        res.send(person);
                        return console.error(err);
                    }
                    result.user_id = newUser._id;
                    person.result = result;
                    res.send(person);
                });

            }
        });

    });


    router.post('/account/basic/:userid', function (req, res) {
        let userId = req.params.userid;
        let requestBody = req.body;
        console.log("get request user id:" + userId);
        console.log("get request body:" + JSON.stringify(requestBody));
        let person = {};
        User.findOne({token: requestBody.token, _id: userId}, function (err, user) {
            if (err) {
                person.code = UNKONW_ERROR;
                person.msg = err;
                res.send(person);
                return console.error(err);
            }
            if (user) {
                if (requestBody.sex <=0 || requestBody.sex > 3) {
                    person.code = PARAMETER_ERROR;
                    person.msg = "sex error";
                    res.send(person);
                } else if (requestBody.age_range <=0 || requestBody.age_range>6) {
                    person.code = PARAMETER_ERROR;
                    person.msg = "age error";
                    res.send(person);
                } else if (requestBody.live_province <=0 || requestBody.live_province>34) {
                    person.code = PARAMETER_ERROR;
                    person.msg = "province error";
                    res.send(person);
                } else {
                    user.sex = requestBody.sex;
                    user.ageRange = requestBody.age_range;
                    user.liveProvince = requestBody.live_province;
                    user.save(function (err, u) {
                        if (err) {
                            person.code = UNKONW_ERROR;
                            person.msg = err;
                            res.send(person);
                            return console.error(err);
                        }
                        person.code = 0;
                        person.msg = "success";
                        res.send(person);
                    });
                }
            } else {
                //没有找到用户
                person.code = NO_USER;
                person.msg = "no user found";
                res.send(person);
            }
        });
    });

});

module.exports = router;

接下来要做的事情

api已经实现了,接下来要手机端来实现了,这个是我的老本行,会稍微容易一点,哈哈,js已经把我弄得欲仙欲死了。网络请求我会使用okhttp,这个我在先前的项目中已经封装好了,但是是Java语言的,要花一点时间转为Kotlin。明天搞吧。

猜你喜欢

转载自blog.csdn.net/nanzhinan/article/details/80444804