/** 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 = { 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(['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, ): Record { 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; 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, ): Record { 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): Record { 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 { 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 { return buildCompanyPrintFieldsConfigPatch({ ...DEFAULT_COMPANY_PRINT_FIELDS }); }