companyPrintFields.ts 5.55 KB
/** Company 控件:标签上可选打印的公司地址字段(与后端 companyIncludeFields 对齐) */
export type CompanyPrintFieldKey = 'address' | 'city' | 'state' | 'zip' | 'email';

export const COMPANY_PRINT_FIELD_OPTIONS: ReadonlyArray<{
  key: CompanyPrintFieldKey;
  label: string;
}> = [
  { key: 'address', label: 'Address' },
  { key: 'city', label: 'City' },
  { key: 'state', label: 'State' },
  { key: 'zip', label: 'Zip' },
  { key: 'email', label: 'Email' },
];

export const DEFAULT_COMPANY_PRINT_FIELDS: Record<CompanyPrintFieldKey, boolean> = {
  address: true,
  city: true,
  state: true,
  zip: true,
  email: true,
};

/** 编辑器预览用示例数据(实际打印由后端按门店所属 Company 填充) */
export const COMPANY_PRINT_PREVIEW_SAMPLES = {
  name: 'Acme Foods Inc',
  address: '123 Main Street',
  city: 'New York',
  state: 'NY',
  zip: '10001',
  email: 'sales@acme.com',
} as const;

function readBool(raw: unknown, fallback: boolean): boolean {
  if (typeof raw === 'boolean') return raw;
  if (raw === 'true' || raw === 1 || raw === '1') return true;
  if (raw === 'false' || raw === 0 || raw === '0') return false;
  return fallback;
}

function readIncludeArray(raw: unknown): CompanyPrintFieldKey[] | null {
  if (!Array.isArray(raw)) return null;
  const allowed = new Set<CompanyPrintFieldKey>(['address', 'city', 'state', 'zip', 'email']);
  const out: CompanyPrintFieldKey[] = [];
  for (const item of raw) {
    const key = String(item ?? '').trim().toLowerCase() as CompanyPrintFieldKey;
    if (allowed.has(key) && !out.includes(key)) out.push(key);
  }
  return out;
}

/** 从元素 config 读取 Company 打印字段开关(兼容 companyIncludeFields / include* / 旧 companyPrintFields) */
export function readCompanyPrintFields(
  cfg: Record<string, unknown>,
): Record<CompanyPrintFieldKey, boolean> {
  const defaults = { ...DEFAULT_COMPANY_PRINT_FIELDS };

  const includeArr = readIncludeArray(cfg.companyIncludeFields ?? cfg.CompanyIncludeFields);
  if (includeArr) {
    return {
      address: includeArr.includes('address'),
      city: includeArr.includes('city'),
      state: includeArr.includes('state'),
      zip: includeArr.includes('zip'),
      email: includeArr.includes('email'),
    };
  }

  const hasIncludeFlags =
    cfg.includeAddress !== undefined ||
    cfg.IncludeAddress !== undefined ||
    cfg.includeCity !== undefined ||
    cfg.IncludeCity !== undefined ||
    cfg.includeState !== undefined ||
    cfg.IncludeState !== undefined ||
    cfg.includeZip !== undefined ||
    cfg.IncludeZip !== undefined ||
    cfg.includeEmail !== undefined ||
    cfg.IncludeEmail !== undefined;
  if (hasIncludeFlags) {
    return {
      address: readBool(cfg.includeAddress ?? cfg.IncludeAddress, false),
      city: readBool(cfg.includeCity ?? cfg.IncludeCity, false),
      state: readBool(cfg.includeState ?? cfg.IncludeState, false),
      zip: readBool(cfg.includeZip ?? cfg.IncludeZip, false),
      email: readBool(cfg.includeEmail ?? cfg.IncludeEmail, false),
    };
  }

  const raw = cfg.companyPrintFields ?? cfg.CompanyPrintFields;
  if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
    const o = raw as Record<string, unknown>;
    return {
      address: readBool(o.address ?? o.Address, defaults.address),
      city: readBool(o.city ?? o.City, defaults.city),
      state: readBool(o.state ?? o.State ?? o.stateCode ?? o.StateCode, defaults.state),
      zip: readBool(o.zip ?? o.Zip ?? o.zipCode ?? o.ZipCode, defaults.zip),
      email: readBool(o.email ?? o.Email, defaults.email),
    };
  }

  return defaults;
}

/** 保存模板时写入后端约定格式:companyIncludeFields 数组 */
export function buildCompanyPrintFieldsConfigPatch(
  fields: Record<CompanyPrintFieldKey, boolean>,
): Record<string, unknown> {
  const companyIncludeFields = COMPANY_PRINT_FIELD_OPTIONS.filter((item) => fields[item.key]).map(
    (item) => item.key,
  );
  return { companyIncludeFields };
}

/** 提交 API 前规范化 Company config,去掉旧字段避免歧义 */
export function normalizeCompanyElementConfig(cfg: Record<string, unknown>): Record<string, unknown> {
  const fields = readCompanyPrintFields(cfg);
  const next = { ...cfg };
  delete next.companyPrintFields;
  delete next.CompanyPrintFields;
  delete next.includeAddress;
  delete next.IncludeAddress;
  delete next.includeCity;
  delete next.IncludeCity;
  delete next.includeState;
  delete next.IncludeState;
  delete next.includeZip;
  delete next.IncludeZip;
  delete next.includeEmail;
  delete next.IncludeEmail;
  return { ...next, ...buildCompanyPrintFieldsConfigPatch(fields) };
}

/** 按选中字段拼接编辑器预览文案(首行固定为公司名称,格式与后端一致) */
export function formatCompanyPrintPreviewText(cfg: Record<string, unknown>): string {
  const fields = readCompanyPrintFields(cfg);
  const lines: string[] = [COMPANY_PRINT_PREVIEW_SAMPLES.name];
  if (fields.address) {
    lines.push(COMPANY_PRINT_PREVIEW_SAMPLES.address);
  }
  const cityStateZip: string[] = [];
  if (fields.city) cityStateZip.push(COMPANY_PRINT_PREVIEW_SAMPLES.city);
  if (fields.state) cityStateZip.push(COMPANY_PRINT_PREVIEW_SAMPLES.state);
  if (fields.zip) cityStateZip.push(COMPANY_PRINT_PREVIEW_SAMPLES.zip);
  if (cityStateZip.length > 0) {
    lines.push(cityStateZip.join(', '));
  }
  if (fields.email) {
    lines.push(COMPANY_PRINT_PREVIEW_SAMPLES.email);
  }
  return lines.join('\n');
}

export function createDefaultCompanyPrintFieldsConfig(): Record<string, unknown> {
  return buildCompanyPrintFieldsConfigPatch({ ...DEFAULT_COMPANY_PRINT_FIELDS });
}