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();
|
||
}
|
||
}
|