当前位置:网站首页>基于 koa2 + mysql 实现用户管理的 CRUD 代码实践
基于 koa2 + mysql 实现用户管理的 CRUD 代码实践
2022-07-17 12:02:00 【柯晓楠】
项目结构
|-- bin
|-- www
|-- src
|-- controller // 控制层
|-- user.js
|-- db
|-- model // 模型层
|-- User.js
|-- index.js
|-- seq.js // 数据库连接配置
|-- types.js // 数据类型
|-- model // 公共模型
|-- ErrorInfo.js
|-- ResModel.js
|-- routes // 路由管理
|-- user.js
|-- service // 服务层
|-- user.js
|-- utils // 工具管理
|-- app.js
|-- package.json
连接数据库
src/db/seq.js 文件:
/** * @description 配置数据库 */
const Sequelize = require('sequelize')
const database = 'mytest' // 数据库名称
const user = 'root' // 用户名
const password = 'root' // 密码
const conf = {
host: 'localhost', // 数据库地址
port: '3306',
dialect: 'mysql', // 指定mysql类型
pool: {
// 数据库连接池配置
max: 5,
min: 0,
idle: 10000
}
}
const seq = new Sequelize(database, user, password, conf)
module.exports = seq
src/db/types.js 文件:
配置数据类型
/** * @description 封装 sequelize 数据类型 */
const Sequelize = require('sequelize')
module.exports = {
STRING: Sequelize.STRING,
DECIMAL: Sequelize.DECIMAL,
TEXT: Sequelize.TEXT,
INTEGER: Sequelize.INTEGER,
BOOLEAN: Sequelize.BOOLEAN
}
创建工具类
src/utils/_format.js 格式化类:
/** * @description 数据格式化 */
const moment = require('moment')
// 格式化新用户注册时间
module.exports.formatRegDate = function() {
return moment().format('YYYY-MM-DD hh:mm:ss')
}
module.exports.randomString = function(size) {
const sourceData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
const len = sourceData.length
let result = ''
for (let i = 0; i < size; i++) {
result += sourceData.charAt(Math.floor(Math.random() * len))
}
return result
}
创建数据模型层
src/db/model/User.js 文件:
/** * @description 用户数据模型 */
const seq = require('../seq')
const {
STRING, INTEGER } = require('../types')
const User = seq.define('user', {
userid: {
type: STRING,
allowNull: false,
unique: true,
primaryKey: true,
comment: '用户ID, 唯一'
},
nikename: {
type: STRING,
allowNull: false,
comment: '用户昵称'
},
city: {
type: STRING,
allowNull: true,
comment: '城市'
},
isVip: {
type: INTEGER,
allowNull: false,
comment: '是否为VIP, 1为普通用户, 2为vip'
},
avatar: {
type: STRING,
allowNull: true,
comment: '头像img地址'
},
createtime: {
type: STRING,
allowNull: false,
comment: '注册时间'
}
}, {
freezeTableName: true, // 使用自定义表名
tableName: 'user', // 实例对应的表名
timestamps: false, //去除createAt updateAt,如果需要sequelize帮你维护createdAt,updatedAt和deletedAt必须先启用timestamps功能
// createdAt: 'created_at', // 将createdAt对应到数据库的created_at字段
// updatedAt: 'updated_at', // 将updatedAt对应到数据库的updated_at字段
// deletedAt: false, // 'deleted_at', 删除数据时不删除数据,而是更新deleteAt字段 如果需要设置为true
// paranoid: false
})
module.exports = User
src/db/model/index.js 将模型对外暴露
/** * @description 数据模型入口文件 */
const User = require('./User')
module.exports = {
User
}
创建公共模型,处理异常信息:src/model/ErrorInfo.js
/** * @description 失败信息集合,包括 errno 和 message */
module.exports = {
// 注册失败
registerFailInfo: {
errno: 10001,
message: '注册失败,请重试'
},
// 登录失败
loginFailInfo: {
errno: 10002,
message: '登录失败'
},
// 未登录
loginCheckFailInfo: {
errno: 10003,
message: '您尚未登录'
},
// 修改信息失败
updateFailInfo: {
errno: 10004,
message: '修改信息失败'
},
// 删除用户失败
deleteUserFailInfo: {
errno: 10005,
message: '删除用户失败'
},
// 查询失败
queryFailInfo: {
errno: 10006,
message: '查询失败'
},
// 操作失败
operationFailInfo: {
errno: 10007,
message: '操作失败'
}
}
db/model/ResModel.js
/** * @description res 的数据模型 */
/** * 基础模块 */
class BaseModel {
constructor({
errno, data, message}) {
this.errno = errno
if (data) {
this.data = data
}
if (message) {
this.message = message
}
}
}
/** * 成功的数据模型 */
class SuccessModel extends BaseModel {
constructor(data = {
}) {
super({
errno: 0,
data
})
}
}
/** * 失败的数据模型 */
class ErrorModel extends BaseModel {
constructor({
errno, message }) {
super({
errno,
message
})
}
}
module.exports = {
SuccessModel,
ErrorModel
}
创建数据服务层
db/service/user.js
/** * @description User Service */
const {
User } = require('../db/model/index')
const Op = require('sequelize').Op
/** * 新用户注册 * @param {string} userid 用户id * @param {string} nikename 昵称 * @param {string} city 城市 * @param {number} isVip 是否VIP * @param {string} createtime 注册时间 */
async function createUser({
userid, nikename, city, isVip = 1, avatar, createtime}) {
const result = await User.create({
userid,
nikename,
city,
isVip,
avatar,
createtime
})
const data = result.dataValues
return data
}
/** * * @param {string} userid 用户ID */
async function getUserInfo(userid) {
// 查询条件
const whereOption = {
userid
}
const result = await User.findOne({
attributes: ['userid', 'nikename', 'city', 'isVip', 'avatar', 'createtime'],
where: whereOption
})
if (result === null) {
return result
}
return result.dataValues
}
/** * 修改用户信息 * @param {*} param0 要修改的用户信息 * @param {*} param1 查询条件 */
async function updateUser(
{
nikename, city, isVip}, {
userid}
) {
// 拼接修改内容
const updateObj = {
}
if (nikename) {
updateObj.nikename = nikename
}
if (city) {
updateObj.city = city
}
if (isVip) {
updateObj.isVip = isVip
}
// 拼接查询条件
const whereOption = {
}
if (userid) {
whereOption.userid = userid
}
// 执行修改
const result = await User.update(updateObj, {
where: whereOption
})
return result[0] > 0
}
/** * 删除用户 * @param {string} userid 用户id */
async function deleteUser(userid) {
const result = await User.destroy({
where: {
userid
}
})
return result > 0
}
/** * 分页查询所有用户 * @param {number} page 当前页码 * @param {number} pageSize 每页条数 */
async function queryAll({
nikename, userid, page = 1, pageSize = 10 }) {
const whereOption = {
}
if (nikename) {
whereOption.nikename = {
[Op.like]: `%${
nikename}%`
}
}
if (userid) {
whereOption.userid = {
[Op.like]: `%${
userid}%`
}
}
if (page < 1) {
page = 1
}
const result = await User.findAll({
limit: pageSize,
offset: (page - 1) * pageSize,
order: [
['createtime', 'desc']
],
where: whereOption
})
return {
page,
pageSize,
count: result.count,
data: result.map(user => user.dataValues)
}
}
module.exports = {
createUser,
getUserInfo,
updateUser,
deleteUser,
queryAll
}
创建控制层
src/controller/user.js
/** * @description User Controller */
const {
createUser,
getUserInfo,
updateUser,
deleteUser,
queryAll
} = require('../service/user')
const {
SuccessModel, ErrorModel } = require('../model/ResModel')
const {
registerFailInfo,
loginFailInfo,
loginCheckFailInfo,
updateFailInfo,
deleteUserFailInfo,
queryFailInfo,
operationFailInfo
} = require('../model/ErrorInfo')
const {
formatRegDate,
randomString
} = require('../utils/_format')
/** * 用户注册或登录 * @param {string} userid 用户ID * @param {string} nikename 昵称 * @param {string} city 城市 * @param {string} avatar 头像 */
async function registerOrLogin({
userid, nikename, city, avatar }) {
const userInfo = await getUserInfo(userid)
if (userInfo) {
return new SuccessModel(userInfo)
}
const userObj = {
userid: randomString(16),
nikename,
openid,
city,
isVip: 1,
avatar,
createtime: formatRegDate()
}
try {
await createUser(userObj)
return new SuccessModel(userObj)
} catch (ex) {
console.error(ex.message, ex.stack)
return new ErrorModel(registerFailInfo)
}
}
/** * 查询所有用户(支持条件查询和模糊查询) * @param {string} nikename 用户昵称 * @param {string} userid 用户id * @param {number} page 当前页码 * @param {number} pageSize 每页条数 * @returns */
async function queryAllUser({
nikename, userid, page, pageSize }) {
try {
const result = await queryAll({
nikename, userid, page, pageSize })
return new SuccessModel(result)
} catch (ex) {
console.error(ex.message, ex.stack)
return new ErrorModel(queryFailInfo)
}
}
/** * 修改用户信息 * @param {object} updateInfo 要修改的信息 * @param {objcet} whereInfo 查询条件 */
async function updateUserInfo(updateInfo, whereInfo) {
try {
const result = await updateUser(updateInfo, whereInfo)
return new SuccessModel({
result })
} catch (ex) {
console.error(ex.message, ex.stack)
return new ErrorModel(updateFailInfo)
}
}
/** * 冻结账户 * @param {string} userid 用户id */
async function freezeAccount({
userid }) {
try {
const result = await updateUser(
{
isVip: -1 },
{
userid }
)
return new SuccessModel({
result })
} catch (ex) {
console.error(ex.message, ex.stack)
return new ErrorModel(operationFailInfo)
}
}
module.exports = {
registerOrLogin,
queryAllUser,
updateUserInfo,
freezeAccount
}
创建路由
src/routes/user.js
/** * @description User API 路由 */
const router = require('koa-router')()
const {
registerOrLogin,
updateUserInfo,
queryAllUser,
freezeAccount
} = require('../controller/user')
router.prefix('/user')
// 注册或登录
router.post('/login', async (ctx, next) => {
const {
nikename, city, avatar } = ctx.request.body
ctx.body = await registerOrLogin({
nikename,
city,
avatar
})
})
// 修改用户信息
router.post('/update', async (ctx, next) => {
const {
nikename, city, isVip, userid } = ctx.request.body
ctx.body = await updateUserInfo(
{
nikename, city, isVip },
{
userid }
)
})
// 查询用户
router.post('/query', async (ctx, next) => {
const {
nikename, userid, page, pageSize } = ctx.request.body
ctx.body = await queryAllUser({
nikename,
userid,
page,
pageSize
})
})
// 冻结账户
router.post('/freeze', async (ctx, next) => {
const {
userid } = ctx.request.body
ctx.body = await freezeAccount({
userid })
})
module.exports = router
接口测试
- 用户登录与注册
http://localhost:3000/user/login【post请求】 - 修改用户信息
http://localhost:3000/user/update【post请求】 - 查询用户信息
http://localhost:3000/user/query【post请求】 - 冻结用户账号
http://localhost:3000/user/freeze【post请求】
边栏推荐
- AsyncLocalStorage 的妙用
- 半监督学习在恶意软件流量检测中的应用
- 作业:输入1-100的奇数
- Flink entry to practice - stage 5 (processing function)
- 流量排名100W网站
- 快速判断站点是否存活的 3 种编程实现
- 2022-07-16: what is the output of the following go language code? A:[]; B:[5]; C:[5 0 0 0 0]; D:[0 0 0 0 0]。 package main imp
- Relationship between standardization, normalization and regularization
- Flink入门到实战-阶段四(时间和窗口图解)
- vc查看内存泄漏
猜你喜欢

Data Lake (XII): integration of spark3.1.2 and iceberg0.12.1

如何解决谷歌浏览器解决跨域访问的问题

Huawei Shengsi mindspire detailed tutorial

TLS four handshakes

HCIA 静态基础实验 7.8

Ffmpeg record video, stop (vb.net, step on the pit, class library - 10)

Kirin Xin'an operating system derivative solution | host security reinforcement software, to achieve one click rapid reinforcement!

Excel表格转换为Word表格,并且保留Excel表格中公式不发生变化

Pfsense configure tailscal site to site connection

【C语言】浅涉第一个C语言程序及数据类型
随机推荐
空天地海协同应用综述
Flink entry to practice - stage 5 (processing function)
Good news
中职网络安全——(2022网络安全nc批量连接的脚本)免费的脚本哦~~~
English grammar_ Personal pronoun usage
Packet knowledge
网络安全学习(千锋网络安全笔记)1--搭建虚拟机
pfSense配置Tailscal站点到站点连接
ty_ Gr551x code framework
喜报
2022年湖南 省中职组“网络空间安全”Windows渗透测试 (超详细)
laravel 生成分表脚本示例
[C language] string, escape character and comment
【Unity技术积累】实现鼠标画线功能 & LineRenderer
HCIA 静态综合实验报告 7.10
流量排名100W网站
面向6G的智能反射面无线通信综述
2022年浙江省中职组“网络空间安全”编码信息获取解析(完整版)
HCIA 复习作答 2022.7.6
基于信道状态信息的Wi-Fi感知技术与实践