Skip to content
本页目录

五、后台管理端【商家信息】接口

商家信息的构成: 商家名商家地址商家Logo

每个新注册的商家都需要设置商家信息

需要的接口: 商家信息上传, 获取商家信息, 更新商家信息

5.1 七牛云对象存储

什么是对象存储? 基于对象存储技术的存储方式

有什么作用? 降低中心服务器压力、减少服务器请求、降低服务器存储空间

如何理解? 将需要大量供用户访问的资源信息存储到其他服务器中 从而降低主服务器的资源占用

如何使用对象存储?

  1. 注册七牛云账号 https://portal.qiniu.com/新人需要实名认证
  2. 在对象存储中新建空间 【空间需要公开】
  3. 在文件上传中上传资源内容 【上传后即可通过链接访问】

5.2 使用SDK操作对象存储

安装SDK

推荐使用yarn来安装:

bash
yarn install qiniu

获取AK与SK

Node.js SDK 的所有功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的Access KeySecret Key

查看地址: https://portal.qiniu.com/user/key

将AK与SK保存在 config.ts文件中 方便后续使用:

ts
// 七牛云OSS存储
export const qiniu_accessKey  = 'dpmzaIhnPAoDOuE8jRcePWGyTtnwftu6eI9rGpA-' // ak
export const qiniu_secretKey  = '-HTnTmFP0mHulE1lmYJXtEVgrslVq-4gGIog2qIz' // sk
export const qiniu_bucket = 'zengapi' // 存储空间名
export const qiniu_url = 'http://rld84hmgj.hn-bkt.clouddn.com/'    // 访问域名

获取上传凭证

test.ts

ts
import qiniu from 'qiniu'

const putPolicy = new qiniu.rs.PutPolicy({ scope: '存储空间名' })
const mac = new qiniu.auth.digest.Mac('AK', 'SK')
const uploadToken = putPolicy.uploadToken(mac)

构建上传函数

ts
// 代码略...

const config = new qiniu.conf.Config()
// 华东	qiniu.zone.Zone_z0
// 华北	qiniu.zone.Zone_z1
// 华南	qiniu.zone.Zone_z2
// 北美	qiniu.zone.Zone_na0
// @ts-ignore 设置空间对应机房
config.zone = qiniu.zone.Zone_z2
const formUploader = new qiniu.form_up.FormUploader(config)
const putExtra = new qiniu.form_up.PutExtra()
// 文件上传
formUploader.putFile(上传凭证, 上传文件名, 上传文件路径, putExtra, function(respErr,
  respBody, respInfo) {
  if (respErr) {
    throw respErr;
  }
  if (respInfo.statusCode == 200) {
    console.log(respBody);
  } else {
    console.log(respInfo.statusCode);
    console.log(respBody);
  }
});

5.3 Koa文件上传

在koa中我们使用 multer 模块上传文件

安装模块

bash
yarn add @koa/multer multer

快速上手

ts
import multer from '@koa/multer'

// 配置上传文件1.所在的目录和2.更改文件名
const storage = multer.diskStorage({ //磁盘存储引擎方法
	destination:(req, file, cb)=> { //存储前端传来的文件
	    cb(null, 'uploads')
	},
	filename:(req, file, cb)=> {
	   // 防止文件重名更改前缀
	   let fileFormat = (file.originalname).split(".")
	   let num = `${Date.now()}-${Math.floor(Math.random() * 10000000)}${"."}${fileFormat[fileFormat.length - 1]}`
	   cb(null, num)
	 }
})

const upload = multer({ storage, limits: { fileSize: 5 * 1024 * 1024 } })

const router = new Router()

// 单图上传 字段必须为file
router.post('/upload', upload.single('file'), async (ctx) => {
    console.log(ctx.file)
})

// 多图上传 字段必须为photos组成的数组 最多12个
router.post('/upload', upload.array('photos', 12), async (ctx) => {
    console.log(ctx.files)
})

封装为中间件

/middleware/upload.ts

ts
import multer from '@koa/multer'

// 配置上传文件1.所在的目录和2.更改文件名
const storage = multer.diskStorage({ //磁盘存储引擎方法
	destination:(req, file, cb)=> { //存储前端传来的文件
	    cb(null, 'uploads')
	},
	filename:(req, file, cb)=> {
	   // 防止文件重名更改前缀
	   let fileFormat = (file.originalname).split(".")
	   let num = `${Date.now()}-${Math.floor(Math.random() * 10000000)}${"."}${fileFormat[fileFormat.length - 1]}`
	   cb(null, num)
	 }
})

const upload = multer({ storage, limits: { fileSize: 5 * 1024 * 1024 } })

export default upload

/router/admin/shop-info.ts

ts
// * 商家信息管理 API接口
import Router from 'koa-router'
import upload from '../../middleware/upload'
const router = new Router({ prefix: '/merchant' })

// 后台- 图片上传
router.post('/upload', upload.single('file'), async (ctx) => {
 console.log(ctx.file)
})

5.4 上传图片到对象存储

封装qn函数库

由于qnSDK操作代码过于复杂 封装之后便于后期多次使用

config/qn.ts

ts
import { File } from '@koa/multer'
import qiniu from 'qiniu'
import { qiniu_accessKey, qiniu_bucket, qiniu_secretKey, qiniu_url } from '../config'

// 七牛模块
class Qn {
  constructor() {}

  // 构建上传策略函数(获取上传token)
  upToken(bucket: string) {
    const putPolicy = new qiniu.rs.PutPolicy({ scope: bucket })
    const mac = new qiniu.auth.digest.Mac(qiniu_accessKey, qiniu_secretKey)
    const uploadToken = putPolicy.uploadToken(mac)
    return uploadToken
  }

  // 上传图片
  upImg(file: File) {
      // 上传到七牛后保存的文件名
      const key = file.filename
      // 生成上传 Token
      const token = this.upToken(qiniu_bucket)
      //要上传文件的本地路径
      const filePath = file.path

      //构造上传函数
      // 文件上传(以下四行代码都是七牛上传文件的配置设置)
      const config = new qiniu.conf.Config()
      // @ts-ignore 设置空间对应机房
      config.zone = qiniu.zone.Zone_z2
      const formUploader = new qiniu.form_up.FormUploader(config)
      const putExtra = new qiniu.form_up.PutExtra()
      return new Promise((resolve, reject) => {
        formUploader.putFile(token, key, filePath, putExtra,
          function (respErr, respBody, respInfo) {
            if (respErr) {
              reject(respErr)
            }
            if (respInfo.statusCode == 200) {
              resolve(qiniu_url + respBody.key)
            } else {
              // console.log(respInfo, respBody)
              reject({ code: 500, msg: '上传失败', error: respBody.error })
            }
          }
        )
      })
  }
}

export default new Qn();

在路由中使用

ts
// 后台- 图片上传
router.post('/upload', upload.single('file'), async (ctx) => {
  try {
    const res = await qn.upImg(ctx.file)
    ctx.success(res)
  } catch (error) {
    ctx.fail('上传失败', 202)
  }
})

5.5 实现商家信息上传逻辑 🉐

  • 需要的字段: nickname address logo

  • 接口地址: /admin/shopInfo

  • 接口类型: POST

  • 逻辑 :

    1. 校验参数有效性 不能为空
    2. 根据当前uid新增信息
    3. 响应数据

5.6 实现获取商家信息逻辑 💎

  • 需要的字段: 无

  • 接口地址: /admin/shopInfo

  • 接口类型: GET

  • 逻辑 :

    1. 根据当前uid获取信息
    2. 响应数据 【去除id、密码】

5.7 实现更新商家信息 💛

  • 需要的字段: 无

  • 接口地址: nickname address logo

  • 接口类型: PUT

  • 逻辑 :

    1. 校验参数有效性 不能为空
    2. 查询当前用户是否有商家信息
    3. 根据当前uid新增信息
    4. 响应数据