From eee09316df09a01bd9dcba4dddaf190fc22ba7e2 Mon Sep 17 00:00:00 2001 From: "WIN-C27C5MSVTPO\\16961" <1696136552@qq.com> Date: Wed, 4 Feb 2026 17:35:08 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8A=93=E5=8F=96=E8=BD=A6=E5=9E=8B?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/service/BrandSeriesService.php | 111 +++++++++++++++++- app/admin/service/BrandService.php | 33 ++++++ .../controller/BrandSeriesController.php | 36 ++++++ config/route.php | 2 + 4 files changed, 177 insertions(+), 5 deletions(-) diff --git a/app/admin/service/BrandSeriesService.php b/app/admin/service/BrandSeriesService.php index 4ef0db0..1dc7a73 100644 --- a/app/admin/service/BrandSeriesService.php +++ b/app/admin/service/BrandSeriesService.php @@ -398,21 +398,39 @@ class BrandSeriesService */ public function crawlKeywordCreate(Request $request) { - $series_id = $request->input('series_id'); $brand_id = $request->input('brand_id'); + $brand_name = $request->input('brand_name'); + $brand_code = $request->input('brand_code'); + $series_id = $request->input('series_id'); $series_name = $request->input('series_name'); $models = $request->input('models'); - if(empty($brand_id)){ + if(empty($brand_id) && (empty($brand_name) || empty($brand_code))){ throw new \Exception("请选择品牌"); } if(empty($series_id) && empty($series_name)){ throw new \Exception("请选择车系"); } + // 获取品牌信息 + if (empty($brand_id)) { + $brand = Brand::where('id', $brand_id)->where('brand_name', $brand_name)->first(); + if (empty($brand)) { //如果没有该车系则创建 + $brandService = new \app\admin\service\BrandService(); + $brandData = [ + 'brand_code' => $brandService->generateUniqueCode(), + 'brand_name' => $brand_name, + ]; + $brand = CrudUtil::create(Brand::class, $brandData); + } + $brand_id = $brand->id; + }else{ + $brand = Brand::where('id', $brand_id)->first(); + } + if (empty($series_id)) { $series = BrandSeries::where('brand_id', $brand_id)->where('series_name', $series_name)->first(); - if (empty($brandseries)) { //如果没有该车系则创建 + if (empty($series)) { //如果没有该车系则创建 $seriesService = new \app\admin\service\BrandSeriesService(); $seriesData = [ 'brand_id' => $brand_id, @@ -425,8 +443,6 @@ class BrandSeriesService }else{ $series = BrandSeries::where('id', $series_id)->first(); } - // 获取品牌信息 - $brand = Brand::where('id', $series->brand_id)->first(); // 保存车型数据 $createdCount = 0; @@ -481,6 +497,91 @@ class BrandSeriesService return $msg; } + /** + * 抓取 + */ + public function crawl(Request $request): array + { + $keyword = $request->get('keyword'); + if(filter_var($keyword, FILTER_VALIDATE_URL)){ + return $this->crawlUrl($request); + }else{ + return $this->crawlKeyword($request); + } + } + + /** + * 抓取车型数据(通过接口) + * @param Request $request + * @return array + * @throws \Exception + */ + public function crawlUrl(Request $request): array + { + //$url = $request->get('url'); + $url = $request->get('keyword'); + + // 执行抓取 + $crawlService = new CrawlService(); + + //懂车帝提取车系id + $seriesId = $this->get_series_from_url($url); //懂车帝车系id + + if (empty($seriesId)) { + throw new \Exception('抓取失败,未找到该系列车型'); + } + + $brandSerieses = []; + //抓取品牌与系列 + $brandSeries = $crawlService->crawlBrandSeries($seriesId); + $brandSerieses[] = ['brand' => $brandSeries['brand'], 'series' => $brandSeries['series']]; + + $result = []; + try { + foreach ($brandSerieses as $brandSeries) { + $item = []; + // 验证品牌是否存在 + $brand = Brand::where('brand_name', $brandSeries['brand'])->first(); + // 获取品牌信息 + $series = BrandSeries::where('series_name', $brandSeries['series'])->first(); + $item['brand'] = ['brand_name' => $brandSeries['brand'], 'exists' => $brand ? 1 : 0]; + if ($brand) { + $item['brand']['id'] = $brand['id']; + } + $item['series'] = ['series_name' => $brandSeries['series'], 'exists' => $series ? 1 : 0]; + if ($series) { + $item['series']['id'] = $series['id']; + if (empty($item['brand']['id'])) { + $item['brand']['id'] = $series['brand_id']; + } + } + + //获取车型数据 + $item['model'] = []; + if (count($brandSerieses)<2) { + $item['model'] = $this->crawlSeriesModel($seriesId); + } + $result[] = $item; + } + + return ['is_series' => (count($brandSerieses)<2)?1:0, 'data' => $result]; + } catch (\Exception $e) { + throw new \Exception($e->getMessage()); + } + } + + public function get_series_from_url($url) { + // 使用正则表达式匹配 "https://www.dongchedi.com/auto/series/{数字}" + $pattern = '/^https:\/\/www\.dongchedi\.com\/auto\/series\/(\d+)$/'; + if (preg_match($pattern, $url, $matches)) { + // 提取数字部分作为 series ID + $series_id = $matches[1]; + return $series_id; // 返回系列ID + } else { + throw new \Exception("URL格式不匹配"); + } + } + /** * 获取车系下车型数据 * @return array diff --git a/app/admin/service/BrandService.php b/app/admin/service/BrandService.php index c7775b8..fc67ecb 100644 --- a/app/admin/service/BrandService.php +++ b/app/admin/service/BrandService.php @@ -151,4 +151,37 @@ class BrandService $msg .= (!empty($fail))?',失败' . $fail . '条':''; return $msg; } + + /** + * 生成唯一的7位颜色编码 + * 格式:C + (O/I) + 5位字母数字组合 + * + * @param int $type 类型 + * @return string 7位唯一编码 + */ + public function generateUniqueCode() + { + $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $maxAttempts = 10; // 防止无限循环 + + for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { + // 生成后5位随机字符 + $suffix = ''; + for ($i = 0; $i < 8; $i++) { + $suffix .= $chars[rand(0, strlen($chars) - 1)]; + } + + $code = $suffix; + + // 检查是否已存在 + $existing = Brand::where('brand_code', $code)->first(); + if (!$existing) { + return $code; + } + } + + // 如果1000次尝试后仍然重复,使用时间戳确保唯一性 + $timestamp = substr(time(), -6); + return $suffix . $timestamp; + } } \ No newline at end of file diff --git a/app/common/controller/BrandSeriesController.php b/app/common/controller/BrandSeriesController.php index 3cd32d3..75d583a 100644 --- a/app/common/controller/BrandSeriesController.php +++ b/app/common/controller/BrandSeriesController.php @@ -101,6 +101,42 @@ class BrandSeriesController extends BaseController } } + /** + * URL抓取品牌、车系、车型 + * @param Request $request + * @return \support\Response + */ + public function crawlUrl(Request $request){ + try { + $result = $this->service->crawlUrl($request); + if($result){ + return $this->success($result,'抓取成功'); + }else{ + return $this->error('抓取任务失败'); + } + } catch (\Exception $e) { + return $this->error($e->getMessage()); + } + } + + /** + * 抓取品牌、车系、车型 + * @param Request $request + * @return \support\Response + */ + public function crawl(Request $request){ + try { + $result = $this->service->crawl($request); + if($result){ + return $this->success($result,'抓取成功'); + }else{ + return $this->error('抓取任务失败'); + } + } catch (\Exception $e) { + return $this->error($e->getMessage()); + } + } + /** * 保存抓取的系列车型 * @param Request $request diff --git a/config/route.php b/config/route.php index 8039634..9132489 100644 --- a/config/route.php +++ b/config/route.php @@ -116,6 +116,8 @@ Route::group('/common', function () { Route::any('/crawlModelCreate', [app\common\controller\BrandSeriesController::class, 'crawlModelCreate']); Route::any('/crawlKeyword', [app\common\controller\BrandSeriesController::class, 'crawlKeyword']); Route::any('/crawlKeywordCreate', [app\common\controller\BrandSeriesController::class, 'crawlKeywordCreate']); + Route::any('/crawlUrl', [app\common\controller\BrandSeriesController::class, 'crawlUrl']); + Route::any('/crawl', [app\common\controller\BrandSeriesController::class, 'crawl']); }); }); From 30f3e211af2bb67d447ba3f0b86a0ab86e0c5951 Mon Sep 17 00:00:00 2001 From: "WIN-C27C5MSVTPO\\16961" <1696136552@qq.com> Date: Thu, 5 Feb 2026 09:16:24 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8A=93=E5=8F=96=E5=93=81=E7=89=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/service/BrandSeriesService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin/service/BrandSeriesService.php b/app/admin/service/BrandSeriesService.php index 1dc7a73..495db73 100644 --- a/app/admin/service/BrandSeriesService.php +++ b/app/admin/service/BrandSeriesService.php @@ -405,7 +405,7 @@ class BrandSeriesService $series_name = $request->input('series_name'); $models = $request->input('models'); - if(empty($brand_id) && (empty($brand_name) || empty($brand_code))){ + if(empty($brand_id) && empty($brand_name)){ throw new \Exception("请选择品牌"); } if(empty($series_id) && empty($series_name)){