import db from '../config/database'; import { logger } from '../utils/logger'; import { AuditService } from './AuditService'; /** * [BIZ_TRADE_17] 保税仓业务逻辑全链路集成 * 负责保税仓的基础信息管理、海关备案号登记及库存快照监控 */ export class BondedWarehouseService { private static readonly BONDED_TABLE = 'cf_bonded_warehouse'; /** * 初始化数据库表 */ static async initTable() { const hasTable = await db.schema.hasTable(this.BONDED_TABLE); if (!hasTable) { logger.info(`📦 Creating ${this.BONDED_TABLE} table...`); await db.schema.createTable(this.BONDED_TABLE, (table) => { table.increments('id').primary(); table.string('tenant_id', 64).notNullable(); table.string('warehouse_id', 64).notNullable(); table.string('bonded_area_code', 32).notNullable(); table.string('customs_reg_number', 64).notNullable(); table.string('status', 16).defaultTo('ACTIVE'); table.json('inventory_snapshot'); table.timestamp('created_at').defaultTo(db.fn.now()); table.timestamp('updated_at').defaultTo(db.fn.now()); table.index(['tenant_id', 'warehouse_id']); }); logger.info(`✅ Table ${this.BONDED_TABLE} created`); } } /** * 初始化保税仓配置 */ static async setupBondedWarehouse( tenantId: string, warehouseId: string, bondedAreaCode: string, customsRegNumber: string, traceId: string ): Promise { await db.transaction(async (trx) => { await trx('cf_bonded_warehouse').insert({ tenant_id: tenantId, warehouse_id: warehouseId, bonded_area_code: bondedAreaCode, customs_reg_number: customsRegNumber, status: 'ACTIVE' }); // 审计记录 await AuditService.log({ tenant_id: tenantId, action: 'BONDED_WAREHOUSE_SETUP', target_type: 'WAREHOUSE', target_id: warehouseId, trace_id: traceId, new_data: JSON.stringify({ bondedAreaCode, customsRegNumber }), metadata: JSON.stringify({ status: 'ACTIVE' }) }); }); } /** * 更新保税库存快照 */ static async updateInventorySnapshot(tenantId: string, warehouseId: string, snapshot: any): Promise { await db('cf_bonded_warehouse') .where({ tenant_id: tenantId, warehouse_id: warehouseId }) .update({ inventory_snapshot: JSON.stringify(snapshot), updated_at: db.fn.now() }); } /** * 获取租户所有保税仓信息 */ static async getBondedWarehouses(tenantId: string) { return await db('cf_bonded_warehouse') .where({ tenant_id: tenantId }) .orderBy('created_at', 'desc'); } }