143afd59
杨鑫
打印,标签
|
1
|
import type {
|
43d16ca6
杨鑫
打印日志
|
2
3
|
PrintLogGetListInputVo,
PrintLogItemDto,
|
143afd59
杨鑫
打印,标签
|
4
5
6
7
8
|
UsAppLabelCategoryTreeNodeDto,
UsAppLabelingProductNodeDto,
UsAppLabelPreviewInputVo,
UsAppLabelPrintInputVo,
UsAppLabelPrintOutputDto,
|
43d16ca6
杨鑫
打印日志
|
9
|
UsAppLabelReprintInputVo,
|
143afd59
杨鑫
打印,标签
|
10
11
12
|
UsAppLabelTypeNodeDto,
UsAppProductCategoryNodeDto,
} from '../types/usAppLabeling'
|
43d16ca6
杨鑫
打印日志
|
13
|
import { extractPagedItems } from '../utils/pagedList'
|
143afd59
杨鑫
打印,标签
|
14
|
import { usAppApiRequest } from '../utils/usAppApiRequest'
|
699ea6e8
杨鑫
完善打印逻辑
|
15
|
import { enqueueOfflineMutation, fetchWithOfflineCache, isNetworkOnline } from '../utils/sqliteSync'
|
143afd59
杨鑫
打印,标签
|
16
|
|
a001da6d
杨鑫
APP 预览打印
|
17
18
19
|
/** 接口 9:与文档路径一致,供日志与请求共用 */
export const US_APP_LABEL_PRINT_PATH = '/api/app/us-app-labeling/print' as const
|
143afd59
杨鑫
打印,标签
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
function asArr(v: unknown): unknown[] {
return Array.isArray(v) ? v : []
}
/** 兼容 camelCase / PascalCase,对齐《标签模块接口对接说明(6).md》8.1 四级树 */
function normalizeLabelingTreePayload(raw: unknown): UsAppLabelCategoryTreeNodeDto[] {
const list = asArr(raw)
return list.map((node: any) => {
const pcs = asArr(node?.productCategories ?? node?.ProductCategories)
const productCategories: UsAppProductCategoryNodeDto[] = pcs.map((p: any) => {
const prods = asArr(p?.products ?? p?.Products)
const products: UsAppLabelingProductNodeDto[] = prods.map((x: any) => {
const lts = asArr(x?.labelTypes ?? x?.LabelTypes)
const labelTypes: UsAppLabelTypeNodeDto[] = lts.map((t: any) => ({
labelTypeId: String(t?.labelTypeId ?? t?.LabelTypeId ?? ''),
typeName: String(t?.typeName ?? t?.TypeName ?? ''),
orderNum: Number(t?.orderNum ?? t?.OrderNum ?? 0),
labelCode: String(t?.labelCode ?? t?.LabelCode ?? ''),
templateCode: (t?.templateCode ?? t?.TemplateCode ?? null) as string | null,
labelSizeText: (t?.labelSizeText ?? t?.LabelSizeText ?? null) as string | null,
}))
return {
productId: String(x?.productId ?? x?.ProductId ?? ''),
|
dc39baae
李曜臣
后台端:管理员查看日志优化,产品与...
|
43
44
45
46
47
|
templateId: (x?.templateId ?? x?.TemplateId ?? null) as string | null,
templateCode: (x?.templateCode ?? x?.TemplateCode ?? null) as string | null,
templateLabelSizeText: (x?.templateLabelSizeText ?? x?.TemplateLabelSizeText ?? null) as
| string
| null,
|
143afd59
杨鑫
打印,标签
|
48
49
50
51
52
53
54
55
56
57
58
59
|
productName: String(x?.productName ?? x?.ProductName ?? ''),
productCode: String(x?.productCode ?? x?.ProductCode ?? ''),
productImageUrl: (x?.productImageUrl ?? x?.ProductImageUrl ?? null) as string | null,
subtitle: String(x?.subtitle ?? x?.Subtitle ?? ''),
labelTypeCount: Number(x?.labelTypeCount ?? x?.LabelTypeCount ?? labelTypes.length),
labelTypes,
}
})
const catId = p?.categoryId ?? p?.CategoryId
return {
categoryId: catId != null && String(catId).trim() !== '' ? String(catId) : null,
categoryPhotoUrl: (p?.categoryPhotoUrl ?? p?.CategoryPhotoUrl ?? null) as string | null,
|
3ead62fc
杨鑫
优化
|
60
61
62
63
64
65
66
67
|
// 透传平台端扩展字段(用于 APP 按 buttonAppearance 渲染 icon)
displayText: (p?.displayText ?? p?.DisplayText ?? null) as string | null,
buttonAppearance: (p?.buttonAppearance ?? p?.ButtonAppearance ?? null) as string | null,
buttonTextColor: (p?.buttonTextColor ?? p?.ButtonTextColor ?? null) as string | null,
buttonBgColor: (p?.buttonBgColor ?? p?.ButtonBgColor ?? null) as string | null,
buttonImageUrl: (p?.buttonImageUrl ?? p?.ButtonImageUrl ?? null) as string | null,
buttonStyleJson: (p?.buttonStyleJson ?? p?.ButtonStyleJson ?? null) as string | null,
availabilityType: (p?.availabilityType ?? p?.AvailabilityType ?? null) as string | null,
|
143afd59
杨鑫
打印,标签
|
68
69
70
71
72
73
74
75
76
|
name: String(p?.name ?? p?.Name ?? ''),
itemCount: Number(p?.itemCount ?? p?.ItemCount ?? products.length),
products,
}
})
return {
id: String(node?.id ?? node?.Id ?? ''),
categoryName: String(node?.categoryName ?? node?.CategoryName ?? ''),
categoryPhotoUrl: (node?.categoryPhotoUrl ?? node?.CategoryPhotoUrl ?? null) as string | null,
|
699ea6e8
杨鑫
完善打印逻辑
|
77
78
79
80
|
displayText: (node?.displayText ?? node?.DisplayText ?? null) as string | null,
buttonBgColor: (node?.buttonBgColor ?? node?.ButtonBgColor ?? null) as string | null,
buttonImageUrl: (node?.buttonImageUrl ?? node?.ButtonImageUrl ?? null) as string | null,
buttonTextColor: (node?.buttonTextColor ?? node?.ButtonTextColor ?? null) as string | null,
|
3ead62fc
杨鑫
优化
|
81
|
// 透传平台端扩展字段(用于 APP 按 buttonAppearance 渲染 icon)
|
699ea6e8
杨鑫
完善打印逻辑
|
82
83
|
buttonAppearance: (node?.buttonAppearance ?? node?.ButtonAppearance ?? null) as string | string[] | null,
buttonStyleJson: (node?.buttonStyleJson ?? node?.ButtonStyleJson ?? null) as string | null,
|
143afd59
杨鑫
打印,标签
|
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
|
orderNum: Number(node?.orderNum ?? node?.OrderNum ?? 0),
productCategories,
}
})
}
function buildLabelingTreePath(params: {
locationId: string
keyword?: string
labelCategoryId?: string
}): string {
const q: string[] = [`locationId=${encodeURIComponent(params.locationId)}`]
if (params.keyword != null && String(params.keyword).trim() !== '') {
q.push(`keyword=${encodeURIComponent(String(params.keyword).trim())}`)
}
if (params.labelCategoryId != null && String(params.labelCategoryId).trim() !== '') {
q.push(`labelCategoryId=${encodeURIComponent(String(params.labelCategoryId).trim())}`)
}
return `/api/app/us-app-labeling/labeling-tree?${q.join('&')}`
}
/** 接口 8.1 */
export async function fetchUsAppLabelingTree(input: {
locationId: string
keyword?: string
labelCategoryId?: string
}): Promise<UsAppLabelCategoryTreeNodeDto[]> {
|
699ea6e8
杨鑫
完善打印逻辑
|
111
112
113
114
115
116
117
118
|
const key = `labeling-tree:${input.locationId}:${input.keyword || ''}:${input.labelCategoryId || ''}`
return fetchWithOfflineCache('labeling', key, async () => {
const raw = await usAppApiRequest<unknown>({
path: buildLabelingTreePath(input),
method: 'GET',
auth: true,
})
return normalizeLabelingTreePayload(raw)
|
143afd59
杨鑫
打印,标签
|
119
|
})
|
143afd59
杨鑫
打印,标签
|
120
121
122
123
124
125
126
127
128
129
130
131
|
}
/** 接口 8.2 */
export async function postUsAppLabelPreview(body: UsAppLabelPreviewInputVo): Promise<unknown> {
return usAppApiRequest<unknown>({
path: '/api/app/us-app-labeling/preview',
method: 'POST',
auth: true,
data: body,
})
}
|
a001da6d
杨鑫
APP 预览打印
|
132
133
134
135
|
/**
* 接口 9.1 原始请求。
* 注意:仅供业务落库场景调用;打印机设置页「测试打印」、蓝牙页 Test Print 等 **不得** 使用(避免脏数据)。
*/
|
143afd59
杨鑫
打印,标签
|
136
|
export async function postUsAppLabelPrint(body: UsAppLabelPrintInputVo): Promise<UsAppLabelPrintOutputDto> {
|
699ea6e8
杨鑫
完善打印逻辑
|
137
138
139
140
141
142
143
144
|
const online = await isNetworkOnline()
if (!online) {
await enqueueOfflineMutation('/api/app/us-app-labeling/print', 'POST', body)
return {
taskId: body.clientRequestId || `offline-${Date.now()}`,
printQuantity: Math.max(1, Number(body.printQuantity || 1)),
}
}
|
43d16ca6
杨鑫
打印日志
|
145
146
147
148
149
150
151
|
console.log('[UsAppLabelPrint] 接口 9 请求前 — path:', US_APP_LABEL_PRINT_PATH)
console.log('[UsAppLabelPrint] 接口 9 请求体 body:', body)
try {
console.log('[UsAppLabelPrint] 接口 9 请求体 JSON:', JSON.stringify(body))
} catch {
console.log('[UsAppLabelPrint] 接口 9 请求体 JSON 序列化失败(含循环引用等)')
}
|
699ea6e8
杨鑫
完善打印逻辑
|
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
try {
return await usAppApiRequest<UsAppLabelPrintOutputDto>({
path: US_APP_LABEL_PRINT_PATH,
method: 'POST',
auth: true,
data: body,
})
} catch (e: unknown) {
const msg = e instanceof Error ? e.message : String(e)
// 在线请求失败时若是网络类错误,自动降级写入本地队列,避免用户操作丢失
if (/network|timeout|offline|断网|网络/i.test(msg)) {
await enqueueOfflineMutation('/api/app/us-app-labeling/print', 'POST', body)
return {
taskId: body.clientRequestId || `offline-${Date.now()}`,
printQuantity: Math.max(1, Number(body.printQuantity || 1)),
}
}
throw e
}
|
143afd59
杨鑫
打印,标签
|
171
|
}
|
a001da6d
杨鑫
APP 预览打印
|
172
173
174
175
176
177
|
export function buildUsAppLabelPrintRequestBody(input: {
locationId?: string | null
labelCode?: string | null
productId?: string | null
printQuantity: number
|
b04bc3a5
杨鑫
打印日志 重新打印
|
178
|
/** 写入接口 9 `printInputJson`:合并模板快照(可与 `buildPrintInputJson` 结果浅合并),应对齐列表 `renderTemplateJson` */
|
43d16ca6
杨鑫
打印日志
|
179
180
|
mergedTemplate: Record<string, unknown>
clientRequestId?: string | null
|
a001da6d
杨鑫
APP 预览打印
|
181
182
183
184
185
186
187
|
printerMac?: string | null
printerAddress?: string | null
}): UsAppLabelPrintInputVo | null {
const locationId = String(input.locationId || '').trim()
const labelCode = String(input.labelCode || '').trim()
if (!locationId || !labelCode) return null
|
43d16ca6
杨鑫
打印日志
|
188
189
190
191
192
193
194
|
let printInputJson: Record<string, unknown>
try {
printInputJson = JSON.parse(JSON.stringify(input.mergedTemplate)) as Record<string, unknown>
} catch {
return null
}
|
a001da6d
杨鑫
APP 预览打印
|
195
196
197
198
|
const body: UsAppLabelPrintInputVo = {
locationId,
labelCode,
printQuantity: Math.max(1, Math.round(Number(input.printQuantity) || 1)),
|
43d16ca6
杨鑫
打印日志
|
199
|
printInputJson,
|
a001da6d
杨鑫
APP 预览打印
|
200
201
|
baseTime: new Date().toISOString(),
}
|
43d16ca6
杨鑫
打印日志
|
202
203
|
const cid = String(input.clientRequestId || '').trim()
if (cid) body.clientRequestId = cid
|
a001da6d
杨鑫
APP 预览打印
|
204
205
206
207
208
209
210
211
212
213
214
|
const pid = String(input.productId || '').trim()
if (pid) body.productId = pid
const mac = String(input.printerMac || '').trim()
if (mac) body.printerMac = mac
const addr = String(input.printerAddress || '').trim()
if (addr) body.printerAddress = addr
return body
}
/**
* 接口 9:仅在 **标签预览页**(`pages/labels/preview`)用户打印真实标签、出纸成功后落库。
|
43d16ca6
杨鑫
打印日志
|
215
|
* `mergedTemplate` 写入请求体 `printInputJson`(与 label-template 同构);缺少 `locationId` 或 `labelCode` 时不发请求。
|
a001da6d
杨鑫
APP 预览打印
|
216
217
218
219
220
221
222
|
* 测试打印模板(printers / bluetooth Test Print)不走此函数。
*/
export async function reportUsAppLabelPrintIfReady(input: {
locationId?: string | null
labelCode?: string | null
productId?: string | null
printQuantity: number
|
43d16ca6
杨鑫
打印日志
|
223
224
|
mergedTemplate: Record<string, unknown>
clientRequestId?: string | null
|
a001da6d
杨鑫
APP 预览打印
|
225
226
227
228
229
230
231
|
printerMac?: string | null
printerAddress?: string | null
}): Promise<UsAppLabelPrintOutputDto | null> {
const body = buildUsAppLabelPrintRequestBody(input)
if (!body) return null
return postUsAppLabelPrint(body)
}
|
43d16ca6
杨鑫
打印日志
|
232
233
234
|
/** 接口 10:分页打印日志 */
export async function fetchUsAppPrintLogList (input: PrintLogGetListInputVo) {
|
699ea6e8
杨鑫
完善打印逻辑
|
235
236
237
238
239
240
241
242
243
244
245
246
247
|
const key = `print-log:${input.locationId}:${input.skipCount ?? 1}:${input.maxResultCount ?? 20}`
return fetchWithOfflineCache('labeling', key, async () => {
const raw = await usAppApiRequest<unknown>({
path: '/api/app/us-app-labeling/get-print-log-list',
method: 'POST',
auth: true,
data: {
locationId: input.locationId,
skipCount: input.skipCount ?? 1,
maxResultCount: input.maxResultCount ?? 20,
},
})
return extractPagedItems<PrintLogItemDto>(raw)
|
43d16ca6
杨鑫
打印日志
|
248
|
})
|
43d16ca6
杨鑫
打印日志
|
249
250
251
252
|
}
/** 接口 11:重打并返回含 mergedTemplateJson 的出参 */
export async function postUsAppLabelReprint (body: UsAppLabelReprintInputVo): Promise<UsAppLabelPrintOutputDto> {
|
699ea6e8
杨鑫
完善打印逻辑
|
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
const online = await isNetworkOnline()
if (!online) {
await enqueueOfflineMutation('/api/app/us-app-labeling/reprint', 'POST', body)
return {
taskId: body.clientRequestId || body.taskId || `offline-reprint-${Date.now()}`,
printQuantity: Math.max(1, Number(body.printQuantity || 1)),
}
}
try {
return await usAppApiRequest<UsAppLabelPrintOutputDto>({
path: '/api/app/us-app-labeling/reprint',
method: 'POST',
auth: true,
data: body,
})
} catch (e: unknown) {
const msg = e instanceof Error ? e.message : String(e)
if (/network|timeout|offline|断网|网络/i.test(msg)) {
await enqueueOfflineMutation('/api/app/us-app-labeling/reprint', 'POST', body)
return {
taskId: body.clientRequestId || body.taskId || `offline-reprint-${Date.now()}`,
printQuantity: Math.max(1, Number(body.printQuantity || 1)),
}
}
throw e
}
|
43d16ca6
杨鑫
打印日志
|
279
|
}
|