198 lines
7.6 KiB
PHP
198 lines
7.6 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
namespace App\Console\Commands;
|
|||
|
|
|
|||
|
|
use App\Models\ExpressCompany;
|
|||
|
|
use App\Models\ExpressDetail;
|
|||
|
|
use App\Models\ExpressNo;
|
|||
|
|
use Exception;
|
|||
|
|
use Illuminate\Console\Command;
|
|||
|
|
use Illuminate\Support\Collection;
|
|||
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|||
|
|
|
|||
|
|
class ExpressCommand extends Command
|
|||
|
|
{
|
|||
|
|
/**
|
|||
|
|
* The name and signature of the console command.
|
|||
|
|
*
|
|||
|
|
* @var string
|
|||
|
|
*/
|
|||
|
|
protected $signature = 'express {type?} {--code=} {--no=} {--id=}';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The console command description.
|
|||
|
|
*
|
|||
|
|
* @var string
|
|||
|
|
*/
|
|||
|
|
protected $description = '物流相关';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Execute the console command.
|
|||
|
|
*
|
|||
|
|
* @return int
|
|||
|
|
*/
|
|||
|
|
public function handle()
|
|||
|
|
{
|
|||
|
|
$type = $this->argument('type');
|
|||
|
|
switch ($type) {
|
|||
|
|
case 'update': // 物流更新
|
|||
|
|
$this->update();
|
|||
|
|
break;
|
|||
|
|
case 'import': // 快递公司导入 快递公司没有对应API只有文件,所以需要手动更新文件并执行
|
|||
|
|
$this->import();
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
$this->error('参数错误');
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return Command::SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private function update()
|
|||
|
|
{
|
|||
|
|
$code = $this->option('code');
|
|||
|
|
$no = $this->option('no');
|
|||
|
|
$id = $this->option('id');
|
|||
|
|
log_s("物流更新请求参数:--code=$code --no=$no --id=$id", 'express', 'message', true);
|
|||
|
|
if ($code && $no) {
|
|||
|
|
$expressNo = ExpressNo::firstOrCreate([
|
|||
|
|
'express_company_code' => $code,
|
|||
|
|
'express_no' => $no,
|
|||
|
|
]);
|
|||
|
|
try {
|
|||
|
|
$this->updateHandle($expressNo);
|
|||
|
|
} catch (Exception $exception) {
|
|||
|
|
$message = "物流请求错误:$expressNo->express_company_name $expressNo->express_no => {$exception->getMessage()}";
|
|||
|
|
console_error($message);
|
|||
|
|
log_s($message, 'express', 'error', true);
|
|||
|
|
}
|
|||
|
|
} elseif ($id) {
|
|||
|
|
$expressNo = ExpressNo::find($id);
|
|||
|
|
if (!$expressNo) {
|
|||
|
|
$message = "物流请求错误:未找到{$id}对应单号";
|
|||
|
|
console_error($message);
|
|||
|
|
log_s($message, 'express', 'error', true);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
$this->updateHandle($expressNo);
|
|||
|
|
} catch (Exception $exception) {
|
|||
|
|
$message = "物流请求错误:$expressNo->express_company_name $expressNo->express_no => {$exception->getMessage()}";
|
|||
|
|
console_error($message);
|
|||
|
|
log_s($message, 'express', 'error', true);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
ExpressNo::with(['detail'])
|
|||
|
|
->whereNotNull('express_company_code')
|
|||
|
|
->whereNotNull('express_no')
|
|||
|
|
->chunk(100, function (Collection $collection) {
|
|||
|
|
/* @var ExpressNo $expressNo */
|
|||
|
|
foreach ($collection as $expressNo) {
|
|||
|
|
try {
|
|||
|
|
if ($expressNo->detail) {
|
|||
|
|
if ($expressNo->state == ExpressNo::STATE_SIGN) {
|
|||
|
|
if (now()->diffInHours($expressNo->detail->detail_at) > 720) {
|
|||
|
|
$expressNo->update(['sync_at' => now()]);
|
|||
|
|
$message = "物流请求跳过:已签收且超过30天";
|
|||
|
|
console_info($message);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (now()->diffInDays($expressNo->created_at) > 15) {
|
|||
|
|
$expressNo->update(['sync_at' => now()]);
|
|||
|
|
$message = "物流请求跳过:该件15天无物流信息";
|
|||
|
|
console_info($message);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
$this->updateHandle($expressNo);
|
|||
|
|
} catch (Exception $exception) {
|
|||
|
|
$message = "物流请求错误:$expressNo->express_company_name $expressNo->express_no => {$exception->getMessage()}";
|
|||
|
|
console_error($message);
|
|||
|
|
log_s($message, 'express', 'error', true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function updateHandle(ExpressNo $expressNo)
|
|||
|
|
{
|
|||
|
|
console_comment("物流请求开始:$expressNo->express_company_name $expressNo->express_no");
|
|||
|
|
if (!$expressNo->express_company_name) {
|
|||
|
|
$expressNo->load(['company']);
|
|||
|
|
if ($expressNo->company) {
|
|||
|
|
$expressNo->express_company_name = $expressNo->company->name;
|
|||
|
|
$expressNo->save();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if ($expressNo->sync_at && now()->diffInMinutes($expressNo->sync_at) < 60) {
|
|||
|
|
$message = "物流请求跳过:距离上次获取不到60分钟";
|
|||
|
|
console_info($message);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$response = app('express')->track($expressNo->express_no, $expressNo->express_company_code, ['phone' => $expressNo->mobile]);
|
|||
|
|
$result = json_decode($response, true);
|
|||
|
|
if ($result === false) {
|
|||
|
|
$message = "物流请求错误:$expressNo->express_company_name $expressNo->express_no => $response";
|
|||
|
|
console_error($message);
|
|||
|
|
log_s($message, 'express', 'error', true);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
if (($result['status'] ?? '') != 200) {
|
|||
|
|
$message = "物流请求失败:$expressNo->express_company_name $expressNo->express_no =>" . var_export($result, true);
|
|||
|
|
console_info($message);
|
|||
|
|
log_s($message, 'express', 'fail', true);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
$message = "物流请求成功:$expressNo->express_company_name $expressNo->express_no";
|
|||
|
|
console_info($message);
|
|||
|
|
log_s($message, 'express', 'success', true);
|
|||
|
|
|
|||
|
|
$detailIds = [];
|
|||
|
|
foreach ($result['data'] as $value) {
|
|||
|
|
/* @var ExpressDetail $detail */
|
|||
|
|
$detail = $expressNo->details()->updateOrCreate([
|
|||
|
|
'status' => $value['status'],
|
|||
|
|
'detail_at' => $value['ftime'],
|
|||
|
|
'detail' => $value['context'],
|
|||
|
|
]);
|
|||
|
|
console_info("$expressNo->express_company_name $expressNo->express_no => {$value['context']}");
|
|||
|
|
$detailIds[] = $detail->id;
|
|||
|
|
}
|
|||
|
|
$expressNo->details()->whereNotIn('id', $detailIds)->delete();
|
|||
|
|
$expressNo->update([
|
|||
|
|
'state' => $result['state'],
|
|||
|
|
'sync_at' => now(),
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
console_info("$expressNo->express_company_name $expressNo->express_no => {$expressNo->state_string}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private function import()
|
|||
|
|
{
|
|||
|
|
$spreadsheet = IOFactory::load(storage_path('files/快递100快递公司标准编码.xlsx'));
|
|||
|
|
$sheet = $spreadsheet->setActiveSheetIndex(0);
|
|||
|
|
$data = $sheet->toArray();
|
|||
|
|
$ids = [];
|
|||
|
|
foreach ($data as $k => $value) {
|
|||
|
|
if ($k < 2) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
$expressCompany = ExpressCompany::updateOrCreate([
|
|||
|
|
'code' => $value[1],
|
|||
|
|
], [
|
|||
|
|
'name' => $value[0],
|
|||
|
|
'type' => $value[2],
|
|||
|
|
'sort' => $k,
|
|||
|
|
]);
|
|||
|
|
$ids[] = $expressCompany->id;
|
|||
|
|
console_info("$value[1] => $value[0]");
|
|||
|
|
}
|
|||
|
|
ExpressCompany::whereNotIn('id', $ids)->delete();
|
|||
|
|
}
|
|||
|
|
}
|