简介一套基于ThinkPHP框架的药品进销存管理系统源码采用ApacheMySQLPHP架构前端用HTML5CSS3jQuery面向PHP学习者、毕业设计者及小型药店信息化项目参考。压缩包共499个文件、1.69MB其中以321个PHP核心逻辑文件为主另有71个Less样式、17个HTML页面及SQL数据库脚本目录组织清晰便于定位与二次开发。目前已有219人学习下载。系统完整覆盖用户管理、药品信息管理、进货管理、销售管理、库存管理五大模块包含用户增删改查与密码修改、药品录入与过期记录、进货与销售查询、库存盘点及过期处理等功能有助于理解ThinkPHP下的进销存业务实现并支持快速搭建环境二次开发。1. 药品进销存系统源码包ThinkPHP MySQL 的直接可跑项目核心价值在批号与效期“基于ThinkPHP药品进销存管理系统源码-包含mysql数据库.zip”这个标题已经把三件事说清楚技术栈是 ThinkPHP业务是药品进销存交付形态是带 MySQL 数据库文件的完整源码包。药品进销存和普通商品进销存最大的区别不在增删改查而在批号、有效期、批准文号、供应商资质这些合规字段——普通模板根本不给你留这些栏位而这套源码的价值恰恰在于表结构已经按药品业务设计好了。适合接手它的人有三类给自家药店或诊所做信息化的经营者接外包项目需要快速交付基础模块的 PHP 开发者以及拿现成项目做改造练习的学生。不适合的场景也很明确别指望单体 PHP 架构去支撑连锁规模的实时并发那不是这类源码包的定位。我的建议是解压后先别急着配数据库按接下来章节的顺序把框架版本、目录结构、SQL 脚本体检一遍再动手。这个流程能帮你避开初次部署里最常见的几类翻车每一步命令和判断方法后面都会写清楚。2. 接手第一步先别配库识别 ThinkPHP 版本、拆解目录、体检 SQL 脚本2.1 先认版本再定环境ThinkPHP 3.2 与 5.x 的部署路径完全不同这类打包好的源码包里最常见的是 ThinkPHP 3.2.x 版本也有一批项目是 5.x 甚至 6.x 重构过的。版本判断直接决定你后面怎么配环境不能跳过。3.2 是早期的单入口加函数式路由风格5.x 开始引入命名空间、Composer 依赖和 .env 配置两者对应的工作目录、运行目录、配置方式完全不一样。判断方法不复杂解压后看根目录。存在 ThinkPHP 目录、里面又有 Library 子目录的基本是 3.2 系列存在 app、vendor 目录和 composer.json 的是 5.x 及以上有 think 命令行入口文件的通常是 5.1 以上。也可以直接抓版本常量3.2 的版本号定义在框架的公共文件里。# 解压后进入项目根目录先看目录骨架 ls -la # 在框架目录里找版本常量声明 grep -rn THINK_VERSION ThinkPHP/ 2/dev/null | head -3 # 看入口文件是放在 Public 还是根目录 head -30 Public/index.php 2/dev/null || head -30 index.php第一行命令看根目录是哪种布局第二行直接抓版本常量第三行确认入口位置。注意 Windows 命令行里没有 grep建议用文本编辑器的“在文件中查找”功能或者直接在 ThinkPHP 目录下找 base 相关的公共文件看版本号。3.2 的版本常量类似 3.2.35.x 系列同样在框架公共文件里能找到。提示如果源码包里有 composer.json 但没有 vendor 目录说明依赖没打包全5.x 项目需要先执行 composer install否则入口文件会直接报类不存在。这是包不完整的一个典型信号。两种版本需要准备的环境基线也不同先对号入座判断项ThinkPHP 3.2ThinkPHP 5.x应用目录Applicationapp入口目录Public/index.phppublic/index.php配置方式PHP 数组 config.php.env 环境变量加 config 目录最低 PHP5.3建议 5.65.6建议 7.x依赖管理无 Composer 硬依赖必须 Composer3.2 老代码在 PHP 7.2、7.4 环境上有兼容问题比如 each() 函数在高版本直接被移除后面避坑章节会专门展开。部署之前先把版本号记下来后面每条配置都对着它核对这才是节省时间的第一步。2.2 目录结构速查Application、Public、Runtime 各自管什么事以最常见的 3.2 布局为例先认清楚每个目录的职责后面配环境才不会乱猜项目根目录/ │ drug_db.sql ← MySQL 备份文件也就是标题里的数据库 ├─ Application/ │ ├─ Common/Conf/config.php ← 全局配置数据库连接默认在这里 │ ├─ Admin/ ← 后台管理模块 │ ├─ Home/ ← 前台登录、展示页面 │ ├─ Api/ ← 如果有是给移动端或收银端用的接口 │ └─ Runtime/ ← 运行时缓存与日志必须可写 ├─ Public/ │ ├─ index.php ← 入口文件 │ ├─ Static/ ← CSS、JS、图片 │ └─ Uploads/ ← 资质、证件上传目录 └─ ThinkPHP/ ├─ Library/ ← 框架核心类库 └─ Common/ ← 公共函数与约定这套目录里三个地方最容易出问题。第一Runtime 在 3.2 里位于 Application 下Web 服务器用户必须有写权限否则框架缓存写不进去页面会报目录不可写或者每次请求都重新编译模板访问慢得明显。第二Public 才是给 Web 服务器指的根目录Nginx 配 root 时指到项目根目录会出问题避坑章节细说。第三Uploads 是业务上传后落盘的位置很多项目上线后才发现图片传不进去就是因为它不可写。模块划分也要扫一眼。一般 Admin 是后台Home 是前台或收银Api 是接口。登录入口通常由 Home 的 Index 控制器处理后台地址形如 index.php?s/Admin/Index/login。具体路径要看路由配置3.2 开发时用带 s 参数的兼容模式最稳妥不依赖 rewrite 也能跑通。2.3 导入前先体检 SQL建库语句、字符集、引擎和表前缀四个检查点SQL 是整个项目的灵魂但拿到就双击导入是新手踩坑率最高的动作。导入之前花两分钟做四件事的体检后面能省半天排错时间。# 看 SQL 文件头部是否自带建库、USE、字符集声明 head -80 drug_db.sql # 列出建表语句的引擎和字符集 grep -E ENGINE|DEFAULT CHARSET|CREATE TABLE drug_db.sql | head -40检查点一是建库语句。头部如果有 CREATE DATABASE 和 USE说明导入目标库写死在 SQL 里后面数据库连接配置的库名必须和它保持一致如果没有就自己先建空库再导入。检查点二是字符集CREATE TABLE 里的 DEFAULT CHARSET 会告诉你库是 utf8 还是 gbk前面说过很多打包源码默认导出就是 gbk这个值要和配置文件对齐。检查点三是引擎进销存业务涉及订单、库存和资金流水强烈建议全部使用 InnoDB发现 MyISAM 混用的话导入后手动转换更稳妥。检查点四是表前缀。# 用 SQL 查看某张表的完整定义导入后执行 mysql -uroot -p pharmacy -e SHOW CREATE TABLE tp_admin \G注意 SHOW CREATE TABLE 要导入之后才能执行导入前用 grep 看 CREATE TABLE 语句就能知道前缀比如 tp_ 还是 pharm_或者根本没前缀。这个前缀必须和 Application/Common/Conf/config.php 里的 DB_PREFIX 完全一致否则系统启动时所有表都会报“数据表不存在”。许多人不改前缀直接用 SQL 里的原名最省事。体检完 SQL 之后再导入导入命令在下一章写。这里先记住一个原则字符集在导入命令里显式指定不要在导入完成后发现乱码才返工。顺便建议在导入前翻一翻药品主表、批次表、供应商表的字段后面二次开发和调账都靠这个底子。3. 正式部署PHP 环境装配、数据库连接配置与入口改写3.1 环境基线怎么定PHP 版本、扩展检查与运行目录权限Windows 上我一般用各类 PHP 集成环境面板mac 上用系统自带的包管理工具装 PHP 和 MySQLLinux 服务器上有的用面板、有的直接命令行装对应版本包。这套源码如果是 ThinkPHP 3.2PHP 版本锁在 5.6 到 7.0 之间最省心既能避开老函数兼容问题又保留了旧生态里一堆直接能用的组件。如果是 5.xPHP 7.4 或 8.0 都是稳妥选择。装完环境先检查扩展3.2 实际运行至少需要这几个pdo_mysql数据库驱动、gd验证码与缩略图、mbstring中文截断和编码转换、curl对接第三方接口时用。检查方法一条命令php -v php -m | grep -iE pdo_mysql|mysqli|gd|mbstring|curlphp -v 看版本php -m 列出已加载扩展。集成环境面板里一般有扩展勾选入口勾上重启即可Linux 手工环境少哪个装哪个例如 apt install php-gd、php-mbstring版本跟随当前 PHP。有一点要提醒有些面板同时装了多个 PHP 版本命令行里 php -v 显示的和你网站走的可能不是同一个所以最靠谱的做法是在站点根目录放一个 phpinfo 探针直接在浏览器里确认。?php // 探针文件确认 Web 端实际 PHP 版本与扩展 phpinfo();探针文件确认完记得删掉别留在线上目录里这是基本的安全习惯。确认扩展没问题之后给运行时目录授权3.2 必须保证 Application/Runtime 和 Public/Uploads 可写chmod -R 755 Application/Runtime chmod -R 755 Public/Uploads chown -R www-data:www-data Application/Runtime 2/dev/null || true755 就够框架写缓存和日志除非运行用户是 www-data 而文件属主是 root那就需要再 chown 一把。别图省事全部 777后面避坑章节会说明宽松权限带来的隐患。3.2 数据库连接配置四个参数加一个字符集逐项核对数据库连接配置是整个部署里最容易写错的地方写错了页面必挂。ThinkPHP 3.2 的全局配置在 Application/Common/Conf/config.php5.x 在 .env 或 config/database.php打开后先把数据库相关字段改成本机实际值。?php // Application/Common/Conf/config.php 数据库段 return array( DB_TYPE mysql, // 数据库类型 DB_HOST 127.0.0.1, // 主机地址本机建议用127.0.0.1 DB_NAME pharmacy, // 库名和导库目标一致 DB_USER root, // 数据库账号 DB_PWD 你的密码, // 数据库密码 DB_PORT 3306, // 端口 DB_PREFIX tp_, // 表前缀和 SQL 里的前缀必须一致 DB_CHARSET utf8, // 连接字符集 );ThinkPHP 5.x 的 .env 字段名不一样但对应关系一目了然DB_HOST127.0.0.1 DB_PORT3306 DB_NAMEpharmacy DB_USERroot DB_PASSWORD你的密码 DB_PREFIXtp_每个参数的坑点列成表照着核对最省事参数说明常见坑DB_HOST数据库主机localhost 可能走 socket 导致连不上改 127.0.0.1 稳定DB_NAME目标库名必须先建库或先导库否则报 Unknown databaseDB_PREFIX表前缀和 SQL 建表前缀不一致启动就报“表不存在”DB_CHARSET连接字符集库是 gbk 时这里写 utf8 会中文乱码配完别急着开页面先用命令行验证数据库账号能连上再确认表能查出来mysql -uroot -p -e USE pharmacy; SHOW TABLES; SELECT * FROM tp_admin LIMIT 1;这条命令把连接、选库、查表一次做完能出结果说明数据库侧没问题接下来再报错就是 PHP 环境的问题。很多新手跳过这步结果在 PHP 报错和数据库报错之间反复横跳白白浪费一个晚上。3.3 入口与伪静态Apache 和 Nginx 下怎么把登录页跑出来数据库通了之后把项目放到 Web 目录。Apache 环境最简单项目放站点目录下访问 http://localhost/项目目录名/Public/index.php 能打开登录页说明框架本身没问题。如果页面提示“无法加载控制器”多半是伪静态没启用或者 URL 模式解析不了。最省事的做法是在 config.php 里把 URL_MODEL 显式设为 1所有 URL 变成 index.php?s/Home/Index/login 这种带 s 参数的格式不依赖任何 rewrite 规则。Nginx 环境需要多配一段伪静态否则登录后跳转全是 404。常见问题是把 server 的 root 指到项目根目录而不是 Public 子目录导致框架找不到入口。正确的 server 块长这样server { listen 80; server_name pharmacy.dev; root /var/www/html/pharmacy/Public; # 指向入口所在目录 index index.php; location / { try_files $uri $uri/ /index.php?s$uri$args; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }这里的 root 指向 Public 是关键很多部署翻车就翻在这里。try_files 在找不到对应静态文件时把请求交给 index.php 并保留参数TP 的路由才能解析 pathinfo 路径。fastcgi_pass 的地址要和 PHP-FPM 监听地址一致9000 是默认值改过端口要同步改这里。登录页出来之后先改默认密码。这类源码包的默认账号通常是 admin/admin123具体以管理员表里的记录为准别靠猜。登录后台先把管理员密码改掉再把系统设置里的站点名称、经营主体信息换掉这是判断整套系统是否真正“接得住”的第一步。登录后顺手点一遍采购入库、销售出库、库存查询几个菜单确认页面不报错、列表有数据。注意如果登录后列表页提示“数据表不存在”优先检查 DB_PREFIX如果反复提示验证码错误看 5.3 节的 GD 扩展排查。这两个问题占了这类源码包登录环节八成的故障量。4. 业务模块拆解与二开基础批次库存、FIFO 出库、效期预警4.1 药品批次表效期为什么不能只存在药品主表里普通进销存一个商品一条记录就够了药品不行。同一种药不同生产批次、不同效期、不同进货价在库房里就是物理上不同的东西。如果只在药品主表里存一个库存总量和一个效期效期管理根本无从谈起。所以判断一套进销存能不能做药品业务先看数据库里有没有独立的批次库存表。典型批次表里批号、生产日期、有效期、批次库存、进价、售价、货位号这些字段一个都不能少。其中效期放在批次表而不是药品主表是这套系统合不合规的分水岭设计CREATE TABLE tp_drug_batch ( id INT(11) NOT NULL AUTO_INCREMENT, drug_id INT(11) NOT NULL COMMENT 药品主档ID, batch_no VARCHAR(50) NOT NULL COMMENT 生产批号, produce_date DATE DEFAULT NULL COMMENT 生产日期, expiry_date DATE NOT NULL COMMENT 有效期至, stock_qty INT(11) NOT NULL DEFAULT 0 COMMENT 当前批次库存, purchase_price DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 最新进价, sale_price DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 零售价, position_no VARCHAR(30) DEFAULT NULL COMMENT 货位号, create_time DATETIME DEFAULT NULL, PRIMARY KEY (id), KEY idx_drug_expiry (drug_id, expiry_date) ) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT药品批次库存表;这段 SQL 里值得关注的是最后的联合索引 idx_drug_expiry它把药品 ID 和有效期绑在一个索引里后面做近效期查询和 FIFO 出库都能直接走索引。采购入库的流程是先建供应商档案再录采购订单收货时按实收数量登记批号和效期。主表只维护药品基本信息和当前库存总量具体到每个批次的可用量都记在批次表里两表通过 drug_id 关联。这样设计的好处是批次级数据不污染药品主档盘点、调账都按批次做账目才可能对上。导入数据后建议在后台把采购入库页面打开看它是怎么往批次表写数据的。有的源码只在采购单上加了“批号”和“效期”两个输入框有的提供批次列表批量录入。无论界面怎么变底层逻辑都是往批次表插记录同时把药品主表的 stock_qty 累加。如果手工复刻这个流程记住必须同时更新两处否则就会出现“批次表有数、主表没数”的烂账。4.2 销售出库按“先到期先出”扣批次FIFO 分配逻辑与事务提交销售开单时系统要自动决定从哪个批次扣货。药品经营里的规矩是“先产先出”或“近效期先出”本质是 FIFO 的变体——不按入库时间而按效期先后扣减。代码上就是一次带条件的查询加一个循环。下面这段实际项目里常用的分配函数把核心逻辑抽出来了/** * 按近效期优先规则分配出库批次 * param int $drugId 药品ID * param int $qty 出库数量 * return array 批次分配明细 */ public function allocateFifo($drugId, $qty) { $batchModel M(drug_batch); // 只取效期在今天之后、有库存的批次按效期升序排列 $batches $batchModel -where(array( drug_id $drugId, stock_qty array(gt, 0), expiry_date array(egt, date(Y-m-d)), )) -order(expiry_date asc, id asc) -select(); $allocate array(); $need $qty; // 挨个批次分配先到期的先扣 foreach ($batches as $batch) { if ($need 0) break; $take min($batch[stock_qty], $need); $allocate[] array( batch_id $batch[id], take_qty $take, expiry_date $batch[expiry_date], ); $need - $take; } if ($need 0) { throw new Exception(库存不足可出库数量 . ($qty - $need)); } return $allocate; }这段代码三个点值得留意。第一where 里把效期限制在今天之后等于在源头挡住过期批次过期药永远不会被正常销售流程选到。第二order 用效期升序让最早的批次排在前min 函数保证不会把一个批次扣成负数。第三函数返回的是分配明细而不是直接改库存调用方拿到结果再统一写库分配逻辑和写库逻辑可以分开测试。分配完成之后真正扣库存必须放在数据库事务里结构如下M()-startTrans(); try { // 1. 写销售单主表 $saleId M(sale)-add($saleData); if (!$saleId) throw new Exception(销售单保存失败); // 2. 写销售明细并按批次扣减库存 foreach ($allocate as $line) { $line[sale_id] $saleId; M(sale_detail)-add($line); M(drug_batch) -where(array(id $line[batch_id])) -setDec(stock_qty, $line[take_qty]); } // 3. 回写药品主表当前库存 M(drug)-where(array(id $drugId)) -setDec(stock_qty, $qty); M()-commit(); } catch (Exception $e) { M()-rollback(); throw $e; }setDec 是 ThinkPHP 自带的减值方法生成 UPDATE ... SET stock_qty stock_qty - N 的 SQL避免并发时读到旧值覆盖。事务的意义在于销售单写一半挂了批次库存和主表库存会一起回滚不会出现“系统里说卖了库存却没减”的对不上账。如果你发现拿到的源码出库没有事务直接裸 SQL 扣库存这应该列为你二次开发的第一优先级。4.3 效期预警与库存下限两段可以直接落到首页的 SQL药品业务里效期预警比库存预警更敏感。过期药还在货架上不只是钱的问题是用药安全的问题。所以效期预警 SQL 要固化到后台首页每天自动跑一遍。-- 未来90天内到期且仍有库存的批次按剩余天数升序排列 SELECT d.drug_name, b.batch_no, b.expiry_date, b.stock_qty, DATEDIFF(b.expiry_date, CURDATE()) AS remain_days FROM tp_drug_batch b LEFT JOIN tp_drug d ON d.id b.drug_id WHERE b.expiry_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 90 DAY) AND b.stock_qty 0 ORDER BY b.expiry_date ASC;DATEDIFF 算出的 remain_days 用来做分级提醒90 天以内标黄30 天以内标红等于 0 说明当天到期要立即下架。常见做法是在后台首页右侧栏放一个“近效期药品”面板把这段 SQL 的结果渲染出来配合定时任务每天早晨把预警列表推给负责人。库存下限预警的 SQL 更简单直接在药品主表上比较-- 当前库存低于预警下限的品种 SELECT drug_code, drug_name, stock_qty, lower_limit FROM tp_drug WHERE stock_qty lower_limit ORDER BY (lower_limit - stock_qty) DESC;这两段 SQL 改改表名就能用建议先在图形化数据库客户端或命令行里手动执行一遍确认结果再嵌进框架的模型方法。除了 SQL效期管理还要留意业务流程上的规范近效期商品要有醒目标识报损出库要有审批流。源码只要把批次表和有效期字段保留住了流程层面的东西都可以靠二开慢慢补齐。5. 部署避坑指南PHP 版本、中文乱码、验证码和伪静态的四个典型问题这章列的是我在帮人排这类 ThinkPHP 源码包时遇到频次最高的四个问题全部按“现象、原因、解决”展开对号入座即可。5.1 页面白屏 500PHP 7.2 移除了 each()老代码直接 fatal error现象项目在 PHP 5.6 环境一切正常换到 PHP 7.2 以上之后访问入口文件直接白屏浏览器返回 500PHP 错误日志里报 Call to undefined function each()。原因ThinkPHP 3.2 的内核和不少业务控制器还在用 each() 遍历数组PHP 7.2 正式把它移除函数一调用就是 fatal error。这不是源码坏了是环境不兼容。这个版本问题有点玄学——有人 7.0 跑得好好的有人 7.1 就报错最稳的做法是直接锁 5.6。解决有条件就换 PHP 5.6 或 7.0 跑这套源码。如果必须留在高版本把报错点逐个改成 foreach// 报错代码while (list($key, $value) each($list)) while (list($key, $value) each($list)) { $result[$key] $value; } // 修复写法foreach 语义等价 foreach ($list as $key $value) { $result[$key] $value; }修复时注意两点each() 在循环结束时返回 falsewhile 自然退出foreach 也一样语义基本等价如果代码里对 each() 的行指针有依赖改成 foreach 后行为可能有细微差异需要人工复查。建议用编辑器的全局搜索把 each( 全部列出来一次改完。5.2 中文乱码SQL 文件是 GBK 编码连接字符集却是 utf8现象药品名称、供应商名称全是问号但框架代码、菜单标题这些硬编码文字正常。更隐蔽的是有些中文正常、有些不正常因为数据在导入时已经被错误解码过一次无法在页面上修正。原因很多源码包在 Windows 上用老工具导出 SQL默认编码就是 GBK而框架配置 DB_CHARSET 写的是 utf8。导入时 MySQL 按 utf8 去解释 GBK 的字节流编码信息从落库那一刻就丢了。解决导入时显式指定字符集这是唯一正确的做法# 先看 SQL 文件实际是什么编码 file drug_db.sql # 方案一按 GBK 导入框架连接字符集保持 utf8 也不影响 mysql -uroot -p --default-character-setgbk pharmacy drug_db.sql # 方案二把 SQL 整体转成 UTF-8 再导入更干净 iconv -f GBK -t UTF-8 drug_db.sql pharmacy_utf8.sql mysql -uroot -p --default-character-setutf8 pharmacy pharmacy_utf8.sql如果数据已经导坏别试图用 UPDATE 语句去修最省力的是 drop 掉这个库重新来。因为坏数据是导入时解码错误造成的已经不可逆。教训只有一条第一次导入前先执行 file 命令看编码别偷懒。5.3 验证码不显示或一直提示验证码错误GD 扩展没启用现象登录页验证码图片位置是红叉或空白有的人明明按图片输入了却一直提示验证码错误反复刷新都进不去。原因ThinkPHP 3.2 的验证码类依赖 GD 扩展生成图片。集成环境默认 PHP 可能没启用 gd或者没有开启对应的字体支持。更隐蔽的是第二种情况验证码图片没渲染出来输入框里输入的内容其实是空的session 里的验证码字符串和服务端校验值对不上于是永远提示错误。其实不是输错是图片根本没显示。解决在集成环境面板或服务器管理面板的 PHP 设置里把 gd 扩展勾上重启 PHP-FPM强制刷新页面。Linux 手工环境执行对应命令安装例如 apt install php-gd再重启。验证php -m | grep gd没有输出就是没启用。启用后刷新登录页验证码图片应该正常出现。这个坑九成是环境配置问题不是源码问题。5.4 登录成功跳转 404Nginx 没配伪静态规则路由解析不了现象Apache 下跑得好好的换到 Nginx 上登录页能打开输入账号密码点登录浏览器地址栏变成 index.php/Admin/Index/index 这种 pathinfo 格式页面却 404。原因ThinkPHP 的 pathinfo 模式依赖服务器把没有对应文件路径的请求转发给入口文件。Apache 默认读取 .htaccess 里的 rewrite 规则很多打包源码自带所以 Apache 几乎不用配。Nginx 不读 .htaccess必须手动加伪静态规则。解决在 Nginx 配置里加 try_files 一行并确认 root 指向 Publiclocation / { try_files $uri $uri/ /index.php?s$uri$args; }加入后重新加载 Nginx再次登录验证。如果还有问题打开浏览器开发者工具看跳转后的 URL 格式确认是带 s 参数的兼容模式还是 pathinfo 模式再对应调整 URL_MODEL 或 rewrite 配置。伪静态是 Nginx 部署里反复出现的老朋友配好一次以后换其他 ThinkPHP 项目也用得上。6. 接手后的第一件正经事改默认口令、把备份做起来、给二开定优先级6.1 第一时间改默认口令并核对会话配置部署上线后第一件事就是改管理员密码。这类源码包的默认账号密码重合度很高很多系统上线两周内就被扫描爆破成功。改法很简单后台用户管理里重置即可或者直接改库UPDATE tp_admin SET password MD5(你的强密码) WHERE id 1;改密码的同时把 config.php 里会话前缀、Cookie 域名核对一遍。如果服务器配置了 HTTPS 证书顺手启用强制跳转保证后台登录链路不是明文传输。这个小动作成本不超过五分钟收益却立竿见影。6.2 备份做成习惯mysqldump 加定时任务给数据留后悔药数据库是这套系统的核心资产跑起来之后每一天的采购、销售、库存数据都有价值。我在这方面吃过亏——模拟项目X上线后一次误删操作差点把三个月的流水全部清零从那以后备份就是我接手任何项目的第一道工序。mysqldump -uroot -p --single-transaction pharmacy backup_$(date %F).sql--single-transaction 在 InnoDB 下做一致性快照不锁业务表白天跑也不影响正常售卖。配合 crontab 每天凌晨执行一次保留最近 30 天的备份文件再把备份目录同步到另一块磁盘或网盘。药品进销存系统本身不复杂但数据经不起一次失误备份就是你的后悔药。6.3 二次开发优先级追溯码、温湿度、条码枪把基础运维理顺之后再谈二次开发。以我的经验这套系统最容易出价值、也最容易被使用方认可的三个方向是药品追溯码对接、温湿度监测告警、条码枪快速出入库。追溯码是医药流通里的刚需扫码入库时把追溯码和批号、效期绑定销售时扫追溯码完成出库登记既能满足流向管理要求又能让消费者扫码查真伪。代码层面就是在采购入库模块加一个扫码输入框录入后按追溯码规则拆出批号和效期回填到批次表。温湿度监测则是在系统里加一张记录表定时任务每半小时写入一次库房温湿度超限触发告警这是药品经营环节质量管理要求里明确要留痕的事。条码枪属于最容易立刻见效的改造出入库页面加一个支持回车自动提交的输入框扫码枪一响就完成商品选择和数量累加收银效率直接上一个台阶。我给这套系统的定位是拿它做信息化起点绰绰有余拿它做全套合规还不够。所以二开的判断标准很简单——先补流程上必须有、现在没有的功能再谈体验优化。接手源码包之后先跑通、改密码、做备份这三步做完整套系统才算真正交到你手里。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?