Django+LLM大模型驱动的出租车供需平衡优化系统设计
每年三四月份找我咨询毕业设计的同学突然变多问得最密集的题目就是DjangoLLM大模型滴滴出行分析方向的出租车供需平衡优化系统。这个名字虽然长拆开其实就是三件事用Django搭一套完整的Web后台用大数据分析处理订单和车辆数据再用大模型接口让系统具备智能问答和分析报告能力。很多人一听说滴滴出行分析第一反应是以为要碰真实用户隐私和商业数据其实毕业设计真正要做的是拿脱敏公开数据或模拟数据走通一条完整链路。这个系统解决的是打车场景里非常典型的供需错配问题早晚高峰某些区域大量乘客叫不到车同时另一些区域车辆空驶空转。系统通过历史订单数据预测未来一小时的热点区域和车辆缺口给出调度建议再用大模型把统计结果翻译成自然语言汇报。适合的人群大概有三类正在纠结毕设选题的计算机应届生想做数据分析方向又想蹭一点大模型热度的同学以及需要快速搭建一个可用于答辩demo的开发者。下面我按自己做项目时的思路把从选题到交付的全过程拆开讲一遍。1. 先想清楚这个项目到底在做什么选题逻辑与功能拆解1.1 为什么供需平衡优化是毕业设计里的高性价比选题在出行场景里早晚高峰、节假日、恶劣天气下打车难几乎是必然现象。本质上是供需在时间和空间上匹配错位乘客在商圈、车站、机场把手机举了半天叫不到车而两三公里外的区域却停着一排等待派单的空车。用数据科学的话说这是典型的供需失衡也是出行平台最想优化的核心问题之一。毕业设计选这个方向天然就有几个好处。第一业务场景足够真实评委老师一听就懂不需要你花五分钟解释我做了个什么系统。第二有明确的量化指标比如订单应答率、平均等待时长、区域供需比这些都能直接用图表展示。第三可以往上面叠技术层级底层是Django的数据管理中层是机器学习模型做预测顶层是LLM做智能化交互每个技术点都有落点不会让人觉得是硬凑关键词。从我实际辅导经验看这个题的完成度上限很高但下限也不低。有人用纯统计方法加规则引擎就能做出一个效果不错的系统有人硬套神经网络最后连数据都跑不动。我的建议是把重心放在能不能形成闭环上有数据、有分析、有预测、有优化建议、有可视化展示五步走通这个题就立住了。1.2 三层技术栈Django、大数据分析、LLM各负责什么我习惯把这类项目理解成三层结构。第一层是Web应用层用Django来做。为什么选Django因为它自带ORM、Admin后台、用户认证和表单处理开发效率极高。毕设不同于工业级项目核心诉求是快速交付、稳定演示、方便二次开发Django恰好全部满足。项目大了也不会乱App模块可以按业务拆比如订单分析、预测、调度、LLM问答各放一个应用。第二层是数据层也是大数据这个关键词真正落地的地方。这里要澄清一个误区毕业设计里的大数据不一定要上Hadoop/Spark集群。更接地气的做法是用pandas处理几百万条订单数据做分块读取、预聚合、特征提取最后把统计结果落到数据库里。如果你的数据规模真的上千万条再引入Spark离线计算也不迟否则毕设期间维护一个集群就是给自己挖坑。第三层是智能化层也就是LLM大模型。LLM在这个系统里不是用来做预测的而是用来沟通的。它能干的事情包括根据当天统计指标生成交通分析日报、回答XX商圈现在好不好打车这类自然语言问题、把调度建议解释成人话。LLM的引入能让系统看起来活了而不是一堆冷冰冰的图表。三层各司其职演示的时候逻辑非常清晰Django管界面和流程数据层管分析和预测LLM管智能表达。1.3 系统功能清单从演示视角倒推出要做什么我每次带项目都会先让同学写一份演示脚本从答辩场景倒推系统该有哪些功能。按照这个思路这套系统至少有六个模块不能少。第一个是数据概览大屏打开首页就能看到总订单量、总营收、订单完成率、当前空闲车辆数等核心指标。第二个是区域热力图在地图上展示各区域订单热度帮用户直观看出哪里在爆单。第三个是供需预测模块选择某个区域和时间段系统给出未来一小时需求量和供给量的曲线。第四个是调度任务管理系统自动生成调度建议调度员可以查看、确认并下发任务。第五个是LLM智能问答有一个类似聊天窗口的界面用户可以输入今晚十点高铁站附近需要调度多少辆车这类问题。第六个是管理后台维护司机、车辆、区域信息以及查看操作日志。以上六个模块构成了完整的业务闭环。一个模块对应一个技术亮点写论文的时候每个模块都可以作为一章展开页数和内容量都不用愁。反过来如果只做单个功能比如只做一个预测模型那论文会很单薄答辩也容易冷场。2. 数据链路怎么搭从原始订单到可用于预测的特征2.1 数据来源与模型设计别一上来就盲写模型数据是整套系统的地基也是最容易让项目翻车的环节。我自己见过太多项目死在数据集上想法很好结果数据一跑全是空值当场心态就崩了。毕设选题里出现的滴滴出行分析一般建议使用公开的脱敏订单数据集或者是按真实数据分布伪造的模拟数据。网上有不少开放的网约车订单数据常用的字段包括订单ID、上车时间、下车时间、上车点经纬度、下车点经纬度、订单状态、车费金额。如果你的学校对数据来源有要求就明确在论文里写清楚数据已经脱敏用于学术研究。实在找不到合适数据也可以自己写脚本生成模拟数据只要保留真实场景的分布规律即可。对应的Django模型设计我建议至少建三张表from django.db import models class Region(models.Model): name models.CharField(max_length50, uniqueTrue) geohash_prefix models.CharField(max_length10, db_indexTrue) center_lng models.FloatField() center_lat models.FloatField() class Order(models.Model): order_id models.CharField(max_length64, uniqueTrue) region models.ForeignKey(Region, on_deletemodels.SET_NULL, nullTrue) start_time models.DateTimeField(db_indexTrue) end_time models.DateTimeField(nullTrue, blankTrue) status models.CharField(max_length20, db_indexTrue) fare models.FloatField(nullTrue, blankTrue) class Car(models.Model): plate_no models.CharField(max_length16, uniqueTrue) region models.ForeignKey(Region, on_deletemodels.SET_NULL, nullTrue) status models.CharField(max_length20, defaultidle) updated_at models.DateTimeField(auto_nowTrue)订单表存出行记录车辆表存车辆实时状态区域表存网格信息。三张表的关系很清晰后续做聚合统计、预测特征都能直接取数。别为了炫技把表设计得特别复杂没有意义。2.2 清洗、网格化与特征工程预测准不准一半看这里原始数据直接用来训练模型会出问题必须经过清洗和特征工程。很多人以为这一步是浪费时间实际上预测准不准一半看特征一半看算法。清洗阶段主要处理四类问题。一是缺失值比如订单没有下车时间可以根据时长分布做插值或者直接标记为异常样本。二是重复数据同一笔订单出现两条记录要按订单ID去重。三是异常经纬度坐标超出城市范围的就应该剔除。四是时间字段的时区问题数据库存储统一用UTC展示时再转本地时间避免模型训练时出现时间偏移。网格化处理是城市数据分析里很实用的一招。经纬度是连续值直接建模没法体现城市区域结构。比较简单的做法是使用Geohash编码将经纬度转成字符串前缀比如6位Geohash对应大约一公里见方的网格8位对应一百多米的网格。毕设一般用6位就够了既能体现空间信息又不会生成太多空区域。特征工程阶段我常用的一套组合如下表所示特征维度具体特征说明时间特征小时、星期几、是否节假日、是否早晚高峰订单量会有明显的周期性空间特征区域ID、周边POI数量、是否机场/车站/商圈不同区域的供给需求差异很大历史供需特征过去1小时订单量、应答率、空闲车辆数、平均等待时长滑动窗口体现近期趋势外部特征天气代码、温度、降水量可选如果数据集里没有就先不做滑动窗口是时序预测里很关键的一招。比如要预测未来一小时某个区域的需求量就把过去1小时、过去3小时、过去24小时同时间段的数据都作为特征相当于让模型学到短时波动和长期周期性。2.3 数据量大怎么办预聚合、分块处理与定时任务大数据的大字在毕设里主要体现在处理方式而不是集群规模。数据量在百万量级时最简单的做法是分块读取。import pandas as pd chunk_size 100000 for chunk in pd.read_csv(orders.csv, chunksizechunk_size): # 清洗逻辑 chunk chunk.dropna(subset[start_time]) # 分块入库 records chunk.to_dict(records) Order.objects.bulk_create( [Order(**{k: v for k, v in r.items() if k in fields}) for r in records], batch_size5000 )用pandas的chunksize参数分块读然后用Django ORM的bulk_create批量入库比逐条插入快几十倍不止。如果数据量太大导致MySQL写不进去还可以先在本地用pandas做预聚合只把每小时、每区域的统计指标入库原始明细存CSV备份。预聚合是精髓。比如区域订单量统计表不需要保存每一笔订单只要每小时跑一次任务统计各区订单量、应答率、空闲车辆数存到一张简单的统计表里即可。查询大屏数据时直接查统计表秒开。定时任务可以用Celery加Redis也可以用更轻量的APScheduler。毕设演示求稳我更喜欢APScheduler不依赖额外消息队列一个进程就能跑起来。3. 供需预测与调度优化核心算法不写复杂也能出彩3.1 供需指标拆解先定义失衡再谈优化优化这个词听起来抽象落到系统里就是几个公式。我常用的核心指标有三个。第一个是区域供需比公式是空闲车辆数除以订单需求量。比值小于1说明供不应求大于1说明运力过剩。第二个是订单应答率计算方式是成功接单的订单数除以总下单数。应答率越低乘客体验越差。第三个是平均等待时长统计从下单到司机接单的时间间隔。实际项目里可以设置阈值供需比低于0.8判定为运力不足高于1.5判定为运力过剩。这样系统就能自动标记出问题区域不需要人工盯数据看。答辩的时候评委问你你凭什么说这个区域缺车你把这段规则讲清楚就行很有说服力。3.2 需求与供给预测时间序列的三大常见错误预测模块是这个系统里技术含量最高的部分。我不建议一上来就上LSTM或者Transformer毕设的时间和技术积累有限LightGBM、XGBoost这类梯度提升树模型在表格数据上往往比深度学习模型效果更好也更容易调参。训练一个需求预测模型核心流程不复杂import pandas as pd from xgboost import XGBRegressor from sklearn.metrics import mean_absolute_error df pd.read_csv(train_features.csv) df df.sort_values(start_time) # 按时间排序不能乱序 features [hour, weekday, is_holiday, region_id, last_1h_order, last_1h_empty_car, avg_wait_time] X df[features] y df[future_1h_order] split_idx int(len(df) * 0.8) X_train, X_test X.iloc[:split_idx], X.iloc[split_idx:] y_train, y_test y.iloc[:split_idx], y.iloc[split_idx:] model XGBRegressor(n_estimators300, learning_rate0.05, max_depth6) model.fit(X_train, y_train) y_pred model.predict(X_test) print(MAE:, mean_absolute_error(y_test, y_pred))这里有三处坑都是我反复踩过的。第一坑是随机乱打乱数据集。时序数据跟普通回归数据不一样今天的样本不能跟下个月的样本混在一起随机切分否则模型会通过时间泄漏取巧线上效果翻车。正确做法必须按时间顺序切分前80%训练后20%验证。第二坑是特征穿越。构造特征时用了未来时刻的数据模型在训练集上表现极好但一到真实预测就废。比如预测未来一小时需求结果把这一小时的真实订单量放进了特征这叫开卷考试没有任何意义。特征只能用历史时刻的数据。第三坑是只看准确率不看业务效果。对预测模型来说MAE平均绝对误差和RMSE均方根误差比R²更直观。我一般会额外计算一个方向命中率预测值偏高或偏低的方向是否跟真实情况一致。对调度系统来说方向对了才有用数量差一点可以接受。3.3 调度策略引擎用规则生成可解释的调度方案预测出来以后怎么变成可执行的车辆调度方案这里我用的是规则引擎加贪心算法简单可控还能向评委解释。def build_dispatch_plan(regions, pred_demand, pred_supply, safety_margin5): plan [] shortage {} surplus {} for r in regions: demand pred_demand.get(r, 0) supply pred_supply.get(r, 0) if supply 0 or supply / max(demand, 1) 0.8: shortage[r] max(demand - supply - safety_margin, 0) elif supply / max(demand, 1) 1.5: surplus[r] supply - demand - safety_margin for target, num in shortage.items(): if num 0: continue source find_nearest_surplus_region(target, surplus) if not source: continue dispatch_num min(num, surplus[source]) if dispatch_num 0: plan.append({ from_region: source, to_region: target, car_count: dispatch_num }) surplus[source] - dispatch_num return plan这段逻辑的核心是三个关键词缺口、余量、安全边际。某个区域预测需求120辆车空闲只有80辆还要留5辆作为安全余量那最多允许调度35辆。优先从附近运力过剩的区域调车调拨数量不能超过对方可调出的余量。这样做出来调度方案是可解释的每一条调度记录都能回溯哪个区缺、哪个区多、为什么调这个数量。论文里写调度算法优先级排序、约束条件、终止条件都能讲清楚比一句使用神经网络优化要扎实得多。4. LLM大模型接入让系统会说话而不是只会出图表4.1 LLM在系统里的四个正确落地姿势LLM大模型是今年毕设的流量密码但我见过太多项目把LLM做成一个单纯的聊天机器人跟业务毫无关联。真正合理的做法是让LLM围绕业务数据干活下面四个方向是我验证过比较靠谱的。第一是自然语言问答。用户在聊天窗口输入朝阳区哪里最难打车系统先通过规则或检索拿到对应的数据再让LLM组织语言回答。第二是自动生成分析报告。把最近一周的订单量、应答率、调度记录喂给LLM自动生成一篇像样的周报。第三是调度建议解释。系统生成调度方案后由LLM解释为什么要调车、从哪个区调到哪个区。第四是运营知识库辅助决策。把一些经验规则、历史案例整理成知识库用户提问时先检索相关内容再结合数据回答。要特别强调一个边界不要让LLM直接算数或做预测。大模型在数值计算上极不靠谱你把数据喂给它它就可能给你编一个数字。数据计算还是交给pandas和模型LLM只负责表达。4.2 本地部署与API两种接入方式怎么选LLM接入有两种主流方式我建议做成可配置的答辩现场可以灵活切换。方式一是本地部署开源模型。用Ollama加载Qwen2.5-7B-Instruct这类模型完全离线运行不依赖外网答辩现场绝对不会出现网络异常的尴尬。缺点是对电脑配置有要求至少16G内存模型推理速度也就每秒十几个字。方式二是调用云端大模型API比如通义千问、智谱清言、DeepSeek等国内厂商提供的接口。优点是速度快、效果稳定、不需要好显卡缺点是演示时必须保证网络可用而且账号余额要提前充值免费额度经常不够用。我一般建议项目代码里写一个抽象层配置文件里切换后端# settings.py LLM_PROVIDER local # 可选 local / cloud LLM_LOCAL_URL http://127.0.0.1:11434 LLM_LOCAL_MODEL qwen2.5:7b LLM_CLOUD_API_KEY # 云端模型API Key LLM_CLOUD_MODEL 然后封装一个统一的请求函数项目其他模块不用关心底层用的是本地还是云端只要调用这个函数发提示词、收文本就行。这样做的好处是学校机房电脑配置好就切本地配置差就连云端进退都有路。4.3 提示词工程与防幻觉让LLM只看真实数据说话装卸式聊天谁都会难的是让LLM不瞎编。防幻觉只有一个核心原则把真实数据直接拼进提示词要求LLM的答案严格基于这些数据而不是让它凭记忆自由发挥。def build_analysis_prompt(region_name, metrics): prompt f 你是城市出行调度助手。请根据以下真实统计数据生成一条调度建议。 要求 1. 必须基于给定的数据不得虚构数字。 2. 回答控制在80字以内先说结论再说依据。 区域{region_name} 过去1小时订单量{metrics[order_cnt]} 过去1小时空闲车辆{metrics[empty_car_cnt]} 平均应答等待时长{metrics[avg_wait]}分钟 当前供需比{metrics[supply_demand_ratio]} return prompt这样传给LLM的是结构化事实LLM只需要做总结和润色不需要做计算。就算它胡说数字部分也是从代码里取的不会影响系统真实性。如果你想让项目显得更高级一点可以引入RAG检索增强生成。思路是把历史分析报告、运营规则、典型调度案例切成文本块向量化后存进本地向量库。用户提问时先从库里检索相关片段再连同实时指标一起拼进提示词。不过毕设阶段这个属于锦上添花时间不够可以不搞用上面的模板拼接方案已经够用了。5. Django工程化落地后台、接口与可视化大屏5.1 项目结构与核心代码组织一个管不住的App就会乱Django项目最怕的是把所有代码堆在一个App里改两行就出bug。我在搭建这类系统时习惯按业务拆成五个App每个App只做一类事。ride_dispatch/ ├── manage.py ├── config/ # 项目配置 │ ├── settings.py │ ├── urls.py ├── apps/ │ ├── accounts/ # 用户与权限 │ ├── analyses/ # 数据统计分析 │ ├── prediction/ # 供需预测 │ ├── dispatch/ # 调度管理 │ └── llm_qa/ # LLM问答 ├── scripts/ │ ├── init_data.py # 数据初始化脚本 │ ├── train_model.py # 模型训练脚本 │ └── generate_report.py # 自动报告生成脚本 ├── static/ # 前端静态文件 ├── templates/ # HTML模板 └── requirements.txtanalyses模块负责读取订单数据、生成统计指标prediction模块负责训练和调用预测模型dispatch模块负责调度任务的增删改查llm_qa模块负责与大模型交互accounts模块负责登录和权限控制。五个App之间依赖关系尽量单向数据流是analyses → prediction → dispatch避免循环引用。5.2 可视化大屏ECharts地图、指标卡与实时刷新Django负责提供数据接口前端可视化我推荐用ECharts。地图热力图是这套系统的视觉核心效果非常震撼。实现步骤大概是三步。第一步在Django接口中返回按区域聚合的订单量数据格式类似[{name: 国贸, value: 120}, {name: 中关村, value: 85}]。第二步前端通过Ajax请求这个接口。第三步用ECharts的heatmap组件把数据渲染到地图上。$.ajax({ url: /api/analyses/heatmap/, type: GET, data: { date: 2024-12-20 }, success: function (res) { var chart echarts.init(document.getElementById(heatmap)); var option { series: [{ type: map, map: city, data: res.data, visualMap: { min: 0, max: 200 } }] }; chart.setOption(option); } });这里有一个我每次都要提醒的坑如果你的电脑只能离线演示记得把ECharts的JS文件下载到本地static目录不要用CDN地址。不然答辩现场断网首页直接白屏。实时刷新用一个定时器轮询就行比如每30秒请求一次最新数据。毕设场景不需要WebSocket别给自己增加复杂度。5.3 定时任务与权限演示前一定要提前验证系统里很多数据是过期的比如预测结果半小时前算的和现在算的可能完全不一样。我一般推荐每小时跑一次预测任务把未来一小时各区域的需求供给存到预测结果表。前端展示时直接读表查询压力小响应也快。定时任务的实现可以用DjangoCelery但Celery在Windows下经常有兼容问题。我的习惯是推荐APScheduler只要在Django启动时注册一个后台调度器就行没有外部依赖演示前不用额外启动几个服务。权限方面建议设置两个角色管理员和访客。管理员能查看调度任务、编辑车辆信息、触发手动预测访客只能看大屏和问答结果。用Django内置的User模型加一个profile字段就能实现写论文时这部分也能单独成一个章节。6. 交付物组合拳源码、论文、PPT与讲解怎么准备6.1 源码目录与运行说明给答辩老师省时间就是给自己加分毕设交付要求里通常包含源码、论文文档也就是标题里写的LW、PPT和讲解材料。源码这部分的重点是能跑起来。我见过太多同学的代码写得挺好结果答辩前临时跑不起来非常可惜。一个合格的源码包至少要有这些东西完整的README运行说明写清楚Python版本、依赖库、数据库配置、启动命令requirements.txt锁住所有依赖版本scripts目录下放数据初始化脚本一个命令就把测试数据导入数据库以及一份简单的测试账号列表方便评委快速登录系统查看效果。数据初始化脚本值得多花点时间。用python manage.py seed_demo_data一键生成一批带规律的模拟订单数据能让评委在演示时看到预测曲线明显跟着早晚高峰起伏这个效果比数据乱七八糟强多了。6.2 论文框架与创新点写法LW最容易丢分的地方论文部分最容易被扣分的不是字数不够而是答非所问。评委想看到的是你如何一步步解决问题不是你抄了一堆技术文档。我建议按这个框架写摘要加绪论重点写选题背景和国内外研究现状国内外现状里要提到现在大模型在交通领域的应用趋势但不能只是概念罗列。然后是关键技术介绍Django框架、机器学习、大模型相关概念各占一节这节是铺垫不要写太长。接下来是系统需求分析与总体设计画出功能结构图和数据库ER图说明模块怎么划分。然后是核心模块详细设计订单数据清洗、供需预测模型、调度策略、LLM问答流程各占一章每章都要写实现思路加核心代码片段。最后是系统测试与效果分析放可视化大屏截图和预测评估指标。创新点这部分是拿分关键。你在LLM接入方式、调度规则设计、特征工程上的具体优化都可以写成创新点。比如将大模型引入交通调度领域通过结构化数据拼装提示词的方式避免数值幻觉这句话就能当创新点写在摘要里。6.3 PPT与讲解节奏先演示再讲原理效果最好PPT不要做满屏文字我见过太多同学把论文段落直接粘到PPT上评委根本不想看。更有效的做法是PPT只放图表、架构图和关键数据每页讲一个要点。演示顺序我建议这样安排第一分钟介绍选题背景第二分钟展示系统功能架构第三到第八分钟现场演示从大屏、热力图、预测模块一路操作到LLM问答第九到第十二分钟讲核心技术和实验数据最后留几分钟提改进方向。答辩常见问题也要提前准备。比如为什么用Django而不用SpringBoot可以回答Django生态成熟、自带ORM和Admin、开发迭代快适合数据密集型应用。再比如LLM输出的结果如果不准怎么办要解释系统在提示词里嵌入了真实统计指标LLM只做语言组织不下数值结论。还有这个系统跟真实商业产品有什么区别坦诚说明数据规模和策略复杂度上有差距但整体技术流程与工业界一致。7. 高频坑位清单数据、模型与答辩现场的避坑指南7.1 数据与预测相关的坑现象排查思路解决办法训练集R²很高测试集表现很差大概率特征穿越或随机打乱了时间顺序严格按时间切分特征只用历史时刻数据模型预测值全部接近均值特征不够模型学不到模式增加滑动窗口特征和区域ID类别特征导入数据非常慢几百条数据要几分钟逐条insert没有用bulk_create改用bulk_create或分块批量导入大屏图表数据迟迟不出来接口响应慢没有做预聚合建小时级统计表查询时直接读统计结果早晚高峰的波动看不出来模拟数据分布设定太均匀生成数据时加入周期性函数让订单量按小时呈双峰分布7.2 LLM接入的坑本地模型首次启动特别慢甚至可能加载模型就要一两分钟。如果答辩现场用本地部署一定要提前把所有模型预热好不要现场从零加载。更稳妥的做法是提前录好一段完整的问答演示视频现场就算卡死也能用视频兜底。云端API常见的报错是超时和请求失败。代码里要加抛出异常后重试的逻辑重试两到三次仍然失败就降级为返回预设文案当前无法获取智能分析请稍后再试不要让用户看到一堆堆栈信息。关于幻觉我再说一遍凡是涉及数字的结论一律由代码计算LLM只负责修饰语言。这个原则写进论文里也是很大的加分项说明你对大模型的能力边界有清晰认知。7.3 Django与演示环境的坑用Django开发时默认跑在开发服务器上如果现场演示被评委问到项目能不能部署到Linux服务器你得至少知道用gunicorn加Nginx的基本配置思路。如果真要部署要注意静态文件的收集python manage.py collectstatic这步不能漏。还有设置里的调试模式DEBUGTrue时出错会显示详细报错看着很方便但演示时万一报错满屏英文堆栈会显得很不专业。建议演示前至少完整跑一遍操作流程能报的错提前排完。MySQL的时区问题也挺常见如果发现统计出来的数据和实际时间差8小时去检查Django的TIME_ZONE和MySQL连接参数统一改成Asia/Shanghai就能对齐。最后再分享一个我自己的习惯我接这种项目的时候都会先把演示脚本写出来哪怕还没开始写代码。演示脚本就是一句话对应一个页面一个操作比如打开首页大屏展示昨日订单量点击热力地图看到区域热度分布切到预测页跑出未来一小时缺口再问LLM应该怎么调车。等你把演示脚本写清楚了整个系统该有哪些功能、该存哪些表、该接哪些接口全部都会变得特别清晰。这是我踩了不知道多少次坑之后总结出来的办法希望它也能帮你在答辩现场少一点手忙脚乱多一点从容。