# Lastleg Service 模块指引 ## 数据库访问与中文注释约束 - 强制继承 `../AGENTS.md` 的“数据库访问与中文代码注释”全部规则;该节为分层、SQL 执行和方法/核心逻辑中文注释的唯一维护处。根规则已在上下文时不重复读取,本服务不另设例外。 ## 职责与边界 - Mapper 必须标注 `@Mapper`,仅由 `BaiyueLastlegApplication.java` 对 `com.baiyue.lastleg` 根包按 `annotationClass = Mapper.class` 扫描;禁止局部 `*MapperConfiguration` 和包白名单。验证:`scripts/mapper-scan-contract.mjs`、`MapperRegistrationArchitectureTest.java`。 - 消费头程装柜完成事件并保存 Inbox,按实装入仓单建立待分配尾程订单、冻结明细和初始历史;不自动建计划。平台调用 `/api/platform/v1/last-leg/inbound-plans/convert-container` 后才按柜内每票生成计划并推进订单。 - 负责尾程订单查询/导出、入库计划、暂扣/解除、人工节点、目的仓调整、托盘分配与 PDA 入仓;卸柜完成通过本地 Outbox 向头程回传报空事实。 - 不跨库查询头程或回调补建单字段;快照缺失须拒绝消费并保留诊断。 ## 快速索引 业务包相对 `src/main/java/com/baiyue/lastleg/`;`src/`、`docs/`、`scripts/`、`../` 相对服务目录。裸类名在指定包内检索。 拼车余位发布查 `fleet/trip/FleetCapacityOfferService.java`;整车建单与准备查 `dispatch/controller/DispatchAggregateController.java` 和 `dispatch/service/DispatchAggregateService.java`,本土业务接线查 `fleet/business/`;既有外接登记衔接合同为 `fleet-preparation-v1.yaml`,排车流程按 `../../docs/海外仓业务/排车列表统一作业改造契约.md`。 原排车装车后运营视图分别查 `fleet/ownedbusiness/`、`fleet/outsourcedbusiness/` 与各自 `fleet-*-business-v1.yaml`;自有业务按无实际拼车货物、外配任务按已实际接入需求池货物分类;车辆归属仍读取装车快照,完整判定唯一见外配业务契约。两入口可信作用域及权限独立,外配仅整车承运金额、逐目的仓到达和五装车照片;复用四张附加表,不修改原履约/库存/财务状态。共同业务规则见 `../../docs/海外仓业务/自有业务首版开发契约.md`、`../../docs/海外仓业务/外配业务首版开发契约.md`,实际发布及HTTP只查部署主契约。 事件重试:`controller/EventOperationsController.java`,内部 `/internal/lastleg/event-operations/{entryId}` 查询、`/retry` 写入;仅卸柜、派送、暂扣、资金及费用事件,以 `EVENT_OPERATIONS_TOKEN` 保护。原事件不可改,DEAD→PENDING 与 `event_delivery_retry_audit` 同事务;脚本 `scripts/event-outbox-operations.mjs`。 沿代码追踪;状态、权限、资源或接口边界不明时,定向检索 `docs/business-index.md`;局部任务不扩读无关约束。 退货链查 `returnreceipt/`;计划、自动托盘、柜级预览及来源托盘查 `inboundplan/`。 | 功能 | 首个入口 | |---|---| | 内部模块化基线与依赖分析 | `docs/lastleg-internal-modularization-baseline.md` | | 自营领星统计 | `selfoperated/analytics/`;平台入口 `controller/PlatformAnalyticsController.java`,契约见 `../../docs/自营业务/README.md`;权限源 `../iam/src/main/resources/db/selfoperated-analytics-permissions.sql`。 | | 订单查询与控制 / 导出 | `controller/LastlegOrderController.java`;异步导出见 `export/` 与 `lastleg-exports-v1.yaml` | | 尾程订单完整计划、柜级到仓时间、暂扣与人工节点 | `controller/LastlegOrderController.java` | | 客户尾程订单列表与详情 | `controller/MerchantLastlegOrderController.java` | | 装柜完成事件消费 | `service/LoadingCompletedConsumer.java` | | 尾程单号生成 | `service/LastlegOrderNoGenerator.java` | | 订单查询与更新 | `service/LastlegOrderService.java` | | 业务 Inbox | `entity/LastlegEventInbox.java` | | 尾程订单、明细、状态历史 | `entity/LastlegOrder.java` | | 独立尾程入仓单快照 | `entity/LastlegInboundOrder.java` | | 内部令牌保护 | `security/InternalServiceTokenGuard.java` | | 统一会话校验 | 复用 `../common-security/` Redis会话与Auth权威状态校验;Lastleg不维护授权投影 | | 入仓计划分页、柜级预览、转换与详情 | `inboundplan/controller/InboundPlanController.java` | | 自动生成托盘、资源生成失败与重试 | `inboundplan/service/ContainerInboundPlanConversionCoordinator.java` 的 `convertManualAndAutoMaterialize`;详细规则定向查 `docs/business-index.md` 的“人工计划自动生成托盘与资源重试” | | 托盘分配算法 | `inboundplan/service/PalletAllocator.java` | | 跨客户同仓预约、日历 | `InboundPlanController.java`;在途/外接货跟进与覆盖见`appointmentplanning/` | | PDA 入仓、柜号签收、实收、上架与完成 | `inboundplan/pda/controller/ReceivingContainerController.java` → `inboundplan/pda/service/ReceivingContainerService.java`;门禁与状态定向查 `docs/business-index.md` 的“PDA 入仓、实收、上架与完成” | | PDA 卸柜照片上传、归属校验与预览 | `ReceivingContainerController.java` | | PDA 国内装柜照片对照 | `ReceivingContainerController.java` | | 卸柜照片与海外卸柜完成 Outbox | `ReceivingContainerController.java` | | 拆柜打托成本与客户应收分摊 | `inboundplan/service/DestuffingPalletCostJob.java` | | 尾程暂扣状态回传 | `service/InboundOrderDetainedOutboxService.java` | | 派送完成回传 | `delivery/service/DeliveryCompletedOutboxService.java` | | 入仓后 SKU 库存余额、库位和流水 | `inventory/` | | 海外PDA盘点、同仓整托移库、托盘组拆换绑与换标现场作业 | `pda/stocktake/` | | 贴标申请、箱唛/SKU/组合换标与 PDA 完工 | `relabel/` | | PDA 仓内通用扫码与操作历史 | `pda/warehouse/controller/PdaWarehouseController.java` | | 船节点接收与海外 PDA 可收货门禁 | `shipping/service/ContainerShippingNodeConsumer.java` | | 内部散板需求只读来源 | `dispatch/service/DispatchCapacityDemandService.java`、`DispatchQueryController.java`的`/dispatches/capacity-demands`;发布字段仅随智能排车创建保存且缺省不发布,编辑命令不接收该字段;重发须按原门禁取消排车再重新创建,当前业务口径见拼车主契约,不恢复旧车次人工发布入口 | | 平台排车查询、整车四块详情、审核与实载 | `dispatch/controller/DispatchQueryController.java`、`DispatchAggregateController.java`;公开契约`dispatch/port/`,业务规则见`../../docs/海外仓业务/排车列表统一作业改造契约.md` | | 草稿、双端装车发运 | `dispatch/controller/SmartDispatchController.java`、`dispatch/pda/controller/DispatchPdaController.java`;平台维护`DispatchController.java`;自动发运编排`dispatch/service/DispatchLoadingDepartureService.java` | | 仓储资源调用 | `inboundplan/pda/gateway/WarehouseResourceGateway.java` | | 仓储转运、历史订单/入仓绑定、可选换标联动 | `transfer/controller/WarehouseTransferController.java` | | 一件代发接收、SKU/箱唛库存 | `dropship/controller/DropshipOrderController.java` | | 货物废弃、待审锁箱、实际确认扣减 | `discard/controller/CargoDiscardController.java` | | 客户拜访、派送状态与签收附件 | `customervisit/controller/CustomerVisitController.java` | | 派送三类资料、摘要与历史证据 | `delivery/controller/DeliveryDocumentController.java` | | 异常订单与派送退回入仓 | `exceptionorder/controller/ExceptionOrderController.java` | | 海外采购、客户下单、采购审核、客户/采购仓候选与操作流水 | `procurement/controller/` | | 海外业务资金指令与结果 | `wallet/WalletCommandOutboxService.java` | | 海外业务费用来源 | `financefee/controller/PlatformOverseasFeeSourceController.java` | | 美国/本土卡车订单 | `trucking/controller/PlatformUsTruckOrderController.java` | | 本土散板订单 | `looseboard/controller/PlatformLocalLooseboardController.java` | | 海外仓报价、月度汇率、车辆主数据 | `masterdata/quote/` | | 司机档案、证照上传/审核、资格预览与历史 | `fleet/driver/PlatformDriverController.java`、`DriverService.java`;OpenAPI `fleet-drivers-v1.yaml`,表 `ll_fleet_driver` / `ll_fleet_driver_history`;资格规则 `fleet/domain/DriverQualificationPolicy.java` | | 车辆运维:保养、加油、维修、故障、救援、异常 | `fleet/maintenance/PlatformVehicleCareController.java`、`VehicleCareService.java`;合同`fleet-vehicle-records-v1.yaml`。按车/类型隔离,单位/币种明确,处理不等付款;创建/附件幂等,更正留版本历史,不改主档里程/状态。维修救援经`financefee/fleet/VehicleCareFinanceAdapter`入公司成本,Finance为付款权威,未关联UNLINKED,不生成客户应收 | | 车次计划、车/司机分配与占用、客户排车关联 | `fleet/trip/PlatformFleetTripController.java`、`FleetTripService.java`;OpenAPI `fleet-trips-v1.yaml`;`FleetDispatchGateway` 由 `dispatch/fleet/DispatchFleetAdapter.java` 实现,`FleetDispatchBindingGuard` 控制子单独立修改/发车;车辆通过 `VehicleRepository` 和 `VehicleAssignmentGuard` 协作,fleet不直读车辆持久化适配器 | | 整车调度与理货审核 | `dispatch/controller/DispatchAggregateController.java` → `dispatch/service/DispatchAggregateService.java` 的提交及两级审核;同一排车先调度审核、再理货审核,通过后才允许真实扫码。资源、货物或路线关键变更使原依据失效;零扫码显式退回后重新审核,不复用旧客户子单审核状态 | | 外接询价、确认占位及取消 | `fleet/trip/PlatformFleetBookingController.java`、`FleetBookingService.java`、`FleetBookingReservations.java`;客户从`fleet/customer/`读取IAM有效主档与资格,询价不占位,确认后与自有货计划共同校验逐段容量。约定金额不代表应收/实收,`FleetBookingIncomingGateway`由`transfer/fleet/FleetIncomingAdapter`实现来货登记/实收确认,排车关联通过`FleetDispatchGateway.sourceCargo`核对实收来源 | | 拣货前计划容量与逐段余位 | `FleetTripExecutionService.capacityPlan/confirmCapacityPlan`、`/fleet/trips/{tripNo}/capacity-plan`;保存自有货的计划值,不检查拣货完成、不推进审核或扣库存;`planValid`校验当前货物hash,不把计划值当实测值,资源/计划/关联变更后须重新核对 | | 实物装载、逐段容量与双端整车发车 | 两端`dispatches/{dispatchNo}/loading-complete`统一调用`dispatch/service/DispatchLoadingDepartureService.java`,实载确认成功进入`AFTER_LOADING`;请求携带唯一`recordVersion`,原键恢复原装车后结果。`dispatch/service/DispatchLoadingDocumentService.java`复用整车附加照片与账本,平台/PDA均经`loading-documents`保存;五框齐全的最后一次绑定与派送准备、发车同事务,成功`DELIVERING`。公开手工安排派送、`/depart`入口仍不开放。真实PDA拣货须核平,不重复库存SHIP,Fleet容量和资源资格仍复核;未知费用不补零、不阻塞发运,真实已明确外接报价沿原费用来源防重 | | 车次货物结案、车辆和司机分别释放 | `fleet/trip/FleetTripCompletionService.java`、`FleetCompletionModels.java`;平台 `/fleet/trips/{tripNo}/completion`、`/complete`、`/resources/release`,独立complete/release权限。结案核对所有派送终态与实发数量;实际任务结束时间/地点及车辆结束状态单独记录,不以结案或收款自动释放资源 | | 跨服务 HTTP 客户端装配 | `config/LastlegRestClientFactory.java` | | 数据库基线、表索引与中文注释契约 | `src/main/resources/db/lastleg.sql` | | 测试 | `src/test/java/com/baiyue/lastleg/` | | 真实事件消费验收 | `src/test/java/com/baiyue/lastleg/service/TaillegRealConsumerAcceptanceTest.java` | ## 海外仓全流程开发路由 本服务覆盖尾程入仓、库存、库内作业、排车/PDA、派送、异常、采购和车队。状态、数量、资金、资源或跨单联动变化前,须查 `docs/business-index.md` 本节条款;同柜/车/托不合并客户、仓库或来源,页面资格只取服务端结果。 ## 数据库表索引与注释约束 表名与中文含义按需查 `docs/business-index.md` 的“数据库表索引”;修改约束如下。 - 新增或修改表时,表 `COMMENT` 和每个普通字段的 `COMMENT` 必须填写准确的中文业务含义,不得只写英文、字段名或类型名。 - `SchemaChineseCommentContractTest` 自动扫描全部 `ll_` 表,无需维护表名白名单;新增字段必须同步更新基线 SQL、建表增量和存量备注迁移,增量脚本的 `ADD/MODIFY COLUMN` 不得丢失中文备注。 - 表备注、字段备注和索引变更必须可重复执行;存量库的备注修订通过统一增量脚本落地,不依赖基线建表语句。 ## 事件建单规则 校验事件身份、客户/来源、版本/hash、Inbox 幂等与事务;装柜事件不自动完成入仓。修改前查 `docs/business-index.md` 本节条款,ACK/重试按统一通信契约。 ## 查询与租户约束 查询、详情、导出与写入保持一致客户隔离、访问域和绑定仓,不信任请求归属。采购、废弃、主/子状态变化前查 `docs/business-index.md` 本节条款。 ## 修改与验证 - 后端根数据库分层、中文注释、API、Mapper、事件和权限门禁全部适用,SQL遵循本文件数据库约束。 - 换标/托盘/返工、客户状态、锁与并发行为变化前,须查 `docs/business-index.md` 本节及对应条款。 - 跨子域依赖变化核对 `docs/lastleg-internal-modularization-baseline.md`,从后端根运行 `node --test lastleg-service/scripts/analyze-lastleg-dependencies.test.mjs`;不以基线掩盖循环依赖。 - 定向验证:从后端根执行 `mvn -pl lastleg-service -am test`;事件回归覆盖重复/来源唯一性、回滚、并发单号、内部身份及客户越权。 - 指引/索引变更统一运行 `./scripts/agents-index-contract.ps1`,不以离线检查代替部署/验收。