首页 > 编程语言 >基于Vue+Nodejs实现医药商城销售系统

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

时间:2024-06-17 09:58:18浏览次数:13  
标签:Vue Nodejs res req let xColumnName toRes id 商城

作者主页:编程指南针

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

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

 

 

标签:Vue,Nodejs,res,req,let,xColumnName,toRes,id,商城
From: https://blog.csdn.net/whirlwind526/article/details/139730492

相关文章

  • 商城系统小程序
    商城系统小程序:引领零售新时代随着智能手机的普及和移动互联网的发展,小程序成为了一种新的流行应用形式。商城系统小程序优势基于小程序开发的电子商务平台,其便捷易用、功能等优势,迅速获得众多商家的关注。商城系统小程序的优势便捷易用:小程序无需下载安装,用户只需扫描二维......
  • Vue diff算法
    vuediff算法主要体现在renderer.ts中的patchChildren这段代码逻辑。差异算法排序分为无key时的diff算法排序逻辑和有key时的diff算法排序逻辑。无key时的逻辑主要有三步,首先,通过for循环patch重新渲染元素进行替换,其次是删除旧的元素,再次是新增元素。代码如下:constpatchU......
  • AI智能名片S2B2C商城系统小程序在社区团购模式中的应用与影响
    摘要:本文探讨了AI智能名片S2B2C商城系统小程序在社区团购模式中的应用及其带来的商业价值。通过分析2020年新冠疫情期间社区团购模式的崛起和AI智能名片S2B2C商城系统小程序的特点,文章揭示了这两者结合所带来的营销效率提升、用户体验优化以及社区商业生态的创新。一、引言......
  • 开源AI智能名片O2O商城系统小程序在品牌线下开店决策中的应用与价值
    摘要:随着电商的迅猛发展,品牌商在线下开店的决策变得更为复杂。本文探讨了开源AI智能名片O2O商城系统小程序如何助力品牌商在线下开店决策中提高运营效率和用户体验,从而实现本地化最优成本。通过优衣库等案例分析,阐述了线下开店成功的要素,并指出开源AI智能名片O2O商城系统小程......
  • 定制开发AI智能名片商城小程序的服务策略与风险管理
    摘要:随着数字化时代的深入发展,AI技术在商业领域的应用日益广泛。本文探讨了技术公司和个人创业者如何提供定制开发AI智能名片商城小程序的服务,并详细分析了服务过程中需要注意的细节和风险。通过关键词“定制开发AI智能名片商城小程序”的引入,本文旨在为服务提供者和需求方提......
  • 多商家AI智能名片B2B2C商城小程序的商业价值及可持续性探讨
    摘要:随着科技的飞速发展,AI技术已广泛应用于商业领域。多商家AI智能名片B2B2C商城小程序作为一种创新的商业模式,结合了AI技术与电子商务的便利性。本文通过插入关键词“多商家AI智能名片B2B2C商城小程序”,深入探讨了该类小程序的有用性、好用性以及可持续性,旨在分析其商业价值......
  • 解决vue项目报错 ERROR in Conflict:Multiple assets emit different content to the
    vue-cli创建项目ERROR in Conflict: Multiple assets emit different content to the same filename index.html问题的解决办法用vue-cli正常来创建新的项目在运行npmrundev或者npmrunserve有以下报错:ERRORinConflict:Multipleassetsemitdifferentco......
  • 使用vue如何判断当前设备是PC端还是移动端?
    在实际开发中我们经常会遇到一个需求,就是做一个页面链接到移动端,但是要求移动端和PC端页面样式不一样,这就是要判断当前登录网页的设备是PC还是移动,那么我们就需要对当前登录设备进行判断。使用navigator.userAgent字符串检测在PC端开发完做移动端需求,仅在输入框这一个页面......
  • Vue微前端架构与Qiankun实践理论指南
    title:Vue微前端架构与Qiankun实践理论指南date:2024/6/15updated:2024/6/15author:cmdragonexcerpt:这篇文章介绍了微前端架构概念,聚焦于如何在Vue.js项目中应用Qiankun框架实现模块化和组件化,以达到高效开发和维护的目的。讨论了Qiankun的原理、如何设置主应......
  • [vue3]组件通信
    自定义属性父组件中给子组件绑定属性,传递数据给子组件,子组件通过props选项接收数据props传递的数据,在模版中可以直接使用{{message}},在逻辑中使用props.messagedefinePropsdefineProps是编译器宏函数,就是一个编译阶段的标识,实际编译器解析时,遇到后会进......