代码仓库:https://github.com/changeclass/koa2-weibo

文件上传

安装插件(https://www.npmjs.com/package/formidable-upload-koa)

1
yarn add formidable-upload-koa fs-extra
  1. api路由层实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    * @description:utils api 路由
    * @author: 小康
    * @url: https://xiaokang.me
    * @Date: 2020-12-18 14:08:00
    * @LastEditTime: 2020-12-18 14:08:03
    * @LastEditors: 小康
    */

    const router = require('koa-router')()
    const koaFrom = require('formidable-upload-koa')
    const { saveFile } = require('../../controller/utils')
    const { loginCheck } = require('../../middlewares/loginChecks')
    router.prefix('/api/utils')

    // 上传图片
    router.post('/upload', loginCheck, koaFrom(), async (ctx, next) => {
    // 获取文件
    const file = ctx.req.files['file']
    // 获取文件信息
    const { size, path, name, type } = file
    ctx.body = await saveFile({ size, filePath: path, name, type })
    })

    module.exports = router
  2. controller层实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    /**
    * @description: utils controller
    * @author: 小康
    * @url: https://xiaokang.me
    * @Date: 2020-12-18 14:13:20
    * @LastEditTime: 2020-12-18 14:13:20
    * @LastEditors: 小康
    */
    const path = require('path')
    const { uploadFileSizeFailInfo } = require('../model/ErrorInfo')
    const { SuccessModel, ErrorModel } = require('../model/ResModel')
    const fse = require('fs-extra')
    // 文件最大体积 (5m)
    const MAX_SIZE = 5 * 1024 * 1024 * 1024
    // 存储目录
    const DIST_FOLDER_PATH = path.join(__dirname, '..', '..', 'uploadFiles')
    // 是否需要创建目录
    fse.pathExists(DIST_FOLDER_PATH).then((exist) => {
    if (!exist) {
    fse.ensureDir(DIST_FOLDER_PATH)
    }
    })
    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {string} name 文件名
    * @param {String} type 文件类型
    * @param {String} size 文件大小
    * @param {String} filePath 文件地址
    * @description: 存储文件
    */
    async function saveFile({ name, type, size, filePath }) {
    // 如果文件大小超过设定
    if (size > MAX_SIZE) {
    // 删除文件
    await fse.remove(filePath)
    return new ErrorModel(uploadFileSizeFailInfo)
    }
    // 移动文件
    const fileName = Date.now() + '.' + name // 防止重名
    const distFilePath = path.join(DIST_FOLDER_PATH, fileName) // 目的地
    await fse.move(filePath, distFilePath)
    // 返回信息
    return new SuccessModel({
    url: '/' + fileName
    })
    }

    module.exports = {
    saveFile
    }
  3. 最后在入口文件注册路由并且开发目录即可。

    1
    2
    app.use(koaStatic(path.join(__dirname, '..', 'uploadFiles')))
    app.use(utilsAPIRouter.routes(), utilsAPIRouter.allowedMethods())

修改个人基本信息

  1. api路由层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    router.patch(
    '/changeInfo',
    loginCheck,
    genValidator(userValidate),
    async (ctx, next) => {
    const { nickName, city, picture } = ctx.request.body
    ctx.body = await changeInfo(ctx, { nickName, city, picture })
    }
    )
  2. controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {Object} ctx
    * @param {string} nickName 昵称
    * @param {string} city 地区
    * @param {string} picture 头像地址
    * @description: 修改个人信息
    */
    async function changeInfo(ctx, { nickName, city, picture }) {
    const { userName } = ctx.session.userInfo
    if (!nickName) {
    nickName = userName
    }
    // servers
    const result = await updateUser(
    {
    newNickName: nickName,
    newCity: city,
    newPicture: picture
    },
    { userName }
    )
    if (result) {
    Object.assign(ctx.session.userInfo, {
    nickName,
    city,
    picture
    })
    return new SuccessModel()
    } else {
    return new ErrorModel(changeInfoFailInfo)
    }
    }
  3. server

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    /**
    * 更新用户个人信息
    * @author 小康
    * @date 2020-12-18
    * @param {Object} { newPassword,newNickName,newPicture,newcity }
    * @param {Object} { userName,password }
    * @returns {Boolean} 是否修改成功
    */
    async function updateUser(
    { newPassword, newNickName, newPicture, newCity },
    { userName, password }
    ) {
    const updateData = {}
    // 拼接修改内容
    if (newPassword) {
    updateData.password = newPassword
    }
    if (newNickName) {
    updateData.nickName = newNickName
    }
    if (newPicture) {
    updateData.picture = newPicture
    }
    if (newCity) {
    updateData.city = newCity
    }
    // 拼接查询条件
    const whereData = { userName }
    if (password) {
    whereData.password = password
    }
    // 执行修改
    const result = await User.update(updateData, {
    where: whereData
    })
    return result[0] > 0
    }