两个月前我帮一个计算机专业的学弟看毕业设计选题。他已经换了三个题目第一个太简单被导师否了第二个找不到完整源码第三个做到一半发现技术栈太老。最后我给他的建议是做一个微信小程序版的在线问诊与电子处方流转平台。这个选题能在计算机毕业设计里常年保持热度不是没有原因的。它天生就适合做毕业设计前端有微信小程序这种自带真实用户场景的载体后端能覆盖用户体系、医生排班、问诊会话、处方管理、订单支付、权限控制这些高频业务模块。论文好写工作量好展示答辩时也有清晰的功能演示流程。更重要的是这类项目对于后续找工作也有参考价值一个完整的小程序前后端项目放进简历比十个零散 Demo 都有说服力。本文要聊的核心就是基于微信小程序实现在线问诊与电子处方流转平台并附上可直接借鉴的开源项目结构。我会先讲清楚电子处方流转到底是什么、和普通电商订单有什么区别然后从技术选型、数据库设计、核心业务流程、后端接口实现到小程序端代码一步步拆解。同时会给出几个常见的坑和工程建议帮你在毕设阶段少走弯路。如果你正在做这个方向的选题或者被导师要求做一个小程序 电子处方流转的项目这篇文章适合你从头读到底。如果你只是想找开源项目跑通流程从第 3 节和第 5 节开始看可以直接跳到代码部分。1. 在线问诊与电子处方流转到底在做什么先拆解一下这个项目标题里的两个核心概念。在线问诊是一个大家都很容易理解的功能。患者在微信小程序里选择医生、提交病情描述、与医生进行图文或语音问诊医生查看后给出诊断建议。它本质上是一个医患之间的异步/同步沟通工具但又比普通聊天多了一层“诊断”的业务含义。电子处方流转是容易被忽视、但真正决定项目含金量的部分。它不是简单的“医生开个药单”而是一个完整的业务闭环医生在问诊会话中确认患者的病情后在系统里开具电子处方包括药品清单、用法用量、用药天数。处方经过合理性校验比如药品库存是否充足、剂量是否超限、是否存在重复用药。处方被流转到药房系统药房审核通过后进行配药、发货或到店自提。患者在小程序端能实时看到处方的状态待审核、审核通过、已配药、已完成。这个流程意味着你的系统里至少有三个角色在同一个业务链路上协作患者、医生、药师。如果再加上管理员这就是一个典型的多角色 状态机 业务流程流转系统。从毕业设计的评分角度看多角色本身就比单角色的管理系统难一个层级。导师看到的不只是 CRUD而是学生有没有理解真实业务中“谁操作、什么状态下能操作、操作后进入什么状态”这套逻辑。下图描述了系统核心业务状态流转关系文字版便于在论文里使用患者提交问诊单 → 医生接诊 → 问诊对话 → 医生开具处方 → 处方待药师审核 → 药师审核通过 → 药房配药 → 患者确认收货/到店自提 → 订单完成2. 技术选型为什么小程序端 Spring Boot 是主流组合技术选型是毕业设计开题阶段最先要确定的事情。同一个项目用不同技术栈代码量、难度、就业价值完全不同。从我看到的开源项目和近几年热门毕设选题来看这个方向的系统通常采用下面的组合层级技术选择说明前端微信小程序原生 / uni-app原生上手快uni-app 可复用多端代码后端Spring Boot / SSMSpring Boot 为主流生态完善数据库MySQL关系型数据天然适合业务系统ORMMyBatis-Plus / JPAMyBatis-Plus 在中文社区资料最多缓存Redis用于 Token、验证码、热点科室数据权限Spring Security / JWT前后端分离项目常用 Token 鉴权文件存储本地存储 / OSS用于用户头像、处方附件上传为什么 Spring Boot MyBatis-Plus 是小程序后端项目最稳妥的选择我的判断是三个原因第一资料量大。毕业设计最常见的坑是在一个冷门技术栈上卡住后找不到解决方案。Spring Boot MyBatis-Plus 是中文互联网覆盖最全的 Java 后端组合你遇到的 90% 的报错都能搜到答案。第二代码结构清晰。Controller、Service、Mapper 三层结构天然适合论文中的系统设计章节。画分层架构图、写类设计、做数据库 ER 图都方便。第三岗位匹配度高。如果后续求职方向是 Java 后端开发这个技术栈就是面试高频范围。微信小程序端这里有一个决策点用原生小程序还是 uni-app如果你是打算快速跑通项目建议直接使用微信小程序原生。因为大部分开源毕设项目的代码都是原生写的你在学习和改造时可以直接对照。如果你已经会 Vue且希望以后能把代码打包成 H5 或 App则可以选择 uni-app。但要注意uni-app 从项目的整体复杂度上会引入更多概念毕设答辩时反而要花时间解释“为什么多这一层”。有一点必须提醒不要用云开发代替自建后端。某些实时数据库方案虽然开发速度快但论文中很难展开写“服务器端核心代码实现”因为后端逻辑都被云函数替代了。计算机毕业设计最看重的是后端逻辑设计和数据库建模自建 Spring Boot 后端才是稳妥路线。3. 数据库设计一张处方表撑起整个业务闭环在写一行代码之前先把数据库表设计理清楚。我见过太多毕设项目在中期改表结构改到崩溃原因就是前期没有把核心业务表的关系想明白。一个在线问诊与电子处方流转平台最少需要以下核心表表名作用关键字段t_user用户表患者/医生/药师/管理员id, username, password, role, real_namet_doctor医生详细信息表user_id, hospital, department, title, introductiont_patient_info患者详细信息表user_id, real_name, id_card, phonet_department科室表id, name, descriptiont_consultation问诊记录表patient_id, doctor_id, status, consult_timet_message问诊消息表consultation_id, sender_id, content, msg_typet_prescription处方表consultation_id, doctor_id, patient_id, statust_prescription_item处方明细表prescription_id, drug_id, dosage, times, dayst_drug药品表id, name, spec, price, stockt_order订单表prescription_id, order_no, amount, status下面这张表的关系值得多说几句。处方主表t_prescription是整个系统的枢纽。它同时关联了患者、医生和问诊记录。处方明细表t_prescription_item则记录每张处方里的多个药品因为一张处方可以包含多种药明细表和处方表是多对一关系。药品库存信息挂在 t_drug 上而订单表通过 prescription_id 反向关联处方这样“问诊 → 开方 → 购药”才能串成一条完整链路。在建表时有几个字段需要特别设计好状态字段建议使用int存储而不是字符串。处方状态可以用 0 表示待审核1 表示审核通过2 表示已配药3 表示已完成-1 表示已驳回。用数字存储的好处是查询和比较都方便而且逻辑上更清晰。在代码中定义一个状态枚举类统一管理避免魔法数字散落各处。金额字段使用decimal(10,2)。药品价格和订单金额都不能用 float 或 double否则容易出现精度问题。这个问题在答辩时可能会被老师点名提问会正确解释“为什么不用浮点数”是加分项。逻辑删除统一使用deleted字段0 正常1 已删除而不是物理删除。MyBatis-Plus 内置了逻辑删除支持一个注解就能搞定这也是工作量展示的一部分。4. 核心业务模块拆解问诊、处方、订单如何串联在线问诊系统从功能清单上看可能列出二三十个小功能但真正决定业务流程的只有三个闭环。4.1 问诊闭环患者在首页选择科室进入医生列表选择可问诊的医生后提交问诊订单。问诊订单可以有两种交互形式一种是即时对话模式一种是留言问诊模式。对于毕设系统我推荐采用“留言式问诊 医生回复”的简化模式理由是技术复杂度可控核心痛点依然完整。患者提交病情描述后医生在待接诊列表里看到选择接诊后进入问诊室进行多轮对话。这里要强调的是不要为了追求“实时聊天”而引入 WebSocket。虽然 WebSocket 是技术亮点但它会给项目带来额外的复杂度比如连接管理、消息推送、离线消息处理。对于一般毕设可以采用轮询方式小程序端每隔几秒请求一次“获取新消息”的接口。虽然不够“实时”但在演示场景下完全够用而且可以在论文中写“采用定时轮询方案避免长连接的资源开销”这也是一个合理的技术决策解释。4.2 处方闭环问诊结束后医生在问诊详情页录入处方。录入内容包括药品选择、剂量、频次、天数等。医生提交后处方状态为待审核。药师端可以查看所有待审核处方核对药品信息是否合理然后选择通过或驳回。审核通过后处方状态变为可购买状态患者端出现“去购药”按钮。处方审核这个环节非常值得实现因为它是“流转”二字的体现。如果系统只做到医生开方、患者查看那这个项目本质还是一个问诊系统谈不上“处方流转”。多一个药师审核环节业务流程完整度立刻提升一个档次。4.3 订单闭环患者点击“去购药”系统根据处方明细自动生成订单展示药品清单、总价、收货地址。患者提交订单并模拟支付成功毕设项目可以不接真实支付用模拟支付代替订单状态变为已支付。药师端和后台管理端可以看到新订单确认配药发货。患者端订单状态变为配送中最后点击确认收货整个流程闭环。如果追求完整还可以增加一个“退药退款”的流程但这属于加分项不作为核心功能要求。5. 后端代码实现从 controller 到 mapper 的完整链路下面结合代码演示处方创建与查询的核心逻辑。先明确环境Java 8 或 11Spring Boot 2.x版本以实际项目为准MyBatis-PlusMySQL 5.7 或 8.0Maven 3.x5.1 数据库建表脚本-- 处方表 CREATE TABLE t_prescription ( id bigint NOT NULL AUTO_INCREMENT, prescription_no varchar(32) NOT NULL COMMENT 处方编号, consultation_id bigint NOT NULL COMMENT 问诊ID, doctor_id bigint NOT NULL COMMENT 医生用户ID, patient_id bigint NOT NULL COMMENT 患者用户ID, status tinyint NOT NULL DEFAULT 0 COMMENT 状态:0待审核 1审核通过 2已配药 3已完成 -1已驳回, diagnosis varchar(500) DEFAULT NULL COMMENT 诊断结论, audit_remark varchar(255) DEFAULT NULL COMMENT 审核备注, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted tinyint NOT NULL DEFAULT 0, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 处方明细表 CREATE TABLE t_prescription_item ( id bigint NOT NULL AUTO_INCREMENT, prescription_id bigint NOT NULL COMMENT 处方ID, drug_id bigint NOT NULL COMMENT 药品ID, drug_name varchar(100) NOT NULL COMMENT 药品名称, spec varchar(100) DEFAULT NULL COMMENT 规格, price decimal(10,2) NOT NULL COMMENT 单价, dosage varchar(50) NOT NULL COMMENT 每次用量, frequency varchar(50) NOT NULL COMMENT 频次, days int NOT NULL COMMENT 天数, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;一个容易被忽略的细节处方明细表中冗余存储了drug_name、spec、price。为什么不直接关联药品表因为历史数据不可变。如果医生开的处方在患者购买前药品价格发生了调整那处方上的价格必须保持开方时的原价。这就是冗余字段的业务意义在论文数据表设计部分可以写出这样的设计理由。5.2 端点层处方 Controller// 文件路径src/main/java/com/example/medical/controller/PrescriptionController.java RestController RequestMapping(/api/prescription) public class PrescriptionController { Resource private PrescriptionService prescriptionService; /** * 医生提交处方 */ PostMapping(/create) public Result createPrescription(RequestBody PrescriptionCreateDTO dto) { Long prescriptionId prescriptionService.createPrescription(dto); return Result.success(prescriptionId); } /** * 药师审核处方 */ PostMapping(/audit) public Result auditPrescription(RequestBody PrescriptionAuditDTO dto) { prescriptionService.auditPrescription(dto); return Result.success(null); } /** * 患者查询自己的处方列表 */ GetMapping(/list/{patientId}) public Result listByPatient(PathVariable Long patientId, RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize) { PagePrescriptionVO page prescriptionService.pageByPatient(patientId, pageNum, pageSize); return Result.success(page); } }5.3 服务层处方状态流转的核心// 文件路径src/main/java/com/example/medical/service/impl/PrescriptionServiceImpl.java Service Slf4j public class PrescriptionServiceImpl implements PrescriptionService { Resource private PrescriptionMapper prescriptionMapper; Resource private PrescriptionItemMapper prescriptionItemMapper; Resource private DrugMapper drugMapper; Override Transactional(rollbackFor Exception.class) public Long createPrescription(PrescriptionCreateDTO dto) { // 1. 生成处方主记录 Prescription prescription new Prescription(); prescription.setPrescriptionNo(generatePrescriptionNo()); prescription.setConsultationId(dto.getConsultationId()); prescription.setDoctorId(dto.getDoctorId()); prescription.setPatientId(dto.getPatientId()); prescription.setDiagnosis(dto.getDiagnosis()); prescription.setStatus(PrescriptionStatusEnum.PENDING_AUDIT.getCode()); prescriptionMapper.insert(prescription); // 2. 批量插入处方明细 for (PrescriptionItemDTO itemDTO : dto.getItems()) { Drug drug drugMapper.selectById(itemDTO.getDrugId()); if (drug null) { throw new BizException(药品不存在: itemDTO.getDrugId()); } PrescriptionItem item new PrescriptionItem(); item.setPrescriptionId(prescription.getId()); item.setDrugId(drug.getId()); item.setDrugName(drug.getName()); item.setSpec(drug.getSpec()); item.setPrice(drug.getPrice()); item.setDosage(itemDTO.getDosage()); item.setFrequency(itemDTO.getFrequency()); item.setDays(itemDTO.getDays()); prescriptionItemMapper.insert(item); } return prescription.getId(); } Override Transactional(rollbackFor Exception.class) public void auditPrescription(PrescriptionAuditDTO dto) { Prescription prescription prescriptionMapper.selectById(dto.getPrescriptionId()); if (prescription null) { throw new BizException(处方不存在); } // 状态机校验只有待审核状态才能审核 if (!PrescriptionStatusEnum.PENDING_AUDIT.getCode().equals(prescription.getStatus())) { throw new BizException(当前状态不允许审核); } prescription.setStatus(dto.getPassed() ? PrescriptionStatusEnum.AUDITED.getCode() : PrescriptionStatusEnum.REJECTED.getCode()); prescription.setAuditRemark(dto.getRemark()); prescriptionMapper.updateById(prescription); } private String generatePrescriptionNo() { return RX System.currentTimeMillis() RandomUtil.randomNumbers(4); } }这段代码里有两个值得在答辩时展开的点。第一是 Transactional 注解。createPrescription中要插入主表数据和多条明细数据必须放在同一个事务中。如果某一条明细插入失败前面的主表插入也要回滚否则会出现处方主记录存在但明细不完整的数据脏状态。老师问“为什么不拆开写”时答案就是事务一致性。第二是状态机的显式校验。auditPrescription方法中先检查当前状态是否为待审核不是的话直接抛异常。这个简单的判断保证了状态流转的合法性避免了已审核的处方被重复审核或者已被驳回的处方又被误操作通过。5.4 MyBatis-Plus Mapper 接口// 文件路径src/main/java/com/example/medical/mapper/PrescriptionMapper.java public interface PrescriptionMapper extends BaseMapperPrescription { /** * 查询患者处方列表含明细 */ ListPrescriptionVO selectPatientPrescriptionList(Param(patientId) Long patientId); /** * 汇总各状态处方数量用于后台统计 */ ListStatusCountVO selectStatusCount(); }对应的 XML 映射文件需要额外说明一下。用 MyBatis-Plus 做单表 CRUD 完全不需要写 XML但复杂联表查询建议写 XML而不是在 Service 层循环查库。一个典型的反例是循环遍历 20 个处方每个处方再查一次明细造成 1 N 查询问题。正确做法是用一条联表 SQL 一次性查出数据后在 Java 内存中组装。!-- 文件路径src/main/resources/mapper/PrescriptionMapper.xml -- select idselectPatientPrescriptionList resultTypecom.example.medical.vo.PrescriptionVO SELECT p.id, p.prescription_no, p.diagnosis, p.status, d.department_name, u.real_name AS doctor_name, p.create_time FROM t_prescription p LEFT JOIN t_doctor d ON p.doctor_id d.user_id LEFT JOIN t_user u ON p.doctor_id u.id WHERE p.patient_id #{patientId} AND p.deleted 0 ORDER BY p.create_time DESC /select6. 微信小程序端首页、问诊、处方购药的实现思路小程序端至少需要以下页面页面功能首页科室入口、轮播图、推荐医生科室列表按科室查看医生医生详情医生履历、评价、发起问诊问诊会话留言 回复列表处方列表查看历史处方及状态处方详情药品明细、剂量、去购药订单确认收货地址、金额、提交个人中心我的问诊、我的处方、我的订单以“处方详情 去购药”页面为例核心调用逻辑如下// 文件路径pages/prescription/detail.js const app getApp(); Page({ data: { prescriptionId: null, prescription: null, items: [], totalAmount: 0.00, }, onLoad(options) { this.setData({ prescriptionId: options.id }); this.loadDetail(); }, loadDetail() { wx.request({ url: ${app.globalData.baseUrl}/api/prescription/detail/${this.data.prescriptionId}, method: GET, header: { Authorization: Bearer ${wx.getStorageSync(token)} }, success: (res) { if (res.data.code 200) { const detail res.data.data; this.setData({ prescription: detail.prescription, items: detail.items, }); this.calcTotal(detail.items); } else { wx.showToast({ title: res.data.msg, icon: none }); } }, }); }, calcTotal(items) { let total 0; items.forEach(item { total Number(item.price) * item.days * 1; }); this.setData({ totalAmount: total.toFixed(2) }); }, goToOrder() { const { prescription } this.data; if (prescription.status ! 1) { wx.showToast({ title: 处方未通过审核暂不可购药, icon: none }); return; } wx.navigateTo({ url: /pages/order/confirm?prescriptionId${this.data.prescriptionId}, }); }, });这里有一个非常关键的前后端协作细节前端不要自己算总价总价应该由后端计算并返回。前端展示的金额仅作展示用实际支付金额以后端计算为准。如果前端自己相加展示而后端按数据库中的价格计算两者很可能因精度处理不一致而出现分账问题。本文示例中前端为了展示方便做了本地合计但在实际项目中更稳妥的做法是后端在处方详情接口里返回totalAmount字段前端直接渲染。答辩时能指出“金额计算必须以后端为准防止客户端篡改”这会是一个加分回答。7. 常见问题与排查思路毕设阶段会遇到的问题很多都是共性的。下面这张表是这类项目最常见的问题清单问题现象可能原因排查方式解决方案小程序请求后端 404 或超时后端地址仍为 localhost或未关闭域名校验真机调试时改为局域网 IP勾选“不校验合法域名”开发阶段在微信开发者工具中关闭域名校验服务器联调时配置有效域名用户登录后拿不到 openid小程序 AppID 与后端配置的 AppID 不一致或授权流程缺失查看后端日志中的 code检查是否成功调用 code2Session 接口确认前后端 AppID 一致核对微信登录流程处方提交后明细为空前端传参结构是数组对象但后端接收类型不匹配打印后端收到的 JSON查看字段名是否与 DTO 一致统一字段命名使用 JsonProperty 或将前端参数改为后端期望的结构金额出现 0.1 0.2 0.30000000000000004浮点数直接相加检查金额计算方式金额用 decimal 类型合计用 BigDecimal 或后端计算登录状态频繁失效Token 过期时间设置过短或小程序端未在请求拦截器里刷新 Token查看后端返回的 401 频率和过期时间配置设置合理过期时间如 7 天统一封装请求工具类处理 401数据库插入中文乱码数据库连接串未指定 UTF-8或表字符集不是 utf8mb4查看数据库连接 URL 和表字符集URL 添加 characterEncodingutf8表使用 utf8mb4这里重点说两个高频坑。第一个坑是小程序端请求后端接口时出现“不在以下 request 合法域名列表中”。这是微信小程序开发最典型的报错之一。开发阶段可以在微信开发者工具的“详情 → 本地设置”中勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”即可正常调试。真机预览时同样需要开启调试模式。但要注意正式上线时必须配置合法域名且必须是 HTTPS。第二个坑是后端时间字段返回给前端后少 8 小时。这是因为后端将时间按 UTC 存储前端按东八区解析或者反过来。解决方案是在后端配置统一处理时间序列化把 LocalDateTime 转为yyyy-MM-dd HH:mm:ss格式的字符串返回最简单的办法是在 Spring Boot 配置文件中设置 Jackson 的时间格式。# 文件路径src/main/resources/application.yml spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT88. 最佳实践与工程建议8.1 前端请求封装统一处理不要在每个页面都直接写wx.request。应该封装一个request.js工具类统一处理 BaseURL、Token 注入、错误码拦截、401 跳转登录。这样后续改动后端地址或 Token 策略时只需改一个文件。// 文件路径utils/request.js const BASE_URL http://localhost:8080/api; function request(path, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method, data, header: { Content-Type: application/json, Authorization: Bearer ${wx.getStorageSync(token)}, }, success(res) { if (res.data.code 200) { resolve(res.data.data); } else if (res.data.code 401) { wx.navigateTo({ url: /pages/login/login }); reject(res.data); } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }); reject(res.data); } }, fail(err) { wx.showToast({ title: 网络异常, icon: none }); reject(err); }, }); }); } module.exports { request, BASE_URL };8.2 处方单号生成规则处方单号不要使用自增 ID 对外展示。一是容易暴露数据量二是不同表的 ID 可能重复。推荐使用“业务前缀 时间戳 随机数”的方式比如RX yyyyMMddHHmmss 4位随机数。订单号可以用类似规则。8.3 默认密码和初始化数据数据库初始化时要给医生、药师、管理员各准备一个测试账号。用户密码不要明文存储统一使用 BCrypt 加密。如果觉得手动注册流程太慢可以在项目启动时通过 DataInitializer 类自动创建管理员账号。8.4 论文里的系统设计图这类项目写论文时导师通常需要看架构图、功能模块图、业务流程图、ER 图和时序图。这里有一个实用建议用绘图工具画好图后导出成图片插入论文即可。项目代码里不需要内嵌图表但文档目录下建议保留所有设计图的源文件方便后期修改。8.5 演示前的准备工作毕设答辩前一定自己完整走一遍演示流程。建议准备一份“演示脚本”包括用患者账号提交一个问诊、切换到医生账号接诊并开方、切换到药师账号审核再回到患者账号完成购药。这五个步骤十分钟能讲完但完整展示了闭环业务。如果把所有功能点平铺演示反而显得没有重点。9. 代码部署与启动要点毕设系统通常需要在自己电脑上完整跑起来。下面给出一份最小启动指南。9.1 后端启动1. 创建数据库CREATE DATABASE medical_platform DEFAULT CHARACTER SET utf8mb4; 2. 导入 sql/medical_platform.sql 脚本。 3. 修改 application.yml 中的数据库用户名密码。 4. 运行 MedicalApplication.java 的 main 方法。 5. 访问 http://localhost:8080/doc.html如果集成了 Knife4j 或 Swagger则可以查看接口文档。 测试一个接口是否可用curl http://localhost:8080/api/user/info/{id} -H Authorization: Bearer token如果返回 JSON 数据说明后端启动成功。 ### 9.2 小程序端启动 1. 打开微信开发者工具导入小程序项目目录。 2. 在 utils/request.js 中将 BASE_URL 改为后端的局域网地址例如 http://192.168.31.25:8080/api。 3. 在开发者工具详情中勾选“不校验合法域名”。 4. 编译运行进入登录页面。 需要注意真机预览时手机和电脑必须在同一局域网内否则无法访问后端接口。这是联调中出现“真机请求失败”的最常见原因。 ## 10. 关于源码与进一步学习的建议 从一个开源毕设项目的角度拿到源码后不要急着跑起来先做四件事 1. **看数据库脚本。** 认真读每张表的字段和注释理解核心业务的建模思路。 2. **看状态字段。** 找到所有用了 int 状态字段的表梳理状态之间的流转关系。 3. **看接口文档。** 如果项目里集成了 Swagger 或 Knife4j把核心接口全部过一遍记录每个接口的作用。 4. **改一个功能点。** 比如把“医生接诊后自动发送欢迎语”改成“医生接诊后发送一段项目自定义的内容”通过改这段代码快速熟悉前后端交互。 真正拉开毕业生差距的不是代码量而是能不能把业务逻辑讲清楚。在线问诊与电子处方流转平台这个选题胜在业务链完整、角色分明、状态流转清晰。把数据库设计和几个核心接口的实现原理弄明白答辩时基本能把老师的问题全部接住。 如果你是想快速开始优先把患者端问诊和医生端开方这两个闭环跑通再扩展药师审核、订单支付和后台管理。后面这几个模块其实是第一个闭环的复制和扩展难度不会跳跃式上升。 祝各位顺利通过毕设。代码之外把业务流程理解透才是这个项目带给你最大的收获。建议收藏备用做的时候遇到问题可以回来对照排查。