21 KiB
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_vehicle和return_vehicle_task事务事实判断,vehicle_lease_order_record仅用于客户归属交叉校验。
当前不能安全公开 OneOS 接口,主要原因包括:
RemoteVehicleService.listByCustomerId当前忽略客户 ID,存在返回全量车辆风险;- 网关能证明“已登录”,但 93 个业务 Controller 中只有 1 个检出细粒度权限注解,不能证明接口级或客户级授权完整;
- 全局 API 日志拦截器会记录请求头、请求体和响应体,且未像注解切面一样脱敏 Authorization、Token 和 Cookie;
- 注解接口同时被全局拦截器与
@ApiLog切面记录,存在重复日志;两个月日志表约占生产库数据体积 83%; - 租赁聚合表会被合同保存和还车草稿等非最终业务动作影响,不能单独作为授权真值;
- 核心交车、还车和合同类达到 2,700~6,000 行,自动化测试没有覆盖核心生命周期;
- 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 21;Spring Boot 3.5.10;Spring Cloud 2025.0.0;
- MyBatis-Plus 3.5.15,MySQL Connector/J 9.5;
- Nacos 配置与注册、Dubbo 服务、Sa-Token、RabbitMQ、异步和定时任务;
- 主服务端口 8701,网关路由
/asset/**后去除一层前缀; - Dockerfile 默认
testprofile,生产实际配置依赖 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:车型;VehicleRealtimeLocationController:OneOS 内部实时位置投影;PrepareCarController:备车;VehicleLicenseController、批量上牌:证照和上牌;VehicleTransferController:调拨;AftermarketDeviceController:后装设备;AccidentInfoController:事故;VehicleCheckItemController、VehicleMaintenanceItemController:检查和维保配置。
主要表:vehicle_info、vehicle_model、vehicle_status、vehicle_realtime_location、prepare_car、vehicle_transfer、vehicle_license、aftermarket_device、accident_info、tab_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_info、vehicle_lease_contract_log; - 合同车辆:
vehicle_lease_order、vehicle_lease_order_detail; - 交车:
delivery_task_subject、delivery_vehicle、delivery_vehicle_check_item; - 还车:
return_vehicle_task、return_vehicle_check_item; - 换车:
vehicle_replacement; - 当前聚合与历史:
vehicle_lease_order_record、vehicle_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 资产后市场与合规
覆盖领域包括:
- 保险采购、保单、OCR:14 张表、约 69 个 HTTP 方法;
- 车辆异常异动:
vehicle_abnormal_move*; - 故障:
vehicle_fault_manage; - 年检、年审、车辆证书、交通违章;
- 维修站、救援队、检查站;
- 备件、出入库和仓库;
- 培训材料与培训记录。
这些业务可以消费车辆中台的里程、位置、在线、告警证据,但车辆中台不能反向改写合同、保险、证照、结算或事故事实。涉及锁车、控车的能力不在本分析和实施范围。
3.6 能源与工作流
- 加氢站、加氢台账、加氢场站、充电站;
- 消息、通知规则、待办任务和工作台;
- 通过
RemoteWorkflowService、RemoteUserService、RemoteDictService、RemoteFileService等 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_202606 和 api_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_id、vehicle_status.vehicle_id只有普通索引,没有唯一约束;vehicle_lease_order_record.customer_id缺少 Scope 查询索引;delivery_vehicle.vehicle_id和return_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 只有“复制配置”的一句提示。以下只能作为源码推导,不能替代生产值班手册:
- 先启动 MySQL、Redis、Nacos,以及文件存储/资源服务所需基础设施;
- 在对应 namespace/group 中准备
application-common.yml、datasource.yml、ln-asset-management.yaml; - 启动
ruoyi-system、ruoyi-resource、ruoyi-workflow等被 Dubbo 引用的服务; - 启动
ruoyi-auth和ruoyi-gateway; - 最后启动
ln-asset-management,核验 Nacos 注册、Dubbo 引用、数据库、Redis、RabbitMQ、文件服务和 actuator; - 确认只有一个实例执行非幂等
@Scheduled,或先证明所有定时任务具备分布式幂等; - 再开放
/asset/**流量,并检查错误率、Dubbo 超时、数据库连接池、API 日志增速和任务重复执行。
构建时应显式选择 profile,并避免 Maven package 阶段意外连接 Docker daemon:
mvn -Pprod -Ddocker.skip=true clean package
该命令当前仍依赖公司私有 Maven 仓库凭证。Dockerfile 自带的 SPRING_PROFILE_ACTIVE=test 和 NAMESPACE=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_info:VIN、车牌、车型和主档;vehicle_model:车型能力和显示配置;vehicle_status:OneOS 业务运营状态;customer_info、vehicle_lease_contract_info:客户和合同;delivery_vehicle、return_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;
- 完成双客户越权测试后才允许灰度。
阶段 D:OneOS 风险治理(未获授权)
如用户未来批准,应优先按独立批次处理:
- API 日志脱敏、去重、保留策略和访问权限;
- 客户车辆 RPC 失败关闭;
- 聚合写入的事务与生命周期边界;
- 定时任务幂等或分布式锁;
- 凭证轮换、构建和运维门禁。
每个批次都必须先同步文件、行为变化、数据库影响、测试和回滚方案,不与数据修复或 DDL 混合发布。
10. 证据索引
- 系统集成与 Scope:
docs/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-Token:
ln-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/。