温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!
一、 项目背景与意义
随着医疗行业的快速发展与信息化建设的深入,传统的人工或半自动化的医药采购管理模式已难以满足现代医疗机构对效率、透明度和合规性的要求。医药采购涉及供应商管理、药品目录、采购计划、订单执行、库存跟踪、财务结算等多个复杂环节,流程繁琐且数据关联性强。一个高效、智能的医药采购管理系统对于降低采购成本、保障药品质量、优化库存结构、提升管理效率具有至关重要的意义。
本系统旨在设计并实现一个基于SpringBoot后端与Vue.js前端的现代化医药采购管理平台。通过前后端分离的架构,系统能够提供稳定可靠的后台服务与友好交互的前端界面,实现采购流程的数字化、规范化和可视化,为医院、医药公司等机构的采购部门提供全方位的管理支持。
二、 技术栈选型
2.1 后端技术栈 (SpringBoot)
- 核心框架: Spring Boot 2.7+
- 安全框架: Spring Security + JWT (JSON Web Token)
- 数据持久层: MyBatis-Plus
- 数据库: MySQL 8.0
- 缓存: Redis (用于会话管理、数据缓存)
- API文档: Swagger2 / Knife4j
- 构建工具: Maven
- 其他: Lombok (简化代码),Hutool (工具集),Druid (数据库连接池)
2.2 前端技术栈 (Vue.js)
- 核心框架: Vue 3 (Composition API)
- 构建工具: Vite
- UI组件库: Element Plus
- 状态管理: Pinia
- 路由: Vue Router 4
- HTTP客户端: Axios
- 可视化图表: ECharts
- 开发语言: TypeScript
2.3 开发与部署
- 版本控制: Git
- 容器化: Docker
- 项目管理: 前后端分离,通过RESTful API进行通信
三、 系统核心功能模块设计
系统主要分为以下几个核心模块:
- 权限管理模块: 基于RBAC模型,实现用户、角色、菜单的精细化管理。
- 供应商管理模块: 供应商信息维护、资质审核、绩效评估。
- 药品目录管理模块: 药品基本信息、分类、规格、价格管理。
- 采购计划管理模块: 科室需求汇总、计划制定、审批流程。
- 采购订单管理模块: 订单创建、状态跟踪(待审核、已发货、已收货、已结算)。
- 库存管理模块: 入库、出库、盘点、库存预警。
- 财务管理模块: 发票管理、付款申请、对账。
- 报表统计模块: 采购数据分析、供应商对比、库存报表等可视化图表。
四、 核心代码示例
4.1 后端核心:采购订单创建接口 (Controller)
package com.medical.procurement.controller; import com.medical.procurement.common.R; import com.medical.procurement.entity.PurchaseOrder; import com.medical.procurement.service.PurchaseOrderService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @RestController @RequestMapping("/api/purchase-order") @RequiredArgsConstructor @Api(tags = "采购订单管理") public class PurchaseOrderController { private final PurchaseOrderService purchaseOrderService; @PostMapping @PreAuthorize("hasAuthority('purchase:order:add')") @ApiOperation("创建采购订单") public R<String> createOrder(@Valid @RequestBody PurchaseOrder order) { boolean success = purchaseOrderService.createOrder(order); return success ? R.ok("订单创建成功") : R.fail("订单创建失败"); } // 其他接口:查询、修改、删除、状态变更等... }4.2 后端核心:采购订单服务层逻辑 (Service)
package com.medical.procurement.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.medical.procurement.entity.PurchaseOrder; import com.medical.procurement.entity.PurchaseOrderItem; import com.medical.procurement.mapper.PurchaseOrderMapper; import com.medical.procurement.service.PurchaseOrderService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; @Service @RequiredArgsConstructor public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements PurchaseOrderService { @Override @Transactional(rollbackFor = Exception.class) public boolean createOrder(PurchaseOrder order) { // 1. 设置订单基础信息 order.setOrderNo(generateOrderNo()); order.setCreateTime(LocalDateTime.now()); order.setStatus(0); // 0-待审核 // 2. 校验并关联订单明细 List<PurchaseOrderItem> items = order.getItems(); if (items == null || items.isEmpty()) { throw new RuntimeException("订单明细不能为空"); } items.forEach(item -> { item.setOrderId(order.getId()); // 假设order.getId()在插入后由MyBatis-Plus回填 // 此处可补充药品库存校验、价格校验等业务逻辑 }); // 3. 保存订单及明细 (需在Mapper中定义对应方法或使用Service保存) boolean orderSaved = save(order); // 假设有 purchaseOrderItemService.saveBatch(items) // boolean itemsSaved = purchaseOrderItemService.saveBatch(items); return orderSaved; // 简化返回,实际应结合明细保存结果 } private String generateOrderNo() { // 生成订单号逻辑,例如:PO202508160001 return "PO" + LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd")) + "0001"; } }4.3 前端核心:采购订单创建页面 (Vue 3 + Element Plus)
<template> <div class="order-create"> <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> <el-form-item label="供应商" prop="supplierId"> <el-select v-model="form.supplierId" placeholder="请选择供应商" filterable> <el-option v-for="supplier in supplierList" :key="supplier.id" :label="supplier.name" :value="supplier.id" /> </el-select> </el-form-item> <el-form-item label="订单明细"> <el-table :data="form.items" border style="width: 100%"> <el-table-column prop="drugName" label="药品名称"> <template #default="scope"> <el-select v-model="scope.row.drugId" placeholder="选择药品" @change="handleDrugChange(scope.row, $event)"> <el-option v-for="drug in drugList" :key="drug.id" :label="`${drug.name} (${drug.specification})`" :value="drug.id" /> </el-select> </template> </el-table-column> <el-table-column prop="quantity" label="采购数量"> <template #default="scope"> <el-input-number v-model="scope.row.quantity" :min="1" /> </template> </el-table-column> <el-table-column prop="unitPrice" label="单价(元)" /> <el-table-column label="操作"> <template #default="scope"> <el-button type="danger" size="small" @click="removeItem(scope.$index)">删除</el-button> </template> </el-table-column> </el-table> <el-button type="primary" @click="addItem">添加明细</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交订单</el-button> <el-button @click="resetForm">重置</el-button> </el-form-item> </el-form> </div> </template> <script setup lang="ts"> import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import { createPurchaseOrder } from '@/api/purchase' interface OrderItem { drugId: number drugName: string quantity: number unitPrice: number } interface OrderForm { supplierId: number | null items: OrderItem[] } const formRef = ref<FormInstance>() const form = reactive<OrderForm>({ supplierId: null, items: [] }) const rules: FormRules = { supplierId: [{ required: true, message: '请选择供应商', trigger: 'change' }] } const supplierList = ref([]) const drugList = ref([]) // 初始化数据 onMounted(async () => { // 调用API获取供应商和药品列表 // supplierList.value = await getSupplierList() // drugList.value = await getDrugList() }) const addItem = () => { form.items.push({ drugId: 0, drugName: '', quantity: 1, unitPrice: 0 }) } const removeItem = (index: number) => { form.items.splice(index, 1) } const handleDrugChange = (row: OrderItem, drugId: number) => { const selectedDrug = drugList.value.find(drug => drug.id === drugId) if (selectedDrug) { row.drugName = selectedDrug.name row.unitPrice = selectedDrug.price } } const submitForm = async () => { if (!await formRef.value?.validate()) return try { await createPurchaseOrder(form) ElMessage.success('订单创建成功') resetForm() } catch (error) { ElMessage.error('订单创建失败') } } const resetForm = () => { formRef.value?.resetFields() form.items = [] } </script>五、 总结与展望
本文介绍了基于SpringBoot和Vue.js的医药采购管理系统的技术选型、背景意义、核心功能模块以及部分关键代码。该系统通过现代化的技术栈,实现了采购流程的信息化与自动化,能够有效提升管理效率、降低运营成本并增强数据追溯能力。
未来,系统可以进一步集成人工智能算法进行采购需求预测,利用区块链技术增强供应链透明度,或扩展移动端应用以适应更灵活的业务场景。