express+mysql+vue,从零搭建一个商城管理系统11--使用Sequelize
提示:学习express,搭建管理系统
文章目录
- 前言
- 一、安装sequelize和mysql2
- 二、修改config/db.js
- 三、修改models/user.js,models/shop.js,models/goods.js
- 四、新建dao/user.js,dao/shop.js,dao/goods.js
- 五、修改routes/user.js,routes/shop.js,routes/goods.js
- 六、添加商品
- 总结
前言
需求:主要学习express,所以先写service部分
一、安装sequelize和mysql2
sequelize中文官网
sequelize匹配使用mysql2
npm install sequelize mysql2 --save

二、修改config/db.js
config/db.js
const {Sequelize} = require('sequelize');
const dbConfig = {host:'localhost',ipport:'3306',user:'root',password:'123456',database:'express_service'
}
const sequelize = new Sequelize(dbConfig.database,dbConfig.user,dbConfig.password,{host:dbConfig.host,dialect:'mysql',port:dbConfig.ipport,pool: {max: 5, // 最大连接数min: 0, // 最小连接数idle: 10000, // 释放连接的最长空闲时间msacquire: 30000, // 连接错误后,重新连接的间隔时间ms},
});const connectDb = async()=>{try{await sequelize.authenticate();console.log('数据库连接成功√√√√√');}catch{console.log('数据库连接失败×××××');}
}
connectDb();module.exports = sequelize;
三、修改models/user.js,models/shop.js,models/goods.js
models/user.js
const { DataTypes } = require('sequelize');
const sequelize = require('../config/db');const UserModel = sequelize.define('User',{id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true},userId:DataTypes.STRING,userName:{type: DataTypes.STRING,allowNull: false,unique: true,},password:DataTypes.STRING,
},{tableName:'user'
});//无user表创建user表
UserModel.sync();
module.exports = UserModel;
models/shop.js
const { DataTypes } = require('sequelize');
const sequelize = require('../config/db');const ShopModel = sequelize.define('Shop',{id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true},shopId:DataTypes.STRING,shopName:{type: DataTypes.STRING,allowNull: false,unique: true,},createId:DataTypes.STRING,
},{tableName:'shop'
});//无shop表创建shop表
ShopModel.sync();
module.exports = ShopModel;
models/goods.js
const { DataTypes } = require('sequelize');
const sequelize = require('../config/db');const GoodsModel = sequelize.define('Goods',{id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true},//商品IDgoodsId:DataTypes.STRING,//商品名称goodsName:{type: DataTypes.STRING,allowNull: false,unique: true,},//创建人userIdcreateId:DataTypes.STRING,//商户IDshopId:DataTypes.STRING,//商户名shopName:DataTypes.STRING,//价格price:DataTypes.FLOAT,//库存inventory:DataTypes.INTEGER,//规格specs:DataTypes.STRING,
},{tableName:'goods'
});//无goods表创建goods表
GoodsModel.sync();
module.exports = GoodsModel;

四、新建dao/user.js,dao/shop.js,dao/goods.js
dao/user.js
const UserModel = require('../models/user');
const bcrypt = require('../config/bcrypt');
const md5 = require('md5');
const jwt = require('../config/jwt');
const secretKey = 'longlongago';const errFun = (msg,code)=>{return {code:code||500,success:false,msg:msg||'操作失败'}
}
const sucFun = (data,msg)=>{return {code:200,success:true,msg:msg||'操作成功',data,}
}
const UserDao = {//注册register:async(data)=>{//验证账号密码格式const validateResult =UserDao.validateUserNameAndPassword(data);if(!validateResult.success)return errFun(validateResult.msg);//生成userId passwordconst userId = md5(data.userName+secretKey+new Date().getTime());const password = bcrypt.hash(data.password+secretKey);//添加usertry {const user = await UserModel.create({userId,userName: data.userName,password});if(!user) errFun('注册失败!');return sucFun(user,'注册成功!')}catch(err){let errors = (err.errors||[])[0]||{};let messsage = '注册失败';(errors.message||'').indexOf('userName must be unique')>-1&&(messsage = '用户名已存在');(errors.message||'').indexOf('userName cannot be null')>-1&&(messsage = '用户名不能为空');return errFun(messsage);}},//登录login:async(data)=>{//验证账号密码格式const validateResult =UserDao.validateUserNameAndPassword(data);if(!validateResult.success)return errFun(validateResult.msg);//查询用户是否存在try{const user = await UserModel.findOne({ where: {userName:data.userName} });if(!user)return errFun('该用户不存在');//验证密码是否正确const comparePassword = bcrypt.compare(data.password+secretKey,user.password);if(!comparePassword)return errFun('密码错误');//生成tokenuser.token = jwt.sign(data);return sucFun(user,'登录成功');}catch(err){return errFun('登录失败');}},//验证用户名密码validateUserNameAndPassword:(data)=>{//只包含大小写字母数字,包含1种即可let nameReg = /[\da-zA-z]{6,16}$/;let nameValidate = nameReg.test(data.userName);if(!nameValidate)return errFun('用户名格式错误');//大写字母,小写字母,特殊符号,包含2种以上passwordReg = /^(?![\d]+$)(?![a-z]+$)(?![A-Z]+$)(?![~!@#$%^&*.]+$)[\da-zA-z~!@#$%^&*.]{6,16}$/;let passwordValidate = passwordReg.test(data.password);if(!passwordValidate)return errFun('密码格式错误');return sucFun({},'用户名和密码格式正确');},//获取用户列表queryUserList:async()=>{//根据userName查询usertry{const users = await UserModel.findAll();if(users&&users.length>0)return sucFun(users,'查询用户列表成功');return errFun('查询用户列表失败');}catch(err){return errFun('查询失败');}},
}module.exports = UserDao;
dao/shop.js
const ShopModel = require('../models/shop');
const md5 = require('md5');
const secretKey = 'longlongago';const errFun = (msg,code)=>{return {code:code||500,success:false,msg:msg||'操作失败'}
}
const sucFun = (data,msg)=>{return {code:200,success:true,msg:msg||'操作成功',data,}
}
const ShopDao = {//注册addShopByUserId:async(data)=>{//验证账号密码格式const validateResult =ShopDao.validateShopName(data);if(!validateResult.success)return errFun(validateResult.msg);//添加商户const shopId = md5(data.shopName + secretKey + new Date().getTime());try{const shop = await ShopModel.create({ shopId, createId:data.createId, shopName:data.shopName });if(!shop)errFun('添加商户失败');return sucFun(shop,'添加用户成功')}catch(err){let errors = (err.errors||[])[0]||{};let messsage = '添加商户失败';(errors.message||'').indexOf('shopName must be unique')>-1&&(messsage = '商户名已存在');(errors.message||'').indexOf('shopName cannot be null')>-1&&(messsage = '商户名不能为空');return errFun(messsage);}},//验证商户名密码validateShopName:(data)=>{//只包含大小写字母数字,包含1种即可let nameReg = /[\da-zA-z]{6,16}$/;let nameValidate = nameReg.test(data.shopName);if(!nameValidate)return errFun('商户名格式错误');return sucFun({},'商户名格式正确');},
}module.exports = ShopDao;
dao/goods.js
const GoodsModel = require('../models/goods');
const md5 = require('md5');
const secretKey = 'longlongago';const errFun = (msg,code)=>{return {code:code||500,success:false,msg:msg||'操作失败'}
}
const sucFun = (data,msg)=>{return {code:200,success:true,msg:msg||'操作成功',data,}
}
const GoodsDao = {//注册addGoodsByShopId:async(data)=>{//生成goodsIdconst goodsId = md5(data.goodsName+secretKey+new Date().getTime());try{const goods = await GoodsModel.create({goodsId,goodsName:data.goodsName,createId:data.createId,shopId:data.shopId,shopName:data.shopName,price:data.price,inventory:data.inventory,specs:data.specs,});if(!goods)return errFun('添加商品失败');return sucFun(goods,'添加商品成功');}catch(err){let errors = (err.errors||[])[0]||{};console.log(JSON.stringify(errors))let messsage = '添加商品失败';(errors.message||'').indexOf('goodsName must be unique')>-1&&(messsage = '商品名已存在');(errors.message||'').indexOf('goodsName cannot be null')>-1&&(messsage = '商品名不能为空');return errFun(messsage);}},//通过商品ID查询商品信息queryGoodsByGoodsId:async(data)=>{//根据goodsId查询goodsconst goods = GoodsModel.findOne({where:{goodsId:data.goodsId}});if(!goods)errFun('商品已下架或不存在');return sucFun(goods,'添加商品成功');},
}module.exports = GoodsDao;

五、修改routes/user.js,routes/shop.js,routes/goods.js
routes/user.js
const UserDao = require('../dao/user');
const userRoutes = (router)=>{router.post('/user/register',async (req,res)=>{const result = await UserDao.register(req.body);res.json(result);});router.post('/user/login',async (req,res)=>{const result = await UserDao.login(req.body);res.json(result);});router.post('/user/queryUserList',async (req,res)=>{const result = await UserDao.queryUserList(req.body);res.json(result);});
}
module.exports = userRoutes;
routes/shop.js
const ShopDao = require('../dao/shop');
const shopRoutes = (router)=>{router.post('/shop/addShopByUserId',async (req,res)=>{const result = await ShopDao.addShopByUserId(req.body);res.json(result);});
}
module.exports = shopRoutes;
routes/goods.js
const GoodsDao = require('../dao/goods');
const goodsRoutes = (router)=>{router.post('/goods/addGoodsByShopId',async (req,res)=>{const result = await GoodsDao.addGoodsByShopId(req.body);res.json(result);});
}
module.exports = goodsRoutes;
六、添加商品
删除原有数据库表格,新建用户,新建商户,新建商品可以重新创建对应的表
url:http://localhost:1990/goods/addGoodsByShopId
params:{
“goodsName”: “乐事薯片”,
“createId”: “94bca74490de0f84e1f478ed602123d3”,
“shopId”: “098a0c4828d7d0c78f42e6124f911a77”,
“shopName”: “shop01”,
“inventory”: 200,
“price”: 6.40,
“specs”: “160克/罐”
}


总结
踩坑路漫漫长@~@
相关文章:
express+mysql+vue,从零搭建一个商城管理系统11--使用Sequelize
提示:学习express,搭建管理系统 文章目录 前言一、安装sequelize和mysql2二、修改config/db.js三、修改models/user.js,models/shop.js,models/goods.js四、新建dao/user.js,dao/shop.js,dao/goods.js五、修…...
霹雳学习笔记——6.1 ResNet网络结构、BN以及迁移学习
一、ResNet结构 ResNet是一个突破一千层的网络架构。主要是卷积层Conv和池化层的堆叠。但是普通的堆叠会使得错误率更高,如下图所述,这是因为会产生梯度消失/梯度爆炸等。(梯度就是增量,有大小有方向) 解决方法&#…...
Gitee的注册和代码提交(附有下载链接)
目录 一、Git的下载和安装二、安装图形化界面工具三、在Gitee上创建仓库四、如何把仓库开源五、Clone远程仓库到本地六、拷贝代码到本地的仓库七、Add-Commit-Push到远程仓库八、可能出现的问题8.1 建议在本地仓库直接创建项目8.2 第一次Push可能出现的问题8.3 怎么删除Gitee上…...
机器学习是什么?
机器学习是一种人工智能(AI)的分支,其主要目标是使计算机系统能够通过数据和经验来改进和学习,而无需明确地编程。在机器学习中,计算机系统会通过对大量数据进行学习和分析,从中发现模式和规律,…...
复盘-PPT
调整PPT编号起始页码在设计→幻灯片大小 设置所有以及文本项目符号 ## 打开母版,找到对应级别设置重置 当自动生成的smartart图形不符合预期时 1 2...
springcloud gateway网关动态配置限流
上一篇记录了gateway网关的基础功能和配置,并且使用了默认的限流功能。 springcloud gateway网关-CSDN博客 这里简单记录一下gateway网关集成mybatisPlus实现动态限流。gateway网关默认的限流方式各项限流参数都是在配置文件中配置,不够灵活࿰…...
在Linux/Ubuntu/Debian中使用windows应用程序/软件
Wine 是一个兼容层,允许你在类 Unix 操作系统(包括 Ubuntu)上运行 Windows 应用程序。 以下是在 Ubuntu 上安装和使用 Wine 的基本步骤: 在 Ubuntu 上安装 Wine: 更新软件包列表: 打开终端并运行以下命令以…...
idea Springboot 组卷管理系统LayUI框架开发mysql数据库web结构java编程计算机网页
一、源码特点 springboot 组卷管理系统是一套完善的完整信息系统,结合mvc框架和LayUI框架完成本系统springboot spring mybatis ,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整…...
wordpress主题批量修改历史文章标题,文章内容
:wordpress模板,在我映像中还是比较受欢迎的,至少它该有的插件都是应有尽有,不像帝国cms虽然功能多,但是基本用不上,而且很多会出错。也不像织梦cms漏洞太多,搞的建站期间出现很多其他事情&am…...
Unity2019.2.x 导出apk 安装到安卓Android12+及以上的系统版本 安装出现-108 安装包似乎无效的解决办法
Unity2019.2.x 导出apk 安装到安卓Android12及以上的系统版本 安装出现-108 安装包似乎无效的解决办法 导出AndroidStudio工程后 需要设置 build.gradle文件 // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAINbuildscript {repositor…...
创建SpringCloudGateWay
创建SpringCloudGateWay 本案例基于尚硅谷《谷粒商城》项目,视频27 创建测试API网关 1、创建module 2、引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:x…...
鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:StepperItem)
用作Stepper组件的页面子组件。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 接口 StepperItem() 属性 参数名参数类型参数描述prevLabelstring设置左侧文本按钮内…...
游戏盾SDK是如何实现智能加速的?
游戏盾SDK是一款能够提供内含windows、安卓、IOS版本的SDK下载,通过接入SDK,由SDK接管所有的通信流量,进行调度和加密传输,满足抗D、防C、流量加密等业务需求,为用户提供优质的网络环境,游戏极速畅通无阻。…...
西井科技参与IATA全球货运大会 以AI绿动能引领智慧空港新未来
3月12日至14日,由国际航空运输协会IATA主办的全球货运大会(World Cargo Symposium)在中国香港成功举办,这是全球航空货运领域最大规模与影响力的年度盛会。作为大物流领域全球领先的“智能化与新能源化”综合解决方案提供商&#…...
RPC通信原理(二)
RPC序列化 任何一种序列化框架,核心思想就是设计一种序列化协议,将对象的类型、属性类型、属性值一一按照固定的格式写到二进制字节流中来完成序列化,再按照固定的格式把数据一一读取出来,通过这些数据信息创建出一个新的对象&…...
Redis 淘汰策略
Redis 是一个使用键值对存储数据的内存中数据结构存储系统,它支持多种类型的数据结构,如字符串(strings),列表(lists),集合(sets),有序集合&#…...
游戏数据处理
游戏行业关键数据指标 ~ 总激活码发放量、总激活量、总登录账号数 激活率、激活登录率 激活率 激活量 / 安装量 激活率 激活量 / 激活码发放量 激活且登录率 激活且登录量 / 激活码激活量 激活且登录率应用场景 激活且登录率是非常常用的转化率指标之一,广泛…...
Qt+FFmpeg+opengl从零制作视频播放器-14.程序Ubuntu移植
首先查看的是Linux系统的版本,我使用的是Ubuntu20.04.6LTS版本。 去Qt官网下载Qt 的版本。 这里下载的是5.12.12版本,双击运行,然后安装好Qt。 回想一下,在之前的程序,我们都是在Windows上开发,仅仅使用Qt和ffmpeg,Qt前面的步骤运行完成就可以安装好了,所以在linux上…...
Go 语言中的 Cond 机制详解
概述 在并发编程中,条件同步是一个常见的需求。Go 语言提供了 sync.Cond 类型来满足这一需求。sync.Cond 基于互斥锁(sync.Mutex)提供了条件变量的同步机制,允许一组 goroutine 在满足某个条件时进行阻塞等待,或者在条…...
如何使用vue定义组件之——子组件调用父组件数据
1.定义父子模板template <div class"container"><my-father></my-father><my-father></my-father><my-father></my-father><!-- 此处无法调用子组件,子组件必须依赖于父组件进行展示 --><!-- <my-…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
