|
|
@@ -13,6 +13,7 @@ use app\common\repositories\store\product\ProductRepository;
|
|
13
|
13
|
use app\common\repositories\user\UserThirdRepository;
|
|
14
|
14
|
use app\model\common\TbOrderModel;
|
|
15
|
15
|
use app\model\common\UserThirdModel;
|
|
|
16
|
+use app\utils\TimeUtil;
|
|
16
|
17
|
use http\Exception;
|
|
17
|
18
|
use think\facade\Db;
|
|
18
|
19
|
use think\facade\Log;
|
|
|
@@ -217,47 +218,231 @@ class DaTaoKe
|
|
217
|
218
|
//订单查询接口(20分钟一个时间段)
|
|
218
|
219
|
public function getOrder()
|
|
219
|
220
|
{
|
|
|
221
|
+ // // 立即返回响应,断开客户端连接
|
|
|
222
|
+ // header('Content-Length: 0');
|
|
|
223
|
+ // header('Connection: close');
|
|
|
224
|
+ // ob_end_clean();
|
|
|
225
|
+ // ob_start();
|
|
|
226
|
+ // echo 'Request accepted'; // 可选的初始响应
|
|
|
227
|
+ //
|
|
|
228
|
+ // // 获取内容长度并发送头部
|
|
|
229
|
+ // header('Content-Length: ' . ob_get_length());
|
|
|
230
|
+ // ob_end_flush();
|
|
|
231
|
+ // flush();
|
|
|
232
|
+ //
|
|
|
233
|
+ // // 如果是FastCGI,还需要额外的刷新
|
|
|
234
|
+ // if (function_exists('fastcgi_finish_request')) {
|
|
|
235
|
+ // fastcgi_finish_request();
|
|
|
236
|
+ // }
|
|
|
237
|
+
|
|
|
238
|
+ // 从这里开始,客户端已经断开,脚本可以长时间运行
|
|
|
239
|
+ ignore_user_abort(true); // 忽略用户中断
|
|
|
240
|
+ set_time_limit(0); // 取消时间限制
|
|
|
241
|
+
|
|
220
|
242
|
try {
|
|
221
|
|
- $startTime = date("Y-m-d H:i:00", strtotime("-50 minutes"));
|
|
222
|
|
- $endTime = date("Y-m-d H:i:00");
|
|
223
|
243
|
$url = 'https://openapi.dataoke.com/api/tb-service/get-order-details';
|
|
224
|
|
- $queryTypes = [1, 2, 3];//1:按照订单淘客创建时间查询,2:按照订单淘客付款时间查询,3:按照订单淘客结算时间查询
|
|
225
|
244
|
$orders = [];
|
|
226
|
|
- foreach ($queryTypes as $queryType) {
|
|
227
|
|
- $queryData = [
|
|
228
|
|
- 'appKey' => self::$appKey,
|
|
229
|
|
- 'version' => 'v1.0.0',
|
|
230
|
|
- 'queryType' => $queryType,
|
|
231
|
|
- 'pageSize' => 100,
|
|
232
|
|
- 'startTime' => $startTime,
|
|
233
|
|
- 'endTime' => $endTime,
|
|
234
|
|
- //1:常规订单,2:渠道订单,3:会员运营订单 默认为1
|
|
235
|
|
- 'orderScene' => 2,
|
|
236
|
|
- 'tkStatus' => 3
|
|
237
|
|
- ];
|
|
238
|
|
- $queryData['sign'] = self::makeSign($queryData, self::$appSecret);
|
|
239
|
|
- $fullUrl = "{$url}?" . http_build_query($queryData);
|
|
240
|
|
- $response = self::sendCurl($fullUrl);
|
|
241
|
|
- $isError = $response['data']['error_response'] ?? '';
|
|
242
|
|
- if ($isError) {//查询订单出错
|
|
243
|
|
- return app('json')->fail("拉取淘宝客订单出错", $response);
|
|
244
|
|
- }
|
|
245
|
|
- $responseOrders = $response['data']['results']['publisher_order_dto'] ?? [];
|
|
246
|
|
- if ($responseOrders) {
|
|
247
|
|
- $orders = array_merge($orders, $responseOrders);
|
|
248
|
|
- }
|
|
249
|
|
- }
|
|
|
245
|
+
|
|
|
246
|
+ // 场景1:实时同步最近20分钟内有更新的订单
|
|
|
247
|
+ // $recentOrders = $this->queryRecentOrders($url);
|
|
|
248
|
+ // $orders = array_merge($orders, $recentOrders);
|
|
|
249
|
+
|
|
|
250
|
+ // 场景2:分批次查询历史订单(避免时间范围过大)
|
|
|
251
|
+ $refundOrders = $this->queryOrdersByBatch($url);
|
|
|
252
|
+ $orders = array_merge($orders, $refundOrders);
|
|
|
253
|
+
|
|
250
|
254
|
if ($orders) {
|
|
251
|
|
- //格式化拉取到的订单列表
|
|
252
|
|
- $formatLists = self::formatOrderList($orders);
|
|
253
|
|
- //创建/更新淘宝订单
|
|
|
255
|
+ // 去重处理
|
|
|
256
|
+ $uniqueOrders = $this->removeDuplicateOrders($orders);
|
|
|
257
|
+
|
|
|
258
|
+ // 格式化拉取到的订单列表
|
|
|
259
|
+ $formatLists = self::formatOrderList($uniqueOrders);
|
|
|
260
|
+ // 创建/更新淘宝订单
|
|
254
|
261
|
self::operateOrder($formatLists);
|
|
|
262
|
+
|
|
|
263
|
+ Log::info("订单处理完成". json_encode([
|
|
|
264
|
+ '总订单数' => count($orders),
|
|
|
265
|
+ '去重后订单数' => count($uniqueOrders),
|
|
|
266
|
+ '处理时间' => date('Y-m-d H:i:s')
|
|
|
267
|
+ ], JSON_UNESCAPED_UNICODE));
|
|
|
268
|
+ } else {
|
|
|
269
|
+ Log::info("未获取到新订单");
|
|
255
|
270
|
}
|
|
|
271
|
+
|
|
256
|
272
|
return app('json')->success("拉取并处理淘宝客订单成功");
|
|
|
273
|
+
|
|
257
|
274
|
} catch (\Throwable $throwable) {
|
|
258
|
|
- return app('json')->fail("拉取并处理淘宝客订单出错{$throwable->getMessage()}");
|
|
|
275
|
+ Log::error("拉取订单异常". json_encode([
|
|
|
276
|
+ '错误信息' => $throwable->getMessage(),
|
|
|
277
|
+ '堆栈' => $throwable->getTraceAsString()
|
|
|
278
|
+ ], JSON_UNESCAPED_UNICODE));
|
|
|
279
|
+ return app('json')->fail("拉取并处理淘宝客订单出错: {$throwable->getMessage()}");
|
|
|
280
|
+ }
|
|
|
281
|
+
|
|
|
282
|
+ // try {
|
|
|
283
|
+ // $startTime = date("Y-m-d H:i:00", strtotime("-50 minutes"));
|
|
|
284
|
+ // $endTime = date("Y-m-d H:i:00");
|
|
|
285
|
+ // $url = 'https://openapi.dataoke.com/api/tb-service/get-order-details';
|
|
|
286
|
+ // $queryTypes = [1, 2, 3];//1:按照订单淘客创建时间查询,2:按照订单淘客付款时间查询,3:按照订单淘客结算时间查询
|
|
|
287
|
+ // $orders = [];
|
|
|
288
|
+ // foreach ($queryTypes as $queryType) {
|
|
|
289
|
+ // $queryData = [
|
|
|
290
|
+ // 'appKey' => self::$appKey,
|
|
|
291
|
+ // 'version' => 'v1.0.0',
|
|
|
292
|
+ // 'queryType' => $queryType,
|
|
|
293
|
+ // 'pageSize' => 100,
|
|
|
294
|
+ // 'startTime' => $startTime,
|
|
|
295
|
+ // 'endTime' => $endTime,
|
|
|
296
|
+ // //1:常规订单,2:渠道订单,3:会员运营订单 默认为1
|
|
|
297
|
+ // 'orderScene' => 2,
|
|
|
298
|
+ // 'tkStatus' => 3
|
|
|
299
|
+ // ];
|
|
|
300
|
+ // $queryData['sign'] = self::makeSign($queryData, self::$appSecret);
|
|
|
301
|
+ // $fullUrl = "{$url}?" . http_build_query($queryData);
|
|
|
302
|
+ // $response = self::sendCurl($fullUrl);
|
|
|
303
|
+ // $isError = $response['data']['error_response'] ?? '';
|
|
|
304
|
+ // if ($isError) {//查询订单出错
|
|
|
305
|
+ // return app('json')->fail("拉取淘宝客订单出错", $response);
|
|
|
306
|
+ // }
|
|
|
307
|
+ // $responseOrders = $response['data']['results']['publisher_order_dto'] ?? [];
|
|
|
308
|
+ // if ($responseOrders) {
|
|
|
309
|
+ // $orders = array_merge($orders, $responseOrders);
|
|
|
310
|
+ // }
|
|
|
311
|
+ // }
|
|
|
312
|
+ // if ($orders) {
|
|
|
313
|
+ // //格式化拉取到的订单列表
|
|
|
314
|
+ // $formatLists = self::formatOrderList($orders);
|
|
|
315
|
+ // //创建/更新淘宝订单
|
|
|
316
|
+ // self::operateOrder($formatLists);
|
|
|
317
|
+ // }
|
|
|
318
|
+ // return app('json')->success("拉取并处理淘宝客订单成功");
|
|
|
319
|
+ // } catch (\Throwable $throwable) {
|
|
|
320
|
+ // return app('json')->fail("拉取并处理淘宝客订单出错{$throwable->getMessage()}");
|
|
|
321
|
+ // }
|
|
|
322
|
+
|
|
|
323
|
+ }
|
|
|
324
|
+
|
|
|
325
|
+ /**
|
|
|
326
|
+ * 查询最近20分钟内有更新的订单
|
|
|
327
|
+ */
|
|
|
328
|
+ private function queryRecentOrders($url)
|
|
|
329
|
+ {
|
|
|
330
|
+ $endTime = date("Y-m-d H:i:00");
|
|
|
331
|
+ $startTime = date("Y-m-d H:i:00", strtotime("-20 minutes"));
|
|
|
332
|
+
|
|
|
333
|
+ $queryData = [
|
|
|
334
|
+ 'appKey' => self::$appKey,
|
|
|
335
|
+ 'version' => 'v1.0.0',
|
|
|
336
|
+ 'queryType' => 4, // 按照订单更新时间查询
|
|
|
337
|
+ 'pageSize' => 100,
|
|
|
338
|
+ 'startTime' => $startTime,
|
|
|
339
|
+ 'endTime' => $endTime,
|
|
|
340
|
+ 'orderScene' => 2,
|
|
|
341
|
+ ];
|
|
|
342
|
+
|
|
|
343
|
+ $queryData['sign'] = self::makeSign($queryData, self::$appSecret);
|
|
|
344
|
+ $fullUrl = "{$url}?" . http_build_query($queryData);
|
|
|
345
|
+
|
|
|
346
|
+ Log::info("查询最近订单". json_encode(['时间范围' => "{$startTime} 至 {$endTime}"], JSON_UNESCAPED_UNICODE));
|
|
|
347
|
+
|
|
|
348
|
+ $response = self::sendCurl($fullUrl);
|
|
|
349
|
+ $isError = $response['data']['error_response'] ?? '';
|
|
|
350
|
+
|
|
|
351
|
+ if ($isError) {
|
|
|
352
|
+ Log::error("查询最近订单错误". json_encode(['错误' => $isError], JSON_UNESCAPED_UNICODE));
|
|
|
353
|
+ return [];
|
|
|
354
|
+ }
|
|
|
355
|
+
|
|
|
356
|
+ return $response['data']['results']['publisher_order_dto'] ?? [];
|
|
|
357
|
+ }
|
|
|
358
|
+
|
|
|
359
|
+ /**
|
|
|
360
|
+ * 分批查询退款订单
|
|
|
361
|
+ */
|
|
|
362
|
+ private function queryOrdersByBatch($url): array
|
|
|
363
|
+ {
|
|
|
364
|
+ $allRefundOrders = [];
|
|
|
365
|
+
|
|
|
366
|
+ // 定义查询的时间段 大促期间 只能查20分钟的
|
|
|
367
|
+ $batchIntervals = TimeUtil::generateTimeIntervals(
|
|
|
368
|
+ date("Y-m-d H:i:00", strtotime("-1 days")), // 开始时间:10天前
|
|
|
369
|
+ date("Y-m-d H:i:00"), // 结束时间 当前
|
|
|
370
|
+ 20
|
|
|
371
|
+ );
|
|
|
372
|
+
|
|
|
373
|
+ foreach ($batchIntervals as $interval) {
|
|
|
374
|
+ $orders = $this->queryOrdersInInterval($url, $interval['start'], $interval['end']);
|
|
|
375
|
+ $allRefundOrders = array_merge($allRefundOrders, $orders);
|
|
|
376
|
+
|
|
|
377
|
+ // 添加延迟,避免请求过于频繁
|
|
|
378
|
+ // usleep(5000); // 0.5秒延迟
|
|
|
379
|
+ }
|
|
|
380
|
+
|
|
|
381
|
+ Log::info("分批查询退款订单完成". json_encode([
|
|
|
382
|
+ '时间段数量' => count($batchIntervals),
|
|
|
383
|
+ '退款订单数' => count($allRefundOrders)
|
|
|
384
|
+ ], JSON_UNESCAPED_UNICODE));
|
|
|
385
|
+
|
|
|
386
|
+ return $allRefundOrders;
|
|
|
387
|
+ }
|
|
|
388
|
+
|
|
|
389
|
+ /**
|
|
|
390
|
+ * 在指定时间区间内查询退款订单
|
|
|
391
|
+ */
|
|
|
392
|
+ private function queryOrdersInInterval($url, $startTime, $endTime)
|
|
|
393
|
+ {
|
|
|
394
|
+ $queryData = [
|
|
|
395
|
+ 'appKey' => self::$appKey,
|
|
|
396
|
+ 'version' => 'v1.0.0',
|
|
|
397
|
+ 'queryType' => 2, // 按照 付款时间查询
|
|
|
398
|
+ 'pageSize' => 100,
|
|
|
399
|
+ 'startTime' => $startTime,
|
|
|
400
|
+ 'endTime' => $endTime,
|
|
|
401
|
+ 'orderScene' => 2,
|
|
|
402
|
+ // 'tkStatus' => 13
|
|
|
403
|
+ ];
|
|
|
404
|
+
|
|
|
405
|
+ $queryData['sign'] = self::makeSign($queryData, self::$appSecret);
|
|
|
406
|
+ $fullUrl = "{$url}?" . http_build_query($queryData);
|
|
|
407
|
+
|
|
|
408
|
+ Log::debug("查询订单时间段". json_encode([
|
|
|
409
|
+ '开始时间' => $startTime,
|
|
|
410
|
+ '结束时间' => $endTime,
|
|
|
411
|
+ '时间差(分钟)' => round((strtotime($endTime) - strtotime($startTime)) / 60, 2)
|
|
|
412
|
+ ], JSON_UNESCAPED_UNICODE));
|
|
|
413
|
+
|
|
|
414
|
+ $response = self::sendCurl($fullUrl);
|
|
|
415
|
+ Log::debug("查询结果". json_encode($response, JSON_UNESCAPED_UNICODE));
|
|
|
416
|
+ $isError = $response['data']['error_response'] ?? '';
|
|
|
417
|
+
|
|
|
418
|
+ if ($isError) {
|
|
|
419
|
+ Log::warning("查询订单出错". json_encode([
|
|
|
420
|
+ '时间段' => "{$startTime} 至 {$endTime}",
|
|
|
421
|
+ '错误' => $isError
|
|
|
422
|
+ ], JSON_UNESCAPED_UNICODE));
|
|
|
423
|
+ return [];
|
|
|
424
|
+ }
|
|
|
425
|
+
|
|
|
426
|
+ return $response['data']['results']['publisher_order_dto'] ?? [];
|
|
|
427
|
+ }
|
|
|
428
|
+
|
|
|
429
|
+ /**
|
|
|
430
|
+ * 订单去重
|
|
|
431
|
+ */
|
|
|
432
|
+ private function removeDuplicateOrders($orders): array
|
|
|
433
|
+ {
|
|
|
434
|
+ $uniqueOrders = [];
|
|
|
435
|
+ $orderIds = [];
|
|
|
436
|
+
|
|
|
437
|
+ foreach ($orders as $order) {
|
|
|
438
|
+ $orderId = $order['trade_parent_id'] ?? '';
|
|
|
439
|
+ if ($orderId && !in_array($orderId, $orderIds)) {
|
|
|
440
|
+ $uniqueOrders[] = $order;
|
|
|
441
|
+ $orderIds[] = $orderId;
|
|
|
442
|
+ }
|
|
259
|
443
|
}
|
|
260
|
444
|
|
|
|
445
|
+ return $uniqueOrders;
|
|
261
|
446
|
}
|
|
262
|
447
|
|
|
263
|
448
|
//订单查询接口(20分钟一个时间段)
|