作者主页:编程指南针
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师
主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简历模板、学习资料、面试题库、技术互助
收藏点赞不迷路 关注作者有好处
文末获取源码
项目编号:BS-QD-013
一,环境介绍
数据库:Mysql: mysql5.7
应用服务器:Nodejs14.15
开发工具:IDEA或VSCODE
技术:Vue+Nodejs
二,项目简介
随着科学技术的飞速发展,各行各业都在努力与现代互联网技术接轨,特别是网上购物更是生活中不可缺少的一部分。现在网络购物发展迅猛,各行业都想通过互联网售卖自己的产品;对于药品在网络售卖当然也不能排除在外,随着网络技术的不断成熟,带动了药店药品网上销售的份额同时店下也在同时销售,由于之前国家对药品的监管力度比较大,在网上售卖难度比较大,随着互联网+的发展,国家也在对药品在网上售卖大力支持,也有对药品合理的监控下药品网络渠道也在快速发展。对于以上分析便决定了要开发一套基于NodeJS技术和Vue框架的医药商城系统。
医药销售平台具有医药商城信息管理功能的选择。流行性传染病医药销售平台采用NodeJS技术,基于MySQL数据库技术开发,实现了首页、个人中心、用户管理、医药信息管理、类型管理、系统管理、订单管理等内容进行管理,本系统具有良好的兼容性和适应性,为用户提供更多的医药信息,也提供了良好的平台,从而提高系统的核心竞争力。
2.1 功能说明
流行性传染病医药销售平台是两种身份的用户,主要涉及管理员和用户。每个身份都是操作起来都是清楚方便的。对于一些医药商城,必须是已经进行注册登录的用户,或者想修改医药商城信息的话,也是需要用户为登录状态。这些用户的基本信息都由管理员对其统一管理。
根据医药商城实际过程的分析,网站有以下几个部分,其中用户注册,发布个人信息,修改个人信息;用户注册登录,发布医药信息;管理员管理用户信息;一般用户只可以浏览不可以发布信息。以上业务过程从用户角度可以分为两类使用本系统的用户角色,包括管理员和用户。以下针对各类用户说明相应的业务过程。
管理员功能描述:
个人中心:管理员可以在此修改自己的密码和个人用户名信息,以确保账户的安全性。
用户管理:管理员可以管理商城中的用户,包括添加、删除和修改用户信息。
药品信息管理:管理员可以对药品的信息进行管理,包括药品的名称、种类、描述、价格等。
类型管理:管理员可以管理药品的类型,如处方药、非处方药、保健品等。
系统管理:管理员可以对系统进行设置主要包括轮播图和公告信息的管理。
订单管理:管理员可以查看和管理用户的订单信息,包括订单的状态、金额、收货人等。
用户功能描述:
首页:用户进入系统后,可以看到首页展示的药品信息和公告信息以用户轮播图展示。
药品信息:用户可以查看所有药品的信息,包括名称、种类、描述、价格等,以便选择适合自己的药品。
公告信息:用户可以查看商城的公告信息,了解商城的重要通知和更新。
个人中心:用户可以在个人中心查看和修改自己的个人信息,如地址、电话、查看订单信息等。
购物车:用户可以将自己喜欢的药品加入购物车,以便进行结算和支付
2.2 数据库逻辑设计
概念是数据库设计的首要步骤,强调业务需求的抽象表示,是一种概念性的模型,其组成要素包括实体、属性及联系。
医药商城系统的实体及属性如下(主键由下划线标识,外键由波浪线标识):
(1)购物车(购物车主键、创建时间、药品表名、用户id、药品id、药品名称、图片)
(2)地址(地址id、创建时间、用户id、地址、收货人、电话、是否默认、址[是/否])
(3)用户(用户id、主键、创建时间、账号、密码、姓名、性别、邮箱、手机号码、相片、余额)
(4)公告(公告id、公告名称、公告图片、公告类型、公告发布时间、公告详情、创建时间)
(5)管理员表(管理员id、用户名、密码、角色、新增时间)
(6)医药信息(医药信息id、创建时间、医药名称、医药封面、类型、品牌、厂商、医药简介、医药详情、发布日期、最近点击时间、点击次数、价格)
(7)收藏(收藏id、创建时间、用户id、收藏id、表名、收藏名称、收藏图片、类型(1:收藏,21:赞,22:踩)、推荐类型)
(8)订单(订单id、创建时间、订单编号、药品表名、用户id、药品id、药品名称、药品图片、购买数量、价格/积分、折扣价格、总价格/总积、、折扣总价格、支付类型、状态、地址、电话、收货人、物流)
(9)公告(公告id、创建时间、标题、简介、图片、内容)
(10)类型(类型id、创建时间、类型)
(11)医药评价(医药评价id、创建时间、关联表id、用户id、用户名、评、内容、回复内容)
三,系统展示
3.1 前端用户功能
登录与注册
系统首页
药品信息
个人中心
3.2 后台管理功能
用户管理
药品信息管理
药品类型管理
订单管理
系统管理
四,核心代码展示
import { version } from '../../package.json'
import { Router } from 'express'
import { Sequelize, Op, QueryTypes } from 'sequelize'
import sequelize from '../models/sequelize'
import toRes from '../lib/toRes'
import CartModel from '../models/CartModel'
import md5 from 'md5-node'
import util from '../lib/util'
import jwt from 'jsonwebtoken'
import moment from 'moment'
export default ({ config, db }) => {
let api = Router()
// 分页接口(后端)
api.get('/page', async (req, res) => {
try {
let page = parseInt(req.query.page) || 1
let limit = parseInt(req.query.limit) || 10
let sort = req.query.sort || 'id'
let order = req.query.order || 'asc'
let where = {}
if (jwt.decode(req.headers.token).role != '管理员') {
where.userid = {
[Op.eq]: req.session.userinfo === undefined ? jwt.decode(req.headers.token).id : req.session.userinfo.id
}
}
let result = await CartModel.findAndCountAll({
order: [[sort, order]],
where,
offset: (page - 1) * limit,
limit
})
result.currPage = page
result.pageSize = limit
toRes.page(res, 0, result)
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 分页接口(前端)
api.get('/list', async (req, res) => {
try {
let page = parseInt(req.query.page) || 1
let limit = parseInt(req.query.limit) || 10
let sort = req.query.sort || 'id'
let order = req.query.order || 'asc'
let where = {}
let userid = req.query.userid
let goodid = req.query.goodid
if (userid) {
where.userid = {
[Op.eq]: userid
}
}
if (goodid) {
where.goodid = {
[Op.eq]: goodid
}
}
let result = await CartModel.findAndCountAll({
order: [[sort, order]],
where,
offset: (page - 1) * limit,
limit
})
result.currPage = page
result.pageSize = limit
toRes.page(res, 0, result)
} catch(err) {
toRes.session(res, 401, '您的权限不够!', '', 200)
}
})
// 保存接口(后端)
api.post('/save', async (req, res) => {
try {
Object.keys(req.body).forEach(item=>{
if(req.body[item] == '') delete req.body[item]
})
if (!req.body.userid) {
req.body.userid = req.session.userinfo === undefined ? jwt.decode(req.headers.token).id : req.session.userinfo.id
}
const userinfo = await CartModel.create(req.body)
if (userinfo === null) {
toRes.session(res, -1, '添加失败!')
} else {
toRes.session(res, 0, '添加成功!')
}
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 保存接口(前端)
api.post('/add', async (req, res) => {
try {
Object.keys(req.body).forEach(item=>{
if(req.body[item] == '') delete req.body[item]
})
req.body.userid = req.session.userinfo === undefined ? jwt.decode(req.headers.token).id : req.session.userinfo.id
const userinfo = await CartModel.create(req.body)
if (userinfo === null) {
toRes.session(res, -1, '添加失败!')
} else {
toRes.session(res, 0, '添加成功!')
}
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 更新接口
api.post('/update', async (req, res) => {
try {
await CartModel.update(req.body, {
where: {
id: req.body.id
}
})
toRes.session(res, 0, '编辑成功!')
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 删除接口
api.post('/delete', async (req, res) => {
try {
await CartModel.destroy({
where: {
id: {
[Op.in]: req.body
}
}
})
toRes.session(res, 0, '删除成功!')
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 详情接口(后端)
api.all('/info/:id', async (req, res) => {
try {
toRes.record(res, 0, await CartModel.findOne({ where: { id: req.params.id } }))
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 详情接口(前端)
api.all('/detail/:id', async (req, res) => {
try {
toRes.record(res, 0, await CartModel.findOne({ where: { id: req.params.id } }))
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
// 获取需要提醒的记录数接口
api.get('/remind/:columnName/:type', async (req, res) => {
try {
let sql = 'SELECT 0 AS count'
if (req.params.type == 1) {
if (req.query.remindstart) sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " >= '" + req.query.remindstart + "'"
if (req.query.remindend) sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " <= '" + req.query.remindend + "'"
if (req.query.remindstart && req.query.remindend) {
sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " >= '" + req.query.remindstart + "' AND " + req.params.columnName + " <= '" + req.query.remindend + "'"
}
}
if (req.params.type == 2) {
if (req.query.remindstart) {
let remindStart = util.getDateTimeFormat(0 - req.query.remindstart, "yyyy-MM-dd")
sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " >= '" + remindStart + "'"
}
if (req.query.remindend) {
let remindEnd = util.getDateTimeFormat(req.query.remindend, "yyyy-MM-dd")
sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " <= '" + remindEnd + "'"
}
if (req.query.remindstart && req.query.remindend) {
let remindStart = util.getDateTimeFormat(0 - req.query.remindstart, "yyyy-MM-dd")
let remindEnd = util.getDateTimeFormat(req.query.remindend, "yyyy-MM-dd")
sql = "SELECT COUNT(*) AS count FROM cart WHERE " + req.params.columnName + " >= '" + remindStart + "' AND " + req.params.columnName + " <= '" + remindEnd + "'"
}
}
const results = await sequelize.query(sql, {
plain: true,
raw: true,
type: QueryTypes.SELECT
})
toRes.count(res, 0, results.count)
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
api.get('/group/:columnName', async (req, res) => {
try {
let sql = ""
let columnName = req.params.columnName
let tableName = "cart"
let where = " WHERE 1 = 1 "
sql = "SELECT COUNT(*) AS total, " + columnName + " FROM " + tableName + where + " GROUP BY " + columnName
toRes.record(res, 0, await sequelize.query(sql, {
plain: false,
raw: true,
type: QueryTypes.SELECT
}))
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
api.get('/value/:xColumnName/:yColumnName', async (req, res) => {
try {
let sql = ""
let xColumnName = req.params.xColumnName
let yColumnName = req.params.yColumnName
let tableName = "cart"
let where = " WHERE 1 = 1 "
if ("cart" == "orders") {
where += " AND status IN ('已支付', '已发货', '已完成') ";
}
sql = "SELECT " + xColumnName + ", SUM(" + yColumnName + ") AS total FROM " + tableName + where + " GROUP BY " + xColumnName + " DESC"
toRes.record(res, 0, await sequelize.query(sql, {
plain: false,
raw: true,
type: QueryTypes.SELECT
}))
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
api.get('/value/:xColumnName/:yColumnName/:timeStatType', async (req, res) => {
try {
let sql = ""
let xColumnName = req.params.xColumnName
let yColumnName = req.params.yColumnName
let timeStatType = req.params.timeStatType
let tableName = "cart"
let where = " WHERE 1 = 1 "
if ("cart" == "orders") {
where += " AND status IN ('已支付', '已发货', '已完成') ";
}
if (config.dbConnection.dbtype.toLowerCase() == "mysql") {
if (timeStatType == "日")
sql = "SELECT DATE_FORMAT(" + xColumnName + ", '%Y-%m-%d') " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(" + xColumnName + ", '%Y-%m-%d')";
if (timeStatType == "月")
sql = "SELECT DATE_FORMAT(" + xColumnName + ", '%Y-%m') " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(" + xColumnName + ", '%Y-%m')";
if (timeStatType == "年")
sql = "SELECT DATE_FORMAT(" + xColumnName + ", '%Y') " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(" + xColumnName + ", '%Y')";
} else {
if (timeStatType == "日")
sql = "SELECT DATE_FORMAT(VARCHAR(10)," + xColumnName + ", 120) " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(VARCHAR(10)," + xColumnName + ", 120)";
if (timeStatType == "月")
sql = "SELECT DATE_FORMAT(VARCHAR(7)," + xColumnName + ", 120) " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(VARCHAR(7)," + xColumnName + ", 120)";
if (timeStatType == "年")
sql = "SELECT DATE_FORMAT(VARCHAR(4)," + xColumnName + ", 120) " + xColumnName + ", sum(" + yColumnName + ") total FROM " + tableName + where + " GROUP BY DATE_FORMAT(VARCHAR(4)," + xColumnName + ", 120)";
}
toRes.record(res, 0, await sequelize.query(sql, {
plain: false,
raw: true,
type: QueryTypes.SELECT
}))
} catch(err) {
toRes.session(res, 500, '服务器错误!', '', 500)
}
})
return api
}
五,相关作品展示
基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目
基于Nodejs、Vue等前端技术开发的前端实战项目
基于微信小程序和安卓APP应用开发的相关作品
基于51单片机等嵌入式物联网开发应用
基于各类算法实现的AI智能应用
基于大数据实现的各类数据管理和推荐系统