Files

198 lines
7.6 KiB
PHP
Raw Permalink Normal View History

2025-01-11 14:16:20 +08:00
<?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();
}
}