五、后台管理端【商家信息】接口
商家信息的构成: 商家名
、 商家地址
、商家Logo
每个新注册的商家都需要设置商家信息
需要的接口: 商家信息上传
, 获取商家信息
, 更新商家信息
5.1 七牛云对象存储
什么是对象存储? 基于对象存储技术的存储方式
有什么作用? 降低中心服务器压力、减少服务器请求、降低服务器存储空间
如何理解? 将需要大量供用户访问的资源信息存储到其他服务器中 从而降低主服务器的资源占用
如何使用对象存储?
- 注册七牛云账号 https://portal.qiniu.com/ 【新人需要实名认证】
- 在对象存储中新建空间 【空间需要公开】
- 在文件上传中上传资源内容 【上传后即可通过链接访问】
5.2 使用SDK操作对象存储
安装SDK
推荐使用yarn
来安装:
bash
yarn install qiniu
获取AK与SK
Node.js SDK 的所有功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的Access Key
和Secret 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
逻辑 :
- 校验参数有效性 不能为空
- 根据当前uid新增信息
- 响应数据
5.6 实现获取商家信息逻辑 💎
需要的字段: 无
接口地址:
/admin/shopInfo
接口类型:
GET
逻辑 :
- 根据当前uid获取信息
- 响应数据 【去除id、密码】
5.7 实现更新商家信息 💛
需要的字段: 无
接口地址:
nickname
address
logo
接口类型:
PUT
逻辑 :
- 校验参数有效性 不能为空
- 查询当前用户是否有商家信息
- 根据当前uid新增信息
- 响应数据