@chaobinchen/mes-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -0
- package/bin/mes.js +263 -0
- package/package.json +40 -0
- package/src/commands/init.js +77 -0
- package/src/commands/material.js +483 -0
- package/src/commands/progress.js +172 -0
- package/src/commands/reports.js +334 -0
- package/src/commands/weighing.js +490 -0
- package/src/commands/work-order.js +508 -0
- package/src/config.js +90 -0
- package/src/db.js +92 -0
- package/src/display.js +78 -0
- package/src/encoding.js +57 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 报告相关命令(场景 24–25)
|
|
3
|
+
*
|
|
4
|
+
* 24. weighing-report (wr) — 称量报告(表头 + 明细)
|
|
5
|
+
* 25. bulk-report (br) — 半成品报告(表头 + 明细)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { queryWithParams, close, sql } = require('../db');
|
|
11
|
+
const { resolveConfig } = require('../config');
|
|
12
|
+
const { printTable, printDetail } = require('../display');
|
|
13
|
+
const chalk = require('chalk');
|
|
14
|
+
|
|
15
|
+
// ─── 场景 24:称量报告 ─────────────────────────────────────────────────────────
|
|
16
|
+
const WEIGHING_REPORT_HEADER_SQL = `
|
|
17
|
+
;WITH bulk_work_order AS (
|
|
18
|
+
SELECT TOP (1)
|
|
19
|
+
order_num, product_code, product_name, product_file_version,
|
|
20
|
+
quantity, product_units, device_name, workshop_name, production_note
|
|
21
|
+
FROM psm_work_order
|
|
22
|
+
WHERE order_num = @order_num AND tr_type = 2 AND ISNULL(is_deleted, 0) = 0
|
|
23
|
+
ORDER BY id DESC
|
|
24
|
+
),
|
|
25
|
+
weight_work_order AS (
|
|
26
|
+
SELECT TOP (1) id, order_num
|
|
27
|
+
FROM psm_work_order
|
|
28
|
+
WHERE order_num = @order_num AND tr_type = 1 AND ISNULL(is_deleted, 0) = 0
|
|
29
|
+
ORDER BY id DESC
|
|
30
|
+
)
|
|
31
|
+
SELECT
|
|
32
|
+
ww.order_num AS task_num,
|
|
33
|
+
ww.order_num,
|
|
34
|
+
bw.product_code,
|
|
35
|
+
bw.product_name,
|
|
36
|
+
bw.product_code + N'->' + ISNULL(bw.product_file_version, N'') AS recipe_code,
|
|
37
|
+
CAST(bw.quantity AS NVARCHAR(50)) + N' ' + ISNULL(bw.product_units, N'') AS planned_quantity,
|
|
38
|
+
bw.device_name AS device_group,
|
|
39
|
+
bw.workshop_name,
|
|
40
|
+
COALESCE(
|
|
41
|
+
CONVERT(NVARCHAR(10), we.execute_end_time, 23),
|
|
42
|
+
CONVERT(NVARCHAR(10), mx.max_weighing_time, 23)
|
|
43
|
+
) AS weighing_date,
|
|
44
|
+
bw.production_note,
|
|
45
|
+
ww.order_num AS qr_content
|
|
46
|
+
FROM bulk_work_order bw
|
|
47
|
+
INNER JOIN weight_work_order ww ON 1 = 1
|
|
48
|
+
OUTER APPLY (
|
|
49
|
+
SELECT TOP (1) execute_end_time
|
|
50
|
+
FROM psm_weighing_work_order_execute
|
|
51
|
+
WHERE parent_id = ww.id AND ISNULL(is_deleted, 0) = 0
|
|
52
|
+
ORDER BY update_time DESC, id DESC
|
|
53
|
+
) we
|
|
54
|
+
OUTER APPLY (
|
|
55
|
+
SELECT MAX(e.operation_end_time) AS max_weighing_time
|
|
56
|
+
FROM psm_weighing w
|
|
57
|
+
INNER JOIN psm_weighing_execute e ON e.parent_id = w.id
|
|
58
|
+
WHERE w.parent_id = ww.id AND ISNULL(w.is_deleted, 0) = 0
|
|
59
|
+
) mx;
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
const WEIGHING_REPORT_DETAIL_SQL = `
|
|
63
|
+
;WITH weight_work_order AS (
|
|
64
|
+
SELECT TOP (1) id, order_num
|
|
65
|
+
FROM psm_work_order
|
|
66
|
+
WHERE order_num = @order_num AND tr_type = 1 AND ISNULL(is_deleted, 0) = 0
|
|
67
|
+
ORDER BY id DESC
|
|
68
|
+
),
|
|
69
|
+
weighing_task AS (
|
|
70
|
+
SELECT w.id, w.number, w.material_code, w.feeding_phase, w.quantity AS required_quantity
|
|
71
|
+
FROM weight_work_order ww
|
|
72
|
+
INNER JOIN psm_weighing w ON w.parent_id = ww.id AND ISNULL(w.is_deleted, 0) = 0 AND ISNULL(w.is_unweight, 0) = 0
|
|
73
|
+
),
|
|
74
|
+
execute_base AS (
|
|
75
|
+
SELECT e.parent_id, e.id, e.actual_quantity, e.material_batch,
|
|
76
|
+
e.operation_end_time, e.device_name, e.operator
|
|
77
|
+
FROM psm_weighing_execute e
|
|
78
|
+
INNER JOIN weighing_task wt ON wt.id = e.parent_id
|
|
79
|
+
),
|
|
80
|
+
execute_agg AS (
|
|
81
|
+
SELECT
|
|
82
|
+
parent_id,
|
|
83
|
+
SUM(ISNULL(actual_quantity, 0)) AS actual_quantity,
|
|
84
|
+
STRING_AGG(ISNULL(material_batch, N''), CHAR(13) + CHAR(10))
|
|
85
|
+
WITHIN GROUP (ORDER BY operation_end_time, id) AS material_batch,
|
|
86
|
+
STRING_AGG(CONVERT(NVARCHAR(16), operation_end_time, 120), CHAR(13) + CHAR(10))
|
|
87
|
+
WITHIN GROUP (ORDER BY operation_end_time, id) AS weighing_time,
|
|
88
|
+
STRING_AGG(ISNULL(device_name, N''), CHAR(13) + CHAR(10))
|
|
89
|
+
WITHIN GROUP (ORDER BY operation_end_time, id) AS weighing_station,
|
|
90
|
+
STRING_AGG(ISNULL(operator, N''), CHAR(13) + CHAR(10))
|
|
91
|
+
WITHIN GROUP (ORDER BY operation_end_time, id) AS weighing_user
|
|
92
|
+
FROM execute_base
|
|
93
|
+
GROUP BY parent_id
|
|
94
|
+
)
|
|
95
|
+
SELECT
|
|
96
|
+
ROW_NUMBER() OVER (ORDER BY wt.number, wt.id) AS seq_no,
|
|
97
|
+
wt.material_code,
|
|
98
|
+
wt.feeding_phase,
|
|
99
|
+
wt.required_quantity,
|
|
100
|
+
ea.actual_quantity,
|
|
101
|
+
ea.material_batch,
|
|
102
|
+
ea.weighing_time,
|
|
103
|
+
ea.weighing_station,
|
|
104
|
+
ea.weighing_user
|
|
105
|
+
FROM weighing_task wt
|
|
106
|
+
LEFT JOIN execute_agg ea ON ea.parent_id = wt.id
|
|
107
|
+
ORDER BY seq_no;
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
async function weighingReportCommand(orderNum, options, command) {
|
|
111
|
+
let dbConfig;
|
|
112
|
+
try { dbConfig = resolveConfig(command.parent.opts()); }
|
|
113
|
+
catch (err) { console.error(chalk.red('✖ 连接配置错误:'), err.message); process.exitCode = 1; return; }
|
|
114
|
+
|
|
115
|
+
const params = [{ name: 'order_num', type: sql.NVarChar(100), value: orderNum }];
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
console.log(chalk.dim(`⏳ 正在生成称量报告: ${orderNum} …`));
|
|
119
|
+
const [headerRows, detailRows] = await Promise.all([
|
|
120
|
+
queryWithParams(WEIGHING_REPORT_HEADER_SQL, params, dbConfig),
|
|
121
|
+
queryWithParams(WEIGHING_REPORT_DETAIL_SQL, params, dbConfig),
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
if (!headerRows || headerRows.length === 0) {
|
|
125
|
+
console.log(chalk.yellow(`⚠ 未找到工单号 ${orderNum}`));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
printDetail(headerRows[0], `称量报告表头 — ${orderNum}`);
|
|
129
|
+
printTable(detailRows, `称量报告明细 — ${orderNum}`);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
console.error(chalk.red('✖ 查询失败:'), err.message);
|
|
132
|
+
process.exitCode = 1;
|
|
133
|
+
} finally { await close(); }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ─── 场景 25:半成品报告 ───────────────────────────────────────────────────────
|
|
137
|
+
const BULK_REPORT_HEADER_SQL = `
|
|
138
|
+
;WITH bulk_work_order AS (
|
|
139
|
+
SELECT TOP (1)
|
|
140
|
+
id, order_num, batch_num, product_code, product_name, product_file_version,
|
|
141
|
+
quantity, product_units, workshop_name, line_name, device_name, plan_start_time
|
|
142
|
+
FROM psm_work_order
|
|
143
|
+
WHERE order_num = @order_num AND tr_type = 2 AND ISNULL(is_deleted, 0) = 0
|
|
144
|
+
ORDER BY id DESC
|
|
145
|
+
)
|
|
146
|
+
SELECT
|
|
147
|
+
bwo.order_num,
|
|
148
|
+
bwo.batch_num,
|
|
149
|
+
bwo.product_code,
|
|
150
|
+
bwo.product_name,
|
|
151
|
+
CONVERT(NVARCHAR(50), CAST(bwo.quantity AS FLOAT)) + N' ' + ISNULL(bwo.product_units, N'') AS planned_quantity,
|
|
152
|
+
bwo.workshop_name,
|
|
153
|
+
bwo.line_name,
|
|
154
|
+
bwo.device_name,
|
|
155
|
+
CONVERT(NVARCHAR(10), bwo.plan_start_time, 120) AS plan_start_time,
|
|
156
|
+
CONVERT(NVARCHAR(19), be.execute_start_time, 120) AS execute_start_time,
|
|
157
|
+
CONVERT(NVARCHAR(19), be.execute_end_time, 120) AS execute_end_time,
|
|
158
|
+
CASE
|
|
159
|
+
WHEN be.execute_state IS NULL THEN N'未生成生产执行记录'
|
|
160
|
+
WHEN be.execute_state = 0 THEN N'待生产' WHEN be.execute_state = 1 THEN N'生产中'
|
|
161
|
+
WHEN be.execute_state = 2 THEN N'已暂停' WHEN be.execute_state = 4 THEN N'投料完成'
|
|
162
|
+
WHEN be.execute_state = 8 THEN N'出锅中' WHEN be.execute_state = 16 THEN N'已出锅'
|
|
163
|
+
ELSE N'未知状态'
|
|
164
|
+
END AS production_status,
|
|
165
|
+
CASE
|
|
166
|
+
WHEN be.quality_state IS NULL THEN N'未生成生产执行记录'
|
|
167
|
+
WHEN be.quality_state = 0 THEN N'待质检' WHEN be.quality_state = 1 THEN N'已发起质检'
|
|
168
|
+
WHEN be.quality_state = 2 THEN N'部分合格' WHEN be.quality_state = 4 THEN N'不合格'
|
|
169
|
+
WHEN be.quality_state = 8 THEN N'合格' WHEN be.quality_state = 16 THEN N'在线返工'
|
|
170
|
+
WHEN be.quality_state = 32 THEN N'出锅返工' WHEN be.quality_state = 64 THEN N'再次请检'
|
|
171
|
+
WHEN be.quality_state = 128 THEN N'无法识别'
|
|
172
|
+
ELSE N'未知状态'
|
|
173
|
+
END AS quality_status
|
|
174
|
+
FROM bulk_work_order bwo
|
|
175
|
+
LEFT JOIN psm_bulk_execute_work_order be
|
|
176
|
+
ON be.work_order_id = bwo.id AND ISNULL(be.is_deleted, 0) = 0;
|
|
177
|
+
`;
|
|
178
|
+
|
|
179
|
+
const BULK_REPORT_DETAIL_SQL = `
|
|
180
|
+
;WITH bulk_work_order AS (
|
|
181
|
+
SELECT TOP (1) id
|
|
182
|
+
FROM psm_work_order
|
|
183
|
+
WHERE order_num = @order_num AND tr_type = 2 AND ISNULL(is_deleted, 0) = 0
|
|
184
|
+
ORDER BY id DESC
|
|
185
|
+
),
|
|
186
|
+
premix_barcode_base AS (
|
|
187
|
+
SELECT NULL AS pot_sort_num, CAST(p.unit_number AS NVARCHAR(100)) AS pot_sort_text,
|
|
188
|
+
p.name AS pot_name, s.step_number, s.step_desc, b.id AS barcode_id, b.number AS item_sort,
|
|
189
|
+
N'手投料' AS function_name,
|
|
190
|
+
N'项号:' + ISNULL(b.feeding_phase, N'') + CHAR(13)+CHAR(10)
|
|
191
|
+
+ N'编码:' + ISNULL(b.code, N'') + CHAR(13)+CHAR(10)
|
|
192
|
+
+ N'设定数量:' + q2.qty_text AS setting_value
|
|
193
|
+
FROM psm_bulk_trcp_logic_premix_barcode b
|
|
194
|
+
CROSS APPLY (SELECT LTRIM(STR(CONVERT(DECIMAL(38,10), ISNULL(b.quantity,0)),38,10)) AS qty_raw) q0
|
|
195
|
+
CROSS APPLY (SELECT LEFT(q0.qty_raw, LEN(q0.qty_raw)-PATINDEX('%[^0]%',REVERSE(q0.qty_raw))+1) AS qty_trim) q1
|
|
196
|
+
CROSS APPLY (SELECT CASE WHEN RIGHT(q1.qty_trim,1)='.' THEN LEFT(q1.qty_trim,LEN(q1.qty_trim)-1) ELSE q1.qty_trim END AS qty_text) q2
|
|
197
|
+
INNER JOIN psm_bulk_trcp_logic_premix_stepgen s ON b.parent_id = s.id AND ISNULL(s.is_delete,0)=0
|
|
198
|
+
INNER JOIN psm_bulk_trcp_logic_premix p ON s.parent_id = p.id AND ISNULL(p.is_delete,0)=0
|
|
199
|
+
WHERE b.work_order_id = (SELECT id FROM bulk_work_order) AND ISNULL(b.is_delete,0)=0
|
|
200
|
+
),
|
|
201
|
+
premix_barcode_exec_numbered AS (
|
|
202
|
+
SELECT e.put_id, ROW_NUMBER() OVER (PARTITION BY e.put_id ORDER BY e.create_time, e.id) AS pkg_no,
|
|
203
|
+
q2.qty_text, e.batch_number, e.create_time
|
|
204
|
+
FROM psm_bulk_trcp_logic_premix_barcode_execute e
|
|
205
|
+
CROSS APPLY (SELECT LTRIM(STR(CONVERT(DECIMAL(38,10),ISNULL(e.quantity,0)),38,10)) AS qty_raw) q0
|
|
206
|
+
CROSS APPLY (SELECT LEFT(q0.qty_raw,LEN(q0.qty_raw)-PATINDEX('%[^0]%',REVERSE(q0.qty_raw))+1) AS qty_trim) q1
|
|
207
|
+
CROSS APPLY (SELECT CASE WHEN RIGHT(q1.qty_trim,1)='.' THEN LEFT(q1.qty_trim,LEN(q1.qty_trim)-1) ELSE q1.qty_trim END AS qty_text) q2
|
|
208
|
+
WHERE e.work_order_id = (SELECT id FROM bulk_work_order)
|
|
209
|
+
),
|
|
210
|
+
premix_barcode_exec_agg AS (
|
|
211
|
+
SELECT put_id,
|
|
212
|
+
STRING_AGG(N'【第'+CAST(pkg_no AS NVARCHAR(20))+N'包】数量:'+qty_text+N' 批次:'+ISNULL(batch_number,N''), CHAR(13)+CHAR(10)) WITHIN GROUP (ORDER BY pkg_no) AS report_value,
|
|
213
|
+
STRING_AGG(N'【第'+CAST(pkg_no AS NVARCHAR(20))+N'包】'+CONVERT(NVARCHAR(19),create_time,120), CHAR(13)+CHAR(10)) WITHIN GROUP (ORDER BY pkg_no) AS action_time
|
|
214
|
+
FROM premix_barcode_exec_numbered GROUP BY put_id
|
|
215
|
+
),
|
|
216
|
+
premix_feedback_base AS (
|
|
217
|
+
SELECT NULL AS pot_sort_num, CAST(p.unit_number AS NVARCHAR(100)) AS pot_sort_text,
|
|
218
|
+
p.name AS pot_name, s.step_number, s.step_desc, f.id AS feedback_id, f.iNumber AS item_sort,
|
|
219
|
+
N'反馈' AS function_name, ISNULL(f.cName, N'') AS setting_value
|
|
220
|
+
FROM psm_bulk_trcp_logic_premix_feedback f
|
|
221
|
+
INNER JOIN psm_bulk_trcp_logic_premix_stepgen s ON f.FID = s.id AND ISNULL(s.is_delete,0)=0
|
|
222
|
+
INNER JOIN psm_bulk_trcp_logic_premix p ON s.parent_id = p.id AND ISNULL(p.is_delete,0)=0
|
|
223
|
+
WHERE f.iOrdID = (SELECT id FROM bulk_work_order)
|
|
224
|
+
),
|
|
225
|
+
step_phase_base AS (
|
|
226
|
+
SELECT sg.unit_number AS pot_sort_num, CAST(sg.unit_number AS NVARCHAR(100)) AS pot_sort_text,
|
|
227
|
+
sg.unit_name AS pot_name, sg.step_number, sg.step_description AS step_desc,
|
|
228
|
+
sp.id AS phase_id, sp.phase_number AS item_sort,
|
|
229
|
+
ISNULL(sp.function_name,N'') AS function_name, ISNULL(sp.aboutvis,N'') AS setting_value,
|
|
230
|
+
ISNULL(sp.execute_text,N'') AS report_value
|
|
231
|
+
FROM psm_bulk_trcp_logic_step_phase sp
|
|
232
|
+
INNER JOIN psm_bulk_trcp_logic_stepgen sg
|
|
233
|
+
ON sg.work_order_id=sp.work_order_id AND sg.techrcp_id=sp.techrcp_id
|
|
234
|
+
AND sg.unit_number=sp.unit_number AND sg.step_number=sp.step_number AND ISNULL(sg.is_delete,0)=0
|
|
235
|
+
WHERE sp.work_order_id = (SELECT id FROM bulk_work_order)
|
|
236
|
+
AND ISNULL(sp.is_delete,0)=0 AND NOT (sp.ep_type=999901 AND sp.rpar00=5)
|
|
237
|
+
),
|
|
238
|
+
step_phase_first_exec AS (
|
|
239
|
+
SELECT x.parent_id, x.start_time FROM (
|
|
240
|
+
SELECT e.parent_id, e.start_time,
|
|
241
|
+
ROW_NUMBER() OVER (PARTITION BY e.parent_id ORDER BY e.start_time, e.id) AS rn
|
|
242
|
+
FROM psm_bulk_trcp_logic_step_phase_execute e
|
|
243
|
+
WHERE e.work_order_id = (SELECT id FROM bulk_work_order)
|
|
244
|
+
) x WHERE x.rn = 1
|
|
245
|
+
),
|
|
246
|
+
step_barcode_base AS (
|
|
247
|
+
SELECT sg.unit_number AS pot_sort_num, CAST(sg.unit_number AS NVARCHAR(100)) AS pot_sort_text,
|
|
248
|
+
sg.unit_name AS pot_name, sg.step_number, sg.step_description AS step_desc,
|
|
249
|
+
b.id AS barcode_id, b.number AS item_sort, N'手投料' AS function_name,
|
|
250
|
+
N'项号:' + ISNULL(b.feeding_phase,N'') + CHAR(13)+CHAR(10)
|
|
251
|
+
+ N'编码:' + ISNULL(b.code,N'') + CHAR(13)+CHAR(10)
|
|
252
|
+
+ N'设定数量:' + q2.qty_text AS setting_value
|
|
253
|
+
FROM psm_bulk_trcp_logic_step_barcode b
|
|
254
|
+
CROSS APPLY (SELECT LTRIM(STR(CONVERT(DECIMAL(38,10),ISNULL(b.quantity,0)),38,10)) AS qty_raw) q0
|
|
255
|
+
CROSS APPLY (SELECT LEFT(q0.qty_raw,LEN(q0.qty_raw)-PATINDEX('%[^0]%',REVERSE(q0.qty_raw))+1) AS qty_trim) q1
|
|
256
|
+
CROSS APPLY (SELECT CASE WHEN RIGHT(q1.qty_trim,1)='.' THEN LEFT(q1.qty_trim,LEN(q1.qty_trim)-1) ELSE q1.qty_trim END AS qty_text) q2
|
|
257
|
+
INNER JOIN psm_bulk_trcp_logic_stepgen sg
|
|
258
|
+
ON sg.work_order_id=b.work_order_id AND sg.techrcp_id=b.techrcp_id
|
|
259
|
+
AND sg.unit_number=b.unit_number AND sg.step_number=b.step_number AND ISNULL(sg.is_delete,0)=0
|
|
260
|
+
WHERE b.work_order_id = (SELECT id FROM bulk_work_order) AND ISNULL(b.is_delete,0)=0
|
|
261
|
+
),
|
|
262
|
+
step_barcode_exec_numbered AS (
|
|
263
|
+
SELECT r.tr_set_barcode_id,
|
|
264
|
+
ROW_NUMBER() OVER (PARTITION BY r.tr_set_barcode_id ORDER BY r.create_time, r.id) AS pkg_no,
|
|
265
|
+
q2.qty_text, r.barcode_material_batch, r.create_time
|
|
266
|
+
FROM psm_bulk_trcplc_report_put_material_item r
|
|
267
|
+
CROSS APPLY (SELECT LTRIM(STR(CONVERT(DECIMAL(38,10),ISNULL(r.barcode_material_quantity,0)),38,10)) AS qty_raw) q0
|
|
268
|
+
CROSS APPLY (SELECT LEFT(q0.qty_raw,LEN(q0.qty_raw)-PATINDEX('%[^0]%',REVERSE(q0.qty_raw))+1) AS qty_trim) q1
|
|
269
|
+
CROSS APPLY (SELECT CASE WHEN RIGHT(q1.qty_trim,1)='.' THEN LEFT(q1.qty_trim,LEN(q1.qty_trim)-1) ELSE q1.qty_trim END AS qty_text) q2
|
|
270
|
+
WHERE r.work_order_id = (SELECT id FROM bulk_work_order)
|
|
271
|
+
),
|
|
272
|
+
step_barcode_exec_agg AS (
|
|
273
|
+
SELECT tr_set_barcode_id,
|
|
274
|
+
STRING_AGG(N'【第'+CAST(pkg_no AS NVARCHAR(20))+N'包】数量:'+qty_text+N' 批次:'+ISNULL(barcode_material_batch,N''), CHAR(13)+CHAR(10)) WITHIN GROUP (ORDER BY pkg_no) AS report_value,
|
|
275
|
+
STRING_AGG(N'【第'+CAST(pkg_no AS NVARCHAR(20))+N'包】'+CONVERT(NVARCHAR(19),create_time,120), CHAR(13)+CHAR(10)) WITHIN GROUP (ORDER BY pkg_no) AS action_time
|
|
276
|
+
FROM step_barcode_exec_numbered GROUP BY tr_set_barcode_id
|
|
277
|
+
),
|
|
278
|
+
final_report AS (
|
|
279
|
+
SELECT 1 AS section_sort, pb.pot_sort_num, pb.pot_sort_text, pb.step_number, 1 AS type_sort, pb.item_sort,
|
|
280
|
+
pb.pot_name, N'第'+CAST(pb.step_number AS NVARCHAR(20))+N'步' AS step_name, pb.step_desc,
|
|
281
|
+
pb.function_name, pb.setting_value, ISNULL(pa.report_value,N'') AS report_value, ISNULL(pa.action_time,N'') AS action_time
|
|
282
|
+
FROM premix_barcode_base pb LEFT JOIN premix_barcode_exec_agg pa ON pa.put_id = pb.barcode_id
|
|
283
|
+
UNION ALL
|
|
284
|
+
SELECT 1, pf.pot_sort_num, pf.pot_sort_text, pf.step_number, 2, pf.item_sort,
|
|
285
|
+
pf.pot_name, N'第'+CAST(pf.step_number AS NVARCHAR(20))+N'步', pf.step_desc,
|
|
286
|
+
pf.function_name, pf.setting_value, ISNULL(fe.value,N''), CONVERT(NVARCHAR(19), fe.create_time, 120)
|
|
287
|
+
FROM premix_feedback_base pf
|
|
288
|
+
LEFT JOIN psm_bulk_trcp_logic_premix_feedback_execute fe
|
|
289
|
+
ON fe.parent_id = pf.feedback_id AND fe.work_order_id = (SELECT id FROM bulk_work_order)
|
|
290
|
+
UNION ALL
|
|
291
|
+
SELECT 2, sp.pot_sort_num, sp.pot_sort_text, sp.step_number, 1, sp.item_sort,
|
|
292
|
+
sp.pot_name, N'第'+CAST(sp.step_number AS NVARCHAR(20))+N'步', sp.step_desc,
|
|
293
|
+
sp.function_name, sp.setting_value, sp.report_value, CONVERT(NVARCHAR(19), se.start_time, 120)
|
|
294
|
+
FROM step_phase_base sp LEFT JOIN step_phase_first_exec se ON se.parent_id = sp.phase_id
|
|
295
|
+
UNION ALL
|
|
296
|
+
SELECT 2, sb.pot_sort_num, sb.pot_sort_text, sb.step_number, 2, sb.item_sort,
|
|
297
|
+
sb.pot_name, N'第'+CAST(sb.step_number AS NVARCHAR(20))+N'步', sb.step_desc,
|
|
298
|
+
sb.function_name, sb.setting_value, ISNULL(sa.report_value,N''), ISNULL(sa.action_time,N'')
|
|
299
|
+
FROM step_barcode_base sb LEFT JOIN step_barcode_exec_agg sa ON sa.tr_set_barcode_id = sb.barcode_id
|
|
300
|
+
)
|
|
301
|
+
SELECT pot_name, step_name, step_desc, function_name, setting_value, report_value, action_time
|
|
302
|
+
FROM final_report
|
|
303
|
+
ORDER BY section_sort,
|
|
304
|
+
CASE WHEN pot_sort_num IS NULL THEN 1 ELSE 2 END,
|
|
305
|
+
pot_sort_num, pot_sort_text, step_number, type_sort, item_sort;
|
|
306
|
+
`;
|
|
307
|
+
|
|
308
|
+
async function bulkReportCommand(orderNum, options, command) {
|
|
309
|
+
let dbConfig;
|
|
310
|
+
try { dbConfig = resolveConfig(command.parent.opts()); }
|
|
311
|
+
catch (err) { console.error(chalk.red('✖ 连接配置错误:'), err.message); process.exitCode = 1; return; }
|
|
312
|
+
|
|
313
|
+
const params = [{ name: 'order_num', type: sql.NVarChar(100), value: orderNum }];
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
console.log(chalk.dim(`⏳ 正在生成半成品报告: ${orderNum} …`));
|
|
317
|
+
const [headerRows, detailRows] = await Promise.all([
|
|
318
|
+
queryWithParams(BULK_REPORT_HEADER_SQL, params, dbConfig),
|
|
319
|
+
queryWithParams(BULK_REPORT_DETAIL_SQL, params, dbConfig),
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
if (!headerRows || headerRows.length === 0) {
|
|
323
|
+
console.log(chalk.yellow(`⚠ 未找到工单号 ${orderNum}`));
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
printDetail(headerRows[0], `半成品报告表头 — ${orderNum}`);
|
|
327
|
+
printTable(detailRows, `半成品报告明细 — ${orderNum}`);
|
|
328
|
+
} catch (err) {
|
|
329
|
+
console.error(chalk.red('✖ 查询失败:'), err.message);
|
|
330
|
+
process.exitCode = 1;
|
|
331
|
+
} finally { await close(); }
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
module.exports = { weighingReportCommand, bulkReportCommand };
|