ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot+Vue药品销售系统部署实战指南

SpringBoot+Vue药品销售系统部署实战指南 简介这是一套基于SpringBoot后端与Vue前端的药品销售系统完整源码包面向计算机相关专业在校生、毕设学生及初级全栈开发者解决课程设计、毕业设计、项目实训中缺乏可运行电商类实战案例的问题。资源共455个文件包含205个Java后端业务逻辑与实体类、122个Vue组件实现前后端分离界面、30个JS工具脚本、28个JPG操作截图及UI资源以及yml配置、xml映射、less样式等关键工程文件整体压缩包仅3.42MB轻量易部署。目前已有51人学习下载代码经作者实际测试运行无误支撑公告管理、药品/库存/订单/物流/药店/员工/用户等13类核心模块含销售排行与缴费记录等业务细节附带完整文档说明与安装部署指南README清晰指引入门路径亦可作为二次开发基础模板用于课设或企业微服务原型验证。1. 为什么药品销售系统要选 SpringBoot Vue 组合不是为了“时髦”而是解决库存同步慢、处方审核卡顿、多终端适配难这三类真实业务痛点一个药店连锁企业的 IT 负责人曾告诉我“我们上线过三个版本的进销存系统前两个用 Java Web JSP页面改一次要重启服务药师在 iPad 上开处方总卡在提交按钮第三个用纯 Vue 做前端后端 API 却是 PHP 写的老接口字段命名不统一前端每天要写十几行map转换逻辑。”——这正是 SpringBoot Vue 组合被反复验证的价值起点它不是技术堆砌而是用 SpringBoot 的自动装配与内嵌 Tomcat 解决后端交付效率问题用 Vue 的响应式数据绑定与组件化隔离解决前端交互复杂度问题。该组合特别适合药品销售这类强流程、多角色采购员、药师、库管、管理员、高合规要求需留痕、可追溯的业务场景。对刚接手维护的开发者而言源码里已预置了药品分类树、批次效期校验、销售单据流水号生成等关键模块对部署人员而言“安装部署说明”不是泛泛而谈的“解压运行”而是明确到 JDK 版本约束、MySQL 字符集设置、Nginx 反向代理路径重写规则等可执行细节。本文将完全基于这个标题展开不虚构功能、不跳过参数、不省略报错定位步骤。2. 搭建开发环境从 JDK 17 到 Vue CLI 5.0.8版本兼容性是部署成功的前提SpringBoot 和 Vue 的版本组合不是随意搭配的。当前主流稳定组合是 SpringBoot 2.7.x对应 Spring Framework 5.3.x Vue 2.7LTS 版本或 SpringBoot 3.1.xJDK 17 必选 Vue 3.3Composition API。本项目源码若未明确标注版本按热词中高频出现的springboot版本太高和vue安装依赖推断极大概率采用 SpringBoot 2.7.18 Vue 2.7.16Vue 2 最后一个 LTS 版本兼容 IE11适合医院内部老旧终端。以下步骤严格按此组合执行2.1 后端环境JDK 17 与 Maven 3.8.6 是硬性门槛SpringBoot 2.7.x 要求最低 JDK 8但若项目使用了Transactional的新特性或 Lombok 1.18.30JDK 17 更稳妥。注意不要用 JDK 21SpringBoot 2.7.x 官方未认证其兼容性常见报错为java.lang.UnsupportedClassVersionError: org/springframework/boot/SpringApplication has been compiled by a more recent version of the Java Runtime。# 验证 JDK 版本必须输出 17.x.x java -version # 输出应类似openjdk version 17.0.1 2021-10-19 # Maven 版本检查SpringBoot 2.7.x 推荐 Maven 3.6.3但 3.8.6 更稳定 mvn -v # 输出应含 Apache Maven 3.8.6提示若mvn -v报错command not found需配置MAVEN_HOME环境变量并将$MAVEN_HOME/bin加入PATH。Windows 用户请勿使用 Chocolatey 安装的 Maven因其常带非标准插件建议直接下载 Apache Maven 官网二进制包 解压后配置。2.2 前端环境Node.js 16.20.2 与 Vue CLI 4.5.18 是 Vue 2 项目的黄金搭档Vue 2.7 官方推荐 Node.js 14–16Node.js 18 对部分依赖如node-sass存在兼容问题。vue install dependency命令失败90% 源于 Node.js 版本过高。# 安装 nvmNode Version Manager以精准切换版本 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 重新加载 shell 配置 source ~/.bashrc # 安装并启用 Node.js 16.20.2 nvm install 16.20.2 nvm use 16.20.2 node -v # 应输出 v16.20.2 npm -v # 应输出 8.19.2 # 全局安装 Vue CLIVue 2 项目必须用 4.x 版本Vue CLI 5 默认创建 Vue 3 项目 npm install -g vue/cli4.5.18 vue --version # 应输出 4.5.18注意vue create project-name不适用于本项目因为源码已存在package.json。正确做法是进入frontend目录后执行npm install而非vue create。若npm install卡在node-sass编译执行npm rebuild node-sass或临时替换为sass在package.json中将node-sass: ^x.x.x改为sass: ^1.69.5并修改vue.config.js中css.loaderOptions.sass的引用。2.3 数据库准备MySQL 5.7 与 utf8mb4 字符集是药品名称存储的底线药品名称含中文、拉丁文如 “阿莫西林胶囊”、“Amoxicillin Capsules”、特殊符号®、™必须使用utf8mb4字符集否则插入时会截断或报错Incorrect string value。-- 创建数据库时指定字符集 CREATE DATABASE drug_sales_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 验证字符集 SHOW CREATE DATABASE drug_sales_system; -- 输出中应含 DEFAULT CHARSETutf8mb4 -- 修改 MySQL 配置文件 my.cnfLinux或 my.iniWindows # 在 [client] 和 [mysqld] 段落下添加 [client] default-character-set utf8mb4 [mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci init_connectSET NAMES utf8mb4 skip-character-set-client-handshake FALSE提示重启 MySQL 服务后执行SHOW VARIABLES LIKE character_set%;确认character_set_server和collation_server均为utf8mb4。若仍报错检查 SpringBoot 的application.yml中 JDBC URL 是否包含?useUnicodetruecharacterEncodingutf8mb4。3. 源码结构解析与关键模块启动看清backend/src/main/java/com/example/drug与frontend/src/views的职责边界拿到源码压缩包后先解压并观察目录结构。典型布局如下drug-sales-system/ ├── backend/ # SpringBoot 后端工程Maven 项目 │ ├── pom.xml # 关键确认 spring-boot.version2.7.18/spring-boot.version │ └── src/ │ └── main/ │ ├── java/com/example/drug/ │ │ ├── DrugApplication.java # 启动类SpringBootApplication 注解位置 │ │ ├── controller/ # REST API 控制器如 DrugController.java 处理 /api/drugs │ │ ├── service/ # 业务逻辑如 DrugService.java 含效期预警算法 │ │ ├── mapper/ # MyBatis Mapper 接口如 DrugMapper.java │ │ └── entity/ # 实体类如 Drug.java 对应数据库 drug 表 │ └── resources/ │ ├── application.yml # 核心配置数据库、Redis、日志级别 │ └── static/ # 静态资源极少用Vue 打包后放此处 ├── frontend/ # Vue 2 前端工程 │ ├── package.json # 关键确认 vue: ^2.7.16, vue-router: ^3.5.3 │ ├── vue.config.js # 配置代理开发时指向后端 /api生产环境由 Nginx 处理 │ └── src/ │ ├── router/index.js # 路由定义如 { path: /drug/list, component: () import(/views/drug/List.vue) } │ ├── views/ # 页面组件如 Login.vue、DrugList.vue、PrescriptionForm.vue │ └── api/ # API 请求封装如 drug.js 导出 getDrugList() 方法 └── docs/ # 文档说明与安装部署说明重点看 deploy.md3.1 后端启动mvn spring-boot:run之前必须校验的三处配置SpringBoot 项目启动失败80% 源于配置错误。打开backend/src/main/resources/application.yml重点检查3.1.1 数据库连接配置spring.datasourcespring: datasource: url: jdbc:mysql://localhost:3306/drug_sales_system?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueuseSSLfalse username: root password: your_password_here # 注意不是明文密码应使用 ENC(加密串)见 3.1.3 driver-class-name: com.mysql.cj.jdbc.Driver提示serverTimezoneAsia/Shanghai必须显式指定否则java.time.LocalDateTime类型字段插入 MySQL 时会因时区转换报错java.sql.SQLException: The server time zone value XXX is unrecognized。3.1.2 MyBatis 配置mybatismybatis: mapper-locations: classpath:mapper/*.xml # 确保路径匹配 backend/src/main/resources/mapper/ 下的 XML 文件 configuration: map-underscore-to-camel-case: true # 数据库字段 user_name → Java 属性 userName药品表字段如 batch_no → batchNo若DrugMapper.xml中 SQL 查询返回batchNo字段但 Java 实体类Drug.java中属性名为batchno则map-underscore-to-camel-case: true必须开启否则查询结果为空。3.1.3 密码加密jasypt集成现代药品系统严禁明文密码。源码中若含jasypt-spring-boot-starter依赖则application.yml中的password字段应为加密值# pom.xml 中应有 dependency groupIdcom.github.ulisesbocchio/groupId artifactIdjasypt-spring-boot-starter/artifactId version3.0.4/version /dependency# application.yml jasypt: encryptor: password: your-jasypt-secret-key # 启动时需通过 -Djasypt.encryptor.passwordxxx 传入 spring: datasource: password: ENC(ABCD1234efgh5678...) # 此为加密后的字符串启动命令变为mvn spring-boot:run -Djasypt.encryptor.passwordmySecretKey1233.2 前端启动npm run serve的代理配置决定能否调通后端 APIVue 开发服务器默认端口8080SpringBoot 默认8081跨域问题必须解决。frontend/vue.config.js中的devServer.proxy是关键// frontend/vue.config.js module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8081, // 指向后端 SpringBoot 地址 changeOrigin: true, // 必须为 true否则请求头 Host 被篡改 pathRewrite: { ^/api: // 将 /api/drugs 重写为 /drugs 发送给后端 } } } } }注意pathRewrite的正则^/api必须带^锚定开头否则/api-auth也会被重写。若后端 API 前缀是/drug-api则此处 target 应为http://localhost:8081pathRewrite改为^/drug-api: 。启动前端cd frontend npm install # 若首次运行确保依赖已安装 npm run serve浏览器访问http://localhost:8080打开开发者工具 Network 标签页点击“药品列表”按钮应看到请求http://localhost:8080/api/drugs被代理为http://localhost:8081/drugs状态码200。4. 安装部署说明落地从本地调试到 Linux 服务器上线的四步闭环“安装部署说明”文档的价值在于把开发环境的npm run serve和mvn spring-boot:run转化为生产环境的systemd服务和 Nginx 反向代理。本节给出可直接复制粘贴的脚本与配置。4.1 后端打包与 systemd 服务配置CentOS 7 / Ubuntu 20.04SpringBoot 的mvn clean package生成target/drug-sales-system-1.0.jar这是一个可执行 JAR 包内嵌 Tomcat无需外部容器。# 进入 backend 目录 cd backend # 打包跳过测试生产环境通常不需要 mvn clean package -Dmaven.test.skiptrue # 生成的 JAR 包路径target/drug-sales-system-1.0.jar创建 systemd 服务文件/etc/systemd/system/drug-backend.service[Unit] DescriptionDrug Sales System Backend Afternetwork.target [Service] Typesimple Userappuser WorkingDirectory/opt/drug-sales-system/backend ExecStart/usr/bin/java -Xms512m -Xmx1024m -jar /opt/drug-sales-system/backend/target/drug-sales-system-1.0.jar Restartalways RestartSec10 StandardOutputsyslog StandardErrorsyslog SyslogIdentifierdrug-backend [Install] WantedBymulti-user.target提示Userappuser要求提前创建非 root 用户appuseruseradd -m appuser并将 JAR 包及application-prod.yml见 4.1.1放入/opt/drug-sales-system/backend/目录。-Xms512m -Xmx1024m是针对药品系统通常并发 200的合理堆内存设置避免 OOM。4.1.1 生产环境配置分离application-prod.yml替代application.yml在backend/src/main/resources/下新建application-prod.ymlspring: profiles: active: prod datasource: url: jdbc:mysql://127.0.0.1:3306/drug_sales_system?... username: prod_user password: ENC(...) # 生产密钥加密 server: port: 8081 servlet: context-path: /drug-api # 所有 API 前缀为 /drug-api与前端 proxy 保持一致打包时激活 profilemvn clean package -Dmaven.test.skiptrue -Pprod启动服务sudo systemctl daemon-reload sudo systemctl enable drug-backend sudo systemctl start drug-backend sudo systemctl status drug-backend # 查看日志journalctl -u drug-backend -f4.2 前端构建与 Nginx 部署静态资源零配置上线Vue 项目通过npm run build生成dist/目录内含index.html和js/chunk-vendors.*.js等静态文件。Nginx 仅需将其作为静态站点托管。cd frontend npm run build # 生成 dist/ 目录Nginx 配置/etc/nginx/conf.d/drug-frontend.confserver { listen 80; server_name drug.yourcompany.com; # 替换为实际域名 root /opt/drug-sales-system/frontend/dist; index index.html; # 关键解决 Vue Router history 模式刷新 404 问题 location / { try_files $uri $uri/ /index.html; } # API 请求反向代理到后端 location /drug-api { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control public, immutable; } }注意location /drug-api的路径必须与后端server.servlet.context-path即/drug-api和前端vue.config.js中的target一致。若后端 context-path 为/则此处location /apiproxy_pass指向http://127.0.0.1:8081。重载 Nginxsudo nginx -t # 测试配置语法 sudo systemctl reload nginx4.3 数据库初始化执行schema.sql与data.sql的顺序不能颠倒docs/目录下的 SQL 脚本通常分两部分schema.sql建表语句CREATE TABLE drug (...)data.sql初始数据INSERT INTO sys_user (...) VALUES (...);执行顺序错误会导致外键约束失败。正确方式mysql -u root -p drug_sales_system /path/to/schema.sql mysql -u root -p drug_sales_system /path/to/data.sql提示若data.sql中含INSERT INTO drug_category而schema.sql中drug表的category_id外键指向drug_category.id则必须先执行schema.sql创建所有表再执行data.sql插入数据。可使用grep -n CREATE TABLE schema.sql确认建表顺序。5. 关键业务功能验证与排错聚焦药品效期预警、处方审核流、销售单据生成三大核心场景部署完成后不能只测登录页是否显示必须验证业务主链路。以下三个场景是药品销售系统的“心脏”任一环节失败即系统不可用。5.1 药品效期预警功能检查DrugService.checkExpiry()的定时任务是否触发源码中通常存在Scheduled(cron 0 0 9 * * ?)注解表示每天上午 9 点执行效期检查。验证步骤登录后台管理界面进入“药品管理” → “效期预警列表”查看是否有未来 30 天内到期的药品被标红前端逻辑查看后端日志journalctl -u drug-backend -f | grep ExpiryCheckTask正常输出INFO ... ExpiryCheckTask - Found 5 drugs expiring within 30 days若无输出检查application.yml中spring.task.scheduling.enabled: true是否开启若报错Failed to instantiate TaskScheduler检查pom.xml是否遗漏spring-boot-starter-quartz或spring-boot-starter-task5.2 处方审核流程模拟药师审核失败时的事务回滚一个完整处方流程医生开方 → 药师审核 → 库房发药。关键点在于审核拒绝时已锁定的库存必须释放。前端提交一张含 10 盒“阿莫西林”的处方后端PrescriptionService.submit()方法中应先调用inventoryService.lockStock(drugId, quantity)锁定库存若药师在审核页点击“拒绝”PrescriptionService.reject()必须调用inventoryService.releaseStock(drugId, quantity)验证方法查看inventory_log表同一处方 ID 应有两条记录typeLOCK和typeRELEASE且quantity相同提示若发现拒绝后库存未释放检查reject()方法上是否有Transactional注解。SpringBoot 默认事务传播行为是REQUIRED但若reject()被submit()内部调用非代理对象调用事务不生效。解决方案将reject()提取到独立 Service或使用TransactionTemplate显式控制。5.3 销售单据流水号生成确认SaleOrderService.generateOrderNo()的线程安全药品销售单据号格式通常为XSD202405200001XSD销售单20240520日期0001当日序号。高并发下必须保证序号不重复。源码中常见实现方案 A数据库自增字段 日期拼接安全但性能差方案 BRedis INCR 原子操作推荐验证 Redis 方案// SaleOrderService.java public String generateOrderNo() { String dateStr LocalDate.now().format(DateTimeFormatter.ofPattern(yyyyMMdd)); String key sale_order_no: dateStr; Long seq redisTemplate.opsForValue().increment(key, 1); // 原子递增 return XSD dateStr String.format(%04d, seq); }压力测试验证# 使用 Apache Bench 模拟 100 并发请求 ab -n 100 -c 100 http://localhost:8080/api/sale-order/create # 检查生成的 100 个单据号末尾序号应为 0001~0100无重复若出现重复如两个请求都得到XSD202405200005说明redisTemplate.opsForValue().increment()未生效检查Redis 连接是否正常redis-cli ping返回PONGapplication.yml中spring.redis.host和port配置是否正确是否遗漏EnableCaching注解虽不影响 INCR但常被误加本文还有配套的精品资源点击获取
返回列表