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_admin
    if (!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.files
        const 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) * pageSize
    const 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嗷,随时更新,随时不定期上传一些好的代码进行开源,欢迎大家一起交流~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦逼的猿宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值