ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

酒店管理系统需求文档怎么写:从角色权限到状态机的完整指南

酒店管理系统需求文档怎么写:从角色权限到状态机的完整指南 简介一份面向软件工程课程设计、毕业设计及酒店信息化项目的酒店管理系统需求文档适合开发人员、产品经理及计算机相关专业学生参考。文档完整记录系统建设背景、编写目的、任务概述、开发环境及功能模块规划重点给出客房类型、客房信息等核心模块定义并包含业务流程图、前置条件与需求说明可作为需求分析阶段的结构化模板。资源包共1个doc文件大小约58KB内容紧凑、目录层级清晰便于直接查看和借鉴。已有243人学习下载适合需要快速梳理系统范围、撰写需求说明或搭建项目文档框架的读者。1. 酒店管理系统需求文档从零开始定义一家酒店的后台酒店管理系统需求文档.doc这个文件名看起来像是某个项目开始时的产物但真正有用的不是那个.doc后缀而是里面是否把“酒店管理”四个字的业务含义拆成了开发团队能执行的需求。我见过太多需求文档写着“支持预订、入住、退房”结果开发做到一半发现房态、房价、挂账、夜审这些概念根本没人定义清楚。这篇文要讲的是一份合格的酒店管理系统需求文档应该怎么组织结构怎么把角色、数据、流程、接口、非功能需求落到能复现、能验收的程度。不管你是产品经理、架构师还是刚被拉进酒店项目的开发下面的写法都适用。2. 需求文档的结构与角色模型2.1 为什么酒店管理系统的需求文档要先画角色权限矩阵酒店管理系统和普通电商后台最大的区别是同一个动作会被多个角色以不同权限执行而且常常发生在同一个操作界面上。比如“修改房价”前台可以改当天某个房间的售价销售经理可以改协议单位的合同价财务可以改入账科目而店长则需要审批折扣率超过20%的调整。如果不先在需求文档里定义角色权限矩阵开发时只能靠猜测测试时也无法列出有效的权限用例。我一般会在需求文档的第二部分第一部分是背景与目标放置一个矩阵表行是功能模块列是角色单元格填的是“查看/新增/修改/删除/审批/导出”等操作。在表格上方写清楚规则数据级权限只能看本酒店的、字段级权限不能看客人手机号、操作级权限只能提交不能审核。下面是一个简化示例功能模块前台客房主管财务店长房态查看查看查看/修改查看查看/修改散客预订新增/修改/取消查看查看查看价格调整修改门市价修改门市价查看审批折扣20%挂账调整查看查看新增/修改审批夜审执行查看查看执行/回滚查看提示权限矩阵不建议只画功能级至少要到“字段级”。否则后面写接口时每个接口都要重复争论“这个字段谁能写”。角色定义完成后还需要给每个角色写一段“角色卡片”包括角色职责、典型操作、常用报表。比如前台的典型操作是“为到店无预订客人开房”这会引出“无预订入住”这个特殊流程。客房主管的典型操作是“修改房态为维修房”这又引出了“维修房不计可售房”的规则。这些内容直接决定了需求文档里用例的覆盖面。2.1.1 角色与用例角色矩阵不能只停留在表格建议用用例列表将角色与功能场景绑定。每个用例用一段结构化描述至少包含用例编号、角色、前置条件、触发事件、主流程、异常流程、后置条件。下面是一个用例的写法示例用例编号: UC-021 用例名称: 非协议单位挂账消费 角色: 前台收银/财务 前置条件: - 客人已离店或仍在住 - 当前订单无未结清的挂账记录 触发事件: 客人要求将某笔费用录入到公司挂账账户 主流程: 1. 前台选择订单中的费用项 2. 系统校验该订单未完成结账 3. 前台选择挂账单位并输入挂账备注 4. 系统校验挂账单位信用额度未超限 5. 系统生成挂账凭证并将费用状态标记为“待结算” 异常流程: - 挂账单位已停用提示并禁止选择 - 信用额度不足提示余额转为“待审批” 后置条件: 挂账凭证进入财务审核列表费用从当天应收中移除这段描述里的“信用额度未超限”就是一个隐含的需求决策来源。开发时这个条件会映射到一张挂账额度的配置表测试时它可以作为边界值测试的输入。需求文档里的每一个用例都应该达到这种可测试的程度而不是写“支持挂账”四个字。2.2 用实体关系图锁定核心数据对象需求文档不是设计文档但至少要给出核心数据对象之间的关系。酒店管理系统最核心的实体是“房间”、“订单”、“账务”。房间与订单是1对N还是N对N一个房间在同一个时间段只能有一个在住订单但在预订状态下允许被多个预订锁定。订单与账务是1对1还是1对N一个订单可以有多笔账务房费、押金、赔偿、餐费账务之间还有冲销关系。这些关系如果不写清楚数据库模型怎么建都会出问题。我在写这类文档时会用文本画出最小实体关系顺便定义每个实体的关键字段。不要用复杂工具Word里画一个简单的表格加文字说明就可以。2.2.1 房间、订单、账务的最小数据字典数据字典的粒度不需要到数据库级别但字段名、类型、是否必填、说明必须明确。下面是一个房间表的最小数据字典示例字段名类型必填说明room_idstring是房间物理编号如 12A-08floorint是所在楼层room_typestring是关联房型编码statusenum是可用/占用/脏房/维修/预留is_smokingbool是是否可吸烟房max_guestint是最大入住人数注意“status”这个字段枚举里包含了“预留”它和“占用”的区别在于预留状态可以撤销且不需要结账而占用状态必须走退房流程。这个区别会直接影响后面房态图的定义。数据字典后面可以加一列“监管要求”比如“客人证件信息需要脱敏展示”这就是从需求阶段绑定合规要求。订单表的最小数据字典则要包含订单号、入住人、联系手机、抵店时间、离店时间、房间类型、间数、房价码、总金额、支付状态、订单状态。订单状态单独用状态机描述因为它是整个系统最复杂的部分之一。2.2.2 状态机的定义与流转订单状态至少要覆盖待确认、已确认、办理中、在住、已结账、已取消、未到店No-show。光列状态不够还要定义每个状态的流转条件和操作角色。比如“已确认”到“办理中”需要客人到达前台并出示证件“办理中”到“在住”需要完成押金预授权。状态机可以用表格描述也可以用代码注释放在用例里。下面是一个伪代码形式的状态迁移表# 订单状态迁移定义需求层面 TRANSITIONS { pending: [confirmed, cancelled], # 待确认可被确认或取消 confirmed: [checking_in, no_show, cancelled], # 确认后超时未到店转no_show checking_in: [in_house, pending], # 办入住可回退到待确认 in_house: [checked_out], # 在住只能退房不可回退 checked_out: [archived], # 已结账后归档 no_show: [cancelled, archived], # 未到店可取消或直接归档 }这个字典里有一条值得注意checking_in可以回退到pending。为什么因为客人可能在前台拿着身份证但最终没有完成押金付款系统需要在超时后释放房间。这种边界在需求评审时经常被忽略写在状态迁移表里之后后端实现就不会把状态做成一个简单的字段更新而会引入一个状态机引擎或至少一层状态校验。3. 业务功能需求的可落地写法这一章集中写预订、入住、退房、房态、房价这些核心业务。需求文档最容易被挑刺的就是“用例写得太粗”或“规则与流程脱节”。我推荐的做法是每个业务域先用一段“业务规则”把硬性约束写在前面然后用流程图文字版描述正常流程最后用表格列出异常分支。3.1 预订与入住流程的用例文档预订流程的起点可能来自电话、前台、OTA在线旅行社渠道。奇怪的是很多需求文档只写“散客预订”忽略了OTA渠道带来的差异。OTA渠道送来的订单通常包含一个外部单号客人可能已经提前支付所以结账时不能要求客人再付房费。这些差异应该在用例的前置条件里写清楚。我们来看一个预订用例的完整写法用例编号: UC-003 用例名称: OTA渠道订单办理入住 角色: 前台 前置条件: - OTA订单已同步至PMS状态为“已确认” - 房间已分配房态为“可用”或“脏房” 触发事件: 客人报OTA订单号或手机号到店 主流程: 1. 前台输入OTA订单号系统展示订单详情 2. 系统校验订单中的入住人是否与OTA同步的一致 3. 前台录入入住人证件信息系统调用身份证识别接口 4. 系统校验预订房间未处于“维修”或“占用” 5. 前台收取押金预授权或扫码 6. 系统将订单状态改为“在住”房态改为“占用” 异常流程: - OTA订单已支付但系统未标记前台点击“同步支付”后继续 - 入住人证件不符拒绝入住并联系OTA客服 - 押金预授权失败可改用现金或取消入住 后置条件: 订单状态“在住”产生一条入住记录房间状态“占用”这段用例里“系统调用身份证识别接口”是一个常见的集成点。在需求文档中应该给出一段接口约定示例比如请求和响应的JSON结构。这样开发时不用再翻另外的对接文档。{ api: /api/guest/idcard, method: POST, request: { image_base64: ..., side: front }, response: { code: 0, data: { guest_name: 张三, id_number: 110101199001010011, birthday: 1990-01-01, address: 北京市... }, message: success } }这里的code字段要定义成统一错误码后面接口设计会直接复用。要注意真实身份证识别服务可能返回多个候选结果需求文档里需要额外说明“当候选结果数大于1时界面弹窗让操作员选择”。3.1.1 主流程与异常分支主流程通常大家都写得出来异常分支才是区分文档好坏的关键。以入住为例至少还要考虑以下几种情况多个客人同住一个房间但只登记一个主绑卡人客人没有带身份证房间还在脏房状态但客人已经到店预授权成功但消费金额超过预授权额度。这些情况在文档中写出来之后测试人员能直接根据异常流生成测试用例。我习惯把异常分支用表格归类比如异常编号异常条件系统行为后续动作EX-01客人无身份证支持输入护照/临时证件号但需上传证件照片留下备注转交主管审核EX-02房间脏房提示“预计可用时间”允许等待或换房若换房走换房流程EX-03预授权超限提示重新预授权或转现金押金更新押金记录EX-04重复入住已关联有效订单提示已有订单禁止重复创建进入原订单办理这些表格看起来是需求文档里的常规内容但在评审时最有价值因为每一行都对应一个真实场景。开发也能从这些异常分支反推出需要哪些校验服务、状态字段和警告提示。3.1.2 订单状态变更的条件订单状态变更条件要和上面的状态机保持一致。需求文档里建议用一张“状态-操作”权限表来限定谁能触发状态变更。例如“取消订单”不是所有角色都能执行的已确认订单被客人在入住当天取消前台可以直接取消但如果客人已经办了入住并开始计费取消操作就不存在只能走退房和账务减免。这些业务限制需要准确体现在文档里。一个常见错误是把“取消”和“退款”混在一起。取消是订单状态退款是账务操作。需求文档要分开写取消时是否产生违约金由房价码决定退款路径由支付渠道决定。建议在文档中增加一个“取消策略”参数表按渠道、房型、距离入住时间定义不同的取消费用。这样后端实现时取消接口只需要读取策略并计算费用而不是写死在代码里。3.2 房价与房态管理规则房价管理是酒店管理系统中真正难的部分。同一个房间可以有门市价、协议价、会员价、企业合同价、促销价而且不同日期的价格可能不同。需求文档最少要定义清楚价格是按“房价码日期房型”维度存储的变更要有日志并且历史房价不能删除只能停用。否则后续报表统计收益时历史数据会错。3.2.1 价格策略的参数设置一个可操作的需求写法是给出价格策略的表结构示例和配置界面要求。表结构可以这样写-- 房价计划表 (rate_plan) CREATE TABLE rate_plan ( plan_id INT PRIMARY KEY, plan_name VARCHAR(100), -- 门市价/协议价/会员价 channel_id INT, -- 渠道0表示所有渠道 room_type_id INT, -- 关联房型 start_date DATE, -- 生效日期 end_date DATE, -- 失效日期 weekdays VARCHAR(10), -- 如 1-5 或 6,0 base_price DECIMAL(10,2), -- 基准价 min_price DECIMAL(10,2), -- 最低卖价 max_price DECIMAL(10,2), -- 最高卖价 is_active TINYINT -- 是否启用 );注意这里用了min_price和max_price它们决定了折扣边界。需求文档里要注明不同角色能操作的价格范围不同。比如前台只能设置base_price到max_price之间的折扣店长可以突破min_price但需要审批。这个规则在权限部分的矩阵表里已经体现但在这里要补充具体数值逻辑。价格策略还需要考虑“连住优惠”、“早订优惠”、“会员折扣”的叠加顺序。建议在需求文档中用一段文字明确优先级先应用渠道促销再应用会员折扣最后应用连住优惠。并声明所有价格最终不能低于min_price。如果你希望让开发少返工可以加一行公式最终销售价 max(渠道促销后价, 会员折扣后价, 连住优惠后价) 但 最终销售价 min_price且 max_price这里有一个隐藏逻辑三个优惠不叠加而是取对客人最有利的。这是很多酒店业务中的默认规则但不写清楚开发就会做成叠加产生超低价订单。3.2.2 房态更新的触发点房态管理看起来简单但漏一个触发点就会导致房间超卖。常见的房态包括可用、脏房、维修、占用、预留、限制。需求文档要把每一个房态变化的触发点列出来并标注是由系统还是操作员触发。比如客人退房结账后房间从“占用”变为“脏房”由系统自动触发。客房主管报修后房间从“可用”变为“维修”由操作员手动触发。维修完成后房间从“维修”变为“脏房”因为虽然能走人但还没打扫。夜审时所有超过规定时间未入住的“预留”房自动释放为“可用”由系统定时任务触发。这里还要引出一个关键规则脏房不能入住但可以分配。分配指的是将房间与订单绑定但物理上客人还没进房间。需求文档中应该定义“分配房间”和“客人到房”两个时间点这样才能处理换房和超时未到的场景。我用一个状态转换表来归纳当前状态事件新状态触发者可用分配房间预留前台预留客人到房并且完成入住登记占用系统占用办理退房并结账脏房系统脏房打扫完成并检查可用客房主管维修维修完成通知清扫脏房系统这个表格会直接指导前端页面上每个操作按钮的禁用/启用逻辑。例如房间状态为“预留”时桌面端不展示“入住”按钮不对其实要展示。但是“清扫”按钮必须禁用。这些细节需求文档里不用全写但状态图给出来之后开发自然能推出来。4. 非功能需求与验收标准功能需求之外不可能等系统上线后再补性能和安全。酒店管理系统的使用者是7x24运行的前台可能同时面对10个客人排队但后台还有OTA渠道每秒变化房价。非功能需求写少了后续动辄要重做。4.1 性能、并发与数据一致性先估算性能指标。假设一家拥有300间房的酒店入住率90%前台一个高峰小时办理90个入住和90个退房那么平均每20秒有一个入住或退房。这个并发量很低但问题在于查询房态时酒店管理人员可能会快速点击多个房型查价。通常建议单机事务TPS做到50读接口做到200。真正的压力来自连锁集团如果总部门店管理平台需要实时汇总所有门店数据那就要按门店数量乘以每个门店的轮询频率来设计。4.1.1 高峰时段的QPS估算写需求文档时可以直接给一个简单的估算表让开发确认算法。比如场景单次操作耗时秒每小时次数峰值并发估算QPS散客入住39055散客退房29044房价查询0.56001010OTA房价同步124088账务查询112066估算QPS 每小时次数 / 3600 再乘一个峰值系数比如3。拿“散客入住”来说90/36000.025峰值系数5得到0.125不对这样很低。其实可以直接用并发数来请求。更合理的写法是给出响应时间要求核心接口P95不超过500msP99不超过1s报表查询不允许超过3s带缓存。写一个简单的断言式需求并发要求: 高峰时段可支持50个并发用户同时操作 单条订单提交接口响应时间 P95 500ms 房态查询接口 P95 200ms 报表导出类操作使用异步任务允许等待30s。这个比单纯的QPS数值更直观测试也容易做。4.1.2 事务边界设计酒店管理系统经常出现“同一间房在同一时期被两个订单同时占用”的问题。防超卖不能只靠数据库唯一索引因为订单与房间之间还有换房、加床这类额外操作。需求文档里需要定义清楚事务边界即什么环节必须强一致什么环节允许最终一致。比如“下单锁房”必须是强一致事务而“房态同步到OTA渠道”允许最终一致。可以用一条SQL示例来展示锁房时的原子操作建议-- 预占用房间的原子条件更新示例具体由后端实现 UPDATE room_status SET status reserved, reserved_order_id #{orderId}, version version 1 WHERE room_id #{roomId} AND status IN (available, reserved) AND version #{oldVersion} AND (reserved_order_id IS NULL OR reserved_order_id #{orderId});这段SQL里的version字段是一种乐观锁实现思路。需求文档不要求写SQL但如果写出来能让开发和测试更容易理解边界。文档中可以说明如果这个UPDATE影响行数为0说明房间已被抢需要提示用户换房。4.2 接口文档与字段约定需求文档并不等同于接口文档但至少要约定接口风格和错误码。许多团队用一份Word写需求接口定义放在YAPI/Swagger里这种做法没问题但需求文档必须给出关键接口的请求响应示例否则后续模块间联调时会产生字段理解偏差。4.2.1 从需求文档到接口定义的映射每个用例编号都可以作为接口设计的前缀标记。比如UC-003对应/api/order/checkin。需求文档中可以加入一个接口清单表标明接口所属用例、方法、路径、简要说明接口标识关联用例方法路径说明API-01UC-003POST/api/order/checkinOTA订单入住API-02UC-021POST/api/order/foliotransaction挂账消费API-03UC-045PUT/api/room/{id}/status修改房态API-04UC-052GET/api/rate/plan查询房价计划这个表能确保需求评审时不会遗漏接口。没有映射到的用例开发可能会漏掉。4.2.2 统一返回结构与错误码需要定义统一的JSON返回结构。推荐的做法是{ success: true, code: SUCCESS, message: 操作成功, data: {}, requestId: 8f7b3a8e-1024-4a9b-9f00-11f2d3c4e5a6 }其中requestId用于链路追踪。错误码设计要求分模块和严重级别例如1001表示参数错误2001表示订单状态不允许当前操作3001表示房价超出范围。需求文档中应规定所有错误码必须出现在文档的附录中并包含中文说明。文档里可以给出错误码表格错误码严重级别消息模板业务含义1001WARN参数{field}不能为空必填字段缺失2001ERROR订单状态不允许该操作当前状态为{status}状态机校验失败2002WARN房间已占用请更换房间并发抢房失败3001ERROR折扣低于最低售价需审批价格策略校验失败这些错误码不仅要在接口文档中使用前端也需要根据错误码决定弹窗还是静默处理。如果需求文档里提前定义了前后端并行开发时就不会出现“前端等待后端定义错误码”的尴尬。5. 用Word .doc高效维护需求文档的技巧标题中的.doc提示我们很多团队还在用 Word 写需求。.doc是旧格式在兼容性、版本管理上都有不少坑。但现实是酒店这类传统行业的客户经常要求交付.doc。这里给出一些让别人愿意看、也方便维护的实操建议。5.1 样式、目录与修订模式不要直接用普通段落写需求。先从“标题1”开始分层让 Word 的导航窗格能折叠这样评审会非常快。所有图、表、代码示例都用“插入题注”编号。很多同事喜欢手打“表1”“表2”一旦删除某个表编号就乱了。正确做法是右键表格选择“插入题注”Word 自动生成编号。另外把正文里的交叉引用设置为“引用-题注”这样修改后编号能自动刷新。对于.doc文件建议在编辑时保留一份.docx以保存完整功能最终交付时另存为.doc。使用 LibreOffice 可以批量转换libreoffice --headless --convert-to doc *.docx这条命令会把当前目录下所有.docx转换为.doc。如果需要逆向转换用--convert-to docx即可。注意.doc和.docx的转换可能丢失部分图表格式所以转换完成后要抽查几页。另外有的浏览器无法预览.doc可以额外导出一份PDF用于在线评审。5.2 版本变更历史表与评审记录需求文档最怕的是“最终版_final_修订3.doc”这种命名。建议在文档首页第一个表格放“版本变更记录”每修订一次就加一行包含日期、版本、修订人、变更摘要。比如日期版本修订人变更摘要2023-01-05v0.1李工创建初始版本2023-01-12v0.2王蕾增加房态状态机定义修订挂账流程2023-01-20v1.0李工评审通过标记基线版本同时每次评审都会产生一堆讨论把这些结论记录在“评审结论”章节下包括评审日期、参与人、问题描述、结论。这样后续遇到争议时可以直接追溯当时为什么这样决定。能坚持做到这一点的团队需求返工率会明显下降。另外建议在文档末尾放一个“待确认问题”列表列出暂时无法决策的点每个问题都注明提出日期、提出人、期待哪一方协助。这让需求文档从静态论文变成动态协作工具也方便项目经理追踪风险。最后如果可能将需求文档中的状态机、权限矩阵、数据字典导出成CSV或YAML放在仓库的/docs目录下与代码一起版本控制。Word里的表格是给人看的结构化的YAML是给程序用的。每次修订需求时脚本生成的对照报告能直接暴露文档和代码之间的漂移。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进