Files
baiyue-firstleg/firstleg/AGENTS.md
T
2026-09-03 18:05:34 +08:00

25 KiB
Raw Blame History

Firstleg Service 模块指引

职责与边界

  • Mapper 统一显式使用 @Mapper,仅由 BaiyueFirstlegApplication.java 对 com.baiyue.firstleg 根包按 annotationClass = Mapper.class 扫描;禁止恢复业务子域 Mapper 包白名单。静态门禁见根 scripts/mapper-scan-contract.mjs,模块内编译门禁见 MapperRegistrationArchitectureTest.java、BaiyueFirstlegApplicationContractTest.java。
  • 负责履约任务/分配、入库单、测量/OCR、审核后初始计价、FBA 计费、客户在途柜量统计、国内出仓履约链路,以及四期国内出仓后的船节点查询任务和节点事实。
  • 订单主数据归 order/,托盘/库位归 warehouse/,文件对象归 file/,OCR 供应商归 integration-service/;通过客户端 DTO 和内部令牌协作。
  • 入库、分柜、装柜、PDA 和出仓能力均在本模块按对应服务端契约协作;WAIT_SPLIT + APPROVED + CONFIRMED 是入库链路状态节点,不是全量验收的范围终点。财务状态仍归 finance,本模块只生产不可变费用来源和柜次成本快照。

模块入口

目标 入口
内部模块化基线与依赖分析 docs/firstleg-internal-modularization-baseline.md、scripts/analyze-firstleg-dependencies.mjs、scripts/analyze-firstleg-dependencies.test.mjs、src/test/resources/architecture/firstleg-slice-dependencies.json;只约束本服务内部包依赖,不改变部署单元或数据库边界
履约任务/分配 controller/PlatformFulfillmentAssignmentController.java、service/FulfillmentTaskService.java
入库单查询/聚合 controller/PlatformInboundOrderController.java、service/InboundOrderQueryService.java
Order 申报同步与渠道变更履约门禁 controller/InternalInboundOrderController.java 的 /order-channel-changes/validate、/order-declaration-updated,service/OrderDeclarationSyncService.java、mapper/OrderDeclarationSyncMapper.java、dto/OrderDeclarationSync.java;契约 src/main/resources/openapi/firstleg-v1.yaml,只接受内部服务令牌
平台测量/OCR 与箱规计费快照 controller/PlatformInboundMeasurementController.java、service/InboundMeasurementService.java、CartonMeasurementService.java、CustomerDimensionWeightingService.java;手工单箱测量保存实际尺寸、可选外箱修正、chargeRuleId 与 coefficientMode,计算结果以服务端返回值为准
箱唛箱码生成、打印与测量绑定 审核建单生成钩子 controller/InternalInboundOrderController.java;生成/解析 service/InboundCartonLabelService.java、repository/InboundCartonLabelRepository.java;平台与客户打印 controller/PlatformInboundOrderController.java、MerchantInboundCartonLabelController.java、service/InboundCartonLabelPrintService.java;基线/升级 SQL 为 src/main/resources/db/phase2-inbound-carton-label.sql、phase2-carton-label-versioning-migration.sql
墨家设备测量上传 controller/OpenApiInboundMeasurementController.java、dto/MojiaMeasurementDtos.java、service/MojiaMeasurementOpenApiService.java、security/MeasurementRequestAuthenticator.java;接口契约见 src/main/resources/openapi/firstleg-v1.yaml 与 ../../docs/墨家设备测量上传接口说明-V3.md
审核与初始计价 controller/PlatformInboundMeasurementReviewController.java、service/MeasurementReviewService.java、service/InitialInboundPricingService.java、dto/MeasurementApprovalResponse.java
客户四档箱规与默认算法 controller/PlatformCustomerDimensionConfigController.java、service/CustomerDimensionConfigService.java、repository/CustomerDimensionConfigRepository.java;固定 SMALL/MEDIUM/LARGE/EXTRA_LARGE,默认算法只允许 ADD/MULTIPLY
FBA 主数据/计费与客户规则 controller/PlatformFbaMasterDataController.java、PlatformFbaPricingController.java、service/FbaPricingService.java、repository/FbaPricingRepository.java;客户规则可保存多个版本,但每个客户仅一条默认规则,计算请求可提交已确认的重量/体积选择值
入库费用明细 controller/PlatformInboundFeeDetailController.java、service/InboundFeeDetailService.java、dto/InboundFeeDetailDtos.java;Admin 消费端见 ../../apps/admin-web/src/modules/unified-orders/api/inboundFeeDetails.ts
入库/柜次直接已付快照与凭证校验 service/FeePaymentSnapshotValidator.java、client/FeePaymentVoucherFileClient.java;写入入口分别为 InboundFeeDetailService.java、ContainerFeeDetailService.java,File 业务类型固定 FINANCE_VOUCHER
客户费用查询 controller/MerchantInboundBillingController.java、service/MerchantInboundBillingService.java
客户运营统计/在途柜量 customerstatistics/controller/PlatformCustomerTransitStatisticsController.java、customerstatistics/service/CustomerTransitStatisticsService.java;契约见 src/main/resources/openapi/customer-statistics-v1.yaml
费用项目与价格簿 controller/PlatformFeeItemController.java、PlatformPriceBookController.java、MerchantPriceBookController.java
价格簿查询内部切片 pricebookquery/application/port/in/PriceBookQueryUseCase.java、application/PriceBookQueryService.java、application/port/out/PriceBookQueryReader.java、adapter/out/persistence/PriceBookQueryMapper.java;查询行模型位于 application/model/PriceBookQueryRows.java
财务费用来源快照 controller/InternalFinanceFeeSourceController.java;入库费用与柜次费用分别按来源 ID、版本向 Finance 提供不可变快照
柜次费用明细与跨客户分摊组 controller/PlatformContainerFeeDetailController.java、service/ContainerFeeDetailService.java、dto/ContainerFeeDetailDtos.java;跨客户公共柜费使用 allocation-groups 按柜内真实客户和订单原子分摊,入仓 ID/入仓码同时填写或同时留空;各行金额合计必须等于原始柜费,审核、驳回、调整、作废均整组处理,单行入口拒绝分摊组;契约 src/main/resources/openapi/container-fees-v1.yaml;Admin 消费端见 ../../apps/admin-web/src/modules/loading-lists/api/containerFees.ts
财务整柜成本分摊快照 loading/controller/InternalFinanceCostSnapshotController.java、loading/service/FinanceCostSnapshotService.java
分柜、预装、真实柜号后补与正式装柜清单生命周期 split/controller/PlatformSplitPreloadController.java、controller/PlatformLoadingListController.java、service/LoadingListService.java;契约 src/main/resources/openapi/loading-lists-v1.yaml,详情阶段先查 /loading-plans/{planId}/lifecycle。创建柜次时原子生成唯一预装计划,加入入仓码明细时同步创建入库预装聚合与关联,不设推送步骤;同一 planId 在 EDITING/LOADING 返回 PRELOAD,COMPLETED 返回 LOADING_LIST。订舱关联、预装确认和 PDA task 创建不依赖真实集装箱号;可在 EDITING/LOADING 首次补录,最终 PDA 完成前必须存在;已有值纠正仅限 EDITING 且任务未领取、无物理作业事实
同柜不可拆组 loading/coload/controller/PlatformColoadGroupController.java、service/ColoadGroupService.java、persistence/ColoadGroupMapper.java;契约 src/main/resources/openapi/coload-groups-v1.yaml。请求按订单 ID 建组,服务端冻结每票全部 WAIT_SPLIT 可用入仓片段与满箱数;仅要求同国内仓、同渠道,允许跨客户及不同目的仓港;分配、移除、取消均保持整组原子
货柜与全局智能排柜 controller/PlatformContainerController.java、PlatformSmartLoadingController.java、service/SmartLoadingService.java、repository/SmartLoadingRepository.java、loading/;全局候选、工作台柜次和箱数分配分别从 /inbound-candidates、/containers、/plans/{planId}/inbound-assignments 进入,同柜组从 /group-assignments 整组处理,明细规格拆分留在服务端
货柜资料、PDA 证据与业务总览 controller/PlatformContainerController.java 的 /{id}/overview、/{id}/documents/{documentType},聚合 mapper/ContainerOverviewMapper.java;契约 src/main/resources/openapi/phase3-container-overview-v1.yaml,四类资料固定为目的港清关、国内出口报关、DO、PU 的当前唯一版本
PDA 拣货与装柜、证据幂等上传 controller/PlatformLoadingPdaController.java、loading/controller/PlatformLoadingDeliveryController.java、loading/service/CabinetLoadingEvidenceService.java;证据写入和 multipart 上传均先以任务内幂等键匹配请求哈希,上传哈希覆盖仓库、版本、证据类型、锁码、备注、文件名、媒体类型、大小与文件内容;完全重放返回当前视图且不得再次上传 File,相同键不同内容返回冲突
装柜完成跨区事件 service/LoadingCompletedOutboxService.java、LoadingCompletedOutboxRelay.java、repository/LoadingCompletedOutboxRepository.java、mapper/LoadingCartonManifestMapper.java、client/EventBridgeClient.java;从 fl_inbound_order.destination_type 冻结 V2 orders[].destinationType(FBA 或 OVERSEAS),OVERSEAS 按最终实装与稳定箱码冻结,FBA 可仅冻结箱数;真实生产验收 src/test/java/com/baiyue/firstleg/service/TaillegRealProducerAcceptanceTest.java;事件模型见 ../common-event-contract/AGENTS.md
海外卸柜完成事件回写 内部入口 controller/InternalOverseasContainerEventController.java、消费者 service/OverseasContainerEventConsumer.java、Inbox entity/ContainerEventInboxEntity.java 与 mapper/ContainerEventInboxMapper.java;事件模型见 ../common-event-contract/AGENTS.md
三期海运订舱、资料/打印、关联候选与出仓前船期资料 oceanbooking/controller/PlatformOceanBookingController.java、oceanbooking/service/OceanBookingService.java、OceanBookingDocumentService.java、OceanBookingPrintService.java、oceanbooking/mapper/OceanBookingMapper.java、portschedule/controller/PlatformPortScheduleController.java;文件经 client/OceanBookingFileClient.java 进入 File,关联候选 /api/platform/v1/ocean-bookings/link-candidates,契约 src/main/resources/openapi/ocean-bookings-v1.yaml
四期国内出仓后船节点定时查询 outbound/dispatch/service/OutboundDispatchService.java 在确认出仓事务内幂等创建现有 CarrierScheduleQuery;编排与租约 portschedule/service/CarrierScheduleQueryScheduler.java,任务/十节点事实/异常事实/不可变 attempt CarrierScheduleQueryService.java,平台查询与人工补录入口 PlatformCarrierScheduleQueryController.java 的 /{queryId}/manual-nodes;停止只由实际 EMPTY_RETURNED 节点触发,不提供无节点停止入口;外部船司/轨迹调用经 integration-service/;标准见 ../../docs/四期/船节点标准化契约.md
船节点跨区交接事件 portschedule/service/CarrierScheduleNodeOutboxService.java;实际节点落库后发布 FIRST_LEG_CONTAINER_SHIPPING_NODE_RECORDED V1,复用 LoadingCompletedOutboxRepository/Relay 投 Event Bridge;海外消费见 ../lastleg-service/src/main/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumer.java
Firstleg 业务单据编号 service/FirstlegDocumentNumberGenerator.java;当前支持 OB、TA、CB、CAB、LP 前缀,按北京时间每日独立编号;具体业务归属以各调用服务为准
订舱级拖车与整柜出仓调度 controller/PlatformTruckAppointmentController.java 的 /candidates、service/TruckAppointmentService.java、repository/TruckAppointmentRepository.java、outbound/dispatch/controller/PlatformOutboundDispatchController.java;拖车契约 src/main/resources/openapi/truck-appointments-v1.yaml。预约只绑定 RELEASED 订舱,候选排除缺提单/有效订舱文件或已有非终态预约的订舱;API 不含客户、柜次、装柜计划或真实柜号,每订舱最多一张非终态预约,PDA 完成不推进拖车状态
整柜出口报关 customs/container/controller/PlatformContainerCustomsController.java、customs/container/controller/MerchantContainerCustomsController.java、customs/container/service/ContainerCustomsService.java、customs/container/mapper/ContainerCustomsMapper.java;装柜完成后按柜收集退税资料,多对多覆盖入仓码,开始报关冻结,完成文件逐资料一对一回传,全买单柜由平台确认并通过导出中心取明细;契约 src/main/resources/openapi/customs-v1.yaml,基线 src/main/resources/db/phase3-container-customs-schema.sql;消费者为 Admin ../../apps/admin-web/src/modules/container-loading/components/ContainerCustomsPanel.vue 和 Client ../../apps/client-web/src/modules/first-leg/components/CustomsDocumentsDialog.vue
买单订单明细导出 Provider customs/container/controller/LoadingListBuyDeclarationExportController.java、service/LoadingListBuyDeclarationExportService.java;只为 File 导出中心提供 LOADING_LIST_BUY_DECLARATION_ITEMS 的已完成装柜实际买单行,不在 Firstleg 生成文件
跨模型桥接 loading/bridge/controller/PlatformLoadingModelBridgeController.java
跨服务客户端 client/OrderCargoClient.java、WarehousePalletLocationClient.java、MeasurementImageClient.java、LoadingEvidenceFileClient.java、EventBridgeClient.java
仓库公共供应商快照 client/WarehouseSupplierClient.java、service/WarehouseSupplierSnapshotService.java;报关、订舱和拖车分别消费 customs-v1.yaml、ocean-bookings-v1.yaml、truck-appointments-v1.yaml 中的供应商 ID,并由 Warehouse 返回服务端名称快照
SQL/OpenAPI src/main/resources/db/phase2-*.sql、src/main/resources/db/phase3-*.sql、src/main/resources/openapi/;部署统一 ../deploy/sql/头程数据库统一增量-MySQL8.sql
测试/验证 src/test/java/com/baiyue/firstleg/;mvn -pl firstleg -am test

修改约束

  • 移动包、拆分端口/适配器或引入新的跨切片依赖时,先核对内部模块化基线并运行 node --test scripts/analyze-firstleg-dependencies.test.mjs;确需更新依赖基线时必须说明稳定边界变化,不能把临时循环依赖登记为长期豁免。
  • 平台接口必须校验目标客户、权限、乐观锁、幂等键、历史和审计;商户查询只能使用登录态客户。
  • 价格簿查询消费者依赖 PriceBookQueryUseCase 或稳定查询端口,不得反向依赖持久化 Mapper;移动旧查询类时同步更新生产调用、测试、Mock 与 import,避免同一职责在根 repository/mapper 和 pricebookquery/ 双写。
  • 第三方回传必须签名、时间窗、防重放、请求哈希,并绑定订单货物和 File 证据;不得信任外部客户字段。
  • 稳定箱码映射以入库快照和 Order 货物明细为事实;订单审核创建入库单时必须幂等生成,打印接口只复用或补齐同一映射,用户是否下载箱唛不得决定箱码有效性。手工测量、墨家设备和 PDA 扫码统一通过 InboundCartonLabelService 校验客户、入库单、货物明细、总箱数/下标和有效批次,不得在测量时临时伪造箱码或接受跨客户、跨入库箱码。
  • 测量审核通过后直接进入 WAIT_SPLIT,费用仅作为独立初算和人工维护结果,不得阻塞或回退订单主流程;计费量、单价和附加费调整必须版本化并由服务端重算金额。状态或 DTO 变更时逐个检查 Order/Warehouse/File/Integration 消费者。
  • 客户箱规配置必须恰好保持四档且默认算法在四行一致;ADD 以实测尺寸为基准对三个维度分别增加命中箱规的尺寸值,MULTIPLY 使用当前客户唯一默认计费规则,并由服务端按规则中的规格档位选择系数。测量行必须保存实际尺寸、选用规则和算法快照,页面不得自行重算后覆盖服务端结果;计价使用用户确认的重量/体积选择值并纳入幂等请求哈希。
  • 报关、订舱和拖车引用的供应商必须通过 WarehouseSupplierSnapshotService 按 ID 向 Warehouse 校验:报关使用 CUSTOMS,订舱使用 BOOKING(不区分国内/国外 scope),拖车使用 TRUCKING;供应商必须为 ACTIVE。请求中的名称只能作为一致性提示,持久化名称必须来自 Warehouse 快照,禁止用自由文本绕过 ID、类别或启用状态校验。修改任一供应商引用 DTO、OpenAPI 或内部客户端时,必须同步检查三条业务链、Warehouse supplier-v1.yaml、数据库快照字段和对应契约测试。
  • Order 渠道变更门禁必须检查装柜或后续状态、PDA task、预装、分柜及同柜组兼容性;任何不确定结果均失败关闭。ORDER_DECLARATION_UPDATED_V1 消费必须校验订单号/入仓码归属,永久保留 eventId + payload hash 幂等历史并按版本单调更新申报投影;不得覆盖仓库实测、箱码、测量审核或已确认费用。
  • 订舱状态固定为 DRAFT → RELEASED:草稿允许资料不完整并可替换或删除,放舱时校验完整持久化聚合,放舱后永久只读。创建草稿和放舱都只维护订舱聚合、三类参与方及柜型需求,不创建真实 containerNo、货柜行或分配关系;真实货柜只在后续提柜关联时占用已放舱柜型需求。
  • 订舱柜型需求至少一项、最多 20 项,数量必须为正整数,容量和限重必须匹配平台柜型规格。起运仓必须是启用的国内中转仓;物流渠道必须来自该仓当前 ACTIVE 价格版本,服务端保存渠道名称快照,渠道失效时失败关闭。
  • 订舱号统一使用 OB-yyMMdd-####,按北京时间创建日每日独立递增且单日最多 9999;不得以实体 ID 拼接生成。放舱不要求真实柜号,也不得为满足放舱校验伪造柜号。
  • 订舱列表 containerCount 固定为该订舱全部柜型需求 quantity 之和,与真实柜关联/解除无关;关联候选只返回 RELEASED、剩余数量大于 0 且 warehouseId + channelCode + containerType 精确匹配的需求,由服务端集合查询 ACTIVE 分配量。前端不得扇出详情计算或用已关联柜数覆盖该字段,最终关联命令仍须重验目标货柜可修改性。
  • 拖车预约是平台级订舱聚合,不是客户或柜次资源:请求、实体、查询、响应和附件不得恢复 customerId/customerName,公开 DTO 也不得出现 containerBookingId/loadingPlanId/cabinetNo/containerNo。创建候选只返回有提单号、ACTIVE BOOKING_CONFIRMATION 或 BILL_OF_LADING 且没有非终态拖车单的 RELEASED 订舱;创建或编辑只冻结订舱仓库/提单与 TRUCKING 供应商快照。每订舱通过查询锁与唯一约束最多一张非终态预约,重复创建返回现有派车单号;PDA 装柜完成不得改变拖车状态。附件使用 tenantId=0 + TRUCK_APPOINTMENT_ATTACHMENT + appointmentId,提单文件继续归订舱。
  • 四期船节点任务从确认柜子离开国内仓库后启用,必须绑定真实订舱和柜次;十个标准节点、预计/实际时间、异常事实、供应商缺失节点和还柜停止规则统一以 ../../docs/四期/船节点标准化契约.md 为准。CarrierScheduleQuery 的正常业务查询槽位固定为 Asia/Shanghai 每日 09:00、12:30、16:00;每分钟任务只扫描已到期 next_allowed_at,不是每分钟请求船司。成功、无变化、需人工或永久失败进入下一固定槽位;仅技术性 RETRYABLE_FAILURE 在当前槽内按15/30分钟退避,含首次最多3次且不得跨下一槽,实际 EMPTY_RETURNED 后停止。错过的正常槽位直接顺延,不在服务恢复时补跑;单轮按受控批次持续领取并受最大任务数保护。租约、调度尝试和内部停止入口不得暴露为平台页面 API,外部失败不得推进业务节点,不得在三期另建查询任务。
  • 国内出口报关在装柜完成后启用,不再阻塞 LOADED。整柜 fl_customs_container.status=COMPLETED 才通过离仓报关门禁;完成后以系统身份、确定性幂等键立即尝试确认国内离仓,其他门禁未齐时由受控定时补偿重试,禁止部分入仓成功或重复创建离仓/船司查询事实。
  • 国内出仓确认以真实 containerBookingId 聚合全部入仓绑定并锁定校验;装柜证据按物理货柜只计算一次,PDA taskId 仅用于来源审计和任务授权,File 所有权仍固定 tenantId=0 + containerBookingId;拖车状态和独立船期只作参考。全部门禁在同一事务通过后推进所有技术行、记录一条可见历史并幂等创建 CarrierScheduleQuery/DEPARTED_WAREHOUSE,不允许单入仓局部成功。
  • 手工船节点的预计时间只追加事实,不推进 latestStandardNode;携带 actualAt 时标准节点序号必须严格大于最新实际节点,重复、相同或回退节点返回冲突。已审核实际时间修正只能更新同一事实的时间/证据,不得制造第二条同节点实际事实或绕过单调推进。
  • 海外卸柜完成事件只接受 OVERSEAS -> CN 的 OVERSEAS_CONTAINER_UNLOADED V1,并通过内部服务令牌进入。消费者必须校验信封、Payload 哈希、来源货柜和时间顺序,以 event ID + Payload 哈希幂等,使用事件聚合版本阻止乱序覆盖;预计报空时间固定按卸柜照片上传时间加两天计算,实际报空时间可为空。
  • Firstleg 只拥有业务费用及履约事实;Finance 拥有费用入池、账期、账单、收款、成本分摊结果和财务状态。修改费用来源版本、发布条件、柜次归属或体积快照时同步检查 ../finance/src/main/java/com/baiyue/finance/client/FirstlegFeeSourceClient.java、同目录 FirstlegCostSnapshotClient.java 及双方契约测试,不在 Firstleg 复制财务状态机。
  • DIRECT_PAID 仅适用于 PAYABLE,必须同时保存 paidAt、合法 paymentMethod,并至少提供 paymentReferenceNo 或一个当前客户范围内的 FINANCE_VOUCHER;RECEIVABLE 与 ON_ACCOUNT 不得残留付款字段。创建、调整和审核前均通过 FeePaymentSnapshotValidator 失败关闭复核。

三期装柜与 PDA 资源结算

  • 智能装柜全局工作台由服务端把业务渠道分组映射为实际渠道,并分别分页查询候选与 WAIT_LOADING/EDITING/LOADING 柜次;候选只返回具备实际装柜资格的 WAIT_SPLIT 数据,同柜不可拆组必须成员完整、满箱且作为单个分页与分配单元,不能跨页或拆分。分配到柜时继续复核国内中转仓、实际渠道、容量、组锁和版本;推荐顺序按入库时间先进先出。装柜计划状态为 EDITING -> LOADING -> COMPLETED,PDA 全部明细处理完成后自动完成。
  • PDA 拣货以 fl_inbound_carton_label.box_code 对应的稳定箱唛箱码为扫描身份;审核建单、重复打印、手工测量和墨家测量复用同一映射,版本字段只用于并发控制,不进入扫码文本。一个有效且未重复的箱码扫描表示拣出一箱,不得以 SKU、商品件数或页面展示字段替代箱码。任务下发与提交契约见 src/main/resources/openapi/phase3-pda-convergence-v1.yaml。
  • PDA 部分拣货生成二级子入库单时,数量必须守恒:已拣数量 + 子单数量 = 拣货前主单可用数量。子单只允许一层,不能继续拆分。
  • releaseMode=AUTO 时,释放资源数为 ceil(实际拣货箱数 × 原资源数 / 原可用箱数);MANUAL 按 locationIds 选择,空数组表示明确释放 0 个。当前契约中未传模式且 locationIds=null 时按 AUTO 处理。
  • 头程快照必须保存仓库 reservation_id。A0 是共享临时库位,多个托盘可具有相同 location_id,跨服务结算、转移、释放必须使用 reservationId,不得把 locationId 当作唯一资源标识。
  • 部分拣货资源结算必须调用 Warehouse 的 /internal/warehouse/v1/pallet-locations/settlements 原子接口;禁止拆成独立释放和转移调用。全部释放但子单仍有数量时,由仓库服务重新选择同仓普通库位,不足才落 A0。
  • 数据库字段变更直接维护当前模块基线与 ../deploy/sql/头程数据库统一增量-MySQL8.sql;已有 phase3-pda-release-allocation-migration.sql 只作为当前结构来源,不为历史开发数据再新增兼容迁移。

全量验收导航

本模块承载一期履约、二期入库测量计费、三期订单编排/柜次/排柜/订舱/拖车/PDA/LOADED 门禁等全量链路;按本次验收范围读取对应阶段文档、Controller、DTO、OpenAPI、当前 SQL 定义和调用方,不以历史阶段终点阻断联调。PDA 按 uni-app 在线更新安排开发与验收,不另设设备型号门禁。