diff --git a/app/command/UpdateShipInfoCommand.php b/app/command/UpdateShipInfoCommand.php new file mode 100644 index 0000000..c04cc41 --- /dev/null +++ b/app/command/UpdateShipInfoCommand.php @@ -0,0 +1,145 @@ +writeln('开始更新船舶信息...'); + + try { + // 查询需要更新的船舶 + // 如果logistics_ship表有status字段,查询status为2的船舶 + // 如果没有status字段,可以查询所有船舶或者根据其他条件筛选 + $ships = $this->getShipsToUpdate(); + + if ($ships->isEmpty()) { + $output->writeln('没有找到需要更新的船舶'); + return self::SUCCESS; + } + + $output->writeln("找到 {$ships->count()} 艘需要更新的船舶"); + + $successCount = 0; + $errorCount = 0; + + foreach ($ships as $ship) { + try { + $output->write("正在更新船舶 {$ship->mmsi} (ID: {$ship->id})... "); + + // 获取船舶MMSI号,这里假设使用IMO作为MMSI + $mmsi = $ship->mmsi; + + // 通过ShipService获取船舶最新信息 + $shipInfo = ShipService::getShipInfo($mmsi); + + if (!$shipInfo['success']) { + $output->writeln("失败: " . $shipInfo['message']); + $errorCount++; + continue; + } + + $apiData = $shipInfo['data']['data'] ?? null; + if (!$apiData) { + $output->writeln("失败: API返回数据为空"); + $errorCount++; + continue; + } + + // 保存当前船舶信息到历史表 + $this->saveToHistory($ship); + + // 更新船舶信息 + $updateData = $this->mapApiDataToShip($apiData); + $ship->fill($updateData); + $ship->save(); + + $output->writeln("成功"); + $successCount++; + + // 添加延迟避免API请求过于频繁 + sleep(1); + + } catch (\Exception $e) { + $output->writeln("失败: " . $e->getMessage()); + $errorCount++; + Log::error("更新船舶信息失败", [ + 'ship_id' => $ship->id, + 'imo' => $ship->IMO, + 'error' => $e->getMessage() + ]); + } + } + + $output->writeln("更新完成!成功: {$successCount}, 失败: {$errorCount}"); + + } catch (\Exception $e) { + $output->writeln("执行失败: " . $e->getMessage()); + Log::error("船舶信息更新任务执行失败", [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString() + ]); + return self::FAILURE; + } + + return self::SUCCESS; + } + + /** + * 获取需要更新的船舶列表 + * @return \Illuminate\Database\Eloquent\Collection + */ + private function getShipsToUpdate() + { + return LogisticsShip::where('status', 1)->get(); + } + + /** + * 保存船舶信息到历史表 + * @param LogisticsShip $ship + */ + private function saveToHistory(LogisticsShip $ship): void + { + $historyData = $ship->toArray(); + $historyData['ship_id'] = $ship->id; + unset($historyData['id']); // 移除主键,让数据库自动生成 + + LogisticsShipHis::create($historyData); + } + + /** + * 将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'] ?? '', + 'wail' => $apiData['call_sign'] ?? '', + '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, + 'updated_at' => date('Y-m-d H:i:s') + ]; + } +} \ No newline at end of file diff --git a/app/controller/VehicleController.php b/app/controller/VehicleController.php index e43fceb..a00a591 100644 --- a/app/controller/VehicleController.php +++ b/app/controller/VehicleController.php @@ -2,6 +2,7 @@ namespace app\controller; +use app\command\UpdateShipInfoCommand; use app\model\LogisticsShip; use app\model\LogisticsShipHis; use app\model\Vehicle; @@ -18,6 +19,9 @@ 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; @@ -253,6 +257,64 @@ class VehicleController return Util::success($result); } + 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, + 'updated_at' => date('Y-m-d H:i:s') + ]; + } + /** * Get a specific vehicle with its location */ diff --git a/app/process/ShipUpdateScheduler.php b/app/process/ShipUpdateScheduler.php new file mode 100644 index 0000000..b2ff906 --- /dev/null +++ b/app/process/ShipUpdateScheduler.php @@ -0,0 +1,59 @@ +runShipUpdateCommand(); + }); + // 每三天执行一次船舶信息更新 + // 3天 = 3 * 24 * 60 * 60 = 259200秒 +// Timer::add(259200, function() { +// $this->runShipUpdateCommand(); +// }); +// +// // 启动时也执行一次,确保有数据 +// $this->runShipUpdateCommand(); +// +// Log::info('船舶信息更新调度器已启动'); + } + + /** + * 执行船舶信息更新命令 + */ + private function runShipUpdateCommand() + { + try { + Log::info('开始执行船舶信息更新任务'); + + $command = new UpdateShipInfoCommand(); + $input = new ArrayInput([]); + $output = new BufferedOutput(); + + $exitCode = $command->run($input, $output); + + if ($exitCode === 0) { + Log::info('船舶信息更新任务执行成功: ' . $output->fetch()); + } else { + Log::error('船舶信息更新任务执行失败: ' . $output->fetch()); + } + + } catch (\Exception $e) { + Log::error('船舶信息更新任务执行异常', [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString() + ]); + } + } +} \ No newline at end of file diff --git a/config/process.php b/config/process.php index 1ee6a38..d007100 100644 --- a/config/process.php +++ b/config/process.php @@ -58,5 +58,11 @@ return [ 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/', ] ] + ], + // 船舶信息更新定时任务 + 'ship-update-scheduler' => [ + 'handler' => app\process\ShipUpdateScheduler::class, + 'reloadable' => false, + 'constructor' => [] ] ]; diff --git a/plugin/admin/app/controller/LocationController.php b/plugin/admin/app/controller/LocationController.php index 4b4af34..9fc234a 100644 --- a/plugin/admin/app/controller/LocationController.php +++ b/plugin/admin/app/controller/LocationController.php @@ -196,6 +196,15 @@ class LocationController extends Crud $translatorService = new \app\service\TranslatorService(); foreach ($languages as $lang) { + $locationModel = $translationModels[$lang]; + if(!empty($data['id'])){ + $location = $locationModel::find($data['id']); + }else{ + $location = $locationModel; + } + unset($data['name']); + $location->fill($data); + $location->save(); $translatorService->queue($data,$sourceLang,'location',$data['id']?:null,$lang); } } diff --git a/plugin/admin/app/controller/LogisticsShipController.php b/plugin/admin/app/controller/LogisticsShipController.php new file mode 100644 index 0000000..80e000f --- /dev/null +++ b/plugin/admin/app/controller/LogisticsShipController.php @@ -0,0 +1,68 @@ +model = new LogisticsShip; + } + + /** + * 浏览 + * @return Response + */ + public function index(): Response + { + return view('logistics-ship/index'); + } + + /** + * 插入 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return view('logistics-ship/insert'); + } + + /** + * 更新 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return view('logistics-ship/update'); + } + +} diff --git a/plugin/admin/app/model/LogisticsShip.php b/plugin/admin/app/model/LogisticsShip.php new file mode 100644 index 0000000..b6fe2e0 --- /dev/null +++ b/plugin/admin/app/model/LogisticsShip.php @@ -0,0 +1,45 @@ + + + + + 浏览页面 + + + + + + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + diff --git a/plugin/admin/app/view/logistics-ship/insert.html b/plugin/admin/app/view/logistics-ship/insert.html new file mode 100644 index 0000000..ddfdf7c --- /dev/null +++ b/plugin/admin/app/view/logistics-ship/insert.html @@ -0,0 +1,199 @@ + + + + + 新增页面 + + + + + + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + diff --git a/plugin/admin/app/view/logistics-ship/update.html b/plugin/admin/app/view/logistics-ship/update.html new file mode 100644 index 0000000..4411623 --- /dev/null +++ b/plugin/admin/app/view/logistics-ship/update.html @@ -0,0 +1,263 @@ + + + + + 更新页面 + + + + + + + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + +