diff --git a/app/controller/VehicleController.php b/app/controller/VehicleController.php index c32f3d1..98410cd 100644 --- a/app/controller/VehicleController.php +++ b/app/controller/VehicleController.php @@ -2,6 +2,8 @@ namespace app\controller; +use app\model\LogisticsShip; +use app\model\LogisticsShipHis; use app\model\Vehicle; use app\model\VehicleEn; use app\model\VehicleRu; @@ -14,6 +16,7 @@ use app\model\LocationAr; use app\service\OssService; // use plugin\admin\app\model\Location; +use app\service\ShipService; use app\service\TranslatorService; use util\Util; use support\Request; @@ -47,28 +50,42 @@ class VehicleController { $lang = $request->post('lang', 'zh'); + $status = $request->post('status', '4'); // 接收请求参数(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') ->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); + $vehicles = Vehicle::with('location')->with('finalLocation')->where($where)->whereIn('status',$status)->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); $hz = new Location(); break; case 'en': - $vehicles = VehicleEn::with('location')->with('finalLocation')->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); + $vehicles = VehicleEn::with('location')->with('finalLocation')->where($where)->whereIn('status',$status)->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); $hz = new LocationEn(); break; case 'ru': - $vehicles = VehicleRu::with('location')->with('finalLocation')->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); + $vehicles = VehicleRu::with('location')->with('finalLocation')->where($where)->whereIn('status',$status)->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); $hz = new LocationRu(); break; case 'ar': - $vehicles = VehicleAr::with('location')->with('finalLocation')->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); + $vehicles = VehicleAr::with('location')->with('finalLocation')->where($where)->whereIn('status',$status)->offset(($page-1)*$pageSize) ->limit($pageSize)->get(); $hz = new LocationAr(); break; } @@ -118,6 +135,73 @@ class VehicleController 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); + // =================================== new ===================================== end + $count = Vehicle::where($where)->whereIn('status',$status)->count(); + $result = ['list' => $vehicles,'count'=>$count]; + return Util::success($result); + } + + public function ship(Request $request,$id){ + +// $res = ShipService::getShipInfo('413399120'); +// return Util::success($res); + $lang = $request->post('lang', 'zh'); + // 接收请求参数(Webman自动注入) + $page = $request->post('page', 1); // 默认第1页 + $pageSize = $request->post('pageSize', 30); // 默认每页30条 +// var_dump($id);die; + + 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]; + } if(!empty($vehicle['img_url'])) { $img_url = Cache::get('img_dib_'.$vehicle->id); if ($img_url) { @@ -131,11 +215,17 @@ class VehicleController }else{ $vehicle['img_url'] = ''; } + if(!empty($vehicle['ship_id'])){ + $vehicle['ship'] = LogisticsShip::find($vehicle['ship_id'])->toArray(); + } } unset($vehicle); - // =================================== new ===================================== end - $count = Vehicle::count(); - $result = ['list' => $vehicles,'count'=>$count]; + + $logisticsShip = LogisticsShip::where(['id' => $id])->first(); + $logisticsShipHis = LogisticsShipHis::where(['ship_id'=> $id])->get(); + + $count = Vehicle::where(['ship_id' => $id])->count(); + $result = ['list' => $vehicles,'ship' => $logisticsShip,'ship_his' => $logisticsShipHis,'count'=>$count]; return Util::success($result); } diff --git a/app/model/LogisticsShip.php b/app/model/LogisticsShip.php new file mode 100644 index 0000000..21cdf54 --- /dev/null +++ b/app/model/LogisticsShip.php @@ -0,0 +1,41 @@ +belongsTo(Vehicle::class, 'ship_id', 'id'); + } + +} \ No newline at end of file diff --git a/app/model/LogisticsShipHis.php b/app/model/LogisticsShipHis.php new file mode 100644 index 0000000..cd46d94 --- /dev/null +++ b/app/model/LogisticsShipHis.php @@ -0,0 +1,41 @@ +belongsTo(Vehicle::class, 'ship_id', 'id'); + } + +} \ No newline at end of file diff --git a/app/model/Vehicle.php b/app/model/Vehicle.php index e4afff9..85bf4be 100644 --- a/app/model/Vehicle.php +++ b/app/model/Vehicle.php @@ -46,4 +46,10 @@ class Vehicle extends Model { return $this->belongsTo(Location::class, 'final_locations_id', 'id'); } + + + public function ship() + { + return $this->hasOne(Vehicle::class, 'ship_id', 'id'); + } } \ No newline at end of file diff --git a/app/service/ShipService.php b/app/service/ShipService.php new file mode 100644 index 0000000..3b5d8c9 --- /dev/null +++ b/app/service/ShipService.php @@ -0,0 +1,51 @@ + self::API_KEY, + 'mmsi' => $mmsi + ]; + + $response = HttpClient::get($url, $query); + + // 检查API响应状态 + if (!$response['status']) { + return [ + 'success' => false, + 'message' => '请求失败: ' . $response['message'], + 'data' => null + ]; + } + + // 检查API业务状态 + if (isset($response['data']['status']) && $response['data']['status'] !== 0) { + return [ + 'success' => false, + 'message' => '获取船舶信息失败: ' . ($response['data']['msg'] ?? '未知错误'), + 'data' => null + ]; + } + + return [ + 'success' => true, + 'message' => '获取成功', + 'data' => $response['data'] + ]; + } +} \ No newline at end of file diff --git a/app/util/HttpClient.php b/app/util/HttpClient.php new file mode 100644 index 0000000..55b0b86 --- /dev/null +++ b/app/util/HttpClient.php @@ -0,0 +1,227 @@ + 10, // 默认超时时间10秒 + 'verify' => false, // 不验证SSL证书(生产环境建议设为true) + 'http_errors' => false, // 不抛出HTTP异常,自己处理 + ]); + } + return self::$client; + } + + /** + * 发送GET请求 + * @param string $url 请求地址 + * @param array $query 查询参数 + * @param array $headers 请求头 + * @return array + */ + public static function get(string $url, array $query = [], array $headers = []): array + { + $options = [ + 'query' => $query, + 'headers' => $headers + ]; + return self::request('GET', $url, $options); + } + + /** + * 发送POST请求 + * @param string $url 请求地址 + * @param array|string $data 请求数据 + * @param array $headers 请求头 + * @param string $contentType 内容类型(form/json/xml) + * @return array + */ + public static function post(string $url, $data = [], array $headers = [], string $contentType = 'form'): array + { + $options = ['headers' => $headers]; + + switch ($contentType) { + case 'json': + $options['json'] = $data; + $options['headers']['Content-Type'] = 'application/json'; + break; + /*case 'xml': + $options['body'] = is_array($data) ? self::arrayToXml($data) : $data; + $options['headers']['Content-Type'] = 'application/xml'; + break;*/ + default: // form + $options['form_params'] = $data; + $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + return self::request('POST', $url, $options); + } + + /** + * 发送PUT请求 + * @param string $url 请求地址 + * @param array|string $data 请求数据 + * @param array $headers 请求头 + * @return array + */ + public static function put(string $url, $data = [], array $headers = []): array + { + $options = [ + 'json' => $data, + 'headers' => $headers + ]; + return self::request('PUT', $url, $options); + } + + /** + * 发送DELETE请求 + * @param string $url 请求地址 + * @param array $data 请求数据 + * @param array $headers 请求头 + * @return array + */ + public static function delete(string $url, array $data = [], array $headers = []): array + { + $options = [ + 'json' => $data, + 'headers' => $headers + ]; + return self::request('DELETE', $url, $options); + } + + /** + * 发送HTTP请求 + * @param string $method 请求方法 + * @param string $url 请求地址 + * @param array $options 请求选项 + * @return array + */ + public static function request(string $method, string $url, array $options = []): array + { + try { + $response = self::getClient()->request($method, $url, $options); + return self::formatResponse($response); + } catch (GuzzleException $e) { + return [ + 'status' => false, + 'code' => $e->getCode(), + 'message' => $e->getMessage(), + 'data' => null + ]; + } + } + + /** + * 上传文件 + * @param string $url 请求地址 + * @param array $files 文件数组 [['name' => 'field_name', 'path' => 'file_path']] + * @param array $form 其他表单数据 + * @param array $headers 请求头 + * @return array + */ + public static function upload(string $url, array $files, array $form = [], array $headers = []): array + { + $multipart = []; + + // 添加文件 + foreach ($files as $file) { + if (file_exists($file['path'])) { + $multipart[] = [ + 'name' => $file['name'], + 'contents' => fopen($file['path'], 'r'), + 'filename' => basename($file['path']) + ]; + } + } + + // 添加其他表单数据 + foreach ($form as $name => $value) { + $multipart[] = [ + 'name' => $name, + 'contents' => $value + ]; + } + + $options = [ + 'multipart' => $multipart, + 'headers' => $headers + ]; + + return self::request('POST', $url, $options); + } + + /** + * 格式化响应 + * @param ResponseInterface $response + * @return array + */ + private static function formatResponse(ResponseInterface $response): array + { + $contents = $response->getBody()->getContents(); + $contentType = $response->getHeaderLine('Content-Type'); + + $data = $contents; + if (strpos($contentType, 'application/json') !== false) { + $data = json_decode($contents, true) ?? $contents; + } + + return [ + 'status' => $response->getStatusCode() === 200, + 'code' => $response->getStatusCode(), + 'message' => $response->getReasonPhrase(), + 'data' => $data, + 'headers' => $response->getHeaders() + ]; + } + + /** + * 数组转XML + * @param array $data + * @param string $rootNode + * @return string + */ + private static function arrayToXml(array $data, string $rootNode = 'root'): string + { + $xml = new \SimpleXMLElement('<' . $rootNode . '/>'); + self::addDataToXml($xml, $data); + return $xml->asXML(); + } + + /** + * 递归添加数据到XML + * @param \SimpleXMLElement $xml + * @param array $data + */ + private static function addDataToXml(\SimpleXMLElement $xml, array $data) + { + foreach ($data as $key => $value) { + if (is_array($value)) { + if (is_numeric($key)) { + $key = 'item'; + } + $subNode = $xml->addChild($key); + self::addDataToXml($subNode, $value); + } else { + $xml->addChild($key, htmlspecialchars($value)); + } + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 300a1f6..b19778f 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "workerman/crontab": "^1.0", "webman/redis": "dev-main", "illuminate/events": "^12.14", - "webman/redis-queue": "^1.3" + "webman/redis-queue": "^1.3", + "guzzlehttp/guzzle": "^7.9" }, "suggest": { "ext-event": "For better performance. " diff --git a/composer.lock b/composer.lock index 9489f02..152a9f0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5890526c12c278e535143c406c9f1b88", + "content-hash": "6cd3f9d702599d003e58cc41b6635fac", "packages": [ { "name": "aliyuncs/oss-sdk-php", @@ -418,17 +418,23 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.9.3", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", - "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", - "shasum": "" + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-json": "*", @@ -524,7 +530,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.9.3" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -540,7 +546,7 @@ "type": "tidelift" } ], - "time": "2025-03-27T13:37:11+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises",