diff --git a/app/admin/service/BrandSeriesService.php b/app/admin/service/BrandSeriesService.php index bc9d11b..2e7f04c 100644 --- a/app/admin/service/BrandSeriesService.php +++ b/app/admin/service/BrandSeriesService.php @@ -3,10 +3,20 @@ namespace app\admin\service; use app\admin\validate\BrandSeriesValidate; +use app\common\logic\Fingerprint; +use app\common\logic\ModelNaming; +use app\common\logic\SkuCodeBuilder; use app\common\model\Brand; +use app\common\model\VehVehicleSku; +use app\common\service\CrawlService; +use app\common\service\VehVehicleSkuService; use app\common\traits\crud\CrudServiceTrait; use app\common\model\BrandSeries; +use app\common\utils\CrudUtil; +use GuzzleHttp\Client; +use support\Log; use support\Request; +use Webman\RedisQueue\Redis; class BrandSeriesService { @@ -28,7 +38,7 @@ class BrandSeriesService */ public function getValidator() { - return new $this->validator; + return new $this->validator; } /** @@ -50,13 +60,13 @@ class BrandSeriesService // ====== ====== 筛选 ====== ====== $config['where']['brand_id'] = $p['brand_id']; // 状态 - if (isset($p['status']) && in_array($p['status'], [0,1])) { + if (isset($p['status']) && in_array($p['status'], [0, 1])) { $config['where']['status'] = $p['status']; } // 关键字 if (isset($p['keyword']) && $p['keyword']) { $k = '%' . $p['keyword'] . '%'; - foreach (['series_code','series_name'] as $col) { + foreach (['series_code', 'series_name'] as $col) { $config['orWhere'][] = [$col, 'like', $k]; } } @@ -92,7 +102,7 @@ class BrandSeriesService $maxAttempts = 10; // 防止无限循环 $brand_code = Brand::where('id', $brand_id)->value('brand_code'); - $brand_code = $brand_code??'BS'; + $brand_code = $brand_code ?? 'BS'; for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { // 生成后5位随机字符 $suffix = ''; @@ -123,4 +133,231 @@ class BrandSeriesService $data['series_code'] = $this->generateUniqueModificationCode($brand_id); return $data; } + + /** + * 抓取车型数据(通过接口) + * @param Request $request + * @return array + * @throws \Exception + */ + public function crawlModel(Request $request): array + { + $series_id = $request->get('brand_series_id'); + + // 验证品牌是否存在 + $series = BrandSeries::where('id', $series_id)->first(); + if (!$series) { + throw new \Exception("系列ID {$series_id} 不存在"); + } + + // 获取品牌信息 + $series = BrandSeries::where('id', $series_id)->first(); + if (!$series) { + throw new \Exception("系列ID {$series_id} 不存在"); + } + + // 获取品牌信息 + $brand = Brand::where('id', $series->brand_id)->first(); + + // 执行抓取 + $crawlService = new CrawlService(); + $href = $crawlService->modelSearch($brand->brand_name . ' ' . $series->series_name); + $seriesId = $this->extractSeriesId($href); + $client = new Client([ + 'verify' => false, // 禁用 SSL 验证 + 'timeout' => 10 + ]); + try { + $response = $client->get('https://www.dongchedi.com/motor/pc/car/series/car_list', [ + 'query' => ['series_id' => $seriesId], + 'headers' => [ + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + ] + ]); + $data = json_decode($response->getBody()->getContents(), true); + if($data['status'] != 0 || (!isset($data['data']) && !isset($data['data']['tab_list']))){ + Log::error('抓取车型数据失败' . $data['message'], $data); + throw new \Exception('抓取车型数据失败' . $data['message']); + } + $models = []; + foreach ($data['data']['tab_list'] as $item) { + if($item['tab_text'] == '在售' || $item['tab_text'] == '停售'){ + unset($item['data'][0]); + $models = array_merge($models, $item['data']); + } + } + foreach ($models as $key => $model) { + if(!isset($model["info"]['car_name']) || $model['type'] != "1115"){ + unset($models[$key]); + continue; + } + $official_price = 0; + if(!isset($model["info"]['official_price'])){ + $official_price = (int)(str_replace("万", "", $model["info"]['official_price_str']) * 10000) ?? 0; + }else{ + $official_price = $model["info"]['official_price'] * 10000; + } + $models[$key] = [ + 'title' => $model["info"]['year'] . '款 ' .$model["info"]['car_name'], + 'brand_name' => $model["info"]['brand_name'], + 'series_name' => $model["info"]['series_name'], + 'year' => $model["info"]['year'], + 'msrp' => $official_price, + 'car_id' => $model["info"]['id'], + ]; + } + return array_values($models); + } catch (\Exception $e) { + throw new \Exception($e->getMessage()); + } + + +// return $models; + } + + /** + * 从懂车帝URL中提取series ID + * @param string $url 完整的URL + * @return string|null series ID或null + */ + function extractSeriesId($url) { + // 解析URL获取路径部分 + $path = parse_url($url, PHP_URL_PATH); + + if (!$path) { + return null; + } + + // 按斜杠分割路径 + $pathParts = explode('/', trim($path, '/')); + + // 查找 'series' 的位置,下一个元素就是series ID + $seriesIndex = array_search('series', $pathParts); + + if ($seriesIndex !== false && isset($pathParts[$seriesIndex + 1])) { + return $pathParts[$seriesIndex + 1]; + } + + return null; + } + + /** + * 抓取车型数据(通过页面抓取) + * @param Request $request + * @return array + * @throws \Exception + */ + /*public function crawlModel(Request $request) + { + $series_id = $request->get('brand_series_id'); + + // 验证品牌是否存在 + $series = BrandSeries::where('id', $series_id)->first(); + if (!$series) { + throw new \Exception("系列ID {$series_id} 不存在"); + } + + // 获取品牌信息 + $series = BrandSeries::where('id', $series_id)->first(); + if (!$series) { + throw new \Exception("系列ID {$series_id} 不存在"); + } + + // 获取品牌信息 + $brand = Brand::where('id', $series->brand_id)->first(); + + // 执行抓取 + $crawlService = new CrawlService(); + $models = $crawlService->seriesModel($brand->brand_name . ' ' . $series->series_name); + + foreach ($models as $key => $model) { + $models[$key]['year'] = $this->extractYearFromCarModel($model['title']); + } + + return $models; + }*/ + + /** + * @param Request $request + * @return array|string + * @throws \Exception + */ + public function crawlModelCreate(Request $request) + { + $series_id = $request->input('series_id'); +// $brand_id = $request->input('brand_id'); + $models = $request->input('models'); + + // 验证系列是否存在 + $series = BrandSeries::where('id', $series_id)->first(); + if (!$series) { + throw new \Exception("系列ID {$series_id} 不存在"); + } + // 获取品牌信息 + $brand = Brand::where('id', $series->brand_id)->first(); + + // 保存车型数据 + $createdCount = 0; + $repeat = 0; + $fail = 0; + $msg = ''; + + foreach ($models as $item) { + $modelData = [ + 'brand_code' => $brand->brand_code, + 'brand_name' => $brand->brand_name, + 'series_code' => $series->series_code, + 'series_name' => $series->series_name, + 'model_name' => $item['title'], + 'model_year' => $item['year'], + 'msrp' => $item['msrp'], + ]; + $modelData['model_code'] = ModelNaming::buildModelCode($modelData); + $modelData['sku_code'] = SkuCodeBuilder::build($modelData); + // 指纹 + $modelData['fingerprint'] = Fingerprint::makeFromArray($modelData); + + try { + $model = VehVehicleSku::where('brand_name', $brand->brand_name)->where('series_name', $series->series_name)->where('model_name', $item['title'])->first(); + if (!empty($model)) { + $repeat++; + continue; + } + CrudUtil::create(VehVehicleSku::class, $modelData); + $createdCount++; + } catch (\Exception $e) { + // 记录错误但继续处理其他车型 + $msg .= "创建车型失败: " . $e->getMessage() . "\n"; + Log::error("创建车型失败:" . $msg, ['series_id' => $series_id, 'model' => $item]); + $fail++; + } + } + + Log::info('series-crawl-' . $series_id . ' ' . $msg); + $msg = '创建车型成功' . $createdCount . '条'; + $msg .= (!empty($repeat)) ? ',重复' . $repeat . '条' : ''; + $msg .= (!empty($fail)) ? ',失败' . $fail . '条' : ''; + return $msg; + } + + + /** + * 从车型名中提取年份 + * @param string $carModel 车型名称 + * @return string|null 提取到的年份或null + */ + function extractYearFromCarModel($carModel) + { + // 匹配4位数字 + "款" 的模式 + if (preg_match('/(\d{4})款/', $carModel, $matches)) { + return $matches[1]; + } + + // 匹配4位数字 + 空格或结尾的模式 + if (preg_match('/^(\d{4})(?=\s|$)/', $carModel, $matches)) { + return $matches[1]; + } + + return null; + } } \ No newline at end of file diff --git a/app/admin/service/BrandService.php b/app/admin/service/BrandService.php index 61e1e65..c7775b8 100644 --- a/app/admin/service/BrandService.php +++ b/app/admin/service/BrandService.php @@ -3,9 +3,14 @@ namespace app\admin\service; use app\admin\validate\BrandValidate; +use app\common\model\BrandSeries; +use app\common\service\CrawlService; use app\common\traits\crud\CrudServiceTrait; use app\common\model\Brand; +use app\common\utils\CrudUtil; +use support\Log; use support\Request; +use Webman\RedisQueue\Redis; class BrandService { @@ -27,7 +32,7 @@ class BrandService */ public function getValidator() { - return new $this->validator; + return new $this->validator; } /** @@ -49,13 +54,13 @@ class BrandService // ====== ====== 筛选 ====== ====== // 状态 - if (isset($p['status']) && in_array($p['status'], [0,1])) { + if (isset($p['status']) && in_array($p['status'], [0, 1])) { $config['where']['status'] = $p['status']; } // 关键字 if (isset($p['keyword']) && $p['keyword']) { $k = '%' . $p['keyword'] . '%'; - foreach (['brand_code','brand_name'] as $col) { + foreach (['brand_code', 'brand_name'] as $col) { $config['orWhere'][] = [$col, 'like', $k]; } } @@ -77,4 +82,73 @@ class BrandService return $config; } + + public function crawlSeries(Request $request) + { + $brand_id = $request->get('brand_id'); + + // 验证品牌是否存在 + $brand = Brand::where('id', $brand_id)->first(); + if (!$brand) { + throw new \Exception("品牌ID {$brand_id} 不存在"); + } + + // 获取品牌信息 + try { + // 执行抓取 + $crawlService = new CrawlService(); + $series = $crawlService->brandSeries($brand->brand_name); + + if (empty($series)) { + throw new \Exception("未抓取到品牌 {$brand->brand_name} 的系列数据"); + } + + return ['series' => $series]; + + } catch (\Throwable $th) { + Log::error($th); + throw $th; + } + } + + public function crawlSeriesCreate(Request $request) + { + $brand_id = $request->input('brand_id'); + $series = $request->input('series'); + + // 保存系列数据 + $seriesService = new \app\admin\service\BrandSeriesService(); + $createdCount = 0; + $repeat = 0; + $fail = 0; + $msg = ''; + + foreach ($series as $item) { + $seriesData = [ + 'brand_id' => $brand_id, + 'series_code' => $seriesService->generateUniqueModificationCode($brand_id), + 'series_name' => $item, + ]; + + try { + $brandseries = BrandSeries::where('brand_id', $brand_id)->where('series_name', $item)->first(); + if (!empty($brandseries)) { + $repeat++; + continue; + } + CrudUtil::create(BrandSeries::class, $seriesData); + $createdCount++; + + } catch (\Exception $e) { + // 记录错误但继续处理其他系列 + $msg .= "创建系列失败: " . $e->getMessage() . "\n"; + $fail++; + } + } + Log::info('brand-crawl-' . $brand_id . ' ' . $msg); + $msg = '创建系列成功' . $createdCount . '条'; + $msg .= (!empty($repeat))?',重复' . $repeat . '条':''; + $msg .= (!empty($fail))?',失败' . $fail . '条':''; + return $msg; + } } \ No newline at end of file diff --git a/app/common/controller/BrandController.php b/app/common/controller/BrandController.php new file mode 100644 index 0000000..2abe3cb --- /dev/null +++ b/app/common/controller/BrandController.php @@ -0,0 +1,90 @@ +service = new BrandService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + if (!empty($data['logo'])) + $data['logo_full'] = (new OssService)->generatePrivateUrl($data['logo']); + return $data; + } + + /** + * 数据格式化 + * + * @param array $data + * @return array + */ + protected function showFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + if (empty($data['logo'])) + $data['logo_full'] = (new OssService)->generatePrivateUrl($data['logo']); + return $data; + } + + /** + * 抓取品牌系列 + * @param Request $request + * @return \support\Response + */ + public function crawlSeries(Request $request){ + try { + $result = $this->service->crawlSeries($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 crawlSeriesCreate(Request $request){ + try { + $result = $this->service->crawlSeriesCreate($request); + if($result){ + return $this->success([],$result); + }else{ + return $this->error('创建失败'); + } + } catch (\Exception $e) { + return $this->error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/common/controller/BrandSeriesController.php b/app/common/controller/BrandSeriesController.php new file mode 100644 index 0000000..00faa00 --- /dev/null +++ b/app/common/controller/BrandSeriesController.php @@ -0,0 +1,85 @@ +service = new BrandSeriesService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + return $data; + } + + /** + * 数据格式化 + * + * @param array $data + * @return array + */ + protected function showFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + return $data; + } + + /** + * 异步抓取系列车型 + * @param Request $request + * @return \support\Response + */ + public function crawlModels(Request $request){ + try { + $result = $this->service->crawlModel($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 crawlModelCreate(Request $request){ + try { + $result = $this->service->crawlModelCreate($request); + if($result){ + return $this->success($result,'成功'); + }else{ + return $this->error('创建失败'); + } + } catch (\Exception $e) { + return $this->error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/common/controller/SysPortController.php b/app/common/controller/SysPortController.php new file mode 100644 index 0000000..a5cc59d --- /dev/null +++ b/app/common/controller/SysPortController.php @@ -0,0 +1,53 @@ +service = new SysPortService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + if (isset($data['country_id'])) + if (isset($data['country_id'])) + $data['country_name'] = Country::where('id', $data['country_id'])->value('cn_addr'); + return $data; + } + + /** + * 数据格式化 + * + * @param array $data + * @return array + */ + protected function showFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + $data['country_name'] = Country::where('id', $data['country_id'])->value('cn_addr'); + return $data; + } +} \ No newline at end of file diff --git a/app/common/controller/UploadController.php b/app/common/controller/UploadController.php index 678034b..d90c84a 100644 --- a/app/common/controller/UploadController.php +++ b/app/common/controller/UploadController.php @@ -170,6 +170,8 @@ class UploadController 'original_name' => $file->getUploadName(), ]; + $partition = !empty($partition)?$partition:'other'; + $category = !empty($category)?$category:'other'; $recordResult = $uploadedFilesService->recordFileInfo($fileInfo, $request, $partition, $category); $data = []; $data['file_id'] = $recordResult['id']; diff --git a/app/common/controller/VehVehicleSkuController.php b/app/common/controller/VehVehicleSkuController.php index 3272f28..a3661da 100644 --- a/app/common/controller/VehVehicleSkuController.php +++ b/app/common/controller/VehVehicleSkuController.php @@ -2,6 +2,8 @@ namespace app\common\controller; use app\common\controller\BaseController; +use app\common\model\BrandSeries; +use app\common\service\VehModificationService; use app\common\traits\crud\CrudControllerTrait; use app\common\service\VehVehicleSkuService; use support\exception\BusinessException; @@ -89,6 +91,22 @@ class VehVehicleSkuController extends BaseController } } + public function preset(Request $request){ + + + try { + $series_id = $request->input('series_id'); + $series_code = BrandSeries::where('id', $series_id)->value('series_code'); + $data = [ + 'series_code' => $series_code, + ]; + $result = $this->service->getList($data); + return $this->success($result, '获取车型列表'); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + public function fields_desc(Request $request) { diff --git a/app/common/logic/VehVehicleSkuLogic.php b/app/common/logic/VehVehicleSkuLogic.php index 505efde..43f7172 100644 --- a/app/common/logic/VehVehicleSkuLogic.php +++ b/app/common/logic/VehVehicleSkuLogic.php @@ -52,4 +52,9 @@ class VehVehicleSkuLogic $plain = implode('|', $parts); return hash('sha256', $plain); } + + public function getList($data) + { + return VehVehicleSku::where($data)->orderBy('id','desc')->get(['id', 'sku_code', 'brand_code', 'brand_code', 'series_code', 'series_name', 'model_code', 'model_name', 'model_year', 'msrp']); + } } \ No newline at end of file diff --git a/app/common/service/CrawlService.php b/app/common/service/CrawlService.php new file mode 100644 index 0000000..a2c69d4 --- /dev/null +++ b/app/common/service/CrawlService.php @@ -0,0 +1,76 @@ +find('div.card-name')->texts()->map(function($item) use(&$series) { + $series[] = $item; + }); + return $series; + } + + public function seriesModel($series) + { + $href = $this->modelSearch($series); + + //例如 $seriesUrl = "https://www.dongchedi.com/auto/series/4865?anchorId=carModels" + if (empty($href)) { + return []; + } + + $seriesUrl = (strpos($href, 'http') === 0) ? $href : ("https://www.dongchedi.com" . $href); + $ql = QueryList::get($seriesUrl); + + $nodes = $ql->find('div.tw-grid div.tw-relative div.tw-items-center>a'); + $texts = $nodes->texts()->all(); + $links = $nodes->attrs('href')->all(); + $nodes = $ql->find('div.tw-grid div.tw-text-color-gray-800'); + $price = $nodes->texts()->all(); + + $results = []; + foreach ($texts as $index => $text) { + $link = $links[$index] ?? ''; + if (!empty($link) && strpos($link, 'http') !== 0) { + $link = 'https://www.dongchedi.com' . $link; + } + $results[] = [ + 'title' => trim($text), + 'link' => $link, + 'msrp' => (int)(str_replace("万", "", $price[$index]) * 10000) ?? 0, + ]; + } + + return $results; + } + +// public function modelDesc(array $models) +// { +// +// } + + /** + * 返回车系地址 + * @param $series + * @return mixed|string + */ + public function modelSearch($series) + { + $url = "https://www.dongchedi.com/search?keyword=".$series; + $ql = QueryList::get($url ); + $href = ''; + $ql->find('a.fold-btn')->attrs('href') + ->map(function ($item) use(&$href) { + $href = $item; + }); + return $href; + } +} \ No newline at end of file diff --git a/app/common/service/VehVehicleSkuService.php b/app/common/service/VehVehicleSkuService.php index e494122..a81adce 100644 --- a/app/common/service/VehVehicleSkuService.php +++ b/app/common/service/VehVehicleSkuService.php @@ -5,6 +5,9 @@ namespace app\common\service; use app\common\logic\Fingerprint; use app\common\logic\ModelNaming; use app\common\logic\SkuCodeBuilder; +use app\common\logic\VehVehicleSkuLogic; +use app\common\model\Brand; +use app\common\model\BrandSeries; use app\common\validate\VehVehicleSkuValidate; use app\common\traits\crud\CrudServiceTrait; use app\common\model\VehVehicleSku; @@ -25,6 +28,13 @@ class VehVehicleSkuService */ protected $validator = VehVehicleSkuValidate::class; + protected $logic; + + public function __construct() + { + $this->logic = (new VehVehicleSkuLogic()); + } + /** * 获取验证器 */ @@ -111,6 +121,15 @@ class VehVehicleSkuService $config['orWhere'][] = [$col, 'like', $k]; } } + + if(isset($p['brand_id']) && $p['brand_id']){ + $brand_code = Brand::where('id', $p['brand_id'])->value('brand_code'); + $config['where']['brand_code'] = $brand_code; + } + if(isset($p['series_id']) && $p['series_id']){ + $series_code = BrandSeries::where('id', $p['series_id'])->value('series_code'); + $config['where']['series_code'] = $series_code; + } break; case 'show': $config['where']['id'] = $p['id']; @@ -138,6 +157,33 @@ class VehVehicleSkuService if (empty($data['model_name'])) { $data['model_name'] = ModelNaming::buildModelName($data); } + if (empty($data['engine_disp_l'])) { + $data['engine_disp_l'] = 0; + } + if (empty($data['engine_turbo'])) { + $data['engine_turbo'] = 0; + } + if (empty($data['engine_power_kw'])) { + $data['engine_power_kw'] = 0; + } + if (empty($data['battery_kwh'])) { + $data['battery_kwh'] = 0; + } + if (empty($data['gears'])) { + $data['gears'] = 1; + } + if (empty($data['range_km'])) { //续航 + $data['range_km'] = 0; + } + if (empty($data['doors'])) { //车位数 + $data['doors'] = 0; + } + if (empty($data['seats'])) { //座位数 + $data['seats'] = 0; + } + if (empty($data['weight_kg'])) { //整车质量 + $data['weight_kg'] = 0; + } $data['sku_code'] = SkuCodeBuilder::build($data); $data['corp_id'] = 0; $data['created_by'] = $request->user->uid; @@ -177,4 +223,12 @@ class VehVehicleSkuService return $res; } + + /** + * 获取车型list + */ + public function getList($data) + { + return $this->logic->getList($data); + } } \ No newline at end of file diff --git a/app/crm/controller/CustomerController.php b/app/crm/controller/CustomerController.php index e10222c..25b186e 100644 --- a/app/crm/controller/CustomerController.php +++ b/app/crm/controller/CustomerController.php @@ -15,6 +15,7 @@ use app\crm\service\CustomerService; use app\crm\utils\Util; use config\constants\Constants; use support\Db; +use support\Log; use support\Request; class CustomerController extends BaseController @@ -358,6 +359,7 @@ class CustomerController extends BaseController ]; $dis = (new CustomerService())->distinct($distinct,$corpId); if($dis){ + Log::info('客户线索重复-'.$corpId,['user_id'=>$data['user_id'],'distinct'=>$distinct]); return $this->success($dis,'客户线索重复,已经业务跟进','distinct'); } $res = Customer::create($data); diff --git a/app/process/CheckWeb.php b/app/process/CheckWeb.php index c71a625..8baf5b8 100644 --- a/app/process/CheckWeb.php +++ b/app/process/CheckWeb.php @@ -11,7 +11,11 @@ class CheckWeb { if (getenv('ENVIRONMENT') === 'master') { new Crontab('0 */10 * * * *', function(){ - $this->check(); + $result = $this->tocurl('https://magicbridgeauto.com'); + if (!preg_match('/magicbridgeauto/', $result['body'])) { + flg("【magicbridgeauto】疑似被篡改"); + } + return true; }); } } @@ -20,11 +24,12 @@ class CheckWeb public function check() { $result = $this->tocurl('https://magicbridgeauto.com'); - if (preg_match('/magicbridgeauto/', $result['body'])) { - flg("【magicbridgeauto】未检查到异常"); - } else { + if (!preg_match('/magicbridgeauto/', $result['body'])) { + // flg("【magicbridgeauto】未检查到异常"); + // } else { flg("【magicbridgeauto】疑似被篡改"); } + return true; } diff --git a/composer.json b/composer.json index 65fd08b..7ff8ace 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,8 @@ "phpoffice/phpspreadsheet": "^4.5", "phpmailer/phpmailer": "^6.10", "webman/gateway-worker": "^1.0", - "mpdf/mpdf": "^8.2" + "mpdf/mpdf": "^8.2", + "jaeger/querylist": "^4.4" }, "suggest": { "ext-event": "For better performance. " diff --git a/composer.lock b/composer.lock index feaeb5a..c3a23c9 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": "4914e483b0c6fc599378c91d2eab17cf", + "content-hash": "865e38bae84e7de0c95098cc87135440", "packages": [ { "name": "aliyuncs/oss-sdk-php", @@ -1803,6 +1803,161 @@ }, "time": "2025-06-06T18:15:26+00:00" }, + { + "name": "jaeger/g-http", + "version": "V2.0.1", + "source": { + "type": "git", + "url": "https://github.com/jae-jae/GHttp.git", + "reference": "29cb537c57f230980ca10622de190f04831e35e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jae-jae/GHttp/zipball/29cb537c57f230980ca10622de190f04831e35e6", + "reference": "29cb537c57f230980ca10622de190f04831e35e6", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0 || ^7.0", + "php": ">=8.1", + "symfony/cache": "^6.4 || ^7.0" + }, + "require-dev": { + "predis/predis": "^2.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jaeger\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaeger", + "email": "JaegerCode@gmail.com" + } + ], + "description": "Simple Http client base on GuzzleHttp", + "support": { + "issues": "https://github.com/jae-jae/GHttp/issues", + "source": "https://github.com/jae-jae/GHttp/tree/V2.0.1" + }, + "time": "2024-06-14T08:13:32+00:00" + }, + { + "name": "jaeger/phpquery-single", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/jae-jae/phpQuery-single.git", + "reference": "39a650ade692a6b480c22220dce0c198d6a946fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jae-jae/phpQuery-single/zipball/39a650ade692a6b480c22220dce0c198d6a946fb", + "reference": "39a650ade692a6b480c22220dce0c198d6a946fb", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "phpQuery.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobiasz Cudnik", + "email": "tobiasz.cudnik@gmail.com", + "homepage": "https://github.com/TobiaszCudnik", + "role": "Developer" + }, + { + "name": "Jaeger", + "role": "Packager" + } + ], + "description": "phpQuery单文件版本,是Querylist的依赖(http://querylist.cc/),phpQuery项目主页:http://code.google.com/p/phpquery/", + "homepage": "http://code.google.com/p/phpquery/", + "support": { + "issues": "https://github.com/jae-jae/phpQuery-single/issues", + "source": "https://github.com/jae-jae/phpQuery-single/tree/1.1.1" + }, + "time": "2022-03-26T15:01:16+00:00" + }, + { + "name": "jaeger/querylist", + "version": "V4.4.6", + "source": { + "type": "git", + "url": "https://github.com/jae-jae/QueryList.git", + "reference": "939f4e41b94b4d3ef77071fb7f386abd2ceeb59a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jae-jae/QueryList/zipball/939f4e41b94b4d3ef77071fb7f386abd2ceeb59a", + "reference": "939f4e41b94b4d3ef77071fb7f386abd2ceeb59a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "jaeger/g-http": "^2.0", + "jaeger/phpquery-single": "^1", + "php": ">=8.1", + "symfony/var-dumper": ">3.4" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/Collect/Support/helpers.php", + "src/Collect/Support/alias.php" + ], + "psr-4": { + "QL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaeger", + "email": "JaegerCode@gmail.com" + } + ], + "description": "Simple, elegant, extensible PHP Web Scraper (crawler/spider),Use the css3 dom selector,Based on phpQuery! 简洁、优雅、可扩展的PHP采集工具(爬虫),基于phpQuery。", + "homepage": "http://querylist.cc", + "keywords": [ + "QueryList", + "phpQuery", + "spider" + ], + "support": { + "issues": "https://github.com/jae-jae/QueryList/issues", + "source": "https://github.com/jae-jae/QueryList/tree/V4.4.6" + }, + "funding": [ + { + "url": "https://opencollective.com/querylist", + "type": "open_collective" + } + ], + "time": "2024-12-13T06:16:14+00:00" + }, { "name": "laravel/serializable-closure", "version": "v2.0.4", diff --git a/config/route.php b/config/route.php index bcf0203..687c002 100644 --- a/config/route.php +++ b/config/route.php @@ -89,6 +89,37 @@ Route::group('/common', function () { Route::any('/unread', [app\common\controller\MessageUserStatusController::class, 'listUnRead']); }); + + // 品牌 + Route::group('/brand', function () { + Route::any('/list', [app\common\controller\BrandController::class, 'index']); + Route::any('/show', [app\common\controller\BrandController::class, 'show']); + Route::any('/store', [app\common\controller\BrandController::class, 'store']); + Route::any('/update', [app\common\controller\BrandController::class, 'update']); + Route::any('/hot', [app\common\controller\BrandController::class, 'update']); + Route::any('/destroy', [app\common\controller\BrandController::class, 'destroy']); + Route::any('/crawlSeries', [app\common\controller\BrandController::class, 'crawlSeries']); + Route::any('/crawlSeriesCreate', [app\common\controller\BrandController::class, 'crawlSeriesCreate']); + // 车系 + Route::group('/series', function () { + Route::any('/list', [app\common\controller\BrandSeriesController::class, 'index']); + Route::any('/show', [app\common\controller\BrandSeriesController::class, 'show']); + Route::any('/store', [app\common\controller\BrandSeriesController::class, 'store']); + Route::any('/update', [app\common\controller\BrandSeriesController::class, 'update']); + Route::any('/destroy', [app\common\controller\BrandSeriesController::class, 'destroy']); + Route::any('/crawlModels', [app\common\controller\BrandSeriesController::class, 'crawlModels']); + Route::any('/crawlModelCreate', [app\common\controller\BrandSeriesController::class, 'crawlModelCreate']); + }); + }); + + // 港口 + Route::group('/port', function () { + Route::any('/list', [app\common\controller\SysPortController::class, 'index']); + Route::any('/show', [app\common\controller\SysPortController::class, 'show']); + Route::any('/store', [app\common\controller\SysPortController::class, 'store']); + Route::any('/update', [app\common\controller\SysPortController::class, 'update']); + Route::any('/destroy', [app\common\controller\SysPortController::class, 'destroy']); + }); }); // 后台管理 @@ -484,6 +515,7 @@ Route::group('/crm', function () { Route::any('/store', [app\common\controller\VehVehicleSkuController::class, 'store']); Route::any('/update', [app\common\controller\VehVehicleSkuController::class, 'update']); Route::any('/destroy', [app\common\controller\VehVehicleSkuController::class, 'destroy']); + Route::any('/preset', [app\common\controller\VehVehicleSkuController::class, 'preset']); }); });