2025-04-25 11:30:44 +08:00
<? php
namespace app\controller ;
2025-06-10 09:04:40 +08:00
use app\command\UpdateShipInfoCommand ;
2025-06-09 11:37:32 +08:00
use app\model\LogisticsShip ;
use app\model\LogisticsShipHis ;
2025-04-25 11:30:44 +08:00
use app\model\Vehicle ;
2025-05-07 14:19:47 +08:00
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 ;
2025-04-30 14:00:54 +08:00
use app\service\OssService ;
2025-05-07 14:19:47 +08:00
// use plugin\admin\app\model\Location;
2025-06-09 11:37:32 +08:00
use app\service\ShipService ;
2025-05-08 15:53:42 +08:00
use app\service\TranslatorService ;
2025-06-10 09:04:40 +08:00
use support\Log ;
use Symfony\Component\Console\Input\ArrayInput ;
use Symfony\Component\Console\Output\BufferedOutput ;
2025-04-30 11:30:08 +08:00
use util\Util ;
2025-04-25 11:30:44 +08:00
use support\Request ;
2025-05-07 14:19:47 +08:00
use support\Cache ;
2025-04-25 11:30:44 +08:00
class VehicleController
{
2025-04-30 11:30:08 +08:00
2025-05-26 17:02:34 +08:00
// protected $status = ['未知','待发车','在途(发往fbo港口)','抵达发货港口','在途(发往目的地仓库)','抵达目的地','售出'];
protected $status = [
2025-05-29 14:03:42 +08:00
'zh' => [ '未知' , '待发车' , '在途(发往fbo港口)' , '抵达发货港口' , '在途(发往目的地仓库)' , '抵达目的地' , '售出' , '待采购' , '已付定金待提车' ],
'en' => [ 'Unknown' , 'Pending Departure' , 'In Transit (to FBO Port)' , 'Arrived at Shipping Port' , 'In Transit (to Destination Warehouse)' , 'Arrived at Destination' , 'Sold' , 'To be purchased' , 'Deposit paid, waiting to be picked up' ],
'ru' => [ 'Неизвестно' , 'Ожидает отправки' , 'В пути (к порту FBO)' , 'Прибыл в порт отправки' , 'В пути (к складу назначения)' , 'Прибыл в пункт назначения' , 'Продано' , 'Ожидаемые закупки' , 'Выплаченные авансы' ],
'ar' => [ 'غير معروف' , 'في انتظار الشحن' , 'في الطريق (إلى ميناء FBO)' , 'وصل إلى ميناء الشحن' , 'في الطريق (إلى مستودع الوجهة)' , 'وصل إلى الوجهة' , 'تم البيع' , 'في انتظار شراء' , 'دفع عربون السيارة' ],
2025-05-26 17:02:34 +08:00
];
2025-04-25 11:30:44 +08:00
/**
* 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 )
{
2025-05-07 14:19:47 +08:00
$lang = $request -> post ( 'lang' , 'zh' );
2025-06-09 14:40:28 +08:00
$status = $request -> post ( 'status' , '' );
2025-05-08 15:53:42 +08:00
// 接收请求参数(Webman自动注入)
$page = $request -> post ( 'page' , 1 ); // 默认第1页
$pageSize = $request -> post ( 'pageSize' , 30 ); // 默认每页30条
2025-05-07 14:19:47 +08:00
2025-06-09 11:37:32 +08:00
$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 ];
}
2025-05-07 14:19:47 +08:00
switch ( $lang ) {
case 'zh' :
2025-06-09 14:40:28 +08:00
$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 ();
2025-05-07 14:19:47 +08:00
$hz = new Location ();
break ;
case 'en' :
2025-06-09 14:40:28 +08:00
$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 ();
2025-05-07 14:19:47 +08:00
$hz = new LocationEn ();
break ;
case 'ru' :
2025-06-09 14:40:28 +08:00
$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 ();
2025-05-07 14:19:47 +08:00
$hz = new LocationRu ();
break ;
case 'ar' :
2025-06-09 14:40:28 +08:00
$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 ();
2025-05-07 14:19:47 +08:00
$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 ;
}
2025-05-20 08:59:38 +08:00
$ossservice = null ;
2025-05-07 14:19:47 +08:00
// 组装数据
foreach ( $vehicles as & $vehicle ) {
2025-04-25 11:30:44 +08:00
if ( isset ( $vehicle -> vin )) {
$vehicle -> vin = $this -> maskVin ( $vehicle -> vin );
}
2025-05-29 10:57:15 +08:00
$vehicle -> purchase_location = '' ;
$vehicle -> procedure_location = '' ;
2025-05-07 14:19:47 +08:00
$vehicle -> fbo_destination = isset ( $arr [ $vehicle -> fbo_locations_id ]) ? $arr [ $vehicle -> fbo_locations_id ][ 'name' ] : '' ;
2025-05-26 17:02:34 +08:00
$vehicle -> status_val = $vehicle -> status ;
if ( is_numeric ( $vehicle -> status )) {
$vehicle -> status = $this -> status [ $lang ][ $vehicle -> status ] ?? $this -> status [ $lang ][ 0 ];
}
2025-06-10 10:16:06 +08:00
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' ] = '' ;
}
2025-06-09 11:37:32 +08:00
if ( ! empty ( $vehicle [ 'ship_id' ])){
$vehicle [ 'ship' ] = LogisticsShip :: find ( $vehicle [ 'ship_id' ]) -> toArray ();
}
}
unset ( $vehicle );
// =================================== new ===================================== end
2025-06-09 14:40:28 +08:00
if ( ! empty ( $status )){
$count = Vehicle :: where ( $where ) -> whereIn ( 'status' , $status ) -> count ();
} else {
$count = Vehicle :: where ( $where ) -> count ();
}
2025-06-09 11:37:32 +08:00
$result = [ 'list' => $vehicles , 'count' => $count ];
return Util :: success ( $result );
}
2025-06-09 13:48:04 +08:00
public function ship ( Request $request ){
2025-06-09 11:37:32 +08:00
$lang = $request -> post ( 'lang' , 'zh' );
2025-06-09 13:48:04 +08:00
$id = $request -> post ( 'id' );
if ( empty ( $id )){
return Util :: fail ([], 'id不能为空' );
}
2025-06-09 11:37:32 +08:00
// 接收请求参数(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 ();
2025-06-10 10:16:06 +08:00
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 ];
}
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' ]) -> toArray ();
}
}
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' :
2025-06-10 14:47:46 +08:00
$vehicles = Vehicle :: where ([ 'locations_id' => $id ]) -> offset (( $page - 1 ) * $pageSize ) -> limit ( $pageSize ) -> get ();
2025-06-10 10:16:06 +08:00
$hz = new Location ();
break ;
case 'en' :
2025-06-10 14:47:46 +08:00
$vehicles = VehicleEn :: where ([ 'locations_id' => $id ]) -> offset (( $page - 1 ) * $pageSize ) -> limit ( $pageSize ) -> get ();
2025-06-10 10:16:06 +08:00
$hz = new LocationEn ();
break ;
case 'ru' :
2025-06-10 14:47:46 +08:00
$vehicles = VehicleRu :: where ([ 'locations_id' => $id ]) -> offset (( $page - 1 ) * $pageSize ) -> limit ( $pageSize ) -> get ();
2025-06-10 10:16:06 +08:00
$hz = new LocationRu ();
break ;
case 'ar' :
2025-06-10 14:47:46 +08:00
$vehicles = VehicleAr :: where ([ 'locations_id' => $id ]) -> offset (( $page - 1 ) * $pageSize ) -> limit ( $pageSize ) -> get ();
2025-06-10 10:16:06 +08:00
$hz = new LocationAr ();
2025-06-09 11:37:32 +08:00
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 ];
}
2025-05-29 14:03:42 +08:00
if ( ! empty ( $vehicle [ 'img_url' ])) {
2025-05-26 17:43:55 +08:00
$img_url = Cache :: get ( 'img_dib_' . $vehicle -> id );
2025-05-07 14:19:47 +08:00
if ( $img_url ) {
$vehicle [ 'img_url' ] = $img_url ;
} else {
2025-05-20 08:59:38 +08:00
$ossservice = empty ( $ossservice ) ? new OssService () : $ossservice ;
2025-05-07 14:19:47 +08:00
$img_url = $ossservice -> generatePrivateUrl ( $vehicle [ 'img_url' ], 86400 );
$vehicle [ 'img_url' ] = $img_url ;
2025-05-26 17:43:55 +08:00
Cache :: set ( 'img_dib_' . $vehicle -> id , $img_url , 86390 );
2025-05-07 14:19:47 +08:00
}
2025-05-29 14:03:42 +08:00
} else {
$vehicle [ 'img_url' ] = '' ;
2025-04-30 14:00:54 +08:00
}
2025-05-07 14:19:47 +08:00
}
unset ( $vehicle );
2025-06-09 11:37:32 +08:00
2025-06-10 14:47:46 +08:00
$location = $hz :: where ([ 'id' => $id ]) -> first ();
$count = Vehicle :: where ([ 'locations_id' => $id ]) -> count ();
$result = [ 'list' => $vehicles , 'location' => $location , 'count' => $count ];
2025-04-25 11:30:44 +08:00
return Util :: success ( $result );
}
2025-06-10 09:04:40 +08:00
public function shipList ( Request $request ){
$navigate = LogisticsShip :: where ([ 'status' => 0 ]) -> get ();
$pending = LogisticsShip :: where ([ 'status' => 1 ]) -> get ();
$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 ();
if ( $res ){
return Util :: success ( $res , '成功' );
} 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 ,
2025-06-10 09:12:00 +08:00
'status' => '1' ,
2025-06-10 09:04:40 +08:00
'updated_at' => date ( 'Y-m-d H:i:s' )
];
}
2025-04-25 11:30:44 +08:00
/**
* Get a specific vehicle with its location
*/
public function show ( Request $request , $id )
{
2025-05-07 14:19:47 +08:00
$lang = $request -> post ( 'lang' , 'zh' );
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);
2025-04-25 11:30:44 +08:00
if ( ! $vehicle ) {
return Util :: fail ( $vehicle , 'Vehicle not found' );
}
if ( isset ( $vehicle -> vin )) {
$vehicle -> vin = $this -> maskVin ( $vehicle -> vin );
}
return Util :: success ( $vehicle );
}
2025-05-28 10:19:23 +08:00
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 ();
}
2025-04-25 11:30:44 +08:00
}