industry-invoice-platform.md 28 KB

Implementation Plan: Industry Invoice Platform (行业发票平台)

Date: 2026-07-08 Branch: fapiao Status: Planning


Overview

Copy the Alipay industry invoice platform (https://fxkp.alipay.com/industry-invoice-platform/) as a new module in the payment platform. 8 pages with full CRUD, import/export, and mock APIs. Multi-tenant + enterprise + admin data scoping on all tables.


1. Database Tables

All tables use PaymentEnterpriseBaseEntity (inherits PaymentTenantBaseEntityPaymentBaseEntity), providing: id (snowflake), status, description, created_time, updated_time, tenant_id, enterprise_id.

Flyway migration file: V1.2__create_pay_invoice_tables.sql

1.1 pay_invoice_order — 交易及发票订单

Column Type Constraint Notes
id BIGINT PK (snowflake) From PaymentEnterpriseBaseEntity
status VARCHAR(10) DEFAULT '0' From PaymentEnterpriseBaseEntity
description TEXT From PaymentEnterpriseBaseEntity
created_time TIMESTAMP NOT NULL DEFAULT NOW() From PaymentEnterpriseBaseEntity
updated_time TIMESTAMP NOT NULL DEFAULT NOW() From PaymentEnterpriseBaseEntity
tenant_id BIGINT From PaymentTenantBaseEntity
enterprise_id VARCHAR(64) From PaymentEnterpriseBaseEntity
order_no VARCHAR(64) NOT NULL 订单编号
alipay_trade_no VARCHAR(64) 支付宝交易号
payment_time TIMESTAMP 支付时间
natural_person_name VARCHAR(64) 自然人姓名
collection_account_type VARCHAR(32) 收款账户类型: ALIPAY / BANK_CARD
tax_inclusive_amount DECIMAL(18,2) 含税金额
trade_status VARCHAR(32) NOT NULL DEFAULT 'PENDING_ASSOCIATE' 交易状态
invoice_no VARCHAR(64) 发票号码
invoice_pretax_amount DECIMAL(18,2) 发票税前金额
invoice_tax_amount DECIMAL(18,2) 发票税额
red_invoice_no VARCHAR(64) 红票号码
clerk_name VARCHAR(64) 营业员姓名
attachment_url TEXT 附件URL JSON array

Indexes:

  • idx_invoice_order_enterprise ON (enterprise_id)
  • idx_invoice_order_order_no ON (order_no)
  • idx_invoice_order_trade_no ON (alipay_trade_no)
  • idx_invoice_order_trade_status ON (trade_status)
  • idx_invoice_order_created_time ON (created_time)

1.2 pay_invoice_supplier — 供应商

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
supplier_name VARCHAR(128) NOT NULL 供应商名称
account_type VARCHAR(32) NOT NULL ALIPAY_PHONE / ALIPAY_EMAIL
collection_account VARCHAR(128) NOT NULL 收款账户
phone VARCHAR(20) 联系电话
confirm_status VARCHAR(32) NOT NULL DEFAULT 'PENDING' CONFIRMED / PENDING / REJECTED

Indexes:

  • idx_invoice_supplier_enterprise ON (enterprise_id)
  • idx_invoice_supplier_name ON (supplier_name)
  • idx_invoice_supplier_confirm_status ON (confirm_status)

1.3 pay_invoice_employee — 员工管理

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
employee_name VARCHAR(64) NOT NULL 员工姓名
phone VARCHAR(20) NOT NULL 手机号
id_number VARCHAR(20) NOT NULL 身份证号
role VARCHAR(32) NOT NULL CLERK / INVOICER / SUPER_ADMIN
allow_miniapp_supplier BOOLEAN DEFAULT FALSE 允许小程序选供应商

Indexes:

  • idx_invoice_employee_enterprise ON (enterprise_id)
  • idx_invoice_employee_role ON (role)

1.4 pay_invoice_product — 常用商品

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
product_name VARCHAR(128) NOT NULL 商品名称
category VARCHAR(32) NOT NULL 报废产品分类
unit VARCHAR(32) 单位
spec VARCHAR(128) 规格

Indexes:

  • idx_invoice_product_enterprise ON (enterprise_id)
  • idx_invoice_product_category ON (category)

1.5 pay_invoice_company — 企业信息

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
company_name VARCHAR(128) 企业名称
tax_id VARCHAR(64) 税号
bank_name VARCHAR(128) 开户银行
bank_account VARCHAR(64) 银行账号
address VARCHAR(256) 地址
phone VARCHAR(20) 电话
tax_region VARCHAR(64) 纳税地区
issuer VARCHAR(64) 开票人
contact_name VARCHAR(64) 业务联系人姓名
contact_phone VARCHAR(20) 业务联系人电话
monthly_quota DECIMAL(18,2) DEFAULT 10000000 月度授信额度
available_quota DECIMAL(18,2) 可用额度
downloaded_count INTEGER DEFAULT 0 已下载张数
used_count INTEGER DEFAULT 0 已使用张数
tax_calculation_method VARCHAR(32) DEFAULT 'SIMPLE' 计税方式
default_invoice_type VARCHAR(32) DEFAULT 'NORMAL' 默认票种
default_tax_rate VARCHAR(16) DEFAULT '1%' 默认税率
audit_after_payment BOOLEAN DEFAULT TRUE 货品审核后付款
invite_as_supplier BOOLEAN DEFAULT FALSE 邀请为供应商
receipt_plaintext BOOLEAN DEFAULT FALSE 电子回单明文
employee_quota_management BOOLEAN DEFAULT FALSE 员工额度管理

Index:

  • idx_invoice_company_enterprise ON (enterprise_id) UNIQUE (one record per enterprise)

1.6 pay_invoice_task — 任务中心

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
task_type VARCHAR(32) NOT NULL 任务类型
task_status VARCHAR(32) NOT NULL DEFAULT 'PENDING' PENDING / PROCESSING / SUCCESS / FAILED
start_time TIMESTAMP 任务开始时间
completion_time TIMESTAMP 完成时间
product_name VARCHAR(128) 商品名称
file_url VARCHAR(512) 导出文件URL
total_count INTEGER DEFAULT 0 总记录数
success_count INTEGER DEFAULT 0 成功数
fail_count INTEGER DEFAULT 0 失败数
error_message TEXT 错误信息

Indexes:

  • idx_invoice_task_enterprise ON (enterprise_id)
  • idx_invoice_task_type ON (task_type)
  • idx_invoice_task_status ON (task_status)

1.7 pay_invoice_tax_payment — 缴税记录

Column Type Constraint Notes
id BIGINT PK (snowflake)
status, description, created_time, updated_time, tenant_id, enterprise_id From base entities
payment_mode VARCHAR(32) NOT NULL INDIVIDUAL / ENTERPRISE_PROXY
tax_amount DECIMAL(18,2) 缴税金额
tax_period VARCHAR(32) 纳税期间
payment_time TIMESTAMP 缴税时间
payment_status VARCHAR(32) DEFAULT 'UNPAID' UNPAID / PAID
enterprise_proxy_enabled BOOLEAN DEFAULT FALSE 是否开通企业代缴

Indexes:

  • idx_invoice_tax_enterprise ON (enterprise_id)
  • idx_invoice_tax_status ON (payment_status)

2. Backend Module Structure

module/payment/invoice/
├── InvoiceModuleConfig.java          (optional: module-level @Configuration if needed)

├── order/                             # 1. 交易及发票管理
│   ├── controller/
│   │   └── OrderController.java
│   ├── dto/
│   │   ├── OrderQueryDTO.java
│   │   ├── OrderVO.java
│   │   ├── OrderBatchImportDTO.java
│   │   ├── OrderBatchCancelDTO.java
│   │   └── InvoiceDetailVO.java
│   ├── entity/
│   │   └── OrderEntity.java
│   ├── enums/
│   │   └── OrderEnums.java            (TradeStatus, CollectionAccountType)
│   ├── mapper/
│   │   └── OrderMapper.java
│   └── service/
│       ├── OrderService.java          (list, detail, batchImport, batchCancel, export)
│       └── impl/
│           └── OrderServiceImpl.java  (optional — if following existing pattern)

├── account/                           # 2. 转账账户管理
│   ├── controller/
│   │   └── InvoiceAccountController.java
│   ├── dto/
│   │   └── AccountBalanceVO.java
│   ├── entity/
│   │   └── InvoiceAccountEntity.java
│   ├── mapper/
│   │   └── InvoiceAccountMapper.java
│   └── service/
│       └── InvoiceAccountService.java

├── tax/                               # 3. 缴税管理
│   ├── controller/
│   │   └── TaxPaymentController.java
│   ├── dto/
│   │   ├── TaxPaymentQueryDTO.java
│   │   └── TaxPaymentVO.java
│   ├── entity/
│   │   └── TaxPaymentEntity.java
│   ├── enums/
│   │   └── TaxEnums.java              (PaymentMode, PaymentStatus)
│   ├── mapper/
│   │   └── TaxPaymentMapper.java
│   └── service/
│       └── TaxPaymentService.java

├── employee/                          # 4. 员工管理
│   ├── controller/
│   │   └── InvoiceEmployeeController.java
│   ├── dto/
│   │   ├── EmployeeSaveDTO.java
│   │   └── EmployeeVO.java
│   ├── entity/
│   │   └── InvoiceEmployeeEntity.java
│   ├── enums/
│   │   └── InvoiceEmployeeEnums.java   (EmployeeRole)
│   ├── mapper/
│   │   └── InvoiceEmployeeMapper.java
│   └── service/
│       └── InvoiceEmployeeService.java

├── product/                           # 5. 常用商品管理
│   ├── controller/
│   │   └── ProductController.java
│   ├── dto/
│   │   ├── ProductSaveDTO.java
│   │   └── ProductVO.java
│   ├── entity/
│   │   └── ProductEntity.java
│   ├── enums/
│   │   └── ProductEnums.java          (ProductCategory)
│   ├── mapper/
│   │   └── ProductMapper.java
│   └── service/
│       └── ProductService.java

├── company/                           # 6. 企业信息
│   ├── controller/
│   │   └── CompanyController.java
│   ├── dto/
│   │   ├── CompanyVO.java
│   │   ├── ContactUpdateDTO.java
│   │   └── InvoiceInfoUpdateDTO.java
│   ├── entity/
│   │   └── CompanyEntity.java
│   ├── enums/
│   │   └── CompanyEnums.java          (TaxCalcMethod, DefaultInvoiceType)
│   ├── mapper/
│   │   └── CompanyMapper.java
│   └── service/
│       └── CompanyService.java

├── supplier/                          # 7. 供应商管理
│   ├── controller/
│   │   └── SupplierController.java
│   ├── dto/
│   │   ├── SupplierSaveDTO.java
│   │   ├── SupplierQueryDTO.java
│   │   └── SupplierVO.java
│   ├── entity/
│   │   └── SupplierEntity.java
│   ├── enums/
│   │   └── SupplierEnums.java         (AccountType, ConfirmStatus)
│   ├── mapper/
│   │   └── SupplierMapper.java
│   └── service/
│       └── SupplierService.java

└── task/                              # 8. 任务中心
    ├── controller/
    │   └── TaskController.java
    ├── dto/
    │   ├── TaskQueryDTO.java
    │   └── TaskVO.java
    ├── entity/
    │   └── TaskEntity.java
    ├── enums/
    │   └── TaskEnums.java             (TaskType, TaskStatus)
    ├── mapper/
    │   └── TaskMapper.java
    ├── scheduler/
    │   └── InvoiceTaskScheduler.java   (poll export/import tasks, execute asynchronously)
    └── service/
        ├── TaskService.java
        └── InvoiceMockDataService.java (singleton mock data factory for all modules)

Key design decisions:

  • Controllers: @RestController with @RequestMapping("/payment/invoice/<submodule>")
  • Services: @Service @RequiredArgsConstructor using LambdaQueryWrapper for queries
  • Mappers: @Mapper extends BaseMapper<Entity>
  • All entities extend PaymentEnterpriseBaseEntity (auto-tenant + auto-enterprise)
  • InvoiceMockDataService generates realistic mock data using Faker-like patterns for all modules
  • PageResult wrapping: PageResult.of(pageNo, pageSize, total, items)

3. API Endpoints (Mock Implementations)

3.1 Order Controller

GET    /payment/invoice/order/list           — paginated list with filters
GET    /payment/invoice/order/{id}           — order detail
GET    /payment/invoice/order/invoice/{id}   — invoice detail (红票/蓝票)
POST   /payment/invoice/order/batch-import   — batch import (multipart .xlsx)
POST   /payment/invoice/order/batch-cancel   — batch cancel by order IDs
GET    /payment/invoice/order/export/orders  — export orders as .xlsx
GET    /payment/invoice/order/export/invoices — export invoices as .xlsx
GET    /payment/invoice/order/template       — download import template

3.2 Account Controller

GET    /payment/invoice/account/balance      — get account balance + pending amount
GET    /payment/invoice/account/recharge-info — get recharge bank account info
POST   /payment/invoice/account/recharge     — (mock) recharge

3.3 Tax Payment Controller

GET    /payment/invoice/tax/config            — get tax payment config (mode, proxy enabled)
POST   /payment/invoice/tax/mode              — set payment mode (individual / enterprise)
POST   /payment/invoice/tax/enable-proxy      — enable enterprise proxy payment
GET    /payment/invoice/tax/records           — tax payment history

3.4 Employee Controller

GET    /payment/invoice/employee/list         — employee list
POST   /payment/invoice/employee              — add employee
PUT    /payment/invoice/employee/{id}         — update employee
DELETE /payment/invoice/employee/{id}         — delete employee

3.5 Product Controller

GET    /payment/invoice/product/list          — product list (filter by category)
POST   /payment/invoice/product               — add product
PUT    /payment/invoice/product/{id}          — update product
DELETE /payment/invoice/product/{id}          — delete product
GET    /payment/invoice/product/categories    — category tree

3.6 Company Controller

GET    /payment/invoice/company/info                — get company info (auto-create if missing)
POST   /payment/invoice/company/sync-tax            — mock sync tax info
POST   /payment/invoice/company/verify              — mock company verification
PUT    /payment/invoice/company/contact             — update contact info
PUT    /payment/invoice/company/invoice-info        — update invoice settings
PUT    /payment/invoice/company/trade-rules         — update trade rule toggles

3.7 Supplier Controller

GET    /payment/invoice/supplier/list          — paginated list with search filters
POST   /payment/invoice/supplier               — add supplier
PUT    /payment/invoice/supplier/{id}          — update supplier
DELETE /payment/invoice/supplier/{id}          — delete supplier
POST   /payment/invoice/supplier/batch-import  — batch import (.xlsx)
GET    /payment/invoice/supplier/template      — download import template

3.8 Task Controller

GET    /payment/invoice/task/list              — paginated task list
GET    /payment/invoice/task/{id}              — task detail
GET    /payment/invoice/task/{id}/download     — download export file

Mock Data Strategy

InvoiceMockDataService will be injected into each service constructor. It generates:

  • Orders: 50+ records with realistic Chinese names, amounts, statuses distributed across all 8 statuses
  • Employees: 5-10 records with masked phone/ID
  • Products: 20+ products distributed across all 9 categories
  • Company: 1 record per enterprise with hardcoded defaults (10M quota)
  • Suppliers: 15+ records with various account types and confirm statuses
  • Tasks: 10+ historical tasks with various types and statuses
  • Account: Fixed balance values

Each service method checks if real data exists; if not, falls back to mock data.


4. Frontend Component Structure

src/views/module_payment/invoice/
├── order/
│   ├── index.vue                      # main page with search + table
│   ├── components/
│   │   ├── SearchForm.vue             # search filters
│   │   ├── OrderTable.vue             # data table with actions
│   │   ├── OrderDetailDialog.vue      # order detail modal
│   │   ├── InvoiceDetailDialog.vue    # invoice detail (红票/蓝票) modal
│   │   └── BatchImportDialog.vue      # batch import with template download + upload
│   └── index.ts                       # (if needed for local types)

├── account/
│   ├── index.vue                      # balance display + recharge section
│   └── components/
│       ├── BalanceCard.vue            # account balance + pending amount
│       └── RechargeGuide.vue          # collapsible "how to recharge" section

├── payTaxes/
│   ├── index.vue                      # tax payment mode selection
│   └── components/
│       ├── IndividualPayment.vue      # 个人缴税 view
│       └── EnterpriseProxy.vue        # 企业代缴 view with "立即开通" flow

├── employeeManagement/
│   ├── index.vue                      # employee list + add/edit dialogs
│   └── components/
│       ├── EmployeeTable.vue          # table with masked fields
│       ├── AddEmployeeDialog.vue      # role selector + dynamic form
│       └── EditEmployeeDialog.vue     # role readonly, edit form

├── goods/
│   ├── index.vue                      # left category tree + right product table
│   └── components/
│       ├── CategoryTree.vue           # 9-category scrapped product tree
│       └── ProductTable.vue           # product list by selected category

├── company/
│   ├── index.vue                      # enterprise info dashboard
│   └── components/
│       ├── BasicInfoSection.vue       # 8 read-only fields
│       ├── ContactSection.vue         # editable contact
│       ├── CreditLimitSection.vue     # 授信额度 4 fields
│       ├── InvoiceInfoSection.vue     # editable invoice settings
│       ├── TradeRuleSection.vue       # 4 toggle switches
│       └── ServiceProviderSection.vue # 服务商授权管理 link

├── suppliers/
│   ├── index.vue                      # supplier list with search + batch import
│   └── components/
│       ├── SupplierTable.vue          # table with confirm_status filter
│       ├── AddSupplierDialog.vue      # add/edit with save+next
│       └── BatchImportSupplier.vue    # batch import dialog

└── tasks/
    ├── index.vue                      # task center with search
    └── components/
        ├── TaskTable.vue              # task list
        └── TaskDetailDrawer.vue       # task detail side panel

API modules:

src/api/module_payment/invoice/
├── order.ts
├── account.ts
├── tax.ts
├── employee.ts
├── product.ts
├── company.ts
├── supplier.ts
└── task.ts

5. Menu Tree Structure (sys_menu table)

Insert SQL in a migration or seed file. Menu entries reference the dynamic component paths that the frontend transformRoutes resolves via import.meta.glob("../../views/**/**.vue").

Industry Invoice Platform (parent menu)
├── type: 1 (directory), route_path: /invoice-platform, route_name: InvoicePlatform
│   component_path: (empty, Layout handles it), icon: "invoice", order: 500

├── 交易及发票管理 (type: 2 menu)
│   parent_id: <parent>, route_path: /invoice-platform/order
│   route_name: InvoiceOrder, component_path: module_payment/invoice/order/index
│   permission: module_payment:invoice:order:list

├── 转账账户管理
│   parent_id: <parent>, route_path: /invoice-platform/account
│   route_name: InvoiceAccount, component_path: module_payment/invoice/account/index
│   permission: module_payment:invoice:account:view

├── 缴税管理
│   parent_id: <parent>, route_path: /invoice-platform/payTaxes
│   route_name: InvoicePayTaxes, component_path: module_payment/invoice/payTaxes/index
│   permission: module_payment:invoice:tax:view

├── 员工管理
│   parent_id: <parent>, route_path: /invoice-platform/employee
│   route_name: InvoiceEmployee, component_path: module_payment/invoice/employeeManagement/index
│   permission: module_payment:invoice:employee:list

├── 常用商品管理
│   parent_id: <parent>, route_path: /invoice-platform/goods
│   route_name: InvoiceGoods, component_path: module_payment/invoice/goods/index
│   permission: module_payment:invoice:product:list

├── 企业信息
│   parent_id: <parent>, route_path: /invoice-platform/company
│   route_name: InvoiceCompany, component_path: module_payment/invoice/company/index
│   permission: module_payment:invoice:company:view

├── 供应商管理
│   parent_id: <parent>, route_path: /invoice-platform/suppliers
│   route_name: InvoiceSuppliers, component_path: module_payment/invoice/suppliers/index
│   permission: module_payment:invoice:supplier:list

└── 任务中心
    parent_id: <parent>, route_path: /invoice-platform/tasks
    route_name: InvoiceTasks, component_path: module_payment/invoice/tasks/index
    permission: module_payment:invoice:task:list

Important: The component_path values must match the file structure module_payment/invoice/<folder>/index.vue, because the permission store's transformRoutes resolves these with modules[../../views/${normalizedRoute.component}.vue].


6. Implementation Order (7 phases)

Phase 1: Database + Entities (Foundation)

  1. Create V1.2__create_pay_invoice_tables.sql with all 7 tables + indexes
  2. Run migration
  3. Create all entity classes extending PaymentEnterpriseBaseEntity
  4. Create all enum classes
  5. Create all mapper interfaces

Phase 2: Mock Service + Core Backend

  1. Implement InvoiceMockDataService with mock data generation
  2. Implement CompanyService — single-record per enterprise, auto-create on first access
  3. Implement OrderService — list, detail, batch cancel, export
  4. Implement SupplierService — list, CRUD, batch import
  5. Implement InvoiceEmployeeService — CRUD
  6. Implement ProductService — CRUD + categories
  7. Implement InvoiceAccountService — balance query
  8. Implement TaxPaymentService — config + history
  9. Implement TaskService — list, detail

Phase 3: Backend Controllers

  1. Create all DTOs (VO + QueryDTO + SaveDTO)
  2. Create all controllers with @PreAuthorize annotations matching menu permissions
  3. Wire endpoints to services

Phase 4: Frontend - API Layer + Foundation

  1. Create src/api/module_payment/invoice/ with all 8 API modules
  2. Set up type definitions for request/response shapes

Phase 5: Frontend - Simple Pages (bottom-up)

Implement pages in order of complexity:

  1. 任务中心 — simplest (table + filters, no CRUD)
  2. 供应商管理 — simple CRUD table
  3. 常用商品管理 — left tree + right table
  4. 员工管理 — CRUD with dynamic form
  5. 缴税管理 — radio toggle + button
  6. 转账账户管理 — cards + collapsible section

Phase 6: Frontend - Complex Pages

  1. 企业信息 — multi-section dashboard with edit modes
  2. 交易及发票管理 — most complex (search, table, batch ops, export, detail dialogs)

Phase 7: Menu Config + Integration

  1. Insert sys_menu records
  2. Test navigation and route generation
  3. Test tenant/enterprise scoping (verify mock data returns different records per tenant/enterprise)
  4. Full integration smoke test

7. Critical Design Notes

7.1 Tenant Isolation

All tables have tenant_id + enterprise_id columns. TenantInnerInterceptor auto-injects tenant_id on INSERT and auto-filters on SELECT. The enterprise_id must be set manually in the service layer when creating records (typically from the request context or current enterprise selection).

Mock data handling: InvoiceMockDataService should accept tenantId and enterpriseId parameters so mock data is scoped correctly. Each enterprise sees only their own records.

7.2 Batch Import Flow

  1. Frontend: download template (GET /template returns a pre-formatted .xlsx)
  2. Frontend: upload file (POST /batch-import multipart)
  3. Backend: parse .xlsx with Apache POI (already in project dependencies), validate rows, insert to DB
  4. Create a task record in pay_invoice_task for tracking
  5. Return success/fail counts

7.3 Export Flow

  1. Frontend: click export triggers GET /export/orders or GET /export/invoices
  2. Backend: generates .xlsx using ExcelUtil, saves to temp storage
  3. Create a task record in pay_invoice_task with task_status = 'SUCCESS'
  4. Return download URL in task detail

7.4 Scheduler (InvoiceTaskScheduler)

A @Scheduled job that polls pay_invoice_task for PENDING tasks and processes them asynchronously. This handles:

  • Batch import parsing in background (for large files)
  • Export file generation
  • Cleanup of old/stale tasks

7.5 Frontend Multi-tenant

The frontend already has an enterprise.store.ts for enterprise selection. All API calls should pass enterprise_id as a parameter (the backend's PaymentEnterpriseBaseEntity handles filtering). The current enterprise is available via useEnterpriseStore().

7.6 Mock vs Real Switch

Each service method should follow this pattern:

// In production, real API calls would go here
// For now, return mock data
return invoiceMockDataService.getOrders(tenantId, enterpriseId, queryDTO);

This makes future migration to real APIs straightforward — just replace the mock service call with a real API client call.

7.7 File Upload Size Limit

Configure Spring multipart max size to 3MB for batch import (matches the Alipay constraint):

spring.servlet.multipart.max-file-size: 3MB
spring.servlet.multipart.max-request-size: 3MB

But use a controller-level check to allow larger uploads elsewhere.


8. Files to Create (Total: ~65 files)

Backend (~40 files)

Layer Files
SQL Migration 1 file
Entities 7 files
Enums 7 files
Mappers 8 files
DTOs ~15 files
Services 9 files (8 services + 1 mock service)
Controllers 8 files
Scheduler 1 file

Frontend (~25 files)

Layer Files
API modules 8 files
View pages 8 files
Components ~12 files

9. Risks & Mitigations

Risk Mitigation
Dynamic route resolution fails for new view paths Verify component_path in sys_menu matches actual file path relative to src/views/
Tenant interceptor not working for invoice tables Tables use tenant_id column like existing pay_* tables — automatically picked up
enterprise_id is String not Long (existing convention) Use String enterpriseId consistently; InvoiceMockDataService uses String parameter
Red/Blue invoice display not well-defined Mock it: red invoice = negative amounts + red color; blue = normal
Large batch import ~3MB causing timeout Use task scheduler for async processing; immediate response with task ID

10. Estimated Effort

Phase Effort (hours)
Phase 1: DB + Entities 3-4
Phase 2: Mock + Core Services 6-8
Phase 3: Controllers + DTOs 4-5
Phase 4: Frontend API Layer 2-3
Phase 5: Simple Pages 8-10
Phase 6: Complex Pages 8-10
Phase 7: Menu + Integration 2-4
Total 33-44 hours