Files
lingniu-vehicle-ingest/vehicle-data-platform/docs/oneos-ln-asset-management-system-analysis.md

21 KiB
Raw Blame History

OneOS 与 ln-asset-management 系统分析

更新时间2026-07-14
分析方式:源码静态分析、生产数据库只读元数据与聚合核验
修改边界:本报告未修改 /Users/lingniu/project/ai-coding/oneos。用户已明确要求不修改 ln-asset-management 任何逻辑;所有建议均需另行同步和批准。

1. 结论先行

ln-asset-management 不是单一车辆档案服务,而是 OneOS 的资产和车辆业务单体,覆盖车辆主档、租赁合同、交车、还车、换车、应收、结算、保险、证照、异常异动、维修故障、加氢、备件、培训、消息与工作台等领域。车辆数据中台不能把它当作实时遥测服务,也不能直接把它的现有 REST/Dubbo 接口公开给客户。

推荐的系统职责是:

  • OneOS车辆业务身份、客户、合同、交还车、业务状态的权威来源
  • 车辆数据中台TDengine/Redis/Kafka 中遥测、轨迹、在线状态、告警和分析的权威来源;
  • 两者之间:使用最小权限只读快照,不在客户请求链路上实时查询 OneOS不信任客户端传入的客户 ID
  • 当前客户车辆生命周期:以完成的 delivery_vehiclereturn_vehicle_task 事务事实判断,vehicle_lease_order_record 仅用于客户归属交叉校验。

当前不能安全公开 OneOS 接口,主要原因包括:

  1. RemoteVehicleService.listByCustomerId 当前忽略客户 ID存在返回全量车辆风险
  2. 网关能证明“已登录”,但 93 个业务 Controller 中只有 1 个检出细粒度权限注解,不能证明接口级或客户级授权完整;
  3. 全局 API 日志拦截器会记录请求头、请求体和响应体,且未像注解切面一样脱敏 Authorization、Token 和 Cookie
  4. 注解接口同时被全局拦截器与 @ApiLog 切面记录,存在重复日志;两个月日志表约占生产库数据体积 83%
  5. 租赁聚合表会被合同保存和还车草稿等非最终业务动作影响,不能单独作为授权真值;
  6. 核心交车、还车和合同类达到 2,7006,000 行,自动化测试没有覆盖核心生命周期;
  7. 24 个定时任务未发现分布式锁,服务多副本部署存在重复执行风险。

2. 仓库与运行架构

/Users/lingniu/project/ai-coding/oneos 下是四个独立 Git 仓库,而不是一个单仓:

仓库 主要职责 与车辆数据中台关系
ln-cloud RuoYi Cloud 网关、认证、用户、组织、字典、资源、工作流、Nacos 等 身份和组织来源;外部客户身份尚未建立
ln-asset-management 车辆和资产全生命周期业务 车辆业务主档和客户 Scope 来源
ln-energy-v2 能源及财务类远程能力 OneOS 内部依赖,不作为遥测主源
ln-ocr OCR 能力及共享 API 保险、证照等业务依赖

ln-asset-management 技术基线:

  • Java 21Spring Boot 3.5.10Spring Cloud 2025.0.0
  • MyBatis-Plus 3.5.15MySQL Connector/J 9.5
  • Nacos 配置与注册、Dubbo 服务、Sa-Token、RabbitMQ、异步和定时任务
  • 主服务端口 8701网关路由 /asset/** 后去除一层前缀;
  • Dockerfile 默认 test profile生产实际配置依赖 Nacos 覆盖;
  • Maven 依赖公司私有 SNAPSHOT 包,本机缺少仓库凭证时构建会在依赖解析阶段收到 401
  • 仓库没有发现 Maven Wrapper、CI 工作流、docker-compose 或完整生产运行手册。

源码规模基线:

指标 数量
Java 代码 约 181,425 行
业务 Controller 93 个(按源码注解统计;命名扫描为 95 个)
显式 HTTP 方法 约 815 个
Mapper 约 161 个
@TableName 实体映射 158 个
Dubbo 服务实现 20 个
含 Dubbo 引用的文件 85 个
定时任务文件 24 个
测试文件 30 个、约 4,372 行

3. 业务领域清单

3.1 车辆主档与运营状态

模块路径存在历史拼写 modules/vihicle,但它是车辆核心模块,共 11 个 Controller、约 107 个 HTTP 方法。

主要能力:

  • VehicleInfoController:车辆档案、查询、导入导出;
  • VehicleModelController:车型;
  • VehicleRealtimeLocationControllerOneOS 内部实时位置投影;
  • PrepareCarController:备车;
  • VehicleLicenseController、批量上牌:证照和上牌;
  • VehicleTransferController:调拨;
  • AftermarketDeviceController:后装设备;
  • AccidentInfoController:事故;
  • VehicleCheckItemControllerVehicleMaintenanceItemController:检查和维保配置。

主要表:vehicle_infovehicle_modelvehicle_statusvehicle_realtime_locationprepare_carvehicle_transfervehicle_licenseaftermarket_deviceaccident_infotab_data_attachment 等 19 张显式映射表。

权威性判断:

  • 车辆身份以 vehicle_info.id 和标准化 VIN 为主;
  • 车牌会变化,不能作为跨系统唯一键;
  • vehicle_status 是 OneOS 业务运营状态,不等于车联网在线状态;
  • vehicle_realtime_location 和地图同步表是 OneOS 的展示投影,实时遥测仍应以车辆数据中台 Redis/TDengine 为准;
  • vehicle_info.customer_id 不是可靠客户归属来源,客户关系需通过合同和交还车事实确定。

3.2 租赁合同、交车、还车和换车

contract 是最大领域21 个 Controller、约 237 个 HTTP 方法、46 张显式映射表。

主要链路:

客户/合同
  -> vehicle_lease_contract_info
  -> vehicle_lease_order / vehicle_lease_order_detail
  -> delivery_task_subject / delivery_vehicle
  -> 正式交车完成
  -> 客户当前持有车辆
  -> return_vehicle_task 或 vehicle_replacement
  -> 正式还车/换车完成
  -> 应收、还车付款、还车结算、发票

关键事实表:

  • 合同:vehicle_lease_contract_infovehicle_lease_contract_log
  • 合同车辆:vehicle_lease_ordervehicle_lease_order_detail
  • 交车:delivery_task_subjectdelivery_vehicledelivery_vehicle_check_item
  • 还车:return_vehicle_taskreturn_vehicle_check_item
  • 换车:vehicle_replacement
  • 当前聚合与历史:vehicle_lease_order_recordvehicle_lease_order_record_log
  • 财务:receivable_*return_payment*return_settlement*rental_invoice

当前客户车辆的安全口径:

最新有效 delivery_vehicle.delivery_status IN (2, 3)
AND delivery_time IS NOT NULL
AND 不存在该交车单对应的有效 return_vehicle_task.status IN (2, 3, 5)
AND vehicle_info 有效且 VIN 非空
AND customer_info 有效
AND vehicle_lease_contract_info 有效
AND vehicle_lease_order_record.customer_id
    = COALESCE(contract.other_customer_id, contract.customer_id)
AND 同一车辆和标准化 VIN 不存在多个当前关系

不能仅使用 vehicle_lease_order_record.last_delivery_time/last_return_time:还车草稿保存会提前写 last_return_time;合同保存也可能覆盖交还车聚合字段;部分聚合更新失败只记录日志。用户已要求不修改这些 OneOS 逻辑,因此车辆数据中台必须在读取侧绕开并失败关闭。

3.3 客户、司机与身份

  • customer_info:业务客户档案;
  • driver_info:司机档案、黑名单、手机号和证件;
  • ln-cloud/ry-cloud.sys_user:登录账号;
  • 业务客户 ID 与 sys_user.user_id 没有稳定映射,生产只读审计未发现可直接使用的客户账号体系;
  • 手机号只能作为人工核对线索,不能自动建立授权关系;
  • 合同有甲方和丙方客户,当前有效客户规则为 COALESCE(other_customer_id, customer_id)

结论:车辆数据中台内部管理员可以继续使用独立平台令牌;外部客户入口在可信身份映射建立前不能开放。

3.4 地图与外部定位

map 模块有 5 个 Controller字典、组织、站点、车辆和地理编码。

数据和依赖:

  • tab_truck_remote_sync_realtime_info:车辆地图投影;
  • tab_outside_hydrogen_site:站点投影;
  • Hasp、远程实际车辆接口和高德 REST API
  • MapSyncTask 定期同步车辆与站点。

结论OneOS 地图适合内部业务展示,不适合作为车辆数据中台遥测源。两套地图需要统一 WGS-84 到 GCJ-02 的显示转换,但原始存储坐标必须保留来源和坐标系标识。

3.5 资产后市场与合规

覆盖领域包括:

  • 保险采购、保单、OCR14 张表、约 69 个 HTTP 方法;
  • 车辆异常异动:vehicle_abnormal_move*
  • 故障:vehicle_fault_manage
  • 年检、年审、车辆证书、交通违章;
  • 维修站、救援队、检查站;
  • 备件、出入库和仓库;
  • 培训材料与培训记录。

这些业务可以消费车辆中台的里程、位置、在线、告警证据,但车辆中台不能反向改写合同、保险、证照、结算或事故事实。涉及锁车、控车的能力不在本分析和实施范围。

3.6 能源与工作流

  • 加氢站、加氢台账、加氢场站、充电站;
  • 消息、通知规则、待办任务和工作台;
  • 通过 RemoteWorkflowServiceRemoteUserServiceRemoteDictServiceRemoteFileService 等 Dubbo 服务依赖 ln-cloud
  • 定时生成账单、合同到期提醒、证照到期提醒、台账状态同步等。

4. 接口与安全边界

4.1 已有安全机制

  • 网关 AuthFilter 对非白名单请求执行 StpUtil.checkLogin()
  • 微服务 SecurityConfiguration 可通过 Same-Token 验证请求是否由网关转发;
  • actuator 使用 Basic Auth
  • 网关把 /asset/** 转发到 ln-asset-management

这些机制只能证明请求已登录或来自网关,不能自动证明用户有某个业务动作权限,更不能证明客户只能访问自己的车辆。

4.2 接口级授权缺口

静态扫描 93 个业务 Controller只有 1 个文件出现 @SaCheckPermission 等细粒度权限注解;另有 3 个 Controller/回调路径使用 @SaIgnore。部分数据权限由 Mapper/DataPermission 处理,但没有形成覆盖所有车辆、合同、地图和导出入口的统一客户 Scope。

因此:

  • OneOS 现有 REST API 只能作为内部业务接口;
  • 不能直接公网开放 8701
  • 不能把 customerId 查询参数或 X-Customer-Id 请求头当作授权身份;
  • 车辆数据中台应在自身底层查询统一注入 VIN Scope并对详情返回 404避免泄漏对象存在性。

4.3 Dubbo 接口评估

ln-asset-api 暴露 20 个远程服务,包括车辆、客户、合同匹配、充电/加氢站、异常异动、保险、结算和任务等。

车辆数据中台当前不应直接调用 RemoteVehicleService.listByCustomerId:实现忽略客户 ID并按有效车辆返回全量结果。可复用的 Dubbo 接口必须逐个做参数、范围、分页、超时和失败策略审计RPC 不等于安全边界。

5. 数据库现状

生产只读元数据基线:

指标 结果
基础表 448
数据体积 约 2.63 GB
索引体积 约 381 MB
有效车辆 1,209
当前事务事实候选车辆 639
可安全发布 Scope 613
隔离关系 26

448 张表明显多于 158 个实体映射因为数据库还包含历史表、BI 表、手工迁移表、备份表和动态月表。迁移、备份和运行表混放在同一业务库,增加容量、权限和误操作风险。

5.1 API 请求日志容量与隐私风险

api_request_log_202606api_request_log_202607 合计约 2.19 GB约占全库数据体积 83%。源码证据:

  • ApiLogWebConfig 把全局拦截器挂到几乎所有业务路径;
  • ApiLogConfig 默认记录参数、请求体、响应体和请求头;
  • ApiLogInterceptor.getRequestHeaders() 不脱敏任何请求头;
  • ApiLogAspect.getRequestHeaders() 会脱敏 Authorization/Token/Cookie但仅用于 @ApiLog 切面;
  • @ApiLog 的接口同时被拦截器和切面保存,可能生成两条日志;
  • 清理接口只删除“当前时间减保留天数所在月份”一张表内的旧行,并不会遍历或删除所有更早月表;异常被吞掉;
  • /api-request-log/clean 没有细粒度权限注解。

这是 P0 安全和运维风险:日志可能包含登录凭证、身份证、手机号、合同、签章、附件地址和完整业务响应,并持续快速增长。

5.2 关键索引和约束

已确认:

  • vehicle_info 有车牌索引,但 VIN 没有索引或唯一约束;
  • vehicle_lease_order_record.vehicle_idvehicle_status.vehicle_id 只有普通索引,没有唯一约束;
  • vehicle_lease_order_record.customer_id 缺少 Scope 查询索引;
  • delivery_vehicle.vehicle_idreturn_vehicle_task.delivery_vehicle_id 已有普通/组合索引;
  • 生产数据存在 1 组“一车多聚合记录”和大量聚合/历史差异,不能直接添加唯一约束。

任何清理、唯一约束或索引 DDL 都必须单独审批,不属于当前只读分析。

6. 可靠性与可维护性

6.1 超大类热点

文件 行数(约) 风险
VehicleLeaseContractFullServiceImpl 6,082 合同、工作流、附件和聚合职责耦合
ReturnTaskServiceImpl 4,015 草稿、完成、签章、结算与聚合边界混合
ReturnSettlementServiceImpl 3,902 财务聚合复杂、回滚边界难验证
InsuranceProcurement2ServiceImpl 3,626 OCR、任务、保单、附件和状态混合
HydrogenFuelLedgerServiceImpl 3,322 导入、匹配、财务状态耦合
VehicleTransferServiceImpl 3,268 调拨、车辆状态、工作流耦合
DeliveryTaskServiceImpl 2,715 交车事实和下游副作用耦合

测试集中在加氢、保险辅助逻辑、证照和少量 Mapper没有覆盖合同保存、交车完成、还车草稿、还车完成、再次交车、丙方客户、换车等 Scope 核心用例。

6.2 事务和错误处理

106 个 service/impl 文件中约 63 个文件出现 @Transactional,但“存在注解”不代表跨 Dubbo、工作流、签章、文件和本地数据库具备原子性。核心链路存在捕获异常后只记日志、继续返回成功的模式导致任务状态与聚合表可能不一致。

6.3 定时任务

源码有 24 个 @Scheduled 文件,应用主类全局启用调度,未发现 ShedLock 或等价分布式锁。若生产运行多个实例,账单生成、到期提醒、地图同步、证照状态同步等任务可能重复执行。部署前必须确认生产实例数和任务幂等性。

6.4 配置和交付

  • application.yml 是 Git 跟踪文件,包含邮件、短信和第三方服务的凭证型配置项;部分值看起来不是纯占位符,必须在不打印原值的前提下轮换并迁到密钥管理/Nacos
  • README 只给出 Swagger 地址,没有依赖、构建、配置、迁移、部署、回滚、健康检查和故障处置说明;
  • Dockerfile 默认测试环境,若生产变量遗漏可能连入错误命名空间;
  • 私有 Maven 仓库凭证缺失会阻断可重复构建;
  • 未发现 CI 门禁,无法证明每次发布都执行测试、依赖扫描和镜像校验。

6.5 可从源码推导的运维顺序

仓库没有 OneOS 专用生产运维手册,ln-cloud/README.md 基本是上游 RuoYi 框架说明Nacos README 只有“复制配置”的一句提示。以下只能作为源码推导,不能替代生产值班手册:

  1. 先启动 MySQL、Redis、Nacos以及文件存储/资源服务所需基础设施;
  2. 在对应 namespace/group 中准备 application-common.ymldatasource.ymlln-asset-management.yaml
  3. 启动 ruoyi-systemruoyi-resourceruoyi-workflow 等被 Dubbo 引用的服务;
  4. 启动 ruoyi-authruoyi-gateway
  5. 最后启动 ln-asset-management,核验 Nacos 注册、Dubbo 引用、数据库、Redis、RabbitMQ、文件服务和 actuator
  6. 确认只有一个实例执行非幂等 @Scheduled,或先证明所有定时任务具备分布式幂等;
  7. 再开放 /asset/** 流量并检查错误率、Dubbo 超时、数据库连接池、API 日志增速和任务重复执行。

构建时应显式选择 profile并避免 Maven package 阶段意外连接 Docker daemon

mvn -Pprod -Ddocker.skip=true clean package

该命令当前仍依赖公司私有 Maven 仓库凭证。Dockerfile 自带的 SPRING_PROFILE_ACTIVE=testNAMESPACE=test 必须由生产环境显式覆盖;否则不能视为生产可部署制品。

生产运维说明仍缺少真实部署拓扑、实例数、镜像仓库流程、Nacos 配置版本、SQL 迁移账本、备份恢复、发布回滚、健康检查阈值、告警接收人、日志保留和密钥轮换。未补齐前,不建议自动化改动或独立部署 OneOS。

7. 风险矩阵

等级 风险 当前处置
P0 API 日志可能保存未脱敏认证头和大量敏感请求/响应 不改 OneOS立即限制日志查询/清理接口访问,制定脱敏、保留和轮换方案后另行审批
P0 listByCustomerId 返回全量车辆 数据中台禁用该接口,使用只读事务事实快照
P0 登录校验不等于业务/客户数据权限 OneOS 不公开;数据中台统一执行 VIN Scope
P0 客户账号与业务客户没有可信映射 外部客户入口保持关闭
P1 聚合生命周期被草稿/合同保存影响 读取交还车事务事实,聚合仅作交叉校验
P1 关键业务异常被吞掉,状态可能不一致 快照失败关闭并隔离;上游修复需重新同步批准
P1 多副本定时任务可能重复 上线前确认单实例或任务幂等/分布式锁
P1 VIN、聚合和状态缺少唯一约束 不直接 DDL先清理异常并做影子验证
P1 核心生命周期测试缺失 将合同/交还车/换车作为未来修改的强制回归门禁
P1 凭证型配置进入源码 安全轮换和密钥迁移需单独紧急流程
P2 超大类、命名和 URL 漂移 分领域抽取应用服务,保持兼容接口
P2 运维文档与 CI 缺失 补齐构建、发布、回滚、监控和演练说明

8. 对车辆数据中台的可复用与禁止清单

可只读复用

  • vehicle_infoVIN、车牌、车型和主档
  • vehicle_model:车型能力和显示配置;
  • vehicle_statusOneOS 业务运营状态;
  • customer_infovehicle_lease_contract_info:客户和合同;
  • delivery_vehiclereturn_vehicle_task:当前持有生命周期;
  • 停车场、站点、司机等低频主数据;
  • 所有读取都通过专用表级 SELECT 账号和周期快照。

不作为权威来源

  • OneOS 地图投影中的在线状态、位置和里程;
  • vehicle_info.customer_id
  • 单独的 vehicle_lease_order_record.last_return_time
  • vehicle_lease_order_record_log 最大 ID
  • 客户手机号与系统用户手机号的自动匹配;
  • 客户请求参数中的客户 ID。

禁止回写

  • 合同、交车、还车、换车;
  • 锁车、控车;
  • 保险、事故、违章、证照、结算和发票;
  • OneOS 用户和客户归属;
  • 任何生产数据修复或 DDL除非用户另行明确批准。

9. 分阶段建议

阶段 A只读基线已完成

  • 仓库和模块清单;
  • 生产表规模、车辆/客户/Scope 数据质量;
  • 生命周期和权限风险;
  • OneOS 保持零修改。

阶段 B车辆数据中台只读投影代码已准备尚未部署

  • 专用只读账号只授予 7 张必要表 SELECT
  • 两分钟一次读取交还车事务事实;
  • 613 条安全关系发布26 条隔离;
  • 内容寻址版本、事务整体切换、异常比例门禁;
  • ECS 当前仍缺 ONEOS_MYSQL_DSN、平台迁移 012 和同步 timer。

阶段 C客户身份与 API Scope未完成

  • 明确可信客户身份来源;
  • 平台 Principal 增加主体类型和客户 ID
  • 对监控、车辆、轨迹、历史、统计、告警、导出和地图统一注入 Scope
  • 完成双客户越权测试后才允许灰度。

阶段 DOneOS 风险治理(未获授权)

如用户未来批准,应优先按独立批次处理:

  1. API 日志脱敏、去重、保留策略和访问权限;
  2. 客户车辆 RPC 失败关闭;
  3. 聚合写入的事务与生命周期边界;
  4. 定时任务幂等或分布式锁;
  5. 凭证轮换、构建和运维门禁。

每个批次都必须先同步文件、行为变化、数据库影响、测试和回滚方案,不与数据修复或 DDL 混合发布。

10. 证据索引

  • 系统集成与 Scopedocs/oneos-integration-analysis.md
  • 生产只读审计:docs/oneos-production-audit-report.md
  • 业务影响:docs/oneos-business-impact-matrix.md
  • 客户 API 覆盖:docs/customer-scope-api-enforcement-matrix.md
  • Scope 契约:docs/oneos-customer-vehicle-scope-contract.md
  • OneOS 网关认证:ln-cloud/ruoyi-gateway/.../AuthFilter.java
  • 微服务 Same-Tokenln-cloud/ruoyi-common/ruoyi-common-security/.../SecurityConfiguration.java
  • 全局 API 日志:ln-asset-management/src/main/java/com/ln/asset/common/log/
  • 租赁生命周期:ln-asset-management/src/main/java/com/ln/asset/modules/contract/
  • 车辆主档:ln-asset-management/src/main/java/com/ln/asset/modules/vihicle/
  • 远程接口:ln-asset-management/ln-asset-api/src/main/java/com/ln/asset/api/