@dalehkx/quote-cli 0.3.0 → 0.3.3
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/bin/quote.js +13 -1
- package/package.json +1 -1
- package/src/commands/inquiry.mjs +41 -31
package/bin/quote.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
import { registerInquiryCommands } from '../src/commands/inquiry.mjs';
|
|
5
6
|
import { registerReplyCommands } from '../src/commands/reply.mjs';
|
|
@@ -8,12 +9,23 @@ import { registerOrderCommands } from '../src/commands/order.mjs';
|
|
|
8
9
|
import { registerConfigCommands } from '../src/commands/config.mjs';
|
|
9
10
|
import { registerLoginCommands } from '../src/commands/login.mjs';
|
|
10
11
|
|
|
12
|
+
const { version } = createRequire(import.meta.url)('../package.json');
|
|
13
|
+
|
|
11
14
|
const program = new Command();
|
|
12
15
|
|
|
13
16
|
program
|
|
14
17
|
.name('quote')
|
|
15
18
|
.description('通用询报价 CLI 工具')
|
|
16
|
-
.version(
|
|
19
|
+
.version(version);
|
|
20
|
+
|
|
21
|
+
registerInquiryCommands(program);
|
|
22
|
+
registerReplyCommands(program);
|
|
23
|
+
registerCompareCommand(program);
|
|
24
|
+
registerOrderCommands(program);
|
|
25
|
+
registerConfigCommands(program);
|
|
26
|
+
registerLoginCommands(program);
|
|
27
|
+
|
|
28
|
+
program.parse();
|
|
17
29
|
|
|
18
30
|
registerInquiryCommands(program);
|
|
19
31
|
registerReplyCommands(program);
|
package/package.json
CHANGED
package/src/commands/inquiry.mjs
CHANGED
|
@@ -138,26 +138,36 @@ export function registerInquiryCommands(program) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// 阶段一:记录上一次的状态和报价数,用于判断是否需要进入阶段二
|
|
141
|
-
|
|
142
|
-
let
|
|
141
|
+
// isFirstCheck=true 时只建立基准,不输出报价
|
|
142
|
+
let lastRawStatusId = '';
|
|
143
|
+
let lastQuoteCount = -1; // -1 表示尚未初始化
|
|
143
144
|
|
|
144
145
|
/**
|
|
145
146
|
* 阶段二:调 detailV2 拉完整报价,输出给用户
|
|
146
147
|
* 返回本次报价数量
|
|
148
|
+
*
|
|
149
|
+
* 状态接口和报价数据存在短暂不一致,最多重试 5 次(间隔 3s)
|
|
147
150
|
*/
|
|
148
|
-
const fetchAndReport = async () => {
|
|
149
|
-
const record
|
|
150
|
-
|
|
151
|
+
const fetchAndReport = async (silent = false) => {
|
|
152
|
+
const record = await adapter.getInquiry(id);
|
|
153
|
+
let replies = [];
|
|
154
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
155
|
+
replies = await adapter.listReplies(id);
|
|
156
|
+
if (replies.length > 0 || silent) break;
|
|
157
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
158
|
+
}
|
|
151
159
|
const count = replies.length;
|
|
152
160
|
const time = new Date().toLocaleTimeString();
|
|
153
161
|
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
if (!silent) {
|
|
163
|
+
if (opts.json) {
|
|
164
|
+
console.log(JSON.stringify({ inquiryId: id, status: record.status, quotes: replies }));
|
|
165
|
+
} else {
|
|
166
|
+
console.log(`\n[${time}] 🔔 新报价!共 ${count} 条`);
|
|
167
|
+
replies.slice(Math.max(0, lastQuoteCount)).forEach(r => {
|
|
168
|
+
console.log(` ${r.supplier} | ¥${r.price} | ${r.brand || '-'} | ${r.delivery ? r.delivery + '天' : '货期未知'}`);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
161
171
|
}
|
|
162
172
|
return count;
|
|
163
173
|
};
|
|
@@ -169,38 +179,38 @@ export function registerInquiryCommands(program) {
|
|
|
169
179
|
try {
|
|
170
180
|
// 超时退出
|
|
171
181
|
if (timeout > 0 && Date.now() - startTime >= timeout) {
|
|
172
|
-
if (!opts.json) console.log(`\n等待超时,共 ${lastQuoteCount} 条报价`);
|
|
173
|
-
else console.log(JSON.stringify({ inquiryId: id, timedOut: true, quoteCount: lastQuoteCount }));
|
|
182
|
+
if (!opts.json) console.log(`\n等待超时,共 ${Math.max(0, lastQuoteCount)} 条报价`);
|
|
183
|
+
else console.log(JSON.stringify({ inquiryId: id, timedOut: true, quoteCount: Math.max(0, lastQuoteCount) }));
|
|
174
184
|
process.exit(0);
|
|
175
185
|
}
|
|
176
186
|
|
|
177
187
|
const poll = await adapter.pollInquiryStatus(id);
|
|
178
188
|
if (!poll) return;
|
|
179
189
|
|
|
180
|
-
const time
|
|
190
|
+
const time = new Date().toLocaleTimeString();
|
|
191
|
+
const isFirstCheck = lastQuoteCount === -1;
|
|
181
192
|
const statusChanged = poll.rawStatusId !== lastRawStatusId;
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
(statusChanged && poll.status !== 'pending') || // 状态跳变到有报价
|
|
187
|
-
poll.status === 'quoted'; // 持续处于报价状态,可能新增
|
|
188
|
-
|
|
189
|
-
if (shouldFetchDetail) {
|
|
190
|
-
const count = await fetchAndReport();
|
|
191
|
-
|
|
192
|
-
if (count > lastQuoteCount && !opts.json) {
|
|
193
|
-
// 已在 fetchAndReport 里打印了新报价,这里只更新计数
|
|
194
|
-
}
|
|
195
|
-
|
|
194
|
+
if (isFirstCheck) {
|
|
195
|
+
// 首次:静默拉一次,建立基准值
|
|
196
|
+
const count = await fetchAndReport(true);
|
|
196
197
|
lastQuoteCount = count;
|
|
197
198
|
lastRawStatusId = poll.rawStatusId;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
if (!opts.json) {
|
|
200
|
+
if (count > 0) {
|
|
201
|
+
console.log(`[${time}] 初始状态: ${poll.rawStatusId},已有 ${count} 条报价,继续监听新报价...`);
|
|
202
|
+
} else {
|
|
203
|
+
console.log(`[${time}] 初始状态: ${poll.rawStatusId},等待报价中...`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
} else if ((statusChanged && poll.status !== 'pending') || poll.status === 'quoted') {
|
|
207
|
+
// 状态跳变到有报价,或持续处于已报价状态(可能新增供应商)
|
|
208
|
+
const count = await fetchAndReport(false);
|
|
209
|
+
if (count > 0) {
|
|
201
210
|
if (!opts.json) console.log(`\n已收到 ${count} 条报价,退出监听`);
|
|
202
211
|
process.exit(0);
|
|
203
212
|
}
|
|
213
|
+
// 重试后仍为 0,继续轮询等数据同步
|
|
204
214
|
} else {
|
|
205
215
|
if (statusChanged) {
|
|
206
216
|
if (!opts.json) console.log(`\n[${time}] 状态变更: ${lastRawStatusId || '-'} → ${poll.rawStatusId}`);
|