Files
car_info/app/controller/VehicleController.php
T
2025-06-11 11:47:35 +08:00

475 lines
19 KiB
PHP

<?php
namespace app\controller;
use app\command\UpdateShipInfoCommand;
use app\model\LogisticsShip;
use app\model\LogisticsShipHis;
use app\model\Vehicle;
use app\model\VehicleEn;
use app\model\VehicleRu;
use app\model\VehicleAr;
use app\model\Location;
use app\model\LocationEn;
use app\model\LocationRu;
use app\model\LocationAr;
use app\service\OssService;
// use plugin\admin\app\model\Location;
use app\service\ShipService;
use app\service\TranslatorService;
use support\Log;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use util\Util;
use support\Request;
use support\Cache;
class VehicleController
{
// protected $status = ['未知','待发车','在途(发往fbo港口)','抵达发货港口','在途(发往目的地仓库)','抵达目的地','售出'];
protected $status = [
'zh' => ['未知', '待发车', '在途(发往fbo港口)', '抵达发货港口', '在途(发往目的地仓库)', '已入库', '售出', '待采购', '已付定金待提车'],
'en' => ['Unknown', 'Pending Departure', 'In Transit (to FBO Port)', 'Arrived at Shipping Port', 'In Transit (to Destination Warehouse)', 'Already in stock', 'Sold', 'To be purchased', 'Deposit paid, waiting to be picked up'],
'ru' => ['Неизвестно', 'Ожидает отправки', 'В пути (к порту FBO)', 'Прибыл в порт отправки', 'В пути (к складу назначения)', 'На складе', 'Продано', 'Ожидаемые закупки', 'Выплаченные авансы'],
'ar' => ['غير معروف', 'في انتظار الشحن', 'في الطريق (إلى ميناء FBO)', 'وصل إلى ميناء الشحن', 'في الطريق (إلى مستودع الوجهة)', 'بالفعل في التخزين', 'تم البيع', 'في انتظار شراء', 'دفع عربون السيارة'],
];
/**
* Mask VIN number by showing only first 2 and last 6 characters
*/
private function maskVin($vin)
{
if (strlen($vin) <= 8) {
return $vin;
}
return substr($vin, 0, 2) . str_repeat('*', strlen($vin) - 8) . substr($vin, -6);
}
/**
* Get all vehicles with their locations
*/
public function index(Request $request)
{
$lang = $request->post('lang', 'zh');
$status = $request->post('status', '');
// 接收请求参数(Webman自动注入)
$page = $request->post('page', 1); // 默认第1页
$pageSize = $request->post('pageSize', 30); // 默认每页30条
$where = [];
if($status == 1){
$status = [5,6];
}elseif ($status == 2){
$status = [4];
}elseif ($status == 3){
$status = [1,2,3,7,8];
$where[] = ['vin' ,'!=', null];
}elseif ($status == 4){
$status = [1,2,3,7,8];
$where[] = ['vin' ,'=', null];
}
switch ($lang) {
case 'zh':
$vehicles = Vehicle::with('location')->with('finalLocation')->where($where);
if(!empty($status)){
$vehicles = $vehicles->whereIn('status',$status);
}
$vehicles = $vehicles->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new Location();
break;
case 'en':
$vehicles = VehicleEn::with('location')->with('finalLocation')->where($where);
if(!empty($status)){
$vehicles = $vehicles->whereIn('status',$status);
}
$vehicles = $vehicles->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationEn();
break;
case 'ru':
$vehicles = VehicleRu::with('location')->with('finalLocation')->where($where);
if(!empty($status)){
$vehicles = $vehicles->whereIn('status',$status);
}
$vehicles = $vehicles->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationRu();
break;
case 'ar':
$vehicles = VehicleAr::with('location')->with('finalLocation')->where($where);
if(!empty($status)){
$vehicles = $vehicles->whereIn('status',$status);
}
$vehicles = $vehicles->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationAr();
break;
}
// // $vehicles = Vehicle::with('location')->with('finalLocation')->get();
// $vehicles->each(function ($vehicle) use ($hz) {
// if (isset($vehicle->vin)) {
// $vehicle->vin = $this->maskVin($vehicle->vin);
// }
// // $vehicle->status = $this->status[$vehicle->status]??$this->status[0];
// // $location = Location::find($vehicle->locations_id);
// // $vehicle->location_name = $location ? $location->name : '';
// // $final_location = Location::find($vehicle->final_locations_id);
// // $vehicle->final_location_name = $final_location ? $final_location->name : '';
// $fbo_location = $hz->find($vehicle->fbo_locations_id);
// $vehicle->fbo_destination = $fbo_location ? $fbo_location->name : '';
// if(!str_starts_with($vehicle['img_url'], 'http')){
// $ossservice = new OssService();
// $img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
// $vehicle['img_url'] = $img_url;
// }
// });
// =================================== new ===================================== start
// 单独处理 locations
$fboIds = $vehicles->pluck('fbo_locations_id')->toArray();
$fbo = $hz->whereIn('id', array_unique($fboIds))->get()->toArray();
$arr = [];
foreach ($fbo as $value) {
$arr[$value['id']] = $value;
}
$ossservice = null;
// 组装数据
foreach ($vehicles as &$vehicle) {
if (isset($vehicle->vin)) {
$vehicle->vin = $this->maskVin($vehicle->vin);
}
$vehicle->purchase_location='';
$vehicle->procedure_location='';
$vehicle->fbo_destination = isset($arr[$vehicle->fbo_locations_id]) ? $arr[$vehicle->fbo_locations_id]['name'] : '';
$vehicle->status_val = $vehicle->status;
if(is_numeric($vehicle->status)) {
$vehicle->status = $this->status[$lang][$vehicle->status]??$this->status[$lang][0];
}
$vehicle['vin'] = $vehicle['vin']??'';
$vehicle['brand'] = $vehicle['brand']??'';
$vehicle['model'] = $vehicle['model']??'';
if(!empty($vehicle['img_url'])) {
$img_url = Cache::get('img_dib_'.$vehicle->id);
if ($img_url) {
$vehicle['img_url'] = $img_url;
} else {
$ossservice = empty($ossservice)?new OssService():$ossservice;
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
Cache::set('img_dib_'.$vehicle->id, $img_url, 86390);
}
}else{
$vehicle['img_url'] = '';
}
if(!empty($vehicle['ship_id'])){
$vehicle['ship'] = LogisticsShip::find($vehicle['ship_id']);
}
}
unset($vehicle);
// =================================== new ===================================== end
if(!empty($status)){
$count = Vehicle::where($where)->whereIn('status',$status)->count();
} else {
$count = Vehicle::where($where)->count();
}
$result = ['list' => $vehicles,'count'=>$count];
return Util::success($result);
}
public function ship(Request $request){
$lang = $request->post('lang', 'zh');
$id = $request->post('id');
if(empty($id)){
return Util::fail([],'id不能为空');
}
// 接收请求参数(Webman自动注入)
$page = $request->post('page', 1); // 默认第1页
$pageSize = $request->post('pageSize', 30); // 默认每页30条
switch ($lang) {
case 'zh':
$vehicles = Vehicle::with('location')->with('finalLocation')->where(['ship_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new Location();
break;
case 'en':
$vehicles = VehicleEn::with('location')->with('finalLocation')->where(['ship_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationEn();
break;
case 'ru':
$vehicles = VehicleRu::with('location')->with('finalLocation')->where(['ship_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationRu();
break;
case 'ar':
$vehicles = VehicleAr::with('location')->with('finalLocation')->where(['ship_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationAr();
break;
}
// 组装数据
foreach ($vehicles as &$vehicle) {
if (isset($vehicle->vin)) {
$vehicle->vin = $this->maskVin($vehicle->vin);
}
$vehicle->purchase_location='';
$vehicle->procedure_location='';
$vehicle->fbo_destination = isset($arr[$vehicle->fbo_locations_id]) ? $arr[$vehicle->fbo_locations_id]['name'] : '';
$vehicle->status_val = $vehicle->status;
if(is_numeric($vehicle->status)) {
$vehicle->status = $this->status[$lang][$vehicle->status]??$this->status[$lang][0];
}
$vehicle['vin'] = $vehicle['vin']??'';
$vehicle['brand'] = $vehicle['brand']??'';
$vehicle['model'] = $vehicle['model']??'';
if(!empty($vehicle['img_url'])) {
$img_url = Cache::get('img_dib_'.$vehicle->id);
if ($img_url) {
$vehicle['img_url'] = $img_url;
} else {
$ossservice = empty($ossservice)?new OssService():$ossservice;
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
Cache::set('img_dib_'.$vehicle->id, $img_url, 86390);
}
}else{
$vehicle['img_url'] = '';
}
if(!empty($vehicle['ship_id'])){
$vehicle['ship'] = LogisticsShip::find($vehicle['ship_id']);
}
}
unset($vehicle);
$logisticsShip = LogisticsShip::where(['id' => $id])->first();
$logisticsShipHis = LogisticsShipHis::where(['ship_id'=> $id])->get();
foreach ($logisticsShipHis as &$his) {
$his['eta_utc'] = date('Y-m-d H:i:s', $his['eta_utc']);
$his['last_time_utc'] = date('Y-m-d H:i:s', $his['last_time_utc']);
}
unset($his);
$logisticsShip['last_time_utc'] = date('Y-m-d H:i:s', $logisticsShip['last_time_utc']);
$logisticsShip['eta_utc'] = date('Y-m-d H:i:s', $logisticsShip['eta_utc']);
$count = Vehicle::where(['ship_id' => $id])->count();
$result = ['list' => $vehicles,'ship' => $logisticsShip,'ship_his' => $logisticsShipHis,'count'=>$count];
return Util::success($result);
}
public function location(Request $request){
$lang = $request->post('lang', 'zh');
$id = $request->post('id');
if(empty($id)){
return Util::fail([],'id不能为空');
}
// 接收请求参数(Webman自动注入)
$page = $request->post('page', 1); // 默认第1页
$pageSize = $request->post('pageSize', 30); // 默认每页30条
switch ($lang) {
case 'zh':
$vehicles = Vehicle::where(['locations_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new Location();
break;
case 'en':
$vehicles = VehicleEn::where(['locations_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationEn();
break;
case 'ru':
$vehicles = VehicleRu::where(['locations_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationRu();
break;
case 'ar':
$vehicles = VehicleAr::where(['locations_id' => $id])->offset(($page-1)*$pageSize) ->limit($pageSize)->get();
$hz = new LocationAr();
break;
}
// 组装数据
foreach ($vehicles as &$vehicle) {
if (isset($vehicle->vin)) {
$vehicle->vin = $this->maskVin($vehicle->vin);
}
$vehicle->purchase_location='';
$vehicle->procedure_location='';
$vehicle->fbo_destination = isset($arr[$vehicle->fbo_locations_id]) ? $arr[$vehicle->fbo_locations_id]['name'] : '';
$vehicle->status_val = $vehicle->status;
if(is_numeric($vehicle->status)) {
$vehicle->status = $this->status[$lang][$vehicle->status]??$this->status[$lang][0];
}
$vehicle['vin'] = $vehicle['vin']??'';
$vehicle['brand'] = $vehicle['brand']??'';
$vehicle['model'] = $vehicle['model']??'';
if(!empty($vehicle['img_url'])) {
$img_url = Cache::get('img_dib_'.$vehicle->id);
if ($img_url) {
$vehicle['img_url'] = $img_url;
} else {
$ossservice = empty($ossservice)?new OssService():$ossservice;
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
Cache::set('img_dib_'.$vehicle->id, $img_url, 86390);
}
}else{
$vehicle['img_url'] = '';
}
}
unset($vehicle);
$location = $hz::where(['id' => $id])->first();
$count = Vehicle::where(['locations_id' => $id])->count();
$result = ['list' => $vehicles,'location' => $location,'count'=>$count];
return Util::success($result);
}
public function shipList(Request $request){
$navigate = LogisticsShip::where(['status' => 0])->get();
$pending = LogisticsShip::where(['status' => 1])->get();
foreach ($pending as &$val) {
$val['count'] = Vehicle::where(['ship_id' => $val->id])->count();
}
$result = ['navigate' => $navigate,'pending' => $pending];
return Util::success($result);
}
public function add(Request $request){
try {
Log::info('开始执行船舶信息更新任务');
// 通过ShipService获取船舶最新信息
$shipInfo = ShipService::getShipInfo($request->get('mmsi'));
$apiData = $shipInfo['data']['data'] ?? null;
$ship = new LogisticsShip();
$updateData = $this->mapApiDataToShip($apiData);
$updateData['mmsi'] = $request->get('mmsi');
$ship->fill($updateData);
$res = $ship->save();
$shipHis = new LogisticsShipHis();
$shipHis->fill($updateData);
$shipHis->ship_id = $ship->id;
$shipHis->save();
if($res){
return Util::success($apiData,'成功');
} else{
return Util::fail($res,'成功');
}
} catch (\Exception $e) {
Log::error('船舶信息更新任务执行异常', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
}
}
/**
* 将API数据映射到船舶表字段
* @param array $apiData
* @return array
*/
private function mapApiDataToShip(array $apiData): array
{
return [
'IMO' => $apiData['imo'] ?? '',
'call_sign' => $apiData['call_sign'] ?? '',
'ship_name' => $apiData['ship_name'] ?? '',
'ship_cnname' => $apiData['ship_cnname'] ?? '',
'dest' => $apiData['dest'] ?? '',
'length' => $apiData['length'] ?? '',
'width' => $apiData['width'] ?? '',
'lat' => $apiData['lat'] ?? '',
'lng' => $apiData['lng'] ?? '',
'eta_utc' => $apiData['eta_utc'] ?? null,
'last_time_utc' => $apiData['last_time_utc'] ?? null,
'status' => '1',
'updated_at' => date('Y-m-d H:i:s')
];
}
/**
* Get a specific vehicle with its location
*/
public function show(Request $request)
{
$lang = $request->post('lang', 'zh');
$id = $request->post('id');
switch ($lang) {
case 'zh':
$vehicle = Vehicle::with('location')->find($id);
break;
case 'en':
$vehicle = VehicleEn::with('location')->find($id);
break;
case 'ru':
$vehicle = VehicleRu::with('location')->find($id);
break;
case 'ar':
$vehicle = VehicleAr::with('location')->find($id);
break;
}
// $vehicle = Vehicle::with('location')->find($id);
if (!$vehicle) {
return Util::fail($vehicle,'Vehicle not found');
}
if (isset($vehicle->vin)) {
$vehicle->vin = $this->maskVin($vehicle->vin);
}
if(is_numeric($vehicle->status)) {
$vehicle->status = $this->status[$lang][$vehicle->status]??$this->status[$lang][0];
}
$vehicle['vin'] = $vehicle['vin']??'';
$vehicle['brand'] = $vehicle['brand']??'';
$vehicle['model'] = $vehicle['model']??'';
if(!empty($vehicle['img_url'])) {
$img_url = Cache::get('img_dib_'.$vehicle->id);
if ($img_url) {
$vehicle['img_url'] = $img_url;
} else {
$ossservice = empty($ossservice)?new OssService():$ossservice;
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
Cache::set('img_dib_'.$vehicle->id, $img_url, 86390);
}
}else{
$vehicle['img_url'] = '';
}
if(!empty($vehicle['ship_id'])){
$vehicle['ship'] = LogisticsShip::find($vehicle['ship_id']);
}
return Util::success($vehicle);
}
public function unset(Request $request, $id){
$id = $request->get('id','');
if(!empty($id)){
Cache::delete('img_dib_'.$id);
}elseif($id == 'all'){
Cache::clear();
}
return Util::success();
}
}