尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

微信小程序药店管理系统:SSM+MySQL后端设计与开发全解析

发布时间:2026/9/19 15:00:21

资讯中心
01
ARTICLE

微信小程序药店管理系统:SSM+MySQL后端设计与开发全解析

微信小程序药店管理系统:SSM+MySQL后端设计与开发全解析
简介这是一份面向毕业设计撰写的《基于微信小程序的药店管理系统》论文文档适合计算机、软件工程及相关专业学生作为课题参考。论文围绕药店管理小程序的开发全过程从选题背景、研究现状与研究内容切入详细介绍了微信开发者工具、JAVA技术、MySQL数据库、SSM框架等关键开发技术并系统展开需求分析、可行性分析、界面设计与功能实现等核心章节。资源包共1个docx文档大小3.16MB包含中英文摘要、目录、绪论、开发工具介绍、系统分析等完整结构能够帮助读者快速搭建论文框架系统功能覆盖药品信息管理、库存监控、销售记录、用户反馈与数据分析等模块对完成类似毕业设计或课程论文有直接借鉴价值。目前已有83人学习浏览适合正在筹备药店管理或小程序方向毕业设计的同学参考学习。1. 一个毕业设计题目的真实技术构成药店小程序与 SSM 后端的边界拿到“基于微信小程序的药店管理系统”这个题目很多人的第一反应是“这不就是个 CRUD 小程序嘛”。但真把题目拆开看你会发现它至少包含三条技术线微信小程序端的页面与本地存储、Java 后端的 SSM 框架整合、MySQL 里那些带约束的订单和库存表。这三条线不是割裂的而是靠一套接口协议串起来。这个资源的价值在于它给的不是“能跑就行”的玩具代码而是一套完整的管理员后台加用户端购物流程覆盖了用户登录、药品分类展示、购物车、订单生成、用户充值、在线客服这些真实药店业务里的高频模块。适合两类人一是需要快速完成毕业设计并讲清楚“为什么这么设计”的学生二是想了解小程序SSMMySQL 三端如何分工协作的初级开发者。看懂这张图你就知道论文目录里的“需求分析”和“数据库设计”到底对应代码里的什么东西。2. 从需求到表结构ER 模型与 MySQL 库表设计2.1 为什么先定表结构再写接口药店管理系统的后端基于 SSM 框架MyBatis 负责 SQL 映射数据库用的是 MySQL。开发这类系统时我一般会先画 ER 图再把实体关系转成数据表。论文里给出了用户信息、药品信息等实体的属性图实际落地时表结构比图更重要。因为后端的 Service 层所有业务逻辑比如“用户下单后扣减库存”“管理员修改药品价格”最终都要落到 SQL 上。表设计不合理后面写接口时会反复改表尤其是订单和购物车这类关联表字段少一个都会导致联调失败。2.2 核心业务表的字段与约束参考文档里的表结构yaopinxinxi药品信息是整个系统的核心表它承接了药品的展示、搜索、加购和下单。以下字段在开发中必须关注字段名类型长度说明yaopinbianhaovarchar255药品编号业务上通常唯一yaopinmingchengvarchar50药品名称leibie / yaopinfenleivarchar50分类名称冗余分类信息便于查询tupianvarchar50图片路径小程序端拼接域名访问guigevarchar50规格如“10片/盒”baozhiqivarchar50保质期注意这里不是 date 类型是字符型pricevarchar50价格同样存成字符型计算时需转换onelimittimesvarchar50单次限购数量alllimittimesvarchar50总限购数量这里有个典型的毕业设计风格很多字段都用varchar连价格和限购数量也是。好处是前期插入数据方便不用处理类型转换坏处是写 SQL 做比较运算时容易出错。实际开发中我会把price改成decimal(10,2)把onelimittimes改成int。但如果你要严格复现论文保持原样也能跑通只要在 Java 代码里做转换。订单表orders和购物车表cart是关联最紧密的两张表。cart表记录了用户添加的药品、数量、单价和折扣价字段tablename用来标识来源表这是很多课程设计里常见的“万能购物车”写法。orders表则多出了orderid、total、discounttotal、status、address这几个字段其中orderid是订单号status控制订单状态流转比如“待付款”“已发货”“已完成”。2.3 用户与权限相关的表系统分管理员和用户两个角色。理论上是基于 RBAC 设计角色权限但实际表结构里做得比较简单users表只有username、password、role三个字段登录时按role区分跳转。allusers表这是 SSM 项目里常见的“管理员表”字段包括username、pwd、cx权限级别。yonghu表用户表存放用户姓名、性别等扩展信息。这种设计在中小型毕业设计里很常见管理员和用户分开两张表各自维护登录凭据没有复杂的权限表。如果你要优化可以把users和yonghu合并用role字段区分。但要注意合并后users表需要增加yonghu表中的扩展字段否则用户信息没法完整展示。2.4 建表语句与 MyBatis 映射的对应关系拿到.docx里的表结构第一步不是直接写代码而是把表定义转成实际的 DDL。这里给出yaopinxinxi表的建表语句注意字符集和引擎CREATE TABLE yaopinxinxi ( id int(11) NOT NULL AUTO_INCREMENT, yaopinbianhao varchar(255) DEFAULT NULL, yaopinmingcheng varchar(50) DEFAULT NULL, leibie varchar(50) DEFAULT NULL, yaopinfenlei varchar(50) DEFAULT NULL, tupian varchar(50) DEFAULT NULL, guige varchar(50) DEFAULT NULL, baozhiqi varchar(50) DEFAULT NULL, changjia varchar(50) DEFAULT NULL, yaopinxiangqing varchar(50) DEFAULT NULL, price varchar(50) DEFAULT NULL, onelimittimes varchar(50) DEFAULT NULL, alllimittimes varchar(50) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;为什么用InnoDB因为订单、购物车、余额充值这些操作涉及事务MyBatis 的Transactional注解依赖 InnoDB 的行级锁。如果是MyISAM事务会静默失效下单时并发扣库存就会出现超卖。utf8mb4也是必须的药品名称里如果有特殊符号比如 ℃utf8会报错。allusers表和users表的区别需要特别说明。allusers是管理员登录用的通常在后台系统里存在users是前台用户登录用的。论文里的“管理员”对应allusers而“用户”对应users和yonghu。写登录接口时要分别查询这两张表根据用户输入的账号类型决定走哪条查询。3. 小程序端与后端接口协作从登录流程到购物车实现3.1 微信小程序的目录结构与请求封装微信开发者工具创建的小程序项目目录结构必须包含pages、utils、app.js、app.json、app.wxss。在药店管理系统里前端页面主要是pages/index首页、pages/yaopinxinxi药品列表、pages/cart购物车、pages/orders订单、pages/mine个人中心。这些页面通过wx.request与后端交互。每次写wx.request都带url、method、header很麻烦我习惯在utils/request.js里封装一个公共请求方法const BASE_URL http://localhost:8080/pharmacy; // 后端接口根路径 function request(path, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method: method, data: data, header: { Content-Type: application/json }, success: (res) { if (res.statusCode 200) { resolve(res.data); } else { wx.showToast({ title: 请求失败, icon: none }); reject(res); } }, fail: (err) { wx.showToast({ title: 网络异常, icon: none }); reject(err); } }); }); } module.exports { request, BASE_URL };这段代码做的事情很简单统一管理接口根路径把wx.request的回调风格改造成 Promise 风格。后面页面里调用request(/yaopinxinxi/list, GET, { page: 1 })就能拿到药品列表。注意BASE_URL在真机调试时要改成局域网 IP不能写localhost因为手机访问的localhost是手机自己。3.2 登录流程账号 password 与角色判断论文里画了用户登录流程图实际实现时小程序端先通过wx.login获取临时code但毕业设计里通常不会用微信官方登录而是用账号密码登录。用户输入用户名和密码前端调用登录接口// pages/login/login.js Page({ data: { username: , password: , role: users // 默认用户角色 }, async handleLogin() { const { username, password, role } this.data; if (!username || !password) { wx.showToast({ title: 请输入账号和密码, icon: none }); return; } const res await request(/login, POST, { username, password, role }); if (res.code 0) { wx.setStorageSync(token, res.data.token); wx.setStorageSync(userInfo, res.data.userInfo); wx.switchTab({ url: /pages/index/index }); } else { wx.showToast({ title: res.msg || 登录失败, icon: none }); } } });后端对应的 Controller 逻辑是根据role参数决定查询users表还是allusers表若密码匹配生成一个简单的会话标识。项目里没有引入 Redis 做会话共享常见的做法是返回用户 ID 和用户名前端存到本地。这里有个容易忽视的坑password字段在数据库里如果明文存储登录接口查询时直接比对即可如果做了 MD5前端提交时也要先加密。论文里没有提加密实际答辩时如果老师问安全性要能说出“后续可以引入 MD5 加盐”。3.3 药品列表与分类筛选union 查询还是冗余字段首页要展示药品信息和分类。前端从yaopinfenlei表获取分类列表再从yaopinxinxi表按分类字段筛选。后端接口可以这样写RestController RequestMapping(/yaopinxinxi) public class YaopinxinxiController { Autowired private YaopinxinxiService yaopinxinxiService; GetMapping(/list) public MapString, Object list( RequestParam(value fenlei, required false) String fenlei, RequestParam(value page, defaultValue 1) Integer page, RequestParam(value limit, defaultValue 10) Integer limit) { MapString, Object result new HashMap(); ListYaopinxinxi list yaopinxinxiService.queryList(fenlei, page, limit); int total yaopinxinxiService.count(fenlei); result.put(code, 0); result.put(data, list); result.put(total, total); return result; } }对应的 MyBatis Mapper XML 里如果fenlei为空就查全部不为空就加WHERE yaopinfenlei #{fenlei}。因为yaopinfenlei字段在设计时冗余了分类名称所以不需要 JOIN 分类表这在大数据量下会有冗余问题但毕业设计的药品数据量通常只有几十条查询效率完全可以接受。如果你想要规范化可以把yaopinfenlei改成分类 ID再关联yaopinfenlei表查分类名但这会多一次关联查询前端也要多处理一层数据转换。3.4 购物车前端本地存储还是后端数据库购物车数据存在哪里是这类系统的一个分水岭。论文里设计了cart表说明购物车是存后端的。用户点击“加入购物车”时小程序端向/cart/add发送 POST 请求参数包含userid、goodid、goodname、picture、buynumber、price、discountprice。后端先判断该用户购物车里是否已有同一药品有则更新数量没有则插入新记录。这里有个细节goodid是药品在yaopinxinxi表中的id但前端拿到的goodid可能来自列表页的id字段。如果列表页的id是字符串后端插入时注意类型转换。购物车列表接口返回的数据要按id倒序保证用户后加的商品排在前面。select idqueryCartByUserId resultTypemap SELECT id, goodid, goodname, picture, buynumber, price, discountprice FROM cart WHERE userid #{userid} ORDER BY id DESC /select为什么不直接存小程序本地wx.setStorageSync因为用户如果更换设备本地购物车就丢了。存后端的好处是管理员和用户都能看到购物车数据后续订单管理也能直接关联。坏处是每次加购都要请求后端网络差的时候体验不好。实际生产系统会做“本地缓存后端同步”毕业设计论文里不需要写这么复杂。4. 订单与库存的关键约束并发扣减与事务处理4.1 从购物车生成订单的事务边界用户提交订单时后端要做三件事读取购物车中的商品、生成订单记录、清空购物车。这三步必须在一个事务里完成否则会出现“订单生成了但购物车没清空”或“购物车清了但订单没写成”的脏数据。SSM 框架下使用Transactional注解Service public class OrderServiceImpl implements OrderService { Autowired private CartMapper cartMapper; Autowired private OrdersMapper ordersMapper; Transactional(rollbackFor Exception.class) public void createOrder(Long userId, String address) { // 1. 查询购物车列表 ListCart cartList cartMapper.selectByUserId(userId); if (cartList.isEmpty()) { throw new RuntimeException(购物车为空); } // 2. 计算总金额 BigDecimal total BigDecimal.ZERO; for (Cart cart : cartList) { total total.add(new BigDecimal(cart.getPrice()).multiply(new BigDecimal(cart.getBuynumber()))); } // 3. 插入订单主表 Orders order new Orders(); order.setOrderid(PH System.currentTimeMillis()); order.setUserid(String.valueOf(userId)); order.setTotal(total.toString()); order.setStatus(待付款); order.setAddress(address); ordersMapper.insert(order); // 4. 清空购物车 cartMapper.deleteByUserId(userId); } }rollbackFor Exception.class很关键。默认情况下Spring 只对 RuntimeException 回滚如果步骤 4 抛出受检异常事务不会回滚就会留下一个没有订单明细的订单记录。另外new BigDecimal(cart.getPrice())之前最好做空值校验因为表里price是varchar可能为null。4.2 库存扣减先查再扣还是原子更新药店管理系统的库存体现在onelimittimes单次限购和alllimittimes总限购上但实际下单时不一定会严格校验这两个字段。如果你想把这个项目做成有亮点的版本可以在下订单时增加库存扣减逻辑。常见的错误写法是// 错误示例先查询库存判断够不够再扣减 int stock yaopinxinxiMapper.selectStock(goodId); if (stock buyNumber) { yaopinxinxiMapper.reduceStock(goodId, buyNumber); }这个写法在单机低并发下没问题但如果有两个用户同时提交订单两个请求都读到库存是 10都判断可以扣最后库存变成 -2。正确的做法是用一行 SQL 原子扣减update idreduceStock UPDATE yaopinxinxi SET alllimittimes alllimittimes - #{buyNumber} WHERE yaopinbianhao #{goodId} AND alllimittimes #{buyNumber} /update执行这个 update 后通过返回的受影响行数判断是否扣减成功。如果返回 0说明库存不足事务直接回滚。这种写法依赖 MySQL 的行锁保证同一时间的多个更新请求串行执行避免了超卖问题。4.3 订单状态机与支付回调模拟论文里没有接入真实微信支付订单状态一般由管理员手动修改。前端“我的订单”页面展示订单列表用户点击“确认收货”时前端调用/orders/updateStatus后端把status从“已发货”改成“已完成”。这里需要注意状态流转的合法性比如“待付款”的订单不能直接改成“已完成”。后端可以写一个简单的校验switch (targetStatus) { case 已发货: if (!待付款.equals(currentStatus)) throw new RuntimeException(当前状态不可发货); break; case 已完成: if (!已发货.equals(currentStatus)) throw new RuntimeException(当前状态不可确认收货); break; default: throw new RuntimeException(非法状态); }如果是模拟支付可以添加一个“模拟支付”按钮把订单状态从“待付款”改为“待发货”。这与真实微信支付的差别在于没有回调验签但毕业设计答辩时说清楚“这里是模拟支付生产环境需要接入微信支付 API 并验证回调签名”就足够了。4.4 高并发场景下的乐观锁兜底如果你的论文需要体现“性能分析”可以提到并发控制。除了上面说的原子更新还可以在yaopinxinxi表加一个version字段每次更新时带上版本号UPDATE yaopinxinxi SET alllimittimes alllimittimes - #{buyNumber}, version version 1 WHERE yaopinbianhao #{goodId} AND version #{version}如果更新影响行数为 0说明版本号已被别的请求修改重新读取后再尝试。乐观锁在商品表上通常够用因为单个药品的并发写不会太高。如果要支撑秒杀类场景就需要 Redis 预扣库存了那超出药店管理系统的范围。5. 把整个流程跑通微信开发者工具联调、真机预览与常见坑5.1 本地联调的域名白名单问题用微信开发者工具调试时默认会校验合法域名。如果你的后端是本地http://localhost:8080需要点击开发者工具右上角“详情”-“本地设置”勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。否则wx.request会报url not in domain list。这个选项只对当前项目生效换一台电脑重新导入项目时要再勾一次。5.2 真机预览时的 IP 替换开发者工具里能跑通换到真机就请求失败90% 是BASE_URL的问题。手机和电脑必须处于同一局域网然后把BASE_URL改成电脑的局域网 IP。在微信开发者工具的控制台输入wx.getSystemInfoSync()看不到电脑 IP你需要在命令行执行ipconfigWindows或ifconfigmacOS查询。还有一点后端接口不能被防火墙拦截Windows 开发机最好临时关闭防火墙或者给 8080 端口加放行规则。5.3 后端返回时间字段的坑orders表如果通过OrderServiceImpl直接插入当前时间一般用NOW()没问题。但如果用 Java 的Date类型传给前端小程序端看到的可能是2025-06-01T12:00:00.00000:00这种格式。处理方式是利用 SpringMVC 的JsonFormatJsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8) private Date createtime;timezone必须写成GMT8否则会少了 8 个小时。如果你不想改实体类也可以在前端用正则裁剪字符串但格式问题最好在后端一次性解决。5.4 模拟数据与真实数据的切换项目里通常有一套sql脚本里面有管理员账号admin、用户账号user和若干测试药品。建议在application.yml里配置两个环境开发时用application-dev.yml连本地库部署时用application-prod.yml换远端库。切换环境时只需要改spring.profiles.activedev这一行。最怕的是把测试数据当成真实数据价格带一堆小数点或者过期日期是 2020 年。清理数据可以用下面的 SQLDELETE FROM cart; DELETE FROM orders; DELETE FROM storeup; UPDATE yaopinxinxi SET alllimittimes 100, onelimittimes 10;这样每次测试下单库存都是从 100 开始扣订单和购物车不会越积越多。5.5 验证整个系统是否达标的检查清单联调完成后按照下面的顺序手动检查一遍可以帮你发现八成的问题新用户注册后用yonghu表里的账号登录跳转到用户首页而不是管理员首页。管理员在后台新增药品小程序首页下拉刷新后能看到新药品图片能正常显示。用户将药品加入购物车修改数量提交订单订单状态变为“待付款”。管理员后台看到新订单修改状态为“已发货”用户端“我的订单”页面同步变为“已发货”。重复提交同一个药品到购物车数量不会变成两条记录。清空购物车后cart表里该用户的记录数为 0。断网时点击加购微信客户端有“网络异常”提示不会白屏。把以上步骤在论文的测试章节里写成测试用例再补一张测试结果表比空写“系统运行正常”要有说服力得多。最后提醒一句storeup表是收藏功能用的功能模块图里的“我的收藏管理”对应它别在测试时把它忘了。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。