companyPrintFields.ts
5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/** 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 });
}