灏天阁

Node/Koa2[31]: 开发注册功能

· Yin灏

目录结构

└─src
    ├─app.js
    ├─conf
    │  └─constant.js
    ├─controller
    │  └─user.js
    ├─model
    │  ├─ErrorInfo.js
    │  └─ResModel.js
    ├─routes
    │  └─api
    │      └─user.js
    └─services
        ├─user.js
        └─_format.js

定义常量

src/conf/constant.js

module.exports = {
  DEFAULT_PICTURE: "xxxx",
};

数据格式化处理

src/services/_format.js

const { DEFAULT_PICTURE } = require("../conf/constant");

function _formatUserPicture(obj) {
  if (obj.picture == null) {
    obj.picture = DEFAULT_PICTURE;
  }
  return obj;
}

function formatUser(list) {
  if (list == null) return list;
  if (list instanceof Array) {
    return list.map(_formatUserPicture);
  }
  return _formatUserPicture(list);
}
module.exports = {
  formatUser,
};

创建服务层

src/services/user.js

const { User } = require("../db/model/index");
const { formatUser } = require("./_format");
async function getUserInfo(userName, password) {
  // 处理数据库
  const whereOpt = {
    userName,
  };
  if (password) {
    Object.assign(whereOpt, { password });
  }
  const result = await User.findOne({
    attributes: ["id", "userName", "nickName", "picture", "city"],
    where: whereOpt,
  });
  if (result == null) {
    return result;
  }
  // 格式化处理
  return formatUser(result.dataValues);
}

// service 层处理数据库
async function createUser({ userName, password, gender = 3, nickName }) {
  // 添加注册用户信息到数据库
  const result = await User.create({
    userName,
    password,
    nickName: nickName ? nickName : userName,
    gender,
  });
  return result.dataValues;
}

module.exports = {
  getUserInfo,
};

处理返回数据的模型

src/model/ResModel.js

class BaseModel {
  constructor({ error, data, message }) {
    this.error = error;
    if (data) {
      this.data = data;
    }
    if (message) {
      this.message = message;
    }
  }
}

class SuccessModel extends BaseModel {
  constructor(data = {}) {
    super({
      error: 0,
      data,
    });
  }
}

class ErrorModel extends BaseModel {
  constructor({ errno, message }) {
    super({
      error,
      message,
    });
  }
}

model.exports = {
  SuccessModel,
  ErrorModel,
};

封装错误信息

src/model/ErrorInfo.js

module.exports = {
  // 用户名已存在
  registerUserNameExistInfo: {
    error: 10001,
    message: "用户名已存在",
  },
  // 注册失败
  registerFailInfo: {
    errorno: 10002,
    message: "注册失败,请重试",
  },
  // 用户名不存在
  registerUserNameNotExistInfo: {
    error: 10003,
    message: "用户名未存在",
  },
  // 登录失败
  loginFailInfo: {
    error: 10004,
    message: "登录失败,用户名或密码错误",
  },
  // 未登录
  loginCheckFailInfo: {
    error: 10005,
    message: "您尚未登录",
  },
  // 修改密码失败
  changePasswordFailInfo: {
    error: 10006,
    message: "修改密码失败,请重试",
  },
  // 上传文件尺寸过大
  uploadFileSizeFailInfo: {
    error: 10007,
    message: "上传文件尺寸过大",
  },
  // 修改基本信息失败
  changeInfoFailInfo: {
    error: 10008,
    message: "修改基本信息失败",
  },
  // json schema 校验失败
  jsonSchemaFileInfo: {
    error: 10009,
    message: "数据格式校验错误",
  },
  // 删除用户失败
  deleteUserFailInfo: {
    error: 10010,
    message: "删除用户失败",
  },
  // 添加关注失败
  addFollowerFailInfo: {
    error: 10011,
    message: "添加关注失败",
  },
  // 取消关注失败
  deleteFollowerFailInfo: {
    error: 10012,
    message: "添加关注失败",
  },
  // 创建微博失败
  createBlogFailInfo: {
    errno: 11001,
    message: "创建微博失败,请重试",
  },
  // 删除微博失败
  deleteBlogFailInfo: {
    errno: 11001,
    message: "删除微博失败,请重试",
  },
  // 备注这里没有拷贝完成
};

创建控制层

src/controller/user.js

const { getUserInfo, createUser } = require("../services/user");
const {
  SuccessModel,
  ErrorModel,
  registerFailInfo,
} = require("../model/ResModel");
const {
  registerUserNameNotExistInfo,
  registerUserNameExistInfo,
} = require("../model/ErrorInfo");
async function isExist(userName) {
  // 业务逻辑处理
  // 调用 services 获取数据
  // 统一返回格式
  const userInfo = await getUserInfo(userName);
  if (userInfo) {
    return new SuccessModel(userInfo);
  } else {
    return new ErrorModel(registerUserNameNotExistInfo);
  }
}

async function register({ userName, password, gender }) {
  const userInfo = await getUserInfo(userName);
  if (userInfo) {
    // 用户名已存在
    return new ErrorModel(registerUserNameExistInfo);
  }
  // services
  try {
    await createUser({
      userName,
      password,
      gender,
    });
    return new SuccessModel();
  } catch (ex) {
    console.log(ex.message, ex.stack);
    return new ErrorModel(registerFailInfo);
  }
}

module.exports = {
  isExist,
  register,
};

处理注册相关路由

src/routes/api/user.js

const router = require('koa-router')();
const { isExist, register } = require('../../controller/user');
router.prefix('/api/user');

// 注册路由
router.post('/register', async (ctx, next) => {
  const { userName, password, gender } = ctx.request.body;
  ctx.body = await register({ userName, password, gender })
})
// 用户名是否存在
router.post('/isExist', async (ctx, next) => {
  const { userName } = ctx.request.body;
  ctx.body = await isExist(userName)
})

module.exports = router

入口文件注册路由

src/app.js

//...
const userAPIRouter = require("./routes/api/user");
//...
app.use(userAPIRouter.routes(), userAPIRouter.allowedMethods());

- Book Lists -