Files
mileage-bonus/.claude_plans/stateful-waddling-elephant.md
kkfluous 573f8397a6 chore: 添加输入输出文件 + .claude记忆和计划
输入文件:
- 租赁任务考核_2026年{1,2,3}月.xlsx (考核源数据)
- {1,2}月.xlsx (客户盈亏表)
- 车辆里程考核与奖金发放规则(V.1.2).docx

输出文件:
- 里程任务考核_{1,2,3}月核算.xlsx (月度核算结果)
- 里程任务考核_Q1汇总.xlsx (含车辆台账)
- 3月客户盈亏表(待填写).xlsx (模版)

.claude_memory: 项目记忆(规则/偏好/架构/测试车辆)
.claude_plans: 历次计划文件

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:09:24 +08:00

28 KiB
Raw Permalink Blame History

Phase 2 ETC 模块完成计划Controller + API Client + 前端)

Context

Phase 1 基础设施层FeeType 枚举、DeductionRequest、IDeductionService 重构、ContractMatchService、ReviewConfig 扩展)已完成并编译通过。 Phase 2 ETC 模块后端核心Entity/Mapper/Service/Event/Listener已完成并编译通过。

本次任务: 完成 Phase 2 剩余部分:

  1. ETC 后端 Controller 层3 个 Controller
  2. EtczjApiClientetczj.com HTTP 客户端 + OCR 验证码)
  3. 前端 ETC 配置页面 + ETC 账单查询页面

用户决策:

  • 账户结构:共用一个能源账户(三种费用从同一余额扣款)
  • 账单模式:各费用类型独立账单
  • 业务流程ETC/电费与氢费完全一致(合同匹配 → 审核 → 扣款)
  • 数据源:先设计通用框架,具体 API/Excel 格式后续对接

架构方案:独立明细表 + 共享账户层

modules/
  station/        ← 已有:氢费数据源(不动)
  etc/            ← 新增ETC 数据源
  electricity/    ← 新增:电费数据源
  energy/         ← 已有:共享结算层(小幅扩展)
  payment/        ← 已有:款项管理(小幅扩展)

核心原则: 三种费用的明细/账单各自独立(字段差异大),但扣款引擎、账户、流水、充值、款项管理完全共享。


Phase 1: 基础设施层改造energy 域)

1.1 新增 FeeType 枚举

文件: modules/energy/enums/FeeType.java(新建)

public enum FeeType {
    HYDROGEN(1, "氢费"),
    ETC(2, "高速通行费"),
    ELECTRICITY(3, "电费");

    private final int code;
    private final String label;
}

1.2 重构 IDeductionService → 接受通用扣款请求

改动文件:

  • modules/energy/service/IDeductionService.java
  • modules/energy/service/impl/DeductionServiceImpl.java

改动内容:

新增通用 DTO DeductionRequest

@Data @Builder
public class DeductionRequest {
    private FeeType feeType;
    private Long detailId;          // 明细ID在各自的明细表中
    private Long customerId;
    private String customerName;
    private Long contractId;
    private BigDecimal amount;       // 扣款金额
    private Integer paymentMode;     // 1-预充值 2-月结 3-自行结算
    private Integer deductionStatus; // 当前扣款状态(幂等守卫用)
}

接口签名变更:

// 原DeductionResult deduct(EnergyHydrogenDetail detail);
// 新:
DeductionResult deduct(DeductionRequest request);
void reDeduct(DeductionRequest request, BigDecimal newAmount);

DeductionServiceImpl 改动点:

  • deduct() 方法参数从 EnergyHydrogenDetail 改为 DeductionRequest,逻辑不变(读 customerId/amount/contractId/paymentMode
  • 移除 detailMapper.updateById(detail) —— 扣款服务不再直接更新明细表,改为返回 DeductionResult,由调用方负责更新各自的明细表扣款状态
  • 流水 description 加入 feeType.getLabel()(如 "ETC扣款" / "电费扣款"
  • reDeduct() 同理,不再直接操作 detailMapper

向后兼容:EnergyDetailImportListener(氢费监听器)中构造 DeductionRequest.fromHydrogenDetail(detail),调用新接口后手动更新氢费明细扣款状态。

1.3 energy_account_transaction 表加 fee_type

DDL 迁移脚本: db/energy/V2__add_fee_type_to_transaction.sql

ALTER TABLE energy_account_transaction
  ADD COLUMN fee_type TINYINT NOT NULL DEFAULT 1 COMMENT '费用类型1-氢费 2-ETC 3-电费';
ALTER TABLE energy_account_transaction
  ADD INDEX idx_eat_fee_type (fee_type);

EnergyAccountTransaction.java 新增 feeType 字段。

1.4 customer_payment_item 款项解构扩展

fee_type 枚举扩展(已有字段):

  • 现有1-租赁费 2-氢费充值 3-押金 4-违约金 5-其他
  • 新增6-ETC充值 7-电费充值

PaymentFlowService 的流转逻辑需根据新 fee_type 创建对应充值单。

1.5 通用合同匹配抽取

现有合同匹配逻辑在 EnergyDetailImportListener 中(车牌+时间→合同)。 抽取为共享服务:

新建: modules/energy/service/IContractMatchService.java

public interface IContractMatchService {
    ContractMatchResult matchContract(String plateNumber, Date eventTime);
}

返回 ContractMatchResultcustomerId, customerName, contractId, contractCode, costType, paymentMode。 ETC/电费/氢费三个监听器共用此服务。

1.6 审核配置扩展

energy_review_config 表加 fee_type 列:

ALTER TABLE energy_review_config
  ADD COLUMN fee_type TINYINT NOT NULL DEFAULT 1 COMMENT '费用类型1-氢费 2-ETC 3-电费';
DROP INDEX uk_erc_level_customer ON energy_review_config;
CREATE UNIQUE INDEX uk_erc_level_customer_fee ON energy_review_config (config_level, customer_id, fee_type);

每种费用类型可独立配置"是否需要审核后才扣款"。


Phase 2: ETC 模块(modules/etc/

2.0 ETC 数据源逆向分析etczj.com - 浙江货车ETC

平台信息: https://www.etczj.com Nuxt.js + Element UI 前端nginx/1.27.2 后端)

认证流程:

1. GET  /createCaptcha?verifyCodeSize=null&tmp={random}&secret={guid}  → 图形验证码图片
2. POST /member/toLogin?secret={guid}
   Body: { acctId: "手机号", password: "Base64编码密码", checkCode: "验证码", msgCode: "", secret: guid }
   Response: { state: "1", payload: { randomVal: "xxx", signState: "1" } }
3. 后续请求 Header: Randomval: {randomVal}(存 localStorage

核心业务 API

API 方法 说明 关键参数
/vehicleManage/queryVehicleConsumptionDetailPage POST 通行记录分页 transTimeBegin/End, postingTimeBegin/End, vehicleCode, licenseColor, vcEnStation, vcExStation, currPage, pageSize
/vehicleManage/sumVehicleToll POST 通行费汇总 同上(返回 totalPassAmount, totalServiceAmount
/vehicleManage/viewVehiclePage POST 车辆列表 vehicleCode, currPage, pageSize
/largeFileExport/billDetails POST 通行记录导出 postingTimeBegin/End, transTimeBegin/End, vehicleCode
/member/flowList POST 账单流水 -
/member/viewMember POST 用户信息 -

通行记录响应字段映射 → etc_toll_record 表:

etczj 字段 含义 → 表字段
vehicleCode 车牌号码 plate_number
licenseColor 车牌颜色(0-6) license_color
cardType 卡类型 card_type
cardCode 通行卡号 etc_card_number
postingTimeStr 记账日期 posting_time
transDate + transTime 通行日期+时间 trans_time
enStation 入口站 entry_station_name
exStation 出口站 exit_station_name
dToll 通行费用(元) toll_amount
serviceFee 服务费(元) service_fee
appealStatus 申诉状态 appeal_status

同步策略设计要点:

  • 登录需图形验证码 → 需 OCR 或人工介入。建议:首次登录获取 session 后缓存 randomValsession 过期时告警人工重新登录
  • 增量同步:按 postingTimeBegin/End(记账日期)拉取,每次从 lastSyncTime 开始
  • 去重键:vehicleCode + transDate + transTime + enStation + exStation(平台无唯一订单号)
  • 分页:currPage + pageSize,默认 pageSize=5建议调大到 100
  • 日期限制:时间范围最多 31 天

2.1 数据库表

etc_toll_recordETC通行记录表

字段 类型 说明
id BIGINT 主键
record_code VARCHAR(32) 记录编码(系统生成,唯一)
etc_card_number VARCHAR(64) 通行卡号(cardCode)
card_type VARCHAR(32) 卡类型(cardType)
plate_number VARCHAR(16) 车牌号
license_color TINYINT 车牌颜色(0-6)
vehicle_id BIGINT 车辆ID匹配后
contract_id BIGINT 合同ID匹配后
customer_id BIGINT 客户ID匹配后
customer_name VARCHAR(128) 客户名称
entry_station_name VARCHAR(128) 入口站
exit_station_name VARCHAR(128) 出口站
trans_time DATETIME 通行时间transDate+transTime
posting_time DATETIME 记账日期(postingTimeStr)
toll_amount DECIMAL(10,2) 通行费(元)(dToll)
service_fee DECIMAL(10,2) 服务费(元)(serviceFee)
total_amount DECIMAL(10,2) 合计金额(toll+service)
appeal_status TINYINT 申诉状态
cost_type TINYINT 费用承担方
payment_mode TINYINT 付款模式
contract_matched TINYINT 合同匹配状态
review_status TINYINT 审核状态
deduction_status TINYINT 扣款状态
bill_id BIGINT 关联账单ID
source_type TINYINT 来源1-API同步
source_dedup_key VARCHAR(128) 去重键(车牌+通行时间+入口+出口)
is_oneos_vehicle TINYINT 是否OneOS车辆
+ BaseEntity 审计字段

etc_sync_configetc_sync_log:复用 station 的 sync_config/sync_log 结构,provider_type 固定为 ETCZJ。额外字段:acct_id(手机号)、password(加密存储)。

energy_etc_billETC账单表

字段 类型 说明
id BIGINT 主键
bill_code VARCHAR(32) 账单编码
customer_id BIGINT 客户ID
bill_period_start/end DATE 账单周期
total_toll_count INT 通行笔数
total_toll_amount DECIMAL(12,2) 通行总金额
total_service_fee DECIMAL(12,2) 服务费总额
receivable_amount DECIMAL(12,2) 应收金额
actual_amount DECIMAL(12,2) 实收金额
adjustment_amount DECIMAL(12,2) 调整额
payment_status TINYINT 支付状态
review_status TINYINT 审核状态
+ 审核/财务/审计字段

2.2 代码结构

modules/etc/
  entity/
    record/po/EtcTollRecord.java
    record/vo/EtcTollRecordVO.java
    record/query/EtcTollRecordQuery.java
    record/req/UpdateEtcRecordReq.java
    sync/po/EtcSyncConfig.java
    sync/po/EtcSyncLog.java
    bill/po/EnergyEtcBill.java
    bill/vo/EtcBillVO.java
    bill/req/EtcBillGenerateReq.java
  mapper/
    EtcTollRecordMapper.java
    EtcSyncConfigMapper.java
    EtcSyncLogMapper.java
    EnergyEtcBillMapper.java
  service/
    IEtcTollRecordService.java
    IEtcSyncConfigService.java
    IEtcBillService.java
    impl/EtcTollRecordServiceImpl.java
    impl/EtcSyncConfigServiceImpl.java
    impl/EtcBillServiceImpl.java
    sync/EtcSyncStrategy.java          ← 策略接口
    sync/EtczjSyncStrategy.java        ← etczj.com 具体实现(登录+分页拉取+字段映射)
    sync/EtczjApiClient.java           ← HTTP 客户端(登录/session管理/通行记录查询)
    sync/EtczjApiResponse.java         ← 响应 DTO
    ingest/EtcIngestTemplate.java      ← 模板方法extract→validate→dedup→match→persist→event
  controller/
    EtcTollRecordController.java
    EtcSyncConfigController.java
    EtcBillController.java
  event/
    EtcRecordImportedEvent.java
  listener/
    EtcDetailImportListener.java       ← 监听 EtcRecordImportedEvent执行合同匹配+扣款
  validation/
    EtcValidationChain.java

2.3 数据流

EtczjSyncStrategy 定时/手动同步:
  1. EtczjApiClient.login(acctId, password) → 获取 randomVal session
  2. 按日期范围分页调用 /vehicleManage/queryVehicleConsumptionDetailPage
     - 从 lastSyncTime 开始每次最多31天
     - pageSize=100循环翻页直到无更多数据
  3. 字段映射etczj 响应 → EtcTollRecordDTO
  4. → EtcIngestTemplate.ingest()
       → extract → validate → dedup(source_dedup_key) → matchVehicle → persist(etc_toll_record)
       → publishEvent(EtcRecordImportedEvent)
  5. → EtcDetailImportListener
       → 筛选 is_oneos_vehicle=1
       → contractMatchService.matchContract(plateNumber, transTime)
       → 审核配置检查FeeType.ETC
       → deductionService.deduct(DeductionRequest)
       → 更新 etc_toll_record.deduction_status

Session 管理:
  - randomVal 缓存在 Rediskey: `etc:session:{configId}`,过期后自动重新登录
  - 图形验证码处理OCR 自动识别Tesseract/百度OCR
    - GET /createCaptcha?secret={guid} → 图片
    - OCR 识别 → 4位数字
    - 识别失败重试刷新验证码重试最多3次
    - 3次均失败 → 告警通知人工介入
  - 去重策略vehicleCode + transTime + enStation + exStation 组合键

2.4 API 接口(约 20 个)

模块 接口数
ETC 通行记录 CRUD + 审核 + 导出 8
ETC 同步配置 + 手动触发 + 日志 7
ETC 账单生成 + 审核 + 调整项 8

Phase 3: 电费模块(modules/electricity/

3.1 数据库表

electricity_charge_record(充电记录表):

字段 类型 说明
id BIGINT 主键
record_code VARCHAR(32) 记录编码
charging_station_id BIGINT 充电站ID关联已有 charging_station 表)
charging_station_name VARCHAR(128) 充电站名称
plate_number VARCHAR(16) 车牌号
vehicle_id / contract_id / customer_id BIGINT 匹配后填充
charging_start_time DATETIME 充电开始
charging_end_time DATETIME 充电结束
charging_duration INT 时长(分钟)
kwh DECIMAL(10,4) 充电量(度)
unit_price DECIMAL(10,4) 单价(元/度)
charge_amount DECIMAL(10,2) 电费(元)
service_fee DECIMAL(10,2) 服务费(元)
total_amount DECIMAL(10,2) 合计金额
cost_type / payment_mode / contract_matched / review_status / deduction_status / bill_id 与氢费/ETC 一致
source_type TINYINT 来源1-Excel导入 2-RPA导入
source_row_key VARCHAR(64) 源Excel行唯一键去重
is_oneos_vehicle TINYINT 是否OneOS车辆
+ BaseEntity 审计字段

energy_electricity_bill(电费账单表): 结构类似 ETC 账单,特有字段:total_kwh, total_charge_amount, total_service_fee

3.2 代码结构

与 ETC 模块镜像,核心差异:

  • 无 API 同步(暂时),数据入口为 Excel 导入(手动上传 / RPA 落盘后系统扫描)
  • ElectricityExcelIngestStrategy 实现 ElectricityIngestTemplate
  • 关联已有 chargingstation/ 模块的充电站主数据
  • 校验链包含:电量/金额一致性校验、充电站匹配校验

3.3 数据流

Excel 手动导入 / RPA 定期落盘
  → ElectricityIngestTemplate.ingest()
    → extract(解析Excel) → validate → dedup(source_row_key) → matchVehicle → persist
    → publishEvent(ElectricityRecordImportedEvent)
  → ElectricityDetailImportListener
    → 合同匹配 → 审核配置检查FeeType.ELECTRICITY→ 扣款 → 更新状态

3.4 API 接口(约 15 个)

模块 接口数
充电记录 CRUD + 审核 + 导入/导出 8
电费账单生成 + 审核 + 调整项 7

Phase 4: 账户层统一视图

4.1 流水查询增加 fee_type 过滤

改动文件:

  • TransactionQuery.java — 新增 feeType 可选参数
  • EnergyAccountController.java — 流水分页接口支持按费用类型筛选

4.2 账户汇总接口

新增接口: GET /energy/account/{id}/fee-summary

返回各费用类型的扣款/充值汇总:

{
  "hydrogen": { "totalDeducted": 50000, "count": 320 },
  "etc": { "totalDeducted": 12000, "count": 580 },
  "electricity": { "totalDeducted": 8000, "count": 150 }
}

Phase 5: 前端菜单与页面

5.1 菜单结构

能源管理
  ├── 加氢明细(已有)
  ├── ETC 通行记录(新增)
  ├── 充电记录(新增)
  ├── 能源账户(已有,增加 fee_type 筛选)
  ├── 充值单管理(已有)
  ├── 氢费账单(已有)
  ├── ETC 账单(新增)
  ├── 电费账单(新增)
  └── 审核配置(已有,增加 fee_type 维度)

加氢站管理(已有,不动)

ETC 管理(新增)
  ├── ETC 同步配置
  └── ETC 同步日志

款项管理(已有)
  └── fee_type 解构类型新增 ETC充值/电费充值

实施顺序

步骤 内容 依赖
1 Phase 1 基础设施FeeType枚举、DeductionRequest、IDeductionService重构、DB迁移、ContractMatchService抽取、ReviewConfig扩展
2 Phase 1 向后兼容(更新氢费监听器/服务适配新接口) Step 1
3 Phase 2 ETC 模块实体→Mapper→Service→Controller→事件→监听器→测试 Step 2
4 Phase 3 电费模块(同上) Step 2可与 Step 3 并行
5 Phase 4 账户层统一视图 Step 3 & 4
6 Phase 5 前端页面 Step 3 & 4
7 Payment 域扩展fee_type 解构+流转) Step 1

关键改动文件清单

修改已有文件

文件 改动
energy/service/IDeductionService.java 接口签名改为 DeductionRequest
energy/service/impl/DeductionServiceImpl.java 实现适配,移除 detailMapper 直接操作
energy/entity/account/po/EnergyAccountTransaction.java 新增 feeType 字段
energy/listener/EnergyDetailImportListener.java 适配新 DeductionRequest抽取合同匹配逻辑
energy/entity/review/po/EnergyReviewConfig.java 新增 feeType 字段
energy/service/impl/ReviewConfigServiceImpl.java 查询时加 feeType 条件
energy/controller/EnergyAccountController.java 流水查询加 feeType 过滤
energy/entity/account/query/TransactionQuery.java 新增 feeType 参数
payment/entity/po/CustomerPaymentItem.java fee_type 枚举扩展文档
payment/service/impl/PaymentFlowServiceImpl.java 支持 ETC/电费充值流转

新建文件(按 Phase

  • Phase 1: ~5 文件FeeType, DeductionRequest, ContractMatchService 接口+实现, V2迁移脚本
  • Phase 2: ~20 文件ETC 全套 entity/mapper/service/controller/event/listener+ 3 张表 DDL
  • Phase 3: ~18 文件(电费全套)+ 2 张表 DDL
  • Phase 4: ~2 文件改动

验证方案

单元测试

  • DeductionServiceTest —— 验证新接口支持三种 FeeType
  • EtcIngestTemplateTest —— ETC 数据导入全流程
  • ElectricityIngestTemplateTest —— 电费 Excel 导入全流程
  • ContractMatchServiceTest —— 合同匹配逻辑

集成测试

  • EtcModuleIntegrationTest —— ETC 同步 → 导入 → 合同匹配 → 审核 → 扣款 → 账单生成
  • ElectricityModuleIntegrationTest —— Excel 导入 → 合同匹配 → 审核 → 扣款 → 账单生成
  • MultiFeeBillingIntegrationTest —— 三种费用共享账户扣款 → 流水 fee_type 正确 → 各自独立出账单

回归验证

  • 现有氢费全链路测试通过(EnergyModuleIntegrationTest
  • 现有款项管理测试通过(PaymentModuleIntegrationTest

Phase 2 剩余实施计划(本次任务)

已完成

  • Phase 1 基础设施层FeeType/DeductionRequest/IDeductionService/ContractMatchService/ReviewConfig
  • Phase 2 DDLdb/etc/V1__create_etc_tables.sql - 4 张表)
  • Phase 2 Entity POEtcTollRecord/EtcSyncConfig/EtcSyncLog/EnergyEtcBill
  • Phase 2 DTOEtcTollRecordVO/EtcTollRecordQuery/EtcBillVO/EtcBillGenerateReq
  • Phase 2 Mapper4 个)
  • Phase 2 Service 接口 + 实现IEtcTollRecordService/IEtcSyncConfigService/IEtcBillService
  • Phase 2 EventEtcRecordImportedEvent
  • Phase 2 ListenerEtcDetailImportListener
  • 编译通过

Step 1: ETC 后端 Controller 层

3 个 Controller沿用 EnergyBillController 的精确模式:

1.1 EtcTollRecordController.java

路径: modules/etc/controller/EtcTollRecordController.java 前缀: @RequestMapping("/etc/record") Tag @Tag(name = "ETC通行记录管理")

方法 路径 说明 调用
GET /page 分页查询 service.pageList(query)
GET /detail/{id} 详情 service.getDetail(id)
PUT /review 单条审核 service.review(id, approved, remark)
PUT /batch-review 批量审核 service.batchReview(ids, approved)
PUT /manual-match 手动匹配合同 service.manualMatch(detailId, contractId)
POST /export 导出 TODO
GET /statistics 统计数据 service.getStatistics()

1.2 EtcSyncConfigController.java

路径: modules/etc/controller/EtcSyncConfigController.java 前缀: @RequestMapping("/etc/sync-config") Tag @Tag(name = "ETC同步配置")

方法 路径 说明
GET /page 分页查询
GET /detail/{id} 详情
POST / 新增
PUT / 编辑
DELETE /{id} 删除
PUT /toggle/{id} 启用/停用
POST /trigger/{id} 手动触发同步
GET /log/{configId} 同步日志

1.3 EtcBillController.java

路径: modules/etc/controller/EtcBillController.java 前缀: @RequestMapping("/etc/bill") Tag @Tag(name = "ETC账单管理")

方法 路径 说明
GET /page 分页查询
GET /detail/{id} 详情
POST /generate/preview 生成预览
POST /generate 确认生成
PUT /review 审核
PUT /submit-finance/{id} 提交财务
DELETE /{id} 删除
POST /export 导出
GET /statistics 统计
GET /record/page/{billId} 关联通行记录分页

参考文件:

  • ln-asset-management/src/main/java/com/ln/asset/modules/energy/controller/EnergyBillController.java
  • ln-asset-management/src/main/java/com/ln/asset/modules/station/controller/SyncConfigController.java

Step 2: EtczjApiClientetczj.com HTTP 客户端)

新建文件:

  • modules/etc/service/sync/EtczjApiClient.java — HTTP 客户端
  • modules/etc/service/sync/EtczjApiResponse.java — 响应 DTO
  • modules/etc/service/sync/EtczjTollRecordDTO.java — 通行记录 DTO
  • modules/etc/service/sync/EtczjSyncStrategy.java — 同步策略实现

EtczjApiClient 核心方法:

@Slf4j
@Component
public class EtczjApiClient {
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    // 登录(获取 randomVal session
    public String login(String baseUrl, String acctId, String password) {
        // 1. GET /createCaptcha?secret={guid} → 验证码图片
        // 2. OCR 识别验证码Tesseract
        // 3. POST /member/toLogin?secret={guid}
        //    Body: { acctId, password: Base64(password), checkCode, secret }
        // 4. 返回 randomVal
    }

    // 查询通行记录
    public EtczjApiResponse<List<EtczjTollRecordDTO>> queryTollRecords(
        String baseUrl, String randomVal,
        String transTimeBegin, String transTimeEnd,
        int currPage, int pageSize) {
        // POST /vehicleManage/queryVehicleConsumptionDetailPage
        // Header: Randomval: {randomVal}
    }

    // 查询通行费汇总
    public EtczjApiResponse<Map<String, Object>> sumToll(
        String baseUrl, String randomVal,
        String transTimeBegin, String transTimeEnd) {
        // POST /vehicleManage/sumVehicleToll
    }
}

参考文件:

  • ln-asset-management/src/main/java/com/ln/asset/modules/station/feign/HecriApiClient.javaRestTemplate + ObjectMapper 模式)

Step 3: 前端 ETC 页面

技术栈: Vben Admin (Vue 3 + TypeScript + Ant Design Vue + VxeTable)

模式参考:

  • 路由:playground/src/router/routes/modules/system.ts
  • APIplayground/src/api/system/role.ts
  • 列表页:playground/src/views/system/role/list.vue
  • 列定义:playground/src/views/system/role/data.ts

3.1 API 层

新建文件: playground/src/api/etc/index.ts

export namespace EtcApi {
  export interface EtcSyncConfig { id: string; providerType: string; acctId: string; syncEnabled: 0|1; syncCron: string; lastSyncTime: string; lastSyncStatus: 0|1; }
  export interface EtcTollRecord { id: string; recordCode: string; plateNumber: string; entryStationName: string; exitStationName: string; transTime: string; tollAmount: number; serviceFee: number; totalAmount: number; reviewStatus: number; deductionStatus: number; }
  export interface EtcBill { id: string; billCode: string; customerName: string; billPeriodStart: string; billPeriodEnd: string; totalTollCount: number; totalTollAmount: number; receivableAmount: number; actualAmount: number; reviewStatus: number; paymentStatus: number; }
}

// ETC 同步配置 API
async function getEtcSyncConfigPage(params) { return requestClient.get('/etc/sync-config/page', { params }); }
async function addEtcSyncConfig(data) { return requestClient.post('/etc/sync-config', data); }
async function updateEtcSyncConfig(data) { return requestClient.put('/etc/sync-config', data); }
async function deleteEtcSyncConfig(id) { return requestClient.delete(`/etc/sync-config/${id}`); }
async function toggleEtcSync(id) { return requestClient.put(`/etc/sync-config/toggle/${id}`); }
async function triggerEtcSync(id) { return requestClient.post(`/etc/sync-config/trigger/${id}`); }
async function getEtcSyncLog(configId, params) { return requestClient.get(`/etc/sync-config/log/${configId}`, { params }); }

// ETC 账单 API
async function getEtcBillPage(params) { return requestClient.get('/etc/bill/page', { params }); }
async function getEtcBillDetail(id) { return requestClient.get(`/etc/bill/detail/${id}`); }
async function reviewEtcBill(data) { return requestClient.put('/etc/bill/review', data); }
// ... 其他

3.2 ETC 同步配置页面

新建文件:

  • playground/src/views/etc/sync-config/list.vue — 配置列表useVbenVxeGrid
  • playground/src/views/etc/sync-config/data.ts — 列定义 + 表单 schema
  • playground/src/views/etc/sync-config/modules/form.vue — 新增/编辑表单useVbenDrawer

页面功能:

  • 表格列供应商类型、登录账号、API地址、同步频率、上次同步时间/状态、启用状态
  • 操作:编辑、删除、启用/停用切换、手动触发同步
  • 新增/编辑抽屉账号、密码、API地址、同步 cron 表达式

3.3 ETC 账单查询页面

新建文件:

  • playground/src/views/etc/bill/list.vue — 账单列表
  • playground/src/views/etc/bill/data.ts — 列定义 + 搜索表单
  • playground/src/views/etc/bill/modules/detail.vue — 账单详情抽屉

页面功能:

  • 搜索条件:客户名称、账单周期、审核状态、支付状态
  • 表格列:账单编码、客户名称、账期、通行笔数、通行费总额、服务费总额、应收、实收、审核状态、支付状态
  • 操作:查看详情、审核、提交财务、删除
  • 详情抽屉:账单信息 + 关联通行记录分页列表

3.4 路由配置

新建文件: playground/src/router/routes/modules/etc.ts

const routes: RouteRecordRaw[] = [{
  meta: { icon: 'mdi:highway', order: 30, title: 'ETC管理' },
  name: 'Etc',
  path: '/etc',
  children: [
    { path: '/etc/sync-config', name: 'EtcSyncConfig', meta: { icon: 'mdi:sync', title: 'ETC同步配置' }, component: () => import('#/views/etc/sync-config/list.vue') },
    { path: '/etc/bill', name: 'EtcBill', meta: { icon: 'mdi:file-document-outline', title: 'ETC账单' }, component: () => import('#/views/etc/bill/list.vue') },
  ],
}];

实施顺序

步骤 内容 文件数
1 3 个 ETC Controller 3
2 EtczjApiClient + DTO + SyncStrategy 4
3 前端 API 层 1
4 前端 ETC 同步配置页面 3
5 前端 ETC 账单查询页面 3
6 前端路由配置 1
合计 15 个文件

验证方案

  • 后端:mvn compile 编译通过
  • 前端:cd ln-one-os-web/playground && pnpm dev 启动无报错
  • ETC 同步配置页面:可访问 /etc/sync-config表格加载正常
  • ETC 账单页面:可访问 /etc/bill表格加载正常
  • Swagger/swagger-ui.html 可看到 ETC 相关 3 组 API