首页 前端知识 基于Vue Nodejs实现医药商城销售系统

基于Vue Nodejs实现医药商城销售系统

2024-07-02 23:07:52 前端知识 前端哥 465 503 我要收藏

作者主页:编程指南针

作者简介: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智能应用

基于大数据实现的各类数据管理和推荐系统

 

 

转载请注明出处或者链接地址:https://www.qianduange.cn//article/13806.html
标签
评论
发布的文章

sublime text的json快捷键

2024-07-30 22:07:35

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!