Koa商城项目-轮播图模块(后端)

前言

通过这次独自做前后端发现有很多需要提升的地方,很多细节处理不到位。下面简单看一下本人自己做的效果吧~~

Git地址

https://gitee.com/ah-ah-bao/koa_system

效果图

后端逻辑分析

首先编写route->banner.router.js

/*** @author: zxb* @date: 2024-08-06* @des : 商品路由* @router: /goods/add**/const Router = require('koa-router');const { upload, addBanner, getBannerList, updateBanner, deleteBanner, getBannerDetail } = require('../controller/banner.controller')
const { validateBanner, PageSizeOrPage } = require('../middleware/banner.middleware')
const { auth, hasAdminPermission } = require('../middleware/auth.middleware')const router = new Router({ prefix: '/banner' });router.post('/upload', auth, hasAdminPermission, upload);
router.post('/add', auth, hasAdminPermission, validateBanner, addBanner);
router.post('/update', auth, hasAdminPermission, updateBanner);
router.post('/delete', auth, hasAdminPermission, deleteBanner);
router.post('/detail', getBannerDetail);
router.post('/list', PageSizeOrPage, getBannerList);module.exports = router; // 导出router

上面的auth、hasAdminPermission和validateBanner是中间件`中间件主要的作用类似于拦截一下,判断符不符合条件,就和去电影院检票一样。一般是用来处理数据、身份校验和是否含有token等操作。中间件的代码放在下面了~

auth等中间件

const jsonwebtoken = require('jsonwebtoken');
const { JWT_SECRET } = require('../config/config.development')
const auth = async (ctx, next) => {var { authorization = "" } = ctx.request.header;authorization = authorization.replace('Bearer ', '')try {// user中包含了 jwt加密时的相关信息const user = jsonwebtoken.verify(authorization, JWT_SECRET)ctx.state.user = user} catch (err) {if (err.name) {switch (err.name) {case 'TokenExpiredError':ctx.body = {code: 401,message: 'token过期'}break;case 'JsonWebTokenError':ctx.body = {code: 401,message: 'token无效'}break;default:ctx.body = {code: 401,message: 'token错误'}}return} else {ctx.body = {code: 401,message: 'token错误'}return}}await next()
}
const hasAdminPermission = async (ctx, next) => {const is_admin = ctx.state.user.is_adminif (!is_admin) {ctx.body = {code: 403,message: '您当前没有权限'}return}await next()
}
module.exports = {auth,hasAdminPermission
};
const validateBanner = async (ctx, next) => {// 验证商品信息try {ctx.verifyParams({bannername: { type: 'string', required: true },url: { type: 'string', required: true },})} catch (err) {ctx.body = {code: 500,message: '参数错误',data: err}return}await next()
}

随后到banner.controller.js

const path = require('path')
const { APP_PORT, SYS_LOCATION } = require('../config/config.development');
const { bannerAdd, bannerUpdate, bannerDelete, bannerDetail, bannerList, getBanner } = require('../service/banner.service')
class BannerController {// 轮播图图片上传async upload(ctx) {ctx.body = "图片上传成功"const { file } = ctx.request.filesconst fileType = ['image/jpeg', 'image/png', 'image/gif']if (file) {if (!fileType.includes(file.mimetype)) {return ctx.body = {code: 500,message: '图片格式不正确',data: ""}} else {ctx.body = {code: 200,message: '图片上传成功',data: {url: `http://${SYS_LOCATION}:${APP_PORT}/${path.basename(file.filepath)}`}}}} else {ctx.body = {code: 500,message: '图片上传失败',data: ""}}}// 发布轮播图async addBanner(ctx) {try {const findresult = await getBanner(ctx.request.body.bannername)if (findresult) {ctx.body = {code: 500,message: '轮播图已存在',data: ""}return} else {const res = await bannerAdd(ctx.request.body)ctx.body = {code: 200,message: '添加轮播图成功!',data: res}}} catch (err) {ctx.body = {code: 500,message: '添加轮播图失败',data: err}return}}// 修改轮播图信息async updateBanner(ctx) {try {const res = await bannerUpdate(ctx.request.body)if (res) {ctx.body = {code: 200,message: '更新轮播图成功',data: ''}} else {ctx.body = {code: 500,message: '更新轮播图失败',data: ""}}} catch (err) {ctx.body = {code: 500,message: '更新轮播图失败',data: err}return}}// 删除轮播图async deleteBanner(ctx) {try {const res = await bannerDelete(ctx.request.body.id)if (res) {ctx.body = {code: 200,message: '删除轮播图成功',data: ''}} else {ctx.body = {code: 500,message: '删除轮播图失败',data: ""}}} catch (err) {ctx.body = {code: 500,message: '删除轮播图失败',data: err}}}// 获取详情async getBannerDetail(ctx) {try {const res = await bannerDetail(ctx.request.body.id)if (res) {ctx.body = {code: 200,message: '获取轮播图详情成功',data: res}} else {ctx.body = {code: 500,message: '获取轮播图详情失败',data: ""}}} catch (err) {ctx.body = {code: 500,message: '获取轮播图详情失败',data: err}}}// 获取轮播图列表async getBannerList(ctx) {try {const { res, total } = await bannerList(ctx.request.body.page, ctx.request.body.pageSize, ctx.request.body)if (res) {ctx.body = {code: 200,message: '获取轮播图列表成功',data: res,total: total}} else {ctx.body = {code: 500,message: '获取轮播图列表失败',data: ""}}} catch (err) {ctx.body = {code: 500,message: '获取轮播图列表失败',data: err}}}
}
module.exports = new BannerController()

这个里面主要做的就是响应和一些逻辑,这一段代码最关键的就是上传这一块,使用的插件,可以看第一个栏目作品的详细介绍。

banner.service.js的相关代码

const Banner = require('../model/banner.model');
class BannerService {
async getBanner(bannername){const res = await Banner.findOne({where:{bannername}});return res;
}async bannerAdd(banner) {const res = await Banner.create(banner);return res.dataValues;}async bannerUpdate(banner) {const res = await Banner.update(banner, { where: { id: banner.id } });return res[0] > 0;}async bannerDelete(id) {const res = await Banner.destroy({ where: { id } });return res > 0;}async bannerDetail(id) {const res = await Banner.findByPk(id);return res ? res.dataValues : null;}async bannerList(page = 1, pageSize = 10, otherBannerOptions = {}) {const offset = (page - 1) * pageSizeconst options = {offset,limit: pageSize,};if (otherBannerOptions.bannername != '' && otherBannerOptions.bannername != null && otherBannerOptions.bannername) {options.where = {bannername: otherBannerOptions.bannername // 根据 bannername 进行查询};}const res = await Banner.findAll(options);const total = await Banner.count();return {res,total};}
}
module.exports = new BannerService();

 这个上面主要的功能就是相当于执行sql语句,最后这个就是创建数据库的重要文件//

banner.model.js

const { DataTypes } = require('sequelize');
const sequelize = require('../db/seq')const Goods = sequelize.define('node_banner', {bannername: {type: DataTypes.STRING,allowNull: false,comment: '轮播图名称',unique: true},url: {type: DataTypes.STRING,allowNull: false,comment: '轮播图名称'},
})// 强制同步数据库(创建数据库表)
// force:ture 如果表存在就强行删除表,然后创建一个新的表
// Goods.sync({force:'ture'})module.exports = Goods

后端完整代码

可以关注阿宝的git嗷,随时更新,随时不定期上传一些好的代码进行开源,欢迎大家一起交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403418.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s 部署polardb-x集群

前言 体验了基于源码构建的部署polardb-x 单机部署,当然也想体验性能更好的完全分布式集群。这边文章将重点介绍如何部署polardb-x集群 简介 PolarDB-X 是一款面向超高并发、海量存储、复杂查询场景设计的云原生分布式数据库系统。其采用 Shared-nothing 与存储计…

二叉树详解(1)

文章目录 目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示1.3 树在实际中的运用(表示文件系统的目录树结构) 2. 二叉树的概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构…

Ubuntu基础使用

1.首先我们先获取ubuntu的操作相同其中也分为4部分: 1.云服务器。在服务器里面我们可以去选择3种服务器分别为阿里云,腾讯云,华为云,这3个,有服务器才可以进去进行操作。 2.双系统。双系统有一个特点就是只能同时启动一…

机器学习:线性回归算法(一元和多元回归代码)

1、线性回归 1、数据准备: 描述如何获取和准备数据。 2、图像预处理: 包括图像读取。 3、将数据划分为训练集和测试集。 4、计算数据的相关系数矩阵。 5、模型训练: 详细说明如何使用线性回归算法训练模型&…

AI视频创作原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

打卡学习Python爬虫第二天|Web请求过程刨析

一、服务器渲染 服务器端渲染(Server-Side Rendering,简称SSR)是一种网页渲染技术。在这种技术中,服务器在接收到客户端的请求后,会生成页面的初始HTML内容,并将其发送给客户端。客户端浏览器接收到这些HT…

Go Roadmap-Basics中文笔记

Go Roadmap-Basics 地址:https://roadmap.sh/golang 简介:Github star No.6 学习路线 Go 中译版 Learn the Basics Go特点:静态类型,运行速度快,编译语言,编译速度快,自动垃圾回收&#xff…

Linux中查看修改系统系统时间

当我们项目部署在Linux中,随着服务器运行时间变长,会出现Linux服务器时间变快或者变慢的情况,有些系统对时间准确性要求比较高,笔者有碰到某天服务器突然无法调用第三方接口,最终排查后系统时间超过15分钟,…

SAR靶机笔记

SAR 靶机笔记 概述 SAR 是 Vulnhub 上的靶机,大家可以去 vulnhub 网站上去进行下载。 这里有链接: https://download.vulnhub.com/sar/sar.zip 一丶常规的 nmap 扫描 1)主机发现 sn 只做 ping 扫描,不做端口扫描 nmap -sn …

Linux - 基础工具使用

文章目录 一、yum1、介绍2、功能3、语法4、使用 二、rzsz1、安装rzsz的指令2、介绍3、使用 三、vim基础使用1、介绍2、基础使用 四、gcc/g使用1、生成可执行文件过程2、语法3、常用选项4、编译过程5、动静态库6、包含头文件的多文件编译7、链接外部库 一、yum 1、介绍 Linux中…

类和对象(下)(1)

类和对象(下) 再探构造函数 我们之前在实现构造函数的时候,初始化成员变量使用的方式都是在函数体内进行赋值,其实构造函数初始化成员变量还有一种方式:初始化列表。 初始化列表不只是为了写得方便,还能解…

构建具有音频功能的中英翻译器:一个Python应用程序的旅程

在当今的全球化世界中,语言翻译工具变得越来越重要。作为一名软件开发者,我最近完成了一个有趣的项目:一个结合了翻译、文字转语音和数据管理功能的中英翻译器。在这篇博客中,我将分享这个应用程序的主要特性和开发过程中的一些见…

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息,但是从节点无法获取,且报错“error: You must be logged in to the server (Unauthorized)” 排查思路: 当时证书过期了,只处理的主节点的证书过期,没有处理从节点的 kubeadm alpha …

基于Windows系统和‌Linux系统,以tomcat为案例,讲解如何新增自启动服务。

文章目录 引言‌I Linux系统‌(以CentOS为例)基础知识:运行级别(run level)基于chkconfig 工具,设置服务启动类型。基于systemctl 新增系统服务制定定时任务优化停止Tomcat服务命令II 基于Windows系统设置服务自启动的常规操作安装多个tomcat服务,并设置自启动。引言 场景…

Vue UI - 可视化的Vue项目管理器

概述 Vue CLI 3.0 更新后,提供了一套全新的可视化Vue项目管理器 —— Vue UI。所以要想使用它,你的 Vue CL I版本必须要在v3.0以上。 一、启动Vue UI 1.1 环境准备 1.1.1 安装node.js 访问官网(外网下载速度较慢)或 http://nod…

【HeadFirst 设计模式】装饰者模式的C++实现

一、案例背景 Starbuzz是以扩张速度最快而闻名的咖啡连锁店。如果你在街角看到它的店,在对面街上肯定还会看到另一家。因为扩张速度实在太快了,他们准备更新订单系统,以合乎他们的饮料供应要求。他们原先的类设计是这样的…… 购买咖啡时&am…

西安旅游系统--论文pf

TOC springboot383西安旅游系统--论文pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现,改变了几千年以来人们的生活,不仅仅是生活物资的丰富,还有精神层次的丰富。在互联网诞生之前,地域位置往往是人们思想上不可跨域的鸿…

Linux快捷方式创建、输出重定向(正确输出和错误输出)

一.正确输出 创建一个1.txt文件,然后用vim打开这个文件,然后再开一个窗口 进程号是5602 通过proc可以看到5602这个进程 进入5602里面这里记录了程序的信息,找到fd 进入fd目录下面有0124快捷方式:快捷方式对应的真正的文件是 /de…

HarmonyOS笔记4:从云数据库获取数据

移动应用获取数据的方式主要有: 1.从网络中获取数据接口API。 2.从华为云数据库获取云数据库的资源。 3.从移动终端直接获取本地的数据 在HarmonyOS笔记3中已经完成了方式一从网络中获取数据接口API的方式。在本篇笔记中,将讨论从云数据库中获取数据。 因…

Docker下安装Redis

下载最新Redis镜像 docker pull redis启动Redis容器 docker run -itd --name myFirstRedis -p 6379:6379 redis:latest观察Redis启动效果 docker ps查看Redis的版本 docker exec -it myFirstRedis /bin/bash redis-server --versionRedis服务器和客户端 Redis是基于键值对存…