import * as XLSX from 'xlsx';
import { pgTable, timestamp, text, integer, boolean, jsonb } from 'drizzle-orm/pg-core';
import { sql, relations, eq, and, desc } from 'drizzle-orm';

// src/universalExport/server/UniversalExportService.ts

// src/logger/console-adapter.ts
var ConsoleLoggerAdapter = class {
  constructor() {
    this.colors = {
      DEBUG: "\x1B[36m",
      // Cyan
      INFO: "\x1B[32m",
      // Green
      WARN: "\x1B[33m",
      // Yellow
      ERROR: "\x1B[31m",
      // Red
      RESET: "\x1B[0m"
    };
  }
  log(entry) {
    const { level, message, timestamp: timestamp2, data, context, error } = entry;
    let logMessage = "";
    if (timestamp2) {
      logMessage += "[" + this.formatTimestamp(timestamp2) + "] ";
    }
    const levelName = this.getLevelName(level);
    logMessage += levelName + ": ";
    if (context) {
      logMessage += "[" + context + "] ";
    }
    logMessage += message;
    switch (level) {
      case 0:
        console.debug(this.colorize(logMessage, "DEBUG"), data || "");
        break;
      case 1:
        console.info(this.colorize(logMessage, "INFO"), data || "");
        break;
      case 2:
        console.warn(this.colorize(logMessage, "WARN"), data || "");
        break;
      case 3:
        console.error(this.colorize(logMessage, "ERROR"), data || "");
        if (error) {
          console.error(error);
        }
        break;
    }
  }
  formatTimestamp(date) {
    return date.toISOString();
  }
  getLevelName(level) {
    const names = ["DEBUG", "INFO", "WARN", "ERROR", "NONE"];
    return names[level] || "UNKNOWN";
  }
  colorize(message, level) {
    if (typeof process !== "undefined" && process.stdout?.isTTY) {
      return this.colors[level] + message + this.colors.RESET;
    }
    return message;
  }
};

// src/logger/Logger.ts
var Logger = class _Logger {
  constructor(config, context) {
    const isProduction = typeof process !== "undefined" ? process.env.NODE_ENV === "production" : false;
    this.config = {
      minLevel: config?.minLevel ?? (isProduction ? 1 : 0),
      // INFO in prod, DEBUG in dev
      enableTimestamp: config?.enableTimestamp ?? true,
      enableContext: config?.enableContext ?? true,
      environment: config?.environment ?? (isProduction ? "production" : "development"),
      adapter: config?.adapter ?? new ConsoleLoggerAdapter()
    };
    this.adapter = this.config.adapter;
    this.context = context;
  }
  /**
   * 创建带上下文的子 Logger
   */
  createChild(context) {
    return new _Logger(this.config, context);
  }
  /**
   * 调试日志
   */
  debug(message, data) {
    this.log(0, message, data);
  }
  /**
   * 信息日志
   */
  info(message, data) {
    this.log(1, message, data);
  }
  /**
   * 警告日志
   */
  warn(message, data) {
    this.log(2, message, data);
  }
  /**
   * 错误日志
   */
  error(message, error) {
    this.log(
      3,
      // LogLevel.ERROR
      message,
      error instanceof Error ? void 0 : error,
      error instanceof Error ? error : void 0
    );
  }
  /**
   * 核心日志方法
   */
  log(level, message, data, error) {
    if (level < this.config.minLevel) {
      return;
    }
    if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
      const loggerDebug = localStorage.getItem("logger-debug");
      if (loggerDebug === "false" && level < 3) {
        return;
      }
    }
    const entry = {
      level,
      message,
      timestamp: this.config.enableTimestamp ? /* @__PURE__ */ new Date() : void 0,
      data,
      context: this.config.enableContext ? this.context : void 0,
      error
    };
    this.adapter.log(entry);
  }
  /**
   * 设置日志级别
   */
  setLevel(level) {
    this.config.minLevel = level;
  }
  /**
   * 获取当前日志级别
   */
  getLevel() {
    return this.config.minLevel;
  }
};
new Logger();
function createLogger(context, config) {
  return new Logger(config, context);
}

// src/universalExport/types.ts
var ExportServiceError = class extends Error {
  constructor(message, code, details) {
    super(message);
    this.code = code;
    this.details = details;
    this.name = "ExportServiceError";
  }
};
var ExportConfigError = class extends ExportServiceError {
  constructor(message, details) {
    super(message, "EXPORT_CONFIG_ERROR", details);
    this.name = "ExportConfigError";
  }
};
var ExportDataError = class extends ExportServiceError {
  constructor(message, details) {
    super(message, "EXPORT_DATA_ERROR", details);
    this.name = "ExportDataError";
  }
};
var ExportFileError = class extends ExportServiceError {
  constructor(message, details) {
    super(message, "EXPORT_FILE_ERROR", details);
    this.name = "ExportFileError";
  }
};

// src/universalExport/server/UniversalExportService.ts
var logger2 = createLogger("UniversalExportService");
var DEFAULT_CONFIG = {
  defaultFormat: "csv",
  defaultDelimiter: ",",
  defaultEncoding: "utf-8",
  defaultAddBOM: true,
  maxFileSize: 100 * 1024 * 1024,
  // 100MB
  maxRowsLimit: 1e5,
  maxConcurrentExports: 5,
  exportTimeout: 3e5,
  // 5分钟
  cache: {
    configTTL: 3600,
    // 1小时
    resultTTL: 1800
    // 30分钟
  }
};
var DEFAULT_FORMATTERS = {
  // 日期格式化
  date: (value) => {
    if (!value) return "";
    const date = new Date(value);
    return date.toISOString().split("T")[0];
  },
  // 时间格式化
  datetime: (value) => {
    if (!value) return "";
    const date = new Date(value);
    return date.toLocaleString("zh-CN");
  },
  // 数字格式化
  number: (value) => {
    if (value === null || value === void 0) return "";
    return String(value);
  },
  // 货币格式化
  currency: (value) => {
    if (value === null || value === void 0) return "";
    return "\xA5" + Number(value).toFixed(2);
  },
  // 百分比格式化
  percentage: (value) => {
    if (value === null || value === void 0) return "";
    return (Number(value) * 100).toFixed(2) + "%";
  },
  // 布尔值格式化
  boolean: (value) => {
    if (value === null || value === void 0) return "";
    return value ? "\u662F" : "\u5426";
  },
  // 数组格式化
  array: (value) => {
    if (!Array.isArray(value)) return "";
    return value.join(", ");
  },
  // 对象格式化
  object: (value) => {
    if (!value || typeof value !== "object") return "";
    return JSON.stringify(value);
  }
};
var UniversalExportService = class {
  constructor(config, client) {
    this.eventListeners = /* @__PURE__ */ new Map();
    this.activeExports = /* @__PURE__ */ new Map();
    this.configCache = /* @__PURE__ */ new Map();
    this.resultCache = /* @__PURE__ */ new Map();
    this.config = { ...DEFAULT_CONFIG, ...config };
    this.client = client;
  }
  // ============= 配置管理 =============
  /**
   * 创建导出配置
   */
  async createConfig(config) {
    try {
      this.validateConfig({
        ...config,
        id: "temp",
        createdAt: /* @__PURE__ */ new Date(),
        updatedAt: /* @__PURE__ */ new Date()
      });
      if (!this.client) {
        throw new ExportConfigError("\u672A\u63D0\u4F9B\u5BFC\u51FA\u5BA2\u6237\u7AEF\u670D\u52A1", config);
      }
      const newConfig = await this.client.createConfig(config);
      this.configCache.set(newConfig.id, {
        config: newConfig,
        timestamp: Date.now()
      });
      this.emitEvent({
        type: "config:save",
        exportId: newConfig.id,
        timestamp: /* @__PURE__ */ new Date(),
        data: { config: newConfig }
      });
      return newConfig;
    } catch (error) {
      throw new ExportConfigError(
        "\u521B\u5EFA\u5BFC\u51FA\u914D\u7F6E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
        { originalError: error }
      );
    }
  }
  /**
   * 获取导出配置
   */
  async getConfig(configId) {
    const cached = this.configCache.get(configId);
    if (cached && Date.now() - cached.timestamp < this.config.cache.configTTL * 1e3) {
      return cached.config;
    }
    return null;
  }
  /**
   * 更新导出配置
   */
  async updateConfig(configId, updates) {
    const existing = await this.getConfig(configId);
    if (!existing) {
      throw new ExportConfigError("\u914D\u7F6E\u4E0D\u5B58\u5728: " + configId);
    }
    const updatedConfig = {
      ...existing,
      ...updates,
      updatedAt: /* @__PURE__ */ new Date()
    };
    this.validateConfig(updatedConfig);
    this.configCache.set(configId, {
      config: updatedConfig,
      timestamp: Date.now()
    });
    this.emitEvent({
      type: "config:save",
      exportId: configId,
      timestamp: /* @__PURE__ */ new Date(),
      data: { config: updatedConfig }
    });
    return updatedConfig;
  }
  /**
   * 删除导出配置
   */
  async deleteConfig(configId) {
    const existing = await this.getConfig(configId);
    if (!existing) {
      throw new ExportConfigError("\u914D\u7F6E\u4E0D\u5B58\u5728: " + configId);
    }
    this.configCache.delete(configId);
    this.emitEvent({
      type: "config:delete",
      exportId: configId,
      timestamp: /* @__PURE__ */ new Date(),
      data: { configId }
    });
  }
  /**
   * 获取模块的配置列表
   */
  async getConfigsByModule(moduleId, businessId) {
    if (!this.client) {
      throw new ExportConfigError("\u672A\u63D0\u4F9B\u5BFC\u51FA\u5BA2\u6237\u7AEF\u670D\u52A1", { moduleId, businessId });
    }
    return await this.client.getConfigsByModule(moduleId, businessId);
  }
  // ============= 导出执行 =============
  /**
   * 执行导出
   */
  async export(request) {
    const exportId = this.generateId();
    const startTime = /* @__PURE__ */ new Date();
    logger2.info("\u{1F680} [UniversalExportService] \u5F00\u59CB\u5BFC\u51FA:", {
      exportId,
      configId: request.configId,
      hasDataSource: !!request.dataSource,
      hasCallbacks: !!request.callbacks
    });
    try {
      let config;
      if (typeof request.configId === "object" && request.configId !== null) {
        config = request.configId;
        logger2.info("\u{1F4CB} [UniversalExportService] \u4F7F\u7528\u76F4\u63A5\u4F20\u5165\u7684\u914D\u7F6E:", {
          configId: config.id,
          configName: config.name,
          format: config.format,
          fieldsCount: config.fields.length,
          hasGrouping: !!config.grouping,
          groupingEnabled: config.grouping?.enabled,
          groupingFieldsCount: config.grouping?.fields?.length || 0,
          groupingFields: config.grouping?.fields?.map((f) => ({ key: f.key, mergeCells: f.mergeCells })) || []
        });
      } else {
        logger2.info("\u{1F50D} [UniversalExportService] \u4ECE\u7F13\u5B58\u83B7\u53D6\u914D\u7F6E:", request.configId);
        const cachedConfig = await this.getConfig(request.configId);
        if (!cachedConfig) {
          throw new ExportConfigError("\u5BFC\u51FA\u914D\u7F6E\u4E0D\u5B58\u5728: " + request.configId);
        }
        config = cachedConfig;
        logger2.info("\u2705 [UniversalExportService] \u6210\u529F\u83B7\u53D6\u7F13\u5B58\u914D\u7F6E:", {
          configId: config.id,
          configName: config.name
        });
      }
      const progress = {
        exportId,
        status: "pending",
        progress: 0,
        processedRows: 0,
        totalRows: 0,
        startTime
      };
      this.activeExports.set(exportId, progress);
      this.emitEvent({
        type: "export:start",
        exportId,
        timestamp: startTime,
        data: { config, request }
      });
      if (request.callbacks?.onProgress) {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528 onProgress \u56DE\u8C03 - \u5F00\u59CB");
        request.callbacks.onProgress(progress);
      }
      logger2.info("\u{1F4CA} [UniversalExportService] \u5F00\u59CB\u83B7\u53D6\u6570\u636E...");
      const data = await this.getData(request);
      logger2.info("\u2705 [UniversalExportService] \u6570\u636E\u83B7\u53D6\u6210\u529F:", {
        dataLength: data.length,
        firstItem: data[0] ? Object.keys(data[0]) : [],
        sampleData: data.slice(0, 2)
      });
      progress.totalRows = data.length;
      progress.status = "processing";
      if (request.callbacks?.onProgress) {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528 onProgress \u56DE\u8C03 - \u6570\u636E\u5904\u7406");
        progress.progress = 30;
        request.callbacks.onProgress(progress);
      }
      logger2.info("\u{1F504} [UniversalExportService] \u5F00\u59CB\u5904\u7406\u6570\u636E...");
      const processedData = await this.processData(data, request, config);
      logger2.info("\u2705 [UniversalExportService] \u6570\u636E\u5904\u7406\u5B8C\u6210:", {
        originalLength: data.length,
        processedLength: processedData.length
      });
      if (request.callbacks?.onProgress) {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528 onProgress \u56DE\u8C03 - \u6570\u636E\u5B8C\u6210");
        progress.progress = 60;
        request.callbacks.onProgress(progress);
      }
      logger2.info("\u{1F4C4} [UniversalExportService] \u5F00\u59CB\u751F\u6210\u6587\u4EF6...");
      const result = await this.generateFile(processedData, config, request, exportId);
      logger2.info("\u2705 [UniversalExportService] \u6587\u4EF6\u751F\u6210\u6210\u529F:", {
        fileName: result.fileName,
        fileSize: result.fileSize,
        exportedRows: result.exportedRows
      });
      progress.status = "completed";
      progress.progress = 100;
      progress.processedRows = data.length;
      if (request.callbacks?.onSuccess) {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528 onSuccess \u56DE\u8C03");
        request.callbacks.onSuccess(result);
      }
      this.emitEvent({
        type: "export:complete",
        exportId,
        timestamp: /* @__PURE__ */ new Date(),
        data: { result }
      });
      this.resultCache.set(exportId, {
        result,
        timestamp: Date.now()
      });
      this.activeExports.delete(exportId);
      return result;
    } catch (error) {
      const errorObj = {
        code: "EXPORT_FAILED",
        message: error instanceof Error ? error.message : "\u5BFC\u51FA\u5931\u8D25",
        details: { originalError: error },
        timestamp: /* @__PURE__ */ new Date()
      };
      const progress = this.activeExports.get(exportId);
      if (progress) {
        progress.status = "failed";
        progress.error = errorObj.message;
        this.activeExports.delete(exportId);
      }
      if (request.callbacks?.onError) {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528 onError \u56DE\u8C03");
        request.callbacks.onError(errorObj);
      }
      this.emitEvent({
        type: "export:error",
        exportId,
        timestamp: /* @__PURE__ */ new Date(),
        error: errorObj.message,
        data: { error: errorObj }
      });
      throw error;
    }
  }
  /**
   * 获取导出进度
   */
  getExportProgress(exportId) {
    return this.activeExports.get(exportId) || null;
  }
  /**
   * 取消导出
   */
  cancelExport(exportId) {
    const progress = this.activeExports.get(exportId);
    if (!progress) {
      return false;
    }
    progress.status = "cancelled";
    this.activeExports.delete(exportId);
    this.emitEvent({
      type: "export:cancel",
      exportId,
      timestamp: /* @__PURE__ */ new Date(),
      data: { progress }
    });
    return true;
  }
  // ============= 事件管理 =============
  /**
   * 添加事件监听器
   */
  addEventListener(type, listener) {
    if (!this.eventListeners.has(type)) {
      this.eventListeners.set(type, []);
    }
    this.eventListeners.get(type).push(listener);
  }
  /**
   * 移除事件监听器
   */
  removeEventListener(type, listener) {
    const listeners = this.eventListeners.get(type);
    if (listeners) {
      const index = listeners.indexOf(listener);
      if (index > -1) {
        listeners.splice(index, 1);
      }
    }
  }
  // ============= 私有方法 =============
  /**
   * 生成唯一ID
   */
  generateId() {
    return "export_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
  }
  /**
   * 验证配置
   */
  validateConfig(config) {
    if (!config.name || config.name.trim() === "") {
      throw new ExportConfigError("\u914D\u7F6E\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
    }
    if (!config.fields || config.fields.length === 0) {
      throw new ExportConfigError("\u81F3\u5C11\u9700\u8981\u5B9A\u4E49\u4E00\u4E2A\u5B57\u6BB5");
    }
    const enabledFields = config.fields.filter((f) => f.enabled);
    if (enabledFields.length === 0) {
      throw new ExportConfigError("\u81F3\u5C11\u9700\u8981\u542F\u7528\u4E00\u4E2A\u5B57\u6BB5");
    }
    const keys = config.fields.map((f) => f.key);
    const uniqueKeys = new Set(keys);
    if (keys.length !== uniqueKeys.size) {
      throw new ExportConfigError("\u5B57\u6BB5\u952E\u540D\u5FC5\u987B\u552F\u4E00");
    }
  }
  /**
   * 获取数据
   */
  async getData(request) {
    logger2.info("\u{1F50D} [UniversalExportService] getData \u5F00\u59CB\u6267\u884C...");
    try {
      if (Array.isArray(request.dataSource)) {
        logger2.info("\u{1F4E6} [UniversalExportService] \u4F7F\u7528\u76F4\u63A5\u4F20\u9012\u7684\u6570\u636E\u6570\u7EC4:", {
          length: request.dataSource.length
        });
        return request.dataSource;
      }
      if (typeof request.dataSource === "function") {
        logger2.info("\u{1F4DE} [UniversalExportService] \u8C03\u7528\u6570\u636E\u6E90\u51FD\u6570...");
        const data = await request.dataSource();
        logger2.info("\u2705 [UniversalExportService] \u6570\u636E\u6E90\u51FD\u6570\u6267\u884C\u6210\u529F:", {
          dataType: typeof data,
          isArray: Array.isArray(data),
          length: Array.isArray(data) ? data.length : "N/A"
        });
        return data;
      }
      console.error("\u274C [UniversalExportService] \u6570\u636E\u6E90\u7C7B\u578B\u4E0D\u652F\u6301:", typeof request.dataSource);
      throw new ExportDataError("\u4E0D\u652F\u6301\u7684\u6570\u636E\u6E90\u7C7B\u578B");
    } catch (error) {
      console.error("\u274C [UniversalExportService] \u83B7\u53D6\u6570\u636E\u5931\u8D25:", error);
      throw new ExportDataError(
        "\u83B7\u53D6\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
        { originalError: error }
      );
    }
  }
  /**
   * 处理数据
   */
  async processData(data, request, config) {
    logger2.info("\u{1F504} [UniversalExportService] processData \u5F00\u59CB\u6267\u884C:", {
      dataLength: data.length,
      hasFilters: !!(request.filters && request.filters.length > 0),
      hasSortBy: !!(request.sortBy && request.sortBy.length > 0),
      hasPagination: !!request.pagination,
      hasGrouping: !!(config.grouping && config.grouping.enabled),
      maxRows: config.maxRows
    });
    logger2.info("\u{1F50D} [UniversalExportService] \u8BE6\u7EC6\u5206\u7EC4\u914D\u7F6E\u68C0\u67E5:", {
      configGrouping: config.grouping,
      groupingExists: !!config.grouping,
      groupingEnabled: config.grouping?.enabled,
      groupingFields: config.grouping?.fields,
      groupingFieldsLength: config.grouping?.fields?.length
    });
    let processedData = [...data];
    if (request.filters && request.filters.length > 0) {
      logger2.info("\u{1F50D} [UniversalExportService] \u5E94\u7528\u8FC7\u6EE4\u5668...");
      processedData = this.applyFilters(processedData, request.filters);
      logger2.info("\u2705 [UniversalExportService] \u8FC7\u6EE4\u5668\u5E94\u7528\u5B8C\u6210:", {
        beforeLength: data.length,
        afterLength: processedData.length
      });
    }
    if (request.sortBy && request.sortBy.length > 0) {
      logger2.info("\u{1F4CA} [UniversalExportService] \u5E94\u7528\u6392\u5E8F...");
      processedData = this.applySorting(processedData, request.sortBy);
      logger2.info("\u2705 [UniversalExportService] \u6392\u5E8F\u5E94\u7528\u5B8C\u6210");
    }
    if (config.grouping && config.grouping.enabled) {
      logger2.info("\u{1F4CA} [UniversalExportService] \u5E94\u7528\u5206\u7EC4...");
      processedData = this.applyGrouping(processedData, config.grouping);
      logger2.info("\u2705 [UniversalExportService] \u5206\u7EC4\u5E94\u7528\u5B8C\u6210:", {
        groupsCount: this.countGroups(processedData),
        resultLength: processedData.length
      });
    }
    if (request.pagination) {
      logger2.info("\u{1F4C4} [UniversalExportService] \u5E94\u7528\u5206\u9875...");
      const { page, pageSize } = request.pagination;
      const start = (page - 1) * pageSize;
      const end = start + pageSize;
      processedData = processedData.slice(start, end);
      logger2.info("\u2705 [UniversalExportService] \u5206\u9875\u5E94\u7528\u5B8C\u6210:", {
        page,
        pageSize,
        start,
        end,
        resultLength: processedData.length
      });
    }
    if (config.maxRows && processedData.length > config.maxRows) {
      logger2.info("\u{1F4CF} [UniversalExportService] \u5E94\u7528\u884C\u6570\u9650\u5236...");
      processedData = processedData.slice(0, config.maxRows);
      logger2.info("\u2705 [UniversalExportService] \u884C\u6570\u9650\u5236\u5E94\u7528\u5B8C\u6210:", {
        maxRows: config.maxRows,
        resultLength: processedData.length
      });
    }
    logger2.info("\u2705 [UniversalExportService] processData \u6267\u884C\u5B8C\u6210:", {
      originalLength: data.length,
      finalLength: processedData.length
    });
    return processedData;
  }
  /**
   * 应用过滤器
   */
  applyFilters(data, filters) {
    return data.filter((item) => {
      return filters.every((filter) => {
        const value = this.getNestedValue(item, filter.field);
        switch (filter.operator) {
          case "eq":
            return value === filter.value;
          case "ne":
            return value !== filter.value;
          case "gt":
            return value > filter.value;
          case "gte":
            return value >= filter.value;
          case "lt":
            return value < filter.value;
          case "lte":
            return value <= filter.value;
          case "contains":
            return String(value).includes(String(filter.value));
          case "startsWith":
            return String(value).startsWith(String(filter.value));
          case "endsWith":
            return String(value).endsWith(String(filter.value));
          case "in":
            return Array.isArray(filter.value) && filter.value.includes(value);
          case "notIn":
            return Array.isArray(filter.value) && !filter.value.includes(value);
          default:
            return true;
        }
      });
    });
  }
  /**
   * 应用排序
   */
  applySorting(data, sortBy) {
    return data.sort((a, b) => {
      for (const sort of sortBy) {
        const aValue = this.getNestedValue(a, sort.field);
        const bValue = this.getNestedValue(b, sort.field);
        if (aValue < bValue) {
          return sort.direction === "asc" ? -1 : 1;
        }
        if (aValue > bValue) {
          return sort.direction === "asc" ? 1 : -1;
        }
      }
      return 0;
    });
  }
  /**
   * 获取嵌套值
   */
  getNestedValue(obj, path) {
    return path.split(".").reduce((current, key) => {
      return current && current[key] !== void 0 ? current[key] : null;
    }, obj);
  }
  /**
   * 过滤掉所有行都为空值的字段
   */
  filterEmptyFields(data, fields) {
    const filteredFields = fields.filter((field) => {
      const forceKeepFields = ["pickupMethod", "notes", "adminNotes"];
      if (forceKeepFields.includes(field.key)) {
        logger2.info('\u{1F527} [UniversalExportService] \u5F3A\u5236\u4FDD\u7559\u5B57\u6BB5 "' + field.key + '" (' + field.label + ")");
        return true;
      }
      const hasValue = data.some((item) => {
        const value = this.getNestedValue(item, field.key);
        return value !== null && value !== void 0 && value !== "";
      });
      if (!hasValue) {
        logger2.info(
          '\u{1F50D} [UniversalExportService] \u5B57\u6BB5 "' + field.key + '" (' + field.label + ") \u88AB\u8FC7\u6EE4\u6389 - \u6240\u6709\u884C\u90FD\u4E3A\u7A7A\u503C"
        );
      }
      return hasValue;
    });
    logger2.info("\u{1F4CA} [UniversalExportService] \u5B57\u6BB5\u8FC7\u6EE4\u7ED3\u679C:", {
      \u539F\u59CB\u5B57\u6BB5\u6570: fields.length,
      \u8FC7\u6EE4\u540E\u5B57\u6BB5\u6570: filteredFields.length,
      \u88AB\u8FC7\u6EE4\u7684\u5B57\u6BB5: fields.filter((f) => !filteredFields.includes(f)).map((f) => f.key),
      \u4FDD\u7559\u7684\u5B57\u6BB5: filteredFields.map((f) => f.key)
    });
    return filteredFields;
  }
  /**
   * 生成文件
   */
  async generateFile(data, config, request, exportId) {
    const startTime = /* @__PURE__ */ new Date();
    const enabledFields = config.fields.filter((f) => f.enabled);
    logger2.info("\u{1F4C4} [UniversalExportService] generateFile \u5F00\u59CB\u6267\u884C:", {
      dataLength: data.length,
      enabledFieldsCount: enabledFields.length,
      format: config.format,
      enabledFields: enabledFields.map((f) => ({ key: f.key, label: f.label }))
    });
    try {
      let content;
      let fileName;
      switch (config.format) {
        case "csv":
          logger2.info("\u{1F4CA} [UniversalExportService] \u751F\u6210CSV\u683C\u5F0F...");
          content = this.generateCSV(data, enabledFields, config);
          fileName = this.generateFileName(
            request.customFileName || config.fileNameTemplate,
            "csv"
          );
          logger2.info("\u2705 [UniversalExportService] CSV\u751F\u6210\u5B8C\u6210:", {
            contentLength: content.length,
            fileName
          });
          break;
        case "excel":
          logger2.info("\u{1F4CA} [UniversalExportService] \u751F\u6210Excel\u683C\u5F0F...");
          const excelBuffer = this.generateExcel(data, enabledFields, config);
          fileName = this.generateFileName(
            request.customFileName || config.fileNameTemplate,
            "xlsx"
          );
          logger2.info("\u2705 [UniversalExportService] Excel\u751F\u6210\u5B8C\u6210:", {
            bufferLength: excelBuffer.byteLength,
            fileName
          });
          const excelBlob = new Blob([excelBuffer], { type: this.getMimeType(config.format) });
          const endTime2 = /* @__PURE__ */ new Date();
          const duration2 = endTime2.getTime() - startTime.getTime();
          return {
            exportId,
            fileName,
            fileSize: excelBlob.size,
            fileBlob: excelBlob,
            exportedRows: data.length,
            startTime,
            endTime: endTime2,
            duration: duration2,
            statistics: {
              totalRows: data.length,
              filteredRows: data.length,
              exportedRows: data.length,
              skippedRows: 0
            }
          };
        case "json":
          logger2.info("\u{1F4C4} [UniversalExportService] \u751F\u6210JSON\u683C\u5F0F...");
          content = this.generateJSON(data, enabledFields);
          fileName = this.generateFileName(
            request.customFileName || config.fileNameTemplate,
            "json"
          );
          logger2.info("\u2705 [UniversalExportService] JSON\u751F\u6210\u5B8C\u6210:", {
            contentLength: content.length,
            fileName
          });
          break;
        default:
          console.error("\u274C [UniversalExportService] \u4E0D\u652F\u6301\u7684\u683C\u5F0F:", config.format);
          throw new ExportFileError("\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u683C\u5F0F: " + config.format);
      }
      const blob = new Blob([content], { type: this.getMimeType(config.format) });
      if (blob.size > this.config.maxFileSize) {
        throw new ExportFileError("\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: " + blob.size + " > " + this.config.maxFileSize);
      }
      const endTime = /* @__PURE__ */ new Date();
      const duration = endTime.getTime() - startTime.getTime();
      return {
        exportId,
        fileName,
        fileSize: blob.size,
        fileBlob: blob,
        exportedRows: data.length,
        startTime,
        endTime,
        duration,
        statistics: {
          totalRows: data.length,
          filteredRows: data.length,
          exportedRows: data.length,
          skippedRows: 0
        }
      };
    } catch (error) {
      throw new ExportFileError(
        "\u751F\u6210\u6587\u4EF6\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
        { originalError: error }
      );
    }
  }
  /**
   * 生成CSV内容
   */
  generateCSV(data, fields, config) {
    logger2.info("\u{1F4CA} [UniversalExportService] generateCSV \u5F00\u59CB\u6267\u884C:", {
      dataLength: data.length,
      fieldsCount: fields.length,
      includeHeader: config.includeHeader,
      delimiter: config.delimiter,
      addBOM: config.addBOM
    });
    const lines = [];
    if (config.addBOM) {
      lines.push("\uFEFF");
      logger2.info("\u{1F4DD} [UniversalExportService] \u6DFB\u52A0BOM");
    }
    const nonEmptyFields = this.filterEmptyFields(data, fields);
    logger2.info("\u{1F4CA} [UniversalExportService] \u8FC7\u6EE4\u7A7A\u5B57\u6BB5:", {
      originalFieldsCount: fields.length,
      nonEmptyFieldsCount: nonEmptyFields.length,
      removedFields: fields.filter((f) => !nonEmptyFields.includes(f)).map((f) => f.key)
    });
    if (config.includeHeader) {
      const headers = nonEmptyFields.map((f) => this.escapeCSVField(f.label));
      lines.push(headers.join(config.delimiter));
      logger2.info("\u{1F4CB} [UniversalExportService] \u6DFB\u52A0\u8868\u5934:", headers);
    }
    logger2.info("\u{1F4CA} [UniversalExportService] \u5F00\u59CB\u5904\u7406\u6570\u636E\u884C...");
    for (let i = 0; i < data.length; i++) {
      const item = data[i];
      if (i === 0) {
        logger2.info("\u{1F4CA} [UniversalExportService] \u7B2C\u4E00\u884C\u6570\u636E\u793A\u4F8B:", item);
      }
      const row = nonEmptyFields.map((field) => {
        if (item.__isGroupHeader) {
          return this.escapeCSVField(item[field.key] || "");
        }
        let value = this.getNestedValue(item, field.key);
        if (field.formatter) {
          value = field.formatter(value);
        } else if (DEFAULT_FORMATTERS[field.type]) {
          value = DEFAULT_FORMATTERS[field.type](value);
        } else {
          value = String(value || "");
        }
        return this.escapeCSVField(value);
      });
      lines.push(row.join(config.delimiter));
      if (i === 0) {
        logger2.info("\u{1F4CA} [UniversalExportService] \u7B2C\u4E00\u884C\u5904\u7406\u7ED3\u679C:", row);
      }
    }
    const result = lines.join("\n");
    logger2.info("\u2705 [UniversalExportService] CSV\u751F\u6210\u5B8C\u6210:", {
      totalLines: lines.length,
      resultLength: result.length
    });
    return result;
  }
  /**
   * 生成JSON内容
   */
  generateJSON(data, fields) {
    const processedData = data.map((item) => {
      const processed = {};
      for (const field of fields) {
        let value = this.getNestedValue(item, field.key);
        if (field.formatter) {
          value = field.formatter(value);
        } else if (DEFAULT_FORMATTERS[field.type]) {
          value = DEFAULT_FORMATTERS[field.type](value);
        }
        processed[field.key] = value;
      }
      return processed;
    });
    return JSON.stringify(processedData, null, 2);
  }
  /**
   * 转义CSV字段
   */
  escapeCSVField(value) {
    if (value.includes(",") || value.includes('"') || value.includes("\n")) {
      return '"' + value.replace(/"/g, '""') + '"';
    }
    return value;
  }
  /**
   * 生成文件名
   */
  generateFileName(template, extension) {
    const now = /* @__PURE__ */ new Date();
    const dateStr = now.toISOString().split("T")[0];
    const timeStr = now.toTimeString().split(" ")[0].replace(/:/g, "-");
    return template.replace("{date}", dateStr).replace("{time}", timeStr).replace("{timestamp}", now.getTime().toString()) + "." + extension;
  }
  /**
   * 获取MIME类型
   */
  getMimeType(format) {
    switch (format) {
      case "csv":
        return "text/csv; charset=utf-8";
      case "json":
        return "application/json; charset=utf-8";
      case "excel":
        return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
      default:
        return "application/octet-stream";
    }
  }
  /**
   * 触发事件
   */
  emitEvent(event) {
    const listeners = this.eventListeners.get(event.type);
    if (listeners) {
      listeners.forEach((listener) => {
        try {
          listener(event);
        } catch (error) {
          console.error("\u4E8B\u4EF6\u76D1\u542C\u5668\u6267\u884C\u5931\u8D25:", error);
        }
      });
    }
  }
  // ============= 分组相关方法 =============
  /**
   * 应用分组
   */
  applyGrouping(data, groupingConfig) {
    logger2.info("\u{1F4CA} [UniversalExportService] applyGrouping \u5F00\u59CB\u6267\u884C:", {
      dataLength: data.length,
      groupingFields: groupingConfig.fields.map((f) => f.key),
      preserveOrder: groupingConfig.preserveOrder
    });
    if (!groupingConfig.fields || groupingConfig.fields.length === 0) {
      return data;
    }
    const grouped = this.groupDataByFields(data, groupingConfig);
    const result = this.processGroupedData(grouped, groupingConfig);
    logger2.info("\u2705 [UniversalExportService] applyGrouping \u6267\u884C\u5B8C\u6210:", {
      originalLength: data.length,
      groupedLength: result.length
    });
    return result;
  }
  /**
   * 按字段分组数据
   */
  groupDataByFields(data, groupingConfig) {
    const groups = /* @__PURE__ */ new Map();
    for (const item of data) {
      const groupKey = this.generateGroupKey(item, groupingConfig.fields);
      if (!groups.has(groupKey)) {
        groups.set(groupKey, []);
      }
      groups.get(groupKey).push(item);
    }
    return groups;
  }
  /**
   * 生成分组键
   */
  generateGroupKey(item, groupingFields) {
    const keyParts = groupingFields.map((field) => {
      const value = this.getNestedValue(item, field.key);
      if (value === null || value === void 0 || value === "") {
        return "__NULL__";
      }
      return String(value);
    });
    return keyParts.join("|");
  }
  /**
   * 处理分组后的数据
   */
  processGroupedData(groups, groupingConfig) {
    const result = [];
    for (const [groupKey, groupItems] of groups) {
      if (groupItems.length === 0) continue;
      const groupValues = groupKey.split("|");
      const processedGroup = this.processGroup(groupItems, groupingConfig, groupValues);
      result.push(...processedGroup);
    }
    return result;
  }
  /**
   * 处理单个分组
   */
  processGroup(groupItems, groupingConfig, groupValues) {
    const result = [];
    const showGroupHeader = groupingConfig.fields.some((f) => f.showGroupHeader);
    if (showGroupHeader) {
      const groupHeader = this.createGroupHeader(groupValues, groupingConfig.fields);
      result.push(groupHeader);
    }
    if (groupingConfig.fields.length > 1) {
      result.push(...this.processMultiFieldMergeMode(groupItems, groupingConfig.fields));
    } else {
      const primaryGroupField = groupingConfig.fields[0];
      switch (primaryGroupField.mode) {
        case "merge":
          result.push(...this.processMergeMode(groupItems, primaryGroupField));
          break;
        case "separate":
          result.push(...groupItems);
          break;
        case "nested":
          result.push(...this.processNestedMode(groupItems, groupingConfig));
          break;
        default:
          result.push(...groupItems);
      }
    }
    return result;
  }
  /**
   * 创建分组头行
   */
  createGroupHeader(groupValues, groupingFields) {
    const header = { __isGroupHeader: true };
    groupingFields.forEach((field, index) => {
      const value = groupValues[index] === "__NULL__" ? "" : groupValues[index];
      const template = field.groupHeaderTemplate || field.label + ": {value}";
      header[field.key] = template.replace("{value}", value);
    });
    return header;
  }
  /**
   * 处理合并模式
   */
  processMergeMode(groupItems, groupField) {
    if (groupItems.length === 0) return [];
    const result = [];
    const firstItem = { ...groupItems[0] };
    firstItem.__groupSize = groupItems.length;
    firstItem.__isGroupFirst = true;
    result.push(firstItem);
    for (let i = 1; i < groupItems.length; i++) {
      const item = { ...groupItems[i] };
      item[groupField.key] = "";
      item.__isGroupChild = true;
      item.__groupIndex = i;
      result.push(item);
    }
    return result;
  }
  /**
   * 处理多字段合并模式
   */
  processMultiFieldMergeMode(groupItems, groupFields) {
    if (groupItems.length === 0) return [];
    const result = [];
    const firstItem = { ...groupItems[0] };
    firstItem.__groupSize = groupItems.length;
    firstItem.__isGroupFirst = true;
    groupFields.forEach((field) => {
      firstItem["__" + field.key + "_groupSize"] = groupItems.length;
      firstItem["__" + field.key + "_isGroupFirst"] = true;
    });
    result.push(firstItem);
    logger2.info("\u{1F517} [UniversalExportService] \u5904\u7406\u591A\u5B57\u6BB5\u5408\u5E76\u6A21\u5F0F:", {
      groupItemsLength: groupItems.length,
      groupFields: groupFields.map((f) => f.key),
      firstItem
    });
    for (let i = 1; i < groupItems.length; i++) {
      const item = { ...groupItems[i] };
      groupFields.forEach((field) => {
        item[field.key] = "";
      });
      item.__isGroupChild = true;
      item.__groupIndex = i;
      result.push(item);
    }
    return result;
  }
  /**
   * 处理嵌套模式
   */
  processNestedMode(groupItems, groupingConfig) {
    if (groupingConfig.fields.length === 1) {
      return this.processMergeMode(groupItems, groupingConfig.fields[0]);
    }
    const subGroupingConfig = {
      ...groupingConfig,
      fields: groupingConfig.fields.slice(1)
    };
    return this.applyGrouping(groupItems, subGroupingConfig);
  }
  /**
   * 统计分组数量
   */
  countGroups(data) {
    const groupHeaders = data.filter((item) => item.__isGroupHeader);
    const groupFirsts = data.filter((item) => item.__isGroupFirst);
    return Math.max(groupHeaders.length, groupFirsts.length);
  }
  /**
   * 生成Excel文件
   */
  generateExcel(data, fields, config) {
    logger2.info("\u{1F4CA} [UniversalExportService] generateExcel \u5F00\u59CB\u6267\u884C:", {
      dataLength: data.length,
      fieldsCount: fields.length,
      hasGrouping: !!(config.grouping && config.grouping.enabled)
    });
    const workbook = XLSX.utils.book_new();
    const nonEmptyFields = this.filterEmptyFields(data, fields);
    const worksheetData = this.prepareExcelData(data, nonEmptyFields, config);
    const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);
    if (config.grouping && config.grouping.enabled) {
      this.applyExcelGrouping(
        worksheet,
        data,
        nonEmptyFields,
        config.grouping,
        config.includeHeader
      );
    }
    this.setExcelColumnWidths(worksheet, nonEmptyFields);
    this.applyExcelDataStyles(worksheet, config.includeHeader);
    XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
    const excelBuffer = XLSX.write(workbook, {
      bookType: "xlsx",
      type: "array",
      cellStyles: true
    });
    logger2.info("\u2705 [UniversalExportService] generateExcel \u6267\u884C\u5B8C\u6210");
    return excelBuffer;
  }
  /**
   * 准备Excel数据
   */
  prepareExcelData(data, fields, config) {
    const result = [];
    logger2.info("\u{1F4CA} [UniversalExportService] \u51C6\u5907Excel\u6570\u636E:", {
      dataLength: data.length,
      fieldsCount: fields.length,
      includeHeader: config.includeHeader,
      hasGrouping: !!(config.grouping && config.grouping.enabled)
    });
    if (config.includeHeader) {
      const headers = fields.map((field) => field.label);
      result.push(headers);
      logger2.info("\u{1F4CB} [UniversalExportService] \u6DFB\u52A0\u8868\u5934:", headers);
    }
    for (let i = 0; i < data.length; i++) {
      const item = data[i];
      const row = fields.map((field) => {
        if (item.__isGroupHeader) {
          return item[field.key] || "";
        }
        let value = this.getNestedValue(item, field.key);
        if (field.formatter) {
          value = field.formatter(value);
        } else if (DEFAULT_FORMATTERS[field.type]) {
          value = DEFAULT_FORMATTERS[field.type](value);
        } else {
          value = String(value || "");
        }
        return value;
      });
      result.push(row);
      if (i === 0) {
        logger2.info("\u{1F4CA} [UniversalExportService] \u7B2C\u4E00\u884C\u6570\u636E\u793A\u4F8B:", row);
      }
    }
    logger2.info("\u2705 [UniversalExportService] Excel\u6570\u636E\u51C6\u5907\u5B8C\u6210:", {
      totalRows: result.length,
      headerRows: config.includeHeader ? 1 : 0,
      dataRows: result.length - (config.includeHeader ? 1 : 0)
    });
    return result;
  }
  /**
   * 应用Excel分组和合并单元格
   */
  applyExcelGrouping(worksheet, data, fields, groupingConfig, includeHeader = true) {
    if (!worksheet["!merges"]) {
      worksheet["!merges"] = [];
    }
    const headerOffset = includeHeader ? 1 : 0;
    let currentRow = headerOffset;
    logger2.info("\u{1F4CA} [UniversalExportService] \u5F00\u59CB\u5904\u7406Excel\u5206\u7EC4\u548C\u5408\u5E76\u5355\u5143\u683C:", {
      dataLength: data.length,
      headerOffset,
      groupingFields: groupingConfig.fields.map((f) => ({ key: f.key, mergeCells: f.mergeCells }))
    });
    for (let i = 0; i < data.length; i++) {
      const item = data[i];
      if (item.__isGroupFirst && item.__groupSize > 1) {
        logger2.info("\u{1F517} [UniversalExportService] \u5904\u7406\u5206\u7EC4\u5408\u5E76:", {
          row: currentRow,
          groupSize: item.__groupSize,
          item
        });
        groupingConfig.fields.forEach((groupField) => {
          if (groupField.mergeCells) {
            const fieldIndex = fields.findIndex((f) => f.key === groupField.key);
            if (fieldIndex >= 0) {
              const groupSize = item["__" + groupField.key + "_groupSize"] || item.__groupSize;
              const mergeRange = {
                s: { r: currentRow, c: fieldIndex },
                // 开始行列
                e: { r: currentRow + groupSize - 1, c: fieldIndex }
                // 结束行列
              };
              logger2.info("\u{1F4CA} [UniversalExportService] \u6DFB\u52A0\u5408\u5E76\u533A\u57DF:", {
                field: groupField.key,
                fieldIndex,
                groupSize,
                mergeRange
              });
              worksheet["!merges"].push(mergeRange);
              const startCellAddress = XLSX.utils.encode_cell(mergeRange.s);
              if (worksheet[startCellAddress]) {
                worksheet[startCellAddress].s = {
                  ...worksheet[startCellAddress].s,
                  alignment: { horizontal: "center", vertical: "middle" },
                  fill: { fgColor: { rgb: "F2F2F2" } },
                  border: {
                    top: { style: "thin", color: { rgb: "000000" } },
                    bottom: { style: "thin", color: { rgb: "000000" } },
                    left: { style: "thin", color: { rgb: "000000" } },
                    right: { style: "thin", color: { rgb: "000000" } }
                  }
                };
              }
            }
          }
        });
      }
      currentRow++;
    }
    logger2.info("\u2705 [UniversalExportService] Excel\u5206\u7EC4\u548C\u5408\u5E76\u5355\u5143\u683C\u5904\u7406\u5B8C\u6210:", {
      totalMerges: worksheet["!merges"]?.length || 0
    });
  }
  /**
   * 设置Excel列宽和样式
   */
  setExcelColumnWidths(worksheet, fields) {
    const colWidths = fields.map((field) => ({
      wch: field.width || 15
      // 默认宽度15字符
    }));
    worksheet["!cols"] = colWidths;
    if (worksheet["!ref"]) {
      const range = XLSX.utils.decode_range(worksheet["!ref"]);
      for (let col = range.s.c; col <= range.e.c; col++) {
        const cellAddress = XLSX.utils.encode_cell({ r: 0, c: col });
        if (worksheet[cellAddress]) {
          worksheet[cellAddress].s = {
            font: { bold: true, color: { rgb: "FFFFFF" } },
            fill: { fgColor: { rgb: "4472C4" } },
            alignment: { horizontal: "center", vertical: "center" },
            border: {
              top: { style: "thin", color: { rgb: "000000" } },
              bottom: { style: "thin", color: { rgb: "000000" } },
              left: { style: "thin", color: { rgb: "000000" } },
              right: { style: "thin", color: { rgb: "000000" } }
            }
          };
        }
      }
    }
    logger2.info("\u2705 [UniversalExportService] Excel\u5217\u5BBD\u548C\u6837\u5F0F\u8BBE\u7F6E\u5B8C\u6210:", {
      columnsCount: colWidths.length,
      columnWidths: colWidths.map((col, index) => ({ field: fields[index]?.key, width: col.wch }))
    });
  }
  /**
   * 为Excel数据单元格应用样式
   */
  applyExcelDataStyles(worksheet, includeHeader = true) {
    if (!worksheet["!ref"]) return;
    const range = XLSX.utils.decode_range(worksheet["!ref"]);
    const startRow = includeHeader ? 1 : 0;
    logger2.info("\u{1F3A8} [UniversalExportService] \u5F00\u59CB\u5E94\u7528Excel\u6570\u636E\u6837\u5F0F:", {
      totalRows: range.e.r + 1,
      totalCols: range.e.c + 1,
      startRow
    });
    for (let row = startRow; row <= range.e.r; row++) {
      for (let col = range.s.c; col <= range.e.c; col++) {
        const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
        if (worksheet[cellAddress]) {
          const existingStyle = worksheet[cellAddress].s || {};
          worksheet[cellAddress].s = {
            ...existingStyle,
            border: {
              top: { style: "thin", color: { rgb: "CCCCCC" } },
              bottom: { style: "thin", color: { rgb: "CCCCCC" } },
              left: { style: "thin", color: { rgb: "CCCCCC" } },
              right: { style: "thin", color: { rgb: "CCCCCC" } }
            },
            alignment: {
              ...existingStyle.alignment,
              vertical: "center"
            }
          };
        }
      }
    }
    logger2.info("\u2705 [UniversalExportService] Excel\u6570\u636E\u6837\u5F0F\u5E94\u7528\u5B8C\u6210");
  }
};

// src/universalExport/server/factory.ts
function createExportServiceConfig(options = {}) {
  return {
    db: options.db,
    exportDir: options.exportDir || process.env.EXPORT_DIR || "./exports",
    tempDir: options.tempDir || process.env.TEMP_DIR || "./temp",
    maxRows: options.maxRows || 1e5,
    // 默认最多导出 10 万行
    enableStreaming: options.enableStreaming !== false,
    // 默认启用流式导出
    timeout: options.timeout || 3e5
    // 默认超时 5 分钟
  };
}
function createUniversalExportService(options = {}) {
  const config = createExportServiceConfig(options);
  console.warn(
    "\u26A0\uFE0F  UniversalExportService \u7684\u5B8C\u6574\u5B9E\u73B0\u5C06\u5728\u540E\u7EED Phase \u4E2D\u8FC1\u79FB\u5230 Sa2kit\u3002\n    \u5F53\u524D\u7248\u672C\u4EC5\u5305\u542B\u7C7B\u578B\u5B9A\u4E49\u548C\u914D\u7F6E\u5DE5\u5382\u51FD\u6570\u3002\n    \u8BF7\u6682\u65F6\u7EE7\u7EED\u4ECE LyricNote \u7684 lib/universalExport \u5BFC\u5165\u670D\u52A1\u7C7B\u3002"
  );
  return {
    config,
    // 占位方法
    async export() {
      throw new Error("UniversalExportService \u5C1A\u672A\u5B8C\u5168\u8FC1\u79FB\uFF0C\u8BF7\u4ECE LyricNote \u5BFC\u5165");
    },
    async createTask() {
      throw new Error("UniversalExportService \u5C1A\u672A\u5B8C\u5168\u8FC1\u79FB\uFF0C\u8BF7\u4ECE LyricNote \u5BFC\u5165");
    }
  };
}
function createExportServiceFromEnv(db) {
  return createUniversalExportService({
    db,
    exportDir: process.env.EXPORT_DIR,
    tempDir: process.env.TEMP_DIR,
    maxRows: process.env.EXPORT_MAX_ROWS ? parseInt(process.env.EXPORT_MAX_ROWS) : void 0
  });
}

// src/universalExport/server/presets.ts
function createSmallAppPreset() {
  return {
    maxRows: 1e4,
    // 1万行
    timeout: 6e4,
    // 1分钟
    enableStreaming: false
    // 小数据量不需要流式导出
  };
}
function createMediumAppPreset() {
  return {
    maxRows: 1e5,
    // 10万行
    timeout: 3e5,
    // 5分钟
    enableStreaming: true
  };
}
function createLargeAppPreset() {
  return {
    maxRows: 1e6,
    // 100万行
    timeout: 6e5,
    // 10分钟
    enableStreaming: true
  };
}
function createRealtimeExportPreset() {
  return {
    maxRows: 5e3,
    // 5千行
    timeout: 3e4,
    // 30秒
    enableStreaming: false
  };
}
function createBatchExportPreset() {
  return {
    maxRows: Number.MAX_SAFE_INTEGER,
    // 不限制
    timeout: 18e5,
    // 30分钟
    enableStreaming: true
  };
}
function createSmartExportPreset() {
  const envMaxRows = process.env.EXPORT_MAX_ROWS;
  if (envMaxRows) {
    const maxRows = parseInt(envMaxRows);
    if (maxRows <= 1e4) {
      return createSmallAppPreset();
    } else if (maxRows <= 1e5) {
      return createMediumAppPreset();
    } else {
      return createLargeAppPreset();
    }
  }
  return createMediumAppPreset();
}

// src/universalExport/server/validation.ts
var ConfigValidationError = class extends Error {
  constructor(message, field) {
    super(message);
    this.field = field;
    this.name = "ConfigValidationError";
  }
};
function validateExportConfig(config) {
  if (!config.exportDir) {
    throw new ConfigValidationError("exportDir is required", "exportDir");
  }
  if (!config.tempDir) {
    throw new ConfigValidationError("tempDir is required", "tempDir");
  }
  if (config.maxRows && config.maxRows <= 0) {
    throw new ConfigValidationError(
      "maxRows must be greater than 0",
      "maxRows"
    );
  }
  if (config.timeout && config.timeout <= 0) {
    throw new ConfigValidationError(
      "timeout must be greater than 0",
      "timeout"
    );
  }
  if (config.maxRows && config.maxRows > 1e6) {
    console.warn(
      "\u26A0\uFE0F  Warning: maxRows (" + config.maxRows + `) is very large. Consider using pagination or streaming for better performance.`
    );
  }
}
function validateEnvironment(requiredVars) {
  const missing = [];
  for (const varName of requiredVars) {
    if (!process.env[varName]) {
      missing.push(varName);
    }
  }
  if (missing.length > 0) {
    throw new ConfigValidationError(
      "Missing required environment variables: " + missing.join(", "),
      "environment"
    );
  }
}

// src/universalExport/server/utils/index.ts
function formatFieldValue(value, field) {
  if (field.formatter) {
    return field.formatter(value);
  }
  if (value === null || value === void 0) {
    return "";
  }
  switch (field.type) {
    case "date":
      return value instanceof Date ? value.toISOString().split("T")[0] || "" : String(value);
    case "boolean":
      return value ? "\u662F" : "\u5426";
    case "array":
      return Array.isArray(value) ? value.join(", ") : String(value);
    case "object":
      return typeof value === "object" ? JSON.stringify(value) : String(value);
    case "number":
      return typeof value === "number" ? value.toLocaleString() : String(value);
    default:
      return String(value);
  }
}
function validateFieldValue(value, field) {
  if (field.required && (value === null || value === void 0 || value === "")) {
    return false;
  }
  switch (field.type) {
    case "number":
      return typeof value === "number" || !isNaN(Number(value));
    case "boolean":
      return typeof value === "boolean";
    case "array":
      return Array.isArray(value);
    case "object":
      return typeof value === "object";
    case "date":
      return value instanceof Date || !isNaN(Date.parse(value));
    default:
      return true;
  }
}
function convertFieldType(value, targetType) {
  if (value === null || value === void 0) {
    return value;
  }
  switch (targetType) {
    case "string":
      return String(value);
    case "number":
      return Number(value);
    case "boolean":
      return Boolean(value);
    case "date":
      return value instanceof Date ? value : new Date(value);
    case "array":
      return Array.isArray(value) ? value : [value];
    case "object":
      return typeof value === "object" ? value : { value };
    default:
      return value;
  }
}
function getNestedValue(obj, path) {
  return path.split(".").reduce((current, key) => current?.[key], obj);
}
function escapeCsvValue(value) {
  if (value.includes(",") || value.includes('"') || value.includes("\n")) {
    return '"' + value.replace(/"/g, '""') + '"';
  }
  return value;
}
function generateUniqueFilename(prefix, extension) {
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, -5);
  const random = Math.random().toString(36).substring(2, 8);
  return prefix + "_" + timestamp2 + "_" + random + "." + extension;
}
function calculateProgress(processed, total) {
  if (total === 0) return 0;
  return Math.min(Math.round(processed / total * 100), 100);
}
function estimateRemainingTime(processed, total, elapsedMs) {
  if (processed === 0) return 0;
  const avgTimePerRow = elapsedMs / processed;
  const remainingRows = total - processed;
  return Math.round(remainingRows * avgTimePerRow / 1e3);
}
var exportConfigs = pgTable("ExportConfig", {
  /** 主键ID */
  id: text("id").primaryKey().$defaultFn(() => "export_config_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9)),
  /** 配置名称 */
  name: text("name").notNull(),
  /** 配置描述 */
  description: text("description"),
  /** 导出格式：'csv' | 'excel' | 'json' */
  format: text("format").notNull(),
  /** 导出字段配置（JSON数组） */
  fields: jsonb("fields").notNull(),
  // ExportField[]
  /** 分组配置 */
  grouping: jsonb("grouping"),
  // GroupingConfig
  /** 文件名模板 */
  fileNameTemplate: text("fileNameTemplate").notNull(),
  /** 是否包含表头 */
  includeHeader: boolean("includeHeader").default(true).notNull(),
  /** 分隔符（用于CSV格式） */
  delimiter: text("delimiter").default(",").notNull(),
  /** 编码格式 */
  encoding: text("encoding").default("utf-8").notNull(),
  /** 是否添加BOM（用于Excel打开UTF-8 CSV） */
  addBOM: boolean("addBOM").default(true).notNull(),
  /** 最大导出行数 */
  maxRows: integer("maxRows"),
  /** 模块ID */
  moduleId: text("moduleId").notNull(),
  /** 业务ID */
  businessId: text("businessId"),
  /** 创建者ID */
  createdBy: text("createdBy"),
  /** 创建时间 */
  createdAt: timestamp("createdAt", { precision: 3, mode: "date" }).default(sql`CURRENT_TIMESTAMP`).notNull(),
  /** 更新时间 */
  updatedAt: timestamp("updatedAt", { precision: 3, mode: "date" }).default(sql`CURRENT_TIMESTAMP`).notNull()
});
var exportHistory = pgTable("ExportHistory", {
  /** 主键ID */
  id: text("id").primaryKey().$defaultFn(() => "export_history_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9)),
  /** 关联的配置ID */
  configId: text("configId").notNull(),
  /** 导出的文件名 */
  fileName: text("fileName").notNull(),
  /** 文件大小（字节） */
  fileSize: integer("fileSize").notNull(),
  /** 导出的行数 */
  exportedRows: integer("exportedRows").notNull(),
  /** 导出状态：'pending' | 'processing' | 'completed' | 'failed' */
  status: text("status").notNull(),
  /** 错误信息（如果失败） */
  error: text("error"),
  /** 导出耗时（毫秒） */
  duration: integer("duration"),
  /** 开始时间 */
  startTime: timestamp("startTime", { precision: 3, mode: "date" }).notNull(),
  /** 结束时间 */
  endTime: timestamp("endTime", { precision: 3, mode: "date" }),
  /** 创建者ID */
  createdBy: text("createdBy"),
  /** 创建时间 */
  createdAt: timestamp("createdAt", { precision: 3, mode: "date" }).default(sql`CURRENT_TIMESTAMP`).notNull()
});
var exportConfigsRelations = relations(exportConfigs, ({ many }) => ({
  history: many(exportHistory)
}));
var exportHistoryRelations = relations(exportHistory, ({ one }) => ({
  config: one(exportConfigs, {
    fields: [exportHistory.configId],
    references: [exportConfigs.id]
  })
}));
var ExportConfigDatabaseService = class {
  constructor(db) {
    this.db = db;
  }
  /**
   * 创建导出配置
   */
  async createConfig(config) {
    const id = "export_config_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
    const now = /* @__PURE__ */ new Date();
    const [newConfig] = await this.db.insert(exportConfigs).values({
      id,
      ...config,
      createdAt: now,
      updatedAt: now
    }).returning();
    return newConfig;
  }
  /**
   * 根据ID获取配置
   */
  async getConfigById(id) {
    const [config] = await this.db.select().from(exportConfigs).where(eq(exportConfigs.id, id)).limit(1);
    return config || null;
  }
  /**
   * 根据模块和业务ID获取配置列表
   */
  async getConfigsByModule(moduleId, businessId) {
    const whereConditions = businessId ? and(eq(exportConfigs.moduleId, moduleId), eq(exportConfigs.businessId, businessId)) : eq(exportConfigs.moduleId, moduleId);
    return await this.db.select().from(exportConfigs).where(whereConditions).orderBy(desc(exportConfigs.updatedAt));
  }
  /**
   * 更新配置
   */
  async updateConfig(id, updates) {
    const [updatedConfig] = await this.db.update(exportConfigs).set({
      ...updates,
      updatedAt: /* @__PURE__ */ new Date()
    }).where(eq(exportConfigs.id, id)).returning();
    return updatedConfig || null;
  }
  /**
   * 删除配置
   */
  async deleteConfig(id) {
    await this.db.delete(exportConfigs).where(eq(exportConfigs.id, id));
    return true;
  }
  /**
   * 根据用户ID获取配置列表
   */
  async getConfigsByUser(userId) {
    return await this.db.select().from(exportConfigs).where(eq(exportConfigs.createdBy, userId)).orderBy(desc(exportConfigs.updatedAt));
  }
};
var ExportHistoryDatabaseService = class {
  constructor(db) {
    this.db = db;
  }
  /**
   * 创建导出历史记录
   */
  async createHistory(history) {
    const id = "export_history_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
    const [newHistory] = await this.db.insert(exportHistory).values({
      id,
      ...history,
      createdAt: /* @__PURE__ */ new Date()
    }).returning();
    return newHistory;
  }
  /**
   * 根据配置ID获取历史记录
   */
  async getHistoryByConfigId(configId) {
    return await this.db.select().from(exportHistory).where(eq(exportHistory.configId, configId)).orderBy(desc(exportHistory.createdAt));
  }
  /**
   * 根据用户ID获取历史记录
   */
  async getHistoryByUser(userId) {
    return await this.db.select().from(exportHistory).where(eq(exportHistory.createdBy, userId)).orderBy(desc(exportHistory.createdAt));
  }
  /**
   * 获取最近的导出历史记录
   */
  async getRecentHistory(limit = 10) {
    return await this.db.select().from(exportHistory).orderBy(desc(exportHistory.createdAt)).limit(limit);
  }
};
function createExportDatabaseServices(options) {
  const { db } = options;
  return {
    configDB: new ExportConfigDatabaseService(db),
    historyDB: new ExportHistoryDatabaseService(db)
  };
}

export { ExportConfigDatabaseService, ConfigValidationError as ExportConfigValidationError, ExportHistoryDatabaseService, UniversalExportService, calculateProgress, convertFieldType, createBatchExportPreset, createExportDatabaseServices, createExportServiceConfig, createExportServiceFromEnv, createLargeAppPreset, createMediumAppPreset, createRealtimeExportPreset, createSmallAppPreset, createSmartExportPreset, createUniversalExportService, escapeCsvValue, estimateRemainingTime, exportConfigs, exportConfigsRelations, exportHistory, exportHistoryRelations, formatFieldValue, generateUniqueFilename, getNestedValue, validateExportConfig, validateEnvironment as validateExportEnvironment, validateFieldValue };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map