全棧開發(fā)實(shí)踐)
1. 藥品管理系統(tǒng)技術(shù)架構(gòu)解析這套藥品管理系統(tǒng)的技術(shù)選型采用了當(dāng)前主流的SpringBoot后端Vue前端MySQL數(shù)據(jù)庫全棧方案這種組合在中小型企業(yè)管理系統(tǒng)中具有顯著優(yōu)勢。后端使用SpringBoot 2.7.x版本構(gòu)建RESTful API前端采用Vue 3組合式API開發(fā)數(shù)據(jù)庫選用MySQL 8.0社區(qū)版三者通過axios進(jìn)行數(shù)據(jù)交互。提示系統(tǒng)默認(rèn)使用Java 11運(yùn)行環(huán)境Node.js 16.x進(jìn)行前端構(gòu)建開發(fā)工具推薦IntelliJ IDEA VS Code組合1.1 后端技術(shù)棧深度剖析SpringBoot作為后端框架提供了完整的藥品業(yè)務(wù)邏輯實(shí)現(xiàn)采用分層架構(gòu)設(shè)計(jì)controller-service-dao集成Spring Security實(shí)現(xiàn)RBAC權(quán)限控制使用MyBatis-Plus 3.5.x進(jìn)行數(shù)據(jù)庫操作通過Hutool工具包處理藥品編碼生成采用Lombok減少樣板代碼藥品管理的核心接口包括RestController RequestMapping(/api/drug) public class DrugController { Autowired private DrugService drugService; PostMapping(/add) public Result addDrug(Valid RequestBody DrugDTO dto) { return drugService.addDrug(dto); } GetMapping(/batch/{batchNo}) public Result getByBatch(PathVariable String batchNo) { return drugService.getByBatch(batchNo); } }1.2 前端技術(shù)方案詳解Vue前端采用如下技術(shù)方案基于Vue 3 TypeScript開發(fā)使用Element Plus作為UI組件庫通過Vue Router實(shí)現(xiàn)路由管理采用Pinia進(jìn)行狀態(tài)管理集成ECharts實(shí)現(xiàn)藥品庫存可視化藥品入庫表單的關(guān)鍵實(shí)現(xiàn)template el-form :modelform :rulesrules refformRef el-form-item label藥品名稱 propname el-input v-modelform.name / /el-form-item el-form-item label生產(chǎn)批號 propbatchNo el-input v-modelform.batchNo / /el-form-item /el-form /template script setup langts const form reactive({ name: , batchNo: }) const rules { name: [{ required: true, message: 請輸入藥品名稱 }], batchNo: [{ pattern: /^[A-Z0-9]{8}$/, message: 批號格式不正確 }] } /script1.3 數(shù)據(jù)庫設(shè)計(jì)要點(diǎn)MySQL數(shù)據(jù)庫設(shè)計(jì)遵循藥品管理業(yè)務(wù)特點(diǎn)CREATE TABLE drug ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主鍵, code varchar(20) NOT NULL COMMENT 藥品編碼, name varchar(50) NOT NULL COMMENT 藥品名稱, spec varchar(30) NOT NULL COMMENT 規(guī)格, unit varchar(10) NOT NULL COMMENT 單位, batch_no varchar(20) NOT NULL COMMENT 生產(chǎn)批號, manufacturer varchar(100) NOT NULL COMMENT 生產(chǎn)廠家, price decimal(10,2) NOT NULL COMMENT 單價(jià), stock int NOT NULL DEFAULT 0 COMMENT 庫存數(shù)量, expire_date date NOT NULL COMMENT 有效期至, status tinyint NOT NULL DEFAULT 1 COMMENT 狀態(tài)(1-正常 0-停用), PRIMARY KEY (id), UNIQUE KEY idx_code (code), KEY idx_batch (batch_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT藥品信息表;2. 系統(tǒng)核心功能實(shí)現(xiàn)2.1 藥品全生命周期管理系統(tǒng)實(shí)現(xiàn)了從采購到報(bào)廢的完整藥品管理流程采購入庫支持Excel批量導(dǎo)入、掃碼槍錄入庫存管理實(shí)時(shí)庫存監(jiān)控、效期預(yù)警提前30天處方發(fā)藥與HIS系統(tǒng)對接的處方處理模塊退藥處理完整的退藥審批流程報(bào)損報(bào)廢藥品損耗記錄與原因分析庫存預(yù)警的核心邏輯實(shí)現(xiàn)public ListDrug checkExpireWarning() { LocalDate warningDate LocalDate.now().plusDays(30); return drugMapper.selectList(new QueryWrapperDrug() .lt(expire_date, warningDate) .gt(stock, 0) .eq(status, 1)); }2.2 智能預(yù)警系統(tǒng)系統(tǒng)內(nèi)置多種預(yù)警機(jī)制庫存下限預(yù)警可配置閾值近效期藥品預(yù)警藥品配伍禁忌提醒處方用量超標(biāo)提醒特殊藥品雙人審核提醒預(yù)警配置表示例CREATE TABLE warning_config ( id int NOT NULL AUTO_INCREMENT, type varchar(20) NOT NULL COMMENT 預(yù)警類型, threshold varchar(50) NOT NULL COMMENT 閾值, notify_type varchar(20) NOT NULL COMMENT 通知方式, is_active tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;2.3 統(tǒng)計(jì)報(bào)表模塊系統(tǒng)提供多維度的統(tǒng)計(jì)分析功能藥品出入庫統(tǒng)計(jì)日/月/季度/年處方藥品使用排名供應(yīng)商供貨分析醫(yī)師開藥習(xí)慣分析藥品效期分布圖使用ECharts實(shí)現(xiàn)的庫存統(tǒng)計(jì)前端代碼async function initStockChart() { const res await getDrugStockStats() const chart echarts.init(document.getElementById(chart)) chart.setOption({ tooltip: { trigger: item }, series: [{ type: pie, data: res.data.map(item ({ value: item.stock, name: item.name })) }] }) }3. 系統(tǒng)部署與運(yùn)行指南3.1 環(huán)境準(zhǔn)備與配置后端環(huán)境要求JDK 11Maven 3.6MySQL 8.0Redis 6.x可選用于緩存前端環(huán)境要求Node.js 16.xnpm 8.x 或 yarn 1.22數(shù)據(jù)庫配置示例application.ymlspring: datasource: url: jdbc:mysql://localhost:3306/drug_db?useSSLfalse username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver jpa: show-sql: true hibernate: ddl-auto: update3.2 項(xiàng)目啟動(dòng)流程后端啟動(dòng)步驟導(dǎo)入Maven依賴修改數(shù)據(jù)庫配置執(zhí)行SQL初始化腳本運(yùn)行主類DrugApplication前端啟動(dòng)步驟# 安裝依賴 npm install # 開發(fā)模式運(yùn)行 npm run dev # 生產(chǎn)構(gòu)建 npm run build3.3 常見部署問題解決MySQL連接失敗檢查MySQL服務(wù)是否啟動(dòng)驗(yàn)證用戶名密碼是否正確確認(rèn)數(shù)據(jù)庫drug_db已創(chuàng)建前端跨域問題// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }頁面空白問題檢查dist目錄是否正確部署確認(rèn)Nginx配置了正確的root路徑查看瀏覽器控制臺(tái)報(bào)錯(cuò)信息4. 系統(tǒng)二次開發(fā)指南4.1 代碼結(jié)構(gòu)與擴(kuò)展點(diǎn)項(xiàng)目采用標(biāo)準(zhǔn)Maven多模塊結(jié)構(gòu)drug-system ├── drug-admin -- 后臺(tái)管理模塊 ├── drug-common -- 公共模塊 ├── drug-generator -- 代碼生成器 └── drug-web -- 前端模塊核心擴(kuò)展點(diǎn)設(shè)計(jì)自定義注解DrugLog實(shí)現(xiàn)操作日志全局異常處理器DrugExceptionHandler可插拔的藥品驗(yàn)證接口DrugValidator可配置的審批流程引擎4.2 典型功能擴(kuò)展示例添加新藥品類型支持?jǐn)?shù)據(jù)庫添加type字段后端DTO和Entity添加對應(yīng)屬性前端表單增加類型選擇器在藥品服務(wù)中添加類型處理邏輯對接醫(yī)保系統(tǒng)public interface MedicalInsuranceService { boolean checkReimbursement(String drugCode); BigDecimal getReimbursementRate(String drugCode); } Service public class MedicalInsuranceServiceImpl implements MedicalInsuranceService { Override public boolean checkReimbursement(String drugCode) { // 調(diào)用醫(yī)保系統(tǒng)API } }4.3 性能優(yōu)化建議數(shù)據(jù)庫優(yōu)化為高頻查詢字段添加索引使用連接池配置HikariCP推薦對大表進(jìn)行分表分庫前端優(yōu)化啟用組件懶加載使用keep-alive緩存常用組件對大數(shù)據(jù)表格進(jìn)行虛擬滾動(dòng)緩存策略Cacheable(value drug, key #code) public Drug getByCode(String code) { return drugMapper.selectByCode(code); } CacheEvict(value drug, key #drug.code) public void updateDrug(Drug drug) { drugMapper.updateById(drug); }5. 項(xiàng)目實(shí)戰(zhàn)經(jīng)驗(yàn)分享5.1 開發(fā)中的典型問題藥品編碼沖突解決方案采用類型前綴日期序列號的復(fù)合編碼規(guī)則實(shí)現(xiàn)代碼public String generateDrugCode(String type) { String date LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); long seq redisTemplate.opsForValue().increment(drug:seq: date); return type date String.format(%04d, seq); }效期計(jì)算誤差發(fā)現(xiàn)直接使用new Date()存在時(shí)區(qū)問題修復(fù)統(tǒng)一使用LocalDate處理日期并發(fā)庫存更新方案采用樂觀鎖機(jī)制Update(update drug set stock stock - #{qty}, version version 1 where code #{code} and version #{version}) int reduceStockWithLock(Param(code) String code, Param(qty) int qty, Param(version) int version);5.2 安全性最佳實(shí)踐接口安全防護(hù)啟用Spring Security配置CSRF防護(hù)實(shí)現(xiàn)接口限流數(shù)據(jù)安全措施敏感字段加密存儲(chǔ)如價(jià)格操作日志完整記錄定期數(shù)據(jù)備份權(quán)限控制實(shí)現(xiàn)PreAuthorize(hasRole(PHARMACIST) || hasRole(ADMIN)) PostMapping(/adjust) public Result adjustStock(RequestBody AdjustDTO dto) { return stockService.adjust(dto); }5.3 項(xiàng)目演進(jìn)方向微服務(wù)化改造將庫存、采購、處方拆分為獨(dú)立服務(wù)采用Spring Cloud Alibaba體系引入Sentinel進(jìn)行流量控制智能化升級集成藥品圖像識(shí)別添加智能補(bǔ)貨預(yù)測開發(fā)移動(dòng)端盤點(diǎn)功能生態(tài)對接擴(kuò)展對接醫(yī)保結(jié)算系統(tǒng)連接供應(yīng)商ERP集成電子處方平臺(tái)