Merge remote-tracking branch 'origin/master' into akun
正在显示
45 个修改的文件
包含
1559 行增加
和
153 行删除
| @@ -113,7 +113,7 @@ class AiBlogAutoPublish extends Command | @@ -113,7 +113,7 @@ class AiBlogAutoPublish extends Command | ||
| 113 | } | 113 | } |
| 114 | } | 114 | } |
| 115 | } else { | 115 | } else { |
| 116 | - if($frequency[0] == '1/2'){//一天2篇 | 116 | + if(strpos($frequency[0],'/')){//一天2篇 |
| 117 | $aiBlogTaskModel = new AiBlogTaskModel(); | 117 | $aiBlogTaskModel = new AiBlogTaskModel(); |
| 118 | $frequency = explode('/', $frequency[0]); | 118 | $frequency = explode('/', $frequency[0]); |
| 119 | //查询当前已发布几篇 | 119 | //查询当前已发布几篇 |
| @@ -11,6 +11,7 @@ namespace App\Console\Commands\Geo; | @@ -11,6 +11,7 @@ namespace App\Console\Commands\Geo; | ||
| 11 | 11 | ||
| 12 | use App\Models\Geo\GeoQuestionLog; | 12 | use App\Models\Geo\GeoQuestionLog; |
| 13 | use App\Models\Geo\GeoQuestionResult; | 13 | use App\Models\Geo\GeoQuestionResult; |
| 14 | +use App\Models\Project\Project; | ||
| 14 | use Illuminate\Console\Command; | 15 | use Illuminate\Console\Command; |
| 15 | use Illuminate\Support\Carbon; | 16 | use Illuminate\Support\Carbon; |
| 16 | use App\Models\Geo\GeoCount as GeoCountModel; | 17 | use App\Models\Geo\GeoCount as GeoCountModel; |
| @@ -64,15 +65,23 @@ class GeoCount extends Command | @@ -64,15 +65,23 @@ class GeoCount extends Command | ||
| 64 | $geoQuestionResModel = new GeoQuestionResult(); | 65 | $geoQuestionResModel = new GeoQuestionResult(); |
| 65 | $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; | 66 | $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; |
| 66 | foreach ($project_id as $item){ | 67 | foreach ($project_id as $item){ |
| 68 | + $projectModel = new Project(); | ||
| 69 | + $geo_qualify_num = $projectModel->getValue(['id'=>$item],'geo_qualify_num'); | ||
| 67 | $this->output('执行的项目ID----'.$item); | 70 | $this->output('执行的项目ID----'.$item); |
| 68 | //收录总数 | 71 | //收录总数 |
| 69 | $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | 72 | $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); |
| 73 | + $qualify_total = $geoQuestionResModel->counts(['platform'=>['in',['openai', 'gemini','google_ai_overview']],'project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | ||
| 74 | + if($qualify_total > $geo_qualify_num){ | ||
| 75 | + $is_qualify = 1; | ||
| 76 | + } | ||
| 70 | $data = [ | 77 | $data = [ |
| 71 | 'project_id' => $item, | 78 | 'project_id' => $item, |
| 72 | 'date' => $date, | 79 | 'date' => $date, |
| 73 | 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), | 80 | 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), |
| 74 | 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), | 81 | 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), |
| 75 | 'total'=>$total,//收录总数 | 82 | 'total'=>$total,//收录总数 |
| 83 | + 'is_qualify'=>$is_qualify, | ||
| 84 | + 'qualify_total'=>$qualify_total | ||
| 76 | ]; | 85 | ]; |
| 77 | foreach ($platforms as $platform){ | 86 | foreach ($platforms as $platform){ |
| 78 | if($platform == 'openai-not-network'){ | 87 | if($platform == 'openai-not-network'){ |
| @@ -11,6 +11,7 @@ namespace App\Console\Commands\Geo; | @@ -11,6 +11,7 @@ namespace App\Console\Commands\Geo; | ||
| 11 | 11 | ||
| 12 | use App\Models\Geo\GeoQuestionLog; | 12 | use App\Models\Geo\GeoQuestionLog; |
| 13 | use App\Models\Geo\GeoQuestionResult; | 13 | use App\Models\Geo\GeoQuestionResult; |
| 14 | +use App\Models\Project\Project; | ||
| 14 | use Illuminate\Console\Command; | 15 | use Illuminate\Console\Command; |
| 15 | use Illuminate\Support\Carbon; | 16 | use Illuminate\Support\Carbon; |
| 16 | use App\Models\Geo\GeoCount as GeoCountModel; | 17 | use App\Models\Geo\GeoCount as GeoCountModel; |
| @@ -68,15 +69,23 @@ class GeoCountAll extends Command | @@ -68,15 +69,23 @@ class GeoCountAll extends Command | ||
| 68 | $geoQuestionResModel = new GeoQuestionLog(); | 69 | $geoQuestionResModel = new GeoQuestionLog(); |
| 69 | $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; | 70 | $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; |
| 70 | foreach ($project_id as $item){ | 71 | foreach ($project_id as $item){ |
| 72 | + $projectModel = new Project(); | ||
| 73 | + $geo_qualify_num = $projectModel->getValue(['id'=>$item],'geo_qualify_num'); | ||
| 71 | $this->output('执行的项目ID----'.$item); | 74 | $this->output('执行的项目ID----'.$item); |
| 72 | //收录总数 | 75 | //收录总数 |
| 73 | $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | 76 | $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); |
| 77 | + $qualify_total = $geoQuestionResModel->counts(['platform'=>['in',['openai', 'gemini','google_ai_overview']],'project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | ||
| 78 | + if($total > $geo_qualify_num){ | ||
| 79 | + $is_qualify = 1; | ||
| 80 | + } | ||
| 74 | $data = [ | 81 | $data = [ |
| 75 | 'project_id' => $item, | 82 | 'project_id' => $item, |
| 76 | 'date' => $date, | 83 | 'date' => $date, |
| 77 | 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), | 84 | 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), |
| 78 | 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), | 85 | 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), |
| 79 | 'total'=>$total,//收录总数 | 86 | 'total'=>$total,//收录总数 |
| 87 | + 'is_qualify'=>$is_qualify, | ||
| 88 | + 'qualify_total'=>$qualify_total | ||
| 80 | ]; | 89 | ]; |
| 81 | foreach ($platforms as $platform){ | 90 | foreach ($platforms as $platform){ |
| 82 | if($platform == 'openai-not-network'){ | 91 | if($platform == 'openai-not-network'){ |
| @@ -340,12 +340,11 @@ class GeoQuestionRes extends Command | @@ -340,12 +340,11 @@ class GeoQuestionRes extends Command | ||
| 340 | $task_id = Redis::rpop($key); | 340 | $task_id = Redis::rpop($key); |
| 341 | if(empty($task_id)){ | 341 | if(empty($task_id)){ |
| 342 | //todo::这里需要执行统计一次,统计当前项目当前日期的统计 | 342 | //todo::这里需要执行统计一次,统计当前项目当前日期的统计 |
| 343 | - | ||
| 344 | # TODO 按照项目进行获取, 一个项目当天需要将所有跑完 | 343 | # TODO 按照项目进行获取, 一个项目当天需要将所有跑完 |
| 345 | $project_id = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->value('project_id'); | 344 | $project_id = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->value('project_id'); |
| 346 | if (!empty($project_id)){ | 345 | if (!empty($project_id)){ |
| 347 | $this->project_id = $project_id; | 346 | $this->project_id = $project_id; |
| 348 | - $ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('current_time', '<>', date('Y-m-d'))->pluck('id'); | 347 | + $ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('next_time', '<=', date('Y-m-d'))->pluck('id'); |
| 349 | foreach ($ids as $id) { | 348 | foreach ($ids as $id) { |
| 350 | Redis::lpush($key, $id); | 349 | Redis::lpush($key, $id); |
| 351 | } | 350 | } |
| @@ -9,10 +9,7 @@ | @@ -9,10 +9,7 @@ | ||
| 9 | 9 | ||
| 10 | namespace App\Console\Commands\LyhTest; | 10 | namespace App\Console\Commands\LyhTest; |
| 11 | 11 | ||
| 12 | -use App\Models\CustomModule\CustomModuleCategory; | ||
| 13 | -use App\Models\CustomModule\CustomModuleContent; | ||
| 14 | -use App\Models\CustomModule\CustomModuleExtentContent; | ||
| 15 | -use App\Models\News\News; | 12 | + |
| 16 | use App\Models\Product\Category; | 13 | use App\Models\Product\Category; |
| 17 | use App\Models\Product\CategoryRelated; | 14 | use App\Models\Product\CategoryRelated; |
| 18 | use App\Models\Product\Column; | 15 | use App\Models\Product\Column; |
| @@ -25,6 +22,7 @@ use App\Models\Template\Template; | @@ -25,6 +22,7 @@ use App\Models\Template\Template; | ||
| 25 | use App\Services\ProjectServer; | 22 | use App\Services\ProjectServer; |
| 26 | use Illuminate\Console\Command; | 23 | use Illuminate\Console\Command; |
| 27 | use Illuminate\Support\Facades\DB; | 24 | use Illuminate\Support\Facades\DB; |
| 25 | +use PhpOffice\PhpSpreadsheet\IOFactory; | ||
| 28 | 26 | ||
| 29 | class LyhImportTest extends Command | 27 | class LyhImportTest extends Command |
| 30 | { | 28 | { |
| @@ -52,15 +50,92 @@ class LyhImportTest extends Command | @@ -52,15 +50,92 @@ class LyhImportTest extends Command | ||
| 52 | */ | 50 | */ |
| 53 | public function handle() | 51 | public function handle() |
| 54 | { | 52 | { |
| 55 | - ProjectServer::useProject(3531); | ||
| 56 | - echo date('Y-m-d H:i:s') . 'start->3531' . PHP_EOL; | ||
| 57 | -// $this->importProductCategory('https://ecdn6-nc.globalso.com/upload/p/3654/file/2025-06/products-1.csv',3654); | ||
| 58 | - $this->import3531CustomModule(3531); | 53 | + ProjectServer::useProject(1517); |
| 54 | + echo date('Y-m-d H:i:s') . 'start->1517' . PHP_EOL; | ||
| 55 | + $url1 = 'https://ecdn6.globalso.com/upload/p/1517/file/2025-10/horse-racing-tkd-modification-1.xlsx';//改tdk | ||
| 56 | + $url2 = 'https://v6-file.globalso.com/upload/p/1517/file/2025-10/horse-racing-url-modification.xlsx';//改url路由+tdk | ||
| 57 | + $this->download_1517_action($url2); | ||
| 59 | DB::disconnect('custom_mysql'); | 58 | DB::disconnect('custom_mysql'); |
| 60 | echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; | 59 | echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; |
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | /** | 62 | /** |
| 63 | + * @remark :导入 | ||
| 64 | + * @name :download_1517_action | ||
| 65 | + * @author :lyh | ||
| 66 | + * @method :post | ||
| 67 | + * @time :2025/10/22 16:47 | ||
| 68 | + */ | ||
| 69 | + public function download_1517_action($url) | ||
| 70 | + { | ||
| 71 | + // 临时文件路径(确保目录存在) | ||
| 72 | + $tempDir = storage_path('app'); | ||
| 73 | + if (!is_dir($tempDir)) { | ||
| 74 | + mkdir($tempDir, 0755, true); | ||
| 75 | + } | ||
| 76 | + $tempPath = $tempDir . '/temp_url.xlsx'; | ||
| 77 | + try { | ||
| 78 | + // 使用 cURL 下载文件,防止403问题 | ||
| 79 | + $ch = curl_init($url); | ||
| 80 | + curl_setopt_array($ch, [ | ||
| 81 | + CURLOPT_RETURNTRANSFER => true, | ||
| 82 | + CURLOPT_FOLLOWLOCATION => true, // 跟随重定向 | ||
| 83 | + CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; LaravelApp/1.0)', // 模拟浏览器 | ||
| 84 | + CURLOPT_TIMEOUT => 30, // 超时防止卡死 | ||
| 85 | + ]); | ||
| 86 | + $data = curl_exec($ch); | ||
| 87 | + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
| 88 | + curl_close($ch); | ||
| 89 | + // 检查下载是否成功 | ||
| 90 | + if ($httpCode !== 200 || !$data) { | ||
| 91 | + echo "文件下载失败,HTTP状态码:{$httpCode}"; | ||
| 92 | + } | ||
| 93 | + // 保存到临时文件 | ||
| 94 | + file_put_contents($tempPath, $data); | ||
| 95 | + // 加载 Excel 文件 | ||
| 96 | + $spreadsheet = IOFactory::load($tempPath); | ||
| 97 | + $sheet = $spreadsheet->getActiveSheet(); | ||
| 98 | + $rows = $sheet->toArray(); | ||
| 99 | + // 删除临时文件 | ||
| 100 | + if (file_exists($tempPath)) { | ||
| 101 | + unlink($tempPath); | ||
| 102 | + } | ||
| 103 | + $d = []; | ||
| 104 | + //todo::处理数据 | ||
| 105 | + $productModel = new Product(); | ||
| 106 | + foreach ($rows as $key => $row) { | ||
| 107 | + if($key == 0){ | ||
| 108 | + continue; | ||
| 109 | + } | ||
| 110 | + $path = parse_url($row[1], PHP_URL_PATH); | ||
| 111 | + $path = ltrim(parse_url($path, PHP_URL_PATH), '/'); | ||
| 112 | + $info = $productModel->read(['route'=>$path],['id','title','route','seo_mate']); | ||
| 113 | + if($info === false){ | ||
| 114 | + echo '未找到数据->'.$row[0].PHP_EOL; | ||
| 115 | + $d[] = $row[0]; | ||
| 116 | + continue; | ||
| 117 | + } | ||
| 118 | + $seo_mate = $info['seo_mate']; | ||
| 119 | + $seo_mate['title'] = $row[2] ?? ''; | ||
| 120 | + $seo_mate['keyword'] = $row[3] ?? ''; | ||
| 121 | + //todo::重新生成路由 | ||
| 122 | + $route = RouteMap::setRoute($row[2],RouteMap::SOURCE_PRODUCT,$info['id'],$info['project_id']); | ||
| 123 | + $productModel->edit(['route'=>$route,'old_route'=>$path,'seo_mate'=>json_encode($seo_mate,true),'title'=>$row[2]],['id'=>$info['id']]); | ||
| 124 | + echo '执行的ID:'.$info['id'].PHP_EOL; | ||
| 125 | + } | ||
| 126 | + } catch (\Exception $e) { | ||
| 127 | + // 输出更清晰的错误信息 | ||
| 128 | + echo '文件下载或解析失败:' . $e->getMessage() . PHP_EOL; | ||
| 129 | + // 清理资源 | ||
| 130 | + if (file_exists($tempPath)) { | ||
| 131 | + unlink($tempPath); | ||
| 132 | + } | ||
| 133 | + DB::disconnect('custom_mysql'); | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + | ||
| 138 | + /** | ||
| 64 | * @remark :3951项目导入产品 | 139 | * @remark :3951项目导入产品 |
| 65 | * @name :import3951Product | 140 | * @name :import3951Product |
| 66 | * @author :lyh | 141 | * @author :lyh |
| @@ -86,8 +86,8 @@ class SendProduct extends Command | @@ -86,8 +86,8 @@ class SendProduct extends Command | ||
| 86 | $start_date = date('Y-m-d 00:00:00'); | 86 | $start_date = date('Y-m-d 00:00:00'); |
| 87 | $end_date = date('Y-m-d 23:59:59'); | 87 | $end_date = date('Y-m-d 23:59:59'); |
| 88 | $productModel = new Product(); | 88 | $productModel = new Product(); |
| 89 | - $arr = $productModel->formatQuery(['send_time'=>['between',[$start_date,$end_date]],'status'=>3])->pluck('route')->toArray(); | ||
| 90 | - $productModel->edit(['status'=>1],['send_time'=>['between',[$start_date,$end_date]],'status'=>3]); | 89 | + $arr = $productModel->formatQuery(['send_time'=>['<=',$end_date],'status'=>3])->pluck('route')->toArray(); |
| 90 | + $productModel->edit(['status'=>1],['send_time'=>['<=',$end_date],'status'=>3]); | ||
| 91 | return $arr; | 91 | return $arr; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| @@ -102,8 +102,8 @@ class SendProduct extends Command | @@ -102,8 +102,8 @@ class SendProduct extends Command | ||
| 102 | $start_date = date('Y-m-d 00:00:00'); | 102 | $start_date = date('Y-m-d 00:00:00'); |
| 103 | $end_date = date('Y-m-d 23:59:59'); | 103 | $end_date = date('Y-m-d 23:59:59'); |
| 104 | $blogModel = new Blog(); | 104 | $blogModel = new Blog(); |
| 105 | - $arr = $blogModel->formatQuery(['release_at'=>['between',[$start_date,$end_date]],'status'=>3])->pluck('url')->toArray(); | ||
| 106 | - $blogModel->edit(['status'=>1],['release_at'=>['between',[$start_date,$end_date]],'status'=>3]); | 105 | + $arr = $blogModel->formatQuery(['release_at'=>['<=',$end_date],'status'=>3])->pluck('url')->toArray(); |
| 106 | + $blogModel->edit(['status'=>1],['release_at'=>['<=',$end_date],'status'=>3]); | ||
| 107 | return $arr; | 107 | return $arr; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -118,8 +118,8 @@ class SendProduct extends Command | @@ -118,8 +118,8 @@ class SendProduct extends Command | ||
| 118 | $start_date = date('Y-m-d 00:00:00'); | 118 | $start_date = date('Y-m-d 00:00:00'); |
| 119 | $end_date = date('Y-m-d 23:59:59'); | 119 | $end_date = date('Y-m-d 23:59:59'); |
| 120 | $newsModel = new News(); | 120 | $newsModel = new News(); |
| 121 | - $arr = $newsModel->formatQuery(['release_at'=>['between',[$start_date,$end_date]],'status'=>3])->pluck('url')->toArray(); | ||
| 122 | - $newsModel->edit(['status'=>1],['release_at'=>['between',[$start_date,$end_date]],'status'=>3]); | 121 | + $arr = $newsModel->formatQuery(['release_at'=>['<=',$end_date],'status'=>3])->pluck('url')->toArray(); |
| 122 | + $newsModel->edit(['status'=>1],['release_at'=>['<=',$end_date],'status'=>3]); | ||
| 123 | return $arr; | 123 | return $arr; |
| 124 | } | 124 | } |
| 125 | } | 125 | } |
| @@ -33,11 +33,11 @@ class SyncImage extends Command | @@ -33,11 +33,11 @@ class SyncImage extends Command | ||
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | public function handle(){ | 35 | public function handle(){ |
| 36 | - $str = $this->getProjectConfig(4636); | 36 | + $str = $this->getProjectConfig(2123); |
| 37 | $imageModel = new Image(); | 37 | $imageModel = new Image(); |
| 38 | -// $strImage = '/upload/p/4240/image_other/2025-09/picture-18-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-2.jpg,/upload/p/4240/image_other/2025-09/4-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-20-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-19-copy-1.jpg,/upload/p/4240/image_other/2025-09/image-1-copy.jpg,/upload/p/4240/image_other/2025-09/image-2-copy.jpg,/upload/p/4240/image_other/2025-09/picture-3-copy.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy.jpg,/upload/p/4240/image_other/2025-09/picture-4-copy.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy.jpg,/upload/p/4240/image_other/2025-09/picture-9-copy.jpg,/upload/p/4240/image_other/2025-09/picture-7-copy.jpg,/upload/p/4240/image_other/2025-09/picture-8-copy.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-44-copy.jpg,/upload/p/4240/image_other/2025-08/45.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy.jpg,/upload/p/4240/image_other/2025-08/43.jpg,/upload/p/4240/image_other/2025-08/42.jpg,/upload/p/4240/image_other/2025-08/picture-38-copy.jpg,/upload/p/4240/image_other/2025-08/picture-37-copy.jpg,/upload/p/4240/image_other/2025-08/picture-36-copy.jpg,/upload/p/4240/image_other/2025-08/picture-35-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-30-copy.jpg,/upload/p/4240/image_other/2025-08/29.jpg,/upload/p/4240/image_other/2025-08/28-1.jpg,/upload/p/4240/image_other/2025-08/27-1.jpg,/upload/p/4240/image_other/2025-08/picture-23-copy.jpg,/upload/p/4240/image_other/2025-08/22-1.jpg,/upload/p/4240/image_other/2025-08/21.jpg,/upload/p/4240/image_other/2025-08/17.jpg,/upload/p/4240/image_other/2025-08/16.jpg,/upload/p/4240/image_other/2025-08/picture-15-copy.jpg,/upload/p/4240/image_other/2025-08/11-2.jpg,/upload/p/4240/image_other/2025-08/10-1.jpg,/upload/p/4240/image_other/2025-08/picture-6.jpg,/upload/p/4240/image_other/2025-08/picture-5.jpg,/upload/p/4240/image_other/2025-08/picture-4.jpg,/upload/p/4240/image_other/2025-08/api-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gb-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gost-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/jis-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/asmeastm-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/en-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/api-corrosion-resistant-alloy-cra-pipe.jpg,/upload/p/4240/image_other/2025-08/nickel-alloy-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/duplexsuper-duplex-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/super-austenitic-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/austenitic-stainless-steel-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/thick-zinc-coated-pipe.jpg,/upload/p/4240/image_other/2025-08/galvanized-fbe-pipe.jpg,/upload/p/4240/image_other/2025-08/electro-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/hot-dip-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q235-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q195-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/bare-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/fbe-coated-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/x52-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/q235b-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/low-alloy-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/carbon-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/black-carbon-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/picture-19-copy.jpg,/upload/p/4240/image_other/2025-08/hydrogen-energy-skid.jpg'; | ||
| 39 | - $lists = $imageModel->selectField(['project_id'=>4636],'path'); | ||
| 40 | -// $lists = explode(',',$strImage); | 38 | + $strImage = '/upload/p/2123/image_other/2025-10/1-361.jpg,/upload/p/2123/image_other/2025-10/3-255.jpg,/upload/p/2123/image_other/2025-10/4-237.jpg,/upload/p/2123/image_other/2025-10/5-104.jpg,/upload/p/2123/image_other/2025-10/6-53.jpg,/upload/p/2123/image_other/2025-10/7-31.jpg,/upload/p/2123/image_other/2025-10/8-27.jpg,/upload/p/2123/image_other/2025-10/5-105.jpg'; |
| 39 | +// $lists = $imageModel->selectField(['project_id'=>4636],'path'); | ||
| 40 | + $lists = explode(',',$strImage); | ||
| 41 | $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名 | 41 | $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名 |
| 42 | foreach ($lists as $v){ | 42 | foreach ($lists as $v){ |
| 43 | $url = $domain . $v.'?'.$str; | 43 | $url = $domain . $v.'?'.$str; |
| @@ -100,7 +100,9 @@ class UpdateKeyword extends Command | @@ -100,7 +100,9 @@ class UpdateKeyword extends Command | ||
| 100 | }else{ | 100 | }else{ |
| 101 | $randomNumber = $text[$key] ?? rand(0, $number - 1); | 101 | $randomNumber = $text[$key] ?? rand(0, $number - 1); |
| 102 | } | 102 | } |
| 103 | - $keywordModel->edit(['keyword_content'=>$text[$randomNumber]],['title'=>$item]); | 103 | + if(isset($text[$randomNumber])){ |
| 104 | + $keywordModel->edit(['keyword_content'=>$text[$randomNumber]],['title'=>$item]); | ||
| 105 | + } | ||
| 104 | } | 106 | } |
| 105 | } | 107 | } |
| 106 | //按给定的数量更新 | 108 | //按给定的数量更新 |
| @@ -112,7 +114,9 @@ class UpdateKeyword extends Command | @@ -112,7 +114,9 @@ class UpdateKeyword extends Command | ||
| 112 | }else{ | 114 | }else{ |
| 113 | $randomNumber = $text[$key] ?? rand(0, $number - 1); | 115 | $randomNumber = $text[$key] ?? rand(0, $number - 1); |
| 114 | } | 116 | } |
| 115 | - $keywordModel->edit(['keyword_content'=>$text[$randomNumber]],['title'=>$item]); | 117 | + if(isset($text[$randomNumber])){ |
| 118 | + $keywordModel->edit(['keyword_content'=>$text[$randomNumber]],['title'=>$item]); | ||
| 119 | + } | ||
| 116 | } | 120 | } |
| 117 | } | 121 | } |
| 118 | } | 122 | } |
| @@ -163,6 +163,62 @@ class FormGlobalsoApi | @@ -163,6 +163,62 @@ class FormGlobalsoApi | ||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | /** | 165 | /** |
| 166 | + * | ||
| 167 | + * 自定义邮件发送接口 | ||
| 168 | + * @param string $to_email 接收邮箱 | ||
| 169 | + * @param string $subject 标题 | ||
| 170 | + * @param string $message 发送内容 | ||
| 171 | + * @param string $ip 发送ip | ||
| 172 | + * @param string $refer 来源页面 | ||
| 173 | + * @param string $submit_time 询盘发送时间 | ||
| 174 | + * @param string $reply_email 回复邮箱 | ||
| 175 | + * @return bool | ||
| 176 | + */ | ||
| 177 | + function customizeInquiryEmail($to_email, $subject, $message, $ip, $refer, $submit_time, $reply_email = '') | ||
| 178 | + { | ||
| 179 | + $post_data['from_email'] = 'mail@goodao.cn'; | ||
| 180 | + $post_data['to_email'] = trim($to_email); | ||
| 181 | + $post_data['title'] = trim($subject); | ||
| 182 | + $post_data['message'] = $message; | ||
| 183 | + $post_data['ip'] = trim($ip); | ||
| 184 | + $post_data['refer'] = trim($refer); | ||
| 185 | + $post_data['reply_email'] = trim($reply_email); | ||
| 186 | + if(!$reply_email){ | ||
| 187 | + $post_data['reply_email'] = $post_data['from_email']; | ||
| 188 | + } | ||
| 189 | + $post_data['submit_time'] = $submit_time; | ||
| 190 | + $url = "https://form.globalso.com/api/b4153b7556"; | ||
| 191 | + $curl = curl_init($url); | ||
| 192 | + curl_setopt($curl, CURLOPT_POST, 1); | ||
| 193 | + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | ||
| 194 | + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30); | ||
| 195 | + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); | ||
| 196 | + curl_setopt($curl, CURLOPT_AUTOREFERER, 1); | ||
| 197 | + curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'); | ||
| 198 | + curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); | ||
| 199 | + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); | ||
| 200 | + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); | ||
| 201 | + $curl_response = curl_exec($curl); | ||
| 202 | + curl_close($curl); | ||
| 203 | + return true; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + /** | ||
| 207 | + * 推送自定义询盘短信 | ||
| 208 | + * @param string $phones 多个手机号码, 使用英文逗号隔开 | ||
| 209 | + * @param string $country | ||
| 210 | + * @param string $domain | ||
| 211 | + * @return mixed|string | ||
| 212 | + */ | ||
| 213 | + public function customizeInquirySms($phones, $country, $domain) | ||
| 214 | + { | ||
| 215 | + $param = compact('phones', 'country', 'domain'); | ||
| 216 | + $url = 'https://form.globalso.com/api/send_sms?' . http_build_query($param); | ||
| 217 | + $result = http_get($url,['charset=utf-8']); | ||
| 218 | + return $result; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + /** | ||
| 166 | * @remark :获取当前项目所有询盘及询盘国家 | 222 | * @remark :获取当前项目所有询盘及询盘国家 |
| 167 | * @name :getInquiryAll | 223 | * @name :getInquiryAll |
| 168 | * @author :lyh | 224 | * @author :lyh |
app/Http/Controllers/Api/GeoController.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: zhl | ||
| 5 | + * Date: 2025/10/23 | ||
| 6 | + * Time: 17:29 | ||
| 7 | + */ | ||
| 8 | +namespace App\Http\Controllers\Api; | ||
| 9 | + | ||
| 10 | +use App\Models\Geo\GeoConfirm; | ||
| 11 | +use App\Models\Geo\GeoWritings; | ||
| 12 | +use App\Models\Project\Project; | ||
| 13 | +use Illuminate\Http\Request; | ||
| 14 | +use Illuminate\Support\Facades\Crypt; | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * GEO相关 | ||
| 18 | + * Class GeoController | ||
| 19 | + * @package App\Http\Controllers\Api | ||
| 20 | + */ | ||
| 21 | +class GeoController extends BaseController | ||
| 22 | +{ | ||
| 23 | + /** | ||
| 24 | + * 获取确认文章列表 | ||
| 25 | + * @param Request $request | ||
| 26 | + * @return false|string | ||
| 27 | + */ | ||
| 28 | + public function getWritingsList() | ||
| 29 | + { | ||
| 30 | + try { | ||
| 31 | + $token = trim($this->param['token']); | ||
| 32 | + $param = Crypt::decrypt($token); | ||
| 33 | + if ($param['send_at'] + 86400 < time()) {} | ||
| 34 | + $project_id = $param['project_id']; | ||
| 35 | + } catch (\Exception $e) { | ||
| 36 | + return $this->error('非法请求'); | ||
| 37 | + } | ||
| 38 | + $project = Project::select('title', 'version')->where(['project_id' => $this->param['project_id']])->first(); | ||
| 39 | + $list = GeoWritings::select(['title', 'status', 'uniqid', 'confirm_at'])->where(['project_id' => $project_id, 'is_del' => GeoWritings::IS_DEL_FALSE])->get(); | ||
| 40 | + $result = [ | ||
| 41 | + 'project' => $project, | ||
| 42 | + 'list' => $list | ||
| 43 | + ]; | ||
| 44 | + return $this->success($result); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 获取详情 | ||
| 49 | + * @param Request $request | ||
| 50 | + * @return false|string | ||
| 51 | + */ | ||
| 52 | + public function getWritingsDetail(Request $request) | ||
| 53 | + { | ||
| 54 | + $token = trim($request->input('token')); | ||
| 55 | + $detail = GeoWritings::select(['title', 'content', 'status'])->where(['uniqid' => $token])->first(); | ||
| 56 | + return $this->success($detail); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 确认核心文章数据 | ||
| 62 | + * @param Request $request | ||
| 63 | + * @return false|string | ||
| 64 | + */ | ||
| 65 | + public function confirmWritings(Request $request) | ||
| 66 | + { | ||
| 67 | + $request->validate([ | ||
| 68 | + 'token' => 'required', | ||
| 69 | + 'title' => 'required|max:120', | ||
| 70 | + 'content' => 'required|max:5000' | ||
| 71 | + ], [ | ||
| 72 | + 'token.required' => '非法请求', | ||
| 73 | + 'title.required' => '标题不能为空', | ||
| 74 | + 'title.max' => '最大长度不能超过120字符', | ||
| 75 | + 'content.required' => '内容不能为空', | ||
| 76 | + 'content.max' => '内容过长保存失败', | ||
| 77 | + ]); | ||
| 78 | + $token = trim($request->input('token')); | ||
| 79 | + $data = GeoWritings::where(['uniqid' => $token])->first(); | ||
| 80 | + if (empty($data)){ | ||
| 81 | + return $this->error('非法请求'); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + if ($data->status != GeoWritings::STATUS_RUNNING){ | ||
| 85 | + return $this->error('当前文章已确认,不可再次确认'); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + | ||
| 89 | + // FIXME 验证完成,保存数据,计算内容长度,处理内容中的资源, IP 确认时间 状态 | ||
| 90 | + return $data; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + * 获取确认数据 | ||
| 95 | + * @param Request $request | ||
| 96 | + * @return false|string | ||
| 97 | + */ | ||
| 98 | + public function getConfirm(Request $request) | ||
| 99 | + { | ||
| 100 | + $token = trim($request->input('token')); | ||
| 101 | + $data = GeoConfirm::where(['uniqid' => $token])->first(); | ||
| 102 | + if (empty($data)){ | ||
| 103 | + return $this->error('当前授权已失效'); | ||
| 104 | + } | ||
| 105 | + $content = explode("\n", $data->content); | ||
| 106 | + $confirm = explode("\n", $data->confirm); | ||
| 107 | + $type = $data->type; | ||
| 108 | + $status = $data->status; | ||
| 109 | + $result = compact('content', 'confirm', 'type', 'status'); | ||
| 110 | + return $this->success($result); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * 保存确认数据 | ||
| 115 | + * 验证当前确认数据状态, 不可重复确认 | ||
| 116 | + * @param Request $request | ||
| 117 | + */ | ||
| 118 | + public function saveConfirm(Request $request) | ||
| 119 | + {} | ||
| 120 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoConfirmController.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 11:35 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Controllers\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Enums\Common\Code; | ||
| 13 | +use App\Http\Controllers\Aside\BaseController; | ||
| 14 | +use App\Http\Logic\Aside\Geo\GeoConfirmLogic; | ||
| 15 | +use Illuminate\Http\Request; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * @remark :用户确认信息表 | ||
| 19 | + * @name :GeoConfirmController | ||
| 20 | + * @author :lyh | ||
| 21 | + * @method :post | ||
| 22 | + * @time :2025/10/25 11:37 | ||
| 23 | + */ | ||
| 24 | +class GeoConfirmController extends BaseController | ||
| 25 | +{ | ||
| 26 | + public function __construct(Request $request){ | ||
| 27 | + parent::__construct($request); | ||
| 28 | + $this->logic = new GeoConfirmLogic(); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 保存确认数据, 并推送微信群 | ||
| 33 | + * @param Request $request | ||
| 34 | + * @throws \App\Exceptions\AsideGlobalException | ||
| 35 | + */ | ||
| 36 | + public function saveConfirmContent() | ||
| 37 | + { | ||
| 38 | + $this->request->validate([ | ||
| 39 | + 'project_id' => 'required', | ||
| 40 | + 'type' => 'required|integer', | ||
| 41 | + 'content' => 'required', | ||
| 42 | + 'max_num' => 'required', | ||
| 43 | + ], [ | ||
| 44 | + 'project_id.required' => '项目ID不能为空', | ||
| 45 | + 'type.required' => '确定数据类型不能为空', | ||
| 46 | + 'type.integer' => '确定数据类型不正确', | ||
| 47 | + 'content.required' => '确定数据不能为空', | ||
| 48 | + 'max_num.required' => '最大确认数量不能为空', | ||
| 49 | + ]); | ||
| 50 | + $data = $this->logic->saveConfirmContent($this->param); | ||
| 51 | + $this->response('success', Code::SUCCESS, $data); | ||
| 52 | + } | ||
| 53 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: zhl | ||
| 5 | + * Date: 2025/10/23 | ||
| 6 | + * Time: 10:23 | ||
| 7 | + */ | ||
| 8 | +namespace App\Http\Controllers\Aside\Geo; | ||
| 9 | + | ||
| 10 | +use App\Enums\Common\Code; | ||
| 11 | +use App\Http\Controllers\Aside\BaseController; | ||
| 12 | +use App\Http\Logic\Aside\Geo\GeoLogic; | ||
| 13 | +use App\Models\Geo\GeoConf; | ||
| 14 | +use App\Models\Geo\GeoConfirm; | ||
| 15 | +use App\Models\Manage\ManageHr; | ||
| 16 | +use App\Models\Project\KeywordPrefix; | ||
| 17 | +use App\Models\Project\Project; | ||
| 18 | +use App\Models\ProjectAssociation\ProjectAssociation; | ||
| 19 | +use Illuminate\Http\Request; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Class GeoController | ||
| 23 | + * @package App\Http\Controllers\Aside\Geo | ||
| 24 | + */ | ||
| 25 | +class GeoController extends BaseController | ||
| 26 | +{ | ||
| 27 | + public function __construct(Request $request){ | ||
| 28 | + parent::__construct($request); | ||
| 29 | + $this->logic = new GeoLogic(); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * 获取GEO相关配置 | ||
| 34 | + * @param Request $request | ||
| 35 | + */ | ||
| 36 | + public function getConfig() | ||
| 37 | + { | ||
| 38 | + $this->request->validate([ | ||
| 39 | + 'project_id' => 'required', | ||
| 40 | + ], [ | ||
| 41 | + 'project_id.required' => '项目ID不能为空', | ||
| 42 | + ]); | ||
| 43 | + $data = $this->logic->getCongInfo($this->param['project_id']); | ||
| 44 | + $this->response('success', Code::SUCCESS, $data); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 保存GEO配置 | ||
| 49 | + * TODO 单独保存GEO开启状态, 达标数量 | ||
| 50 | + * @param Request $request | ||
| 51 | + * @throws \App\Exceptions\AsideGlobalException | ||
| 52 | + */ | ||
| 53 | + public function saveConfig() | ||
| 54 | + { | ||
| 55 | + $this->request->validate([ | ||
| 56 | + 'project_id' => 'required', | ||
| 57 | + 'manager_id' => 'nullable|integer', | ||
| 58 | + 'company' => 'nullable|max:200', | ||
| 59 | + 'brand' => 'nullable|max:200', | ||
| 60 | + 'description' => 'nullable|max:500', | ||
| 61 | + ], [ | ||
| 62 | + 'project_id.required' => '项目ID不能为空', | ||
| 63 | + 'manager_id.integer' => '管理员参数非法', | ||
| 64 | + 'company.max' => '公司名称不能超过200个字符', | ||
| 65 | + 'brand.max' => '品牌名不能超过200个字符', | ||
| 66 | + 'description.max' => '描述不能超过500个字符', | ||
| 67 | + ]); | ||
| 68 | + $data = $this->logic->saveConfig($this->param); | ||
| 69 | + $this->response('success', Code::SUCCESS, $data); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * OA后台管理员,保存确认数据 | ||
| 76 | + * 客户可以进行确认, OA后台也可以进行确认,以及修改 | ||
| 77 | + * @param Request $request | ||
| 78 | + */ | ||
| 79 | + public function saveConfirmData(Request $request) | ||
| 80 | + { | ||
| 81 | + | ||
| 82 | + } | ||
| 83 | +} |
| @@ -11,7 +11,7 @@ namespace App\Http\Controllers\Aside\Geo; | @@ -11,7 +11,7 @@ namespace App\Http\Controllers\Aside\Geo; | ||
| 11 | 11 | ||
| 12 | use App\Enums\Common\Code; | 12 | use App\Enums\Common\Code; |
| 13 | use App\Http\Controllers\Aside\BaseController; | 13 | use App\Http\Controllers\Aside\BaseController; |
| 14 | -use App\Http\Logic\Aside\Geo\GeoLogic; | 14 | +use App\Http\Logic\Aside\Geo\GeoQuestionLogic; |
| 15 | use Illuminate\Http\Request; | 15 | use Illuminate\Http\Request; |
| 16 | 16 | ||
| 17 | /** | 17 | /** |
| @@ -26,7 +26,7 @@ class GeoQuestionController extends BaseController | @@ -26,7 +26,7 @@ class GeoQuestionController extends BaseController | ||
| 26 | public function __construct(Request $request) | 26 | public function __construct(Request $request) |
| 27 | { | 27 | { |
| 28 | parent::__construct($request); | 28 | parent::__construct($request); |
| 29 | - $this->logic = new GeoLogic(); | 29 | + $this->logic = new GeoQuestionLogic(); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingTaskController.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 10:40 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Controllers\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Enums\Common\Code; | ||
| 13 | +use App\Http\Controllers\Aside\BaseController; | ||
| 14 | +use App\Http\Logic\Aside\Geo\GeoWritingsTaskLogic; | ||
| 15 | +use App\Http\Requests\Aside\Geo\GeoWritingsTaskRequest; | ||
| 16 | +use Illuminate\Http\Request; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * @remark :文章任务(收集数据) | ||
| 20 | + * @name :GeoWritingTaskController | ||
| 21 | + * @author :lyh | ||
| 22 | + * @method :post | ||
| 23 | + * @time :2025/10/25 10:40 | ||
| 24 | + */ | ||
| 25 | +class GeoWritingTaskController extends BaseController | ||
| 26 | +{ | ||
| 27 | + public function __construct(Request $request) | ||
| 28 | + { | ||
| 29 | + parent::__construct($request); | ||
| 30 | + $this->logic = new GeoWritingsTaskLogic(); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * @remark :ai文章列表页 | ||
| 35 | + * @name :lists | ||
| 36 | + * @author :lyh | ||
| 37 | + * @method :post | ||
| 38 | + * @time :2025/10/25 15:12 | ||
| 39 | + */ | ||
| 40 | + public function lists(){ | ||
| 41 | + $data = $this->logic->listWritingTask($this->map,$this->page,$this->row,$this->order); | ||
| 42 | + $this->response('success',Code::SUCCESS,$data); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * @remark :保存geoAi文章生成数据 | ||
| 47 | + * @name :lists | ||
| 48 | + * @author :lyh | ||
| 49 | + * @method :post | ||
| 50 | + * @time :2025/10/25 10:41 | ||
| 51 | + */ | ||
| 52 | + public function saveWritingTask(){ | ||
| 53 | + $request = new GeoWritingsTaskRequest(); | ||
| 54 | + $request->validated(); | ||
| 55 | + $data = $this->logic->saveWritingTask(); | ||
| 56 | + $this->response('success',Code::SUCCESS,$data); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * @remark :批量删除文章任务 | ||
| 61 | + * @name :delWritingTask | ||
| 62 | + * @author :lyh | ||
| 63 | + * @method :post | ||
| 64 | + * @time :2025/10/25 15:03 | ||
| 65 | + */ | ||
| 66 | + public function delWritingTask(){ | ||
| 67 | + $this->request->validate([ | ||
| 68 | + 'id'=>'required|array', | ||
| 69 | + ],[ | ||
| 70 | + 'id.required' => 'ID不能为空', | ||
| 71 | + 'id.array' => 'ID为数组', | ||
| 72 | + ]); | ||
| 73 | + $data = $this->logic->delWritingTask(); | ||
| 74 | + $this->response('success',Code::SUCCESS,$data); | ||
| 75 | + } | ||
| 76 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingsController.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 10:41 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Controllers\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Http\Controllers\Aside\BaseController; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * @remark :geo文章 | ||
| 16 | + * @name :GeoWritingsController | ||
| 17 | + * @author :lyh | ||
| 18 | + * @method :post | ||
| 19 | + * @time :2025/10/25 10:41 | ||
| 20 | + */ | ||
| 21 | +class GeoWritingsController extends BaseController | ||
| 22 | +{ | ||
| 23 | + | ||
| 24 | +} |
| @@ -160,7 +160,7 @@ class OptimizeController extends BaseController | @@ -160,7 +160,7 @@ class OptimizeController extends BaseController | ||
| 160 | $manageModel = new ManageHr(); | 160 | $manageModel = new ManageHr(); |
| 161 | $plan = Project::planMap(); | 161 | $plan = Project::planMap(); |
| 162 | $seo_plan = Project::seoMap(); | 162 | $seo_plan = Project::seoMap(); |
| 163 | - $item['plan'] = $plan[$item['plan']] ?? $seo_plan[1]; | 163 | + $item['plan'] = $plan[$item['plan']] ?? ($seo_plan[$item['seo_plan']] ?? ''); |
| 164 | $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); | 164 | $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); |
| 165 | $item['build_leader'] = $manageModel->getName($item['leader_mid']); | 165 | $item['build_leader'] = $manageModel->getName($item['leader_mid']); |
| 166 | $item['build_manager'] = $manageModel->getName($item['manager_mid']); | 166 | $item['build_manager'] = $manageModel->getName($item['manager_mid']); |
| @@ -10,7 +10,6 @@ use App\Http\Logic\Aside\Project\OnlineCheckLogic; | @@ -10,7 +10,6 @@ use App\Http\Logic\Aside\Project\OnlineCheckLogic; | ||
| 10 | use App\Http\Logic\Aside\Project\ProcessRecordsLogic; | 10 | use App\Http\Logic\Aside\Project\ProcessRecordsLogic; |
| 11 | use App\Http\Logic\Aside\Project\ProjectLogic; | 11 | use App\Http\Logic\Aside\Project\ProjectLogic; |
| 12 | use App\Http\Requests\Aside\Project\ProcessRecordsRequest; | 12 | use App\Http\Requests\Aside\Project\ProcessRecordsRequest; |
| 13 | -use App\Models\Ai\AiVideo; | ||
| 14 | use App\Models\ASide\APublicModel; | 13 | use App\Models\ASide\APublicModel; |
| 15 | use App\Models\Channel\Channel; | 14 | use App\Models\Channel\Channel; |
| 16 | use App\Models\Channel\User; | 15 | use App\Models\Channel\User; |
| @@ -23,7 +22,10 @@ use App\Models\Devops\ServersIp; | @@ -23,7 +22,10 @@ use App\Models\Devops\ServersIp; | ||
| 23 | use App\Models\Domain\DomainCreateTask; | 22 | use App\Models\Domain\DomainCreateTask; |
| 24 | use App\Models\Domain\DomainInfo; | 23 | use App\Models\Domain\DomainInfo; |
| 25 | use App\Models\Domain\DomainInfo as DomainInfoModel; | 24 | use App\Models\Domain\DomainInfo as DomainInfoModel; |
| 25 | +use App\Models\Geo\GeoArticle; | ||
| 26 | +use App\Models\Geo\GeoConf; | ||
| 26 | use App\Models\Geo\GeoLink; | 27 | use App\Models\Geo\GeoLink; |
| 28 | +use App\Models\Geo\GeoQuestionResult; | ||
| 27 | use App\Models\HomeCount\Count; | 29 | use App\Models\HomeCount\Count; |
| 28 | use App\Models\Industry\ProjectIndustry; | 30 | use App\Models\Industry\ProjectIndustry; |
| 29 | use App\Models\Inquiry\InquirySet; | 31 | use App\Models\Inquiry\InquirySet; |
| @@ -31,7 +33,6 @@ use App\Models\Manage\BelongingGroup; | @@ -31,7 +33,6 @@ use App\Models\Manage\BelongingGroup; | ||
| 31 | use App\Models\Manage\ManageHr; | 33 | use App\Models\Manage\ManageHr; |
| 32 | use App\Models\Project\AiVideoTask; | 34 | use App\Models\Project\AiVideoTask; |
| 33 | use App\Models\Project\DeployBuild; | 35 | use App\Models\Project\DeployBuild; |
| 34 | -use App\Models\Project\DeployOptimize; | ||
| 35 | use App\Models\Project\Payment; | 36 | use App\Models\Project\Payment; |
| 36 | use App\Models\Project\ProcessRecords; | 37 | use App\Models\Project\ProcessRecords; |
| 37 | use App\Models\Project\Project; | 38 | use App\Models\Project\Project; |
| @@ -43,7 +44,7 @@ use App\Models\Task\Task; | @@ -43,7 +44,7 @@ use App\Models\Task\Task; | ||
| 43 | use App\Models\WebSetting\WebLanguage; | 44 | use App\Models\WebSetting\WebLanguage; |
| 44 | use App\Models\WorkOrder\TicketProject; | 45 | use App\Models\WorkOrder\TicketProject; |
| 45 | use Illuminate\Http\Request; | 46 | use Illuminate\Http\Request; |
| 46 | -use Illuminate\Support\Facades\DB; | 47 | +use Illuminate\Support\Facades\Http; |
| 47 | 48 | ||
| 48 | /** | 49 | /** |
| 49 | * 项目管理 | 50 | * 项目管理 |
| @@ -225,7 +226,7 @@ class ProjectController extends BaseController | @@ -225,7 +226,7 @@ class ProjectController extends BaseController | ||
| 225 | if($this->map['domain_type'] == 'domain'){ | 226 | if($this->map['domain_type'] == 'domain'){ |
| 226 | $parsedUrl = parse_url($this->map['domain_search']); | 227 | $parsedUrl = parse_url($this->map['domain_search']); |
| 227 | $this->map['domain_search'] = $parsedUrl['host'] ?? $this->map['domain_search']; | 228 | $this->map['domain_search'] = $parsedUrl['host'] ?? $this->map['domain_search']; |
| 228 | - $ids = DomainInfo::where('domain', 'like', '%'.$this->map['domain_search'].'%')->pluck('id')->toArray(); | 229 | + $ids = DomainInfoModel::where('domain', 'like', '%'.$this->map['domain_search'].'%')->pluck('id')->toArray(); |
| 229 | $query->whereIn('gl_project_deploy_optimize.domain', $ids); | 230 | $query->whereIn('gl_project_deploy_optimize.domain', $ids); |
| 230 | }else{ | 231 | }else{ |
| 231 | $query->where('gl_project_deploy_build.test_domain','like','%'.$this->map['domain_search'].'%'); | 232 | $query->where('gl_project_deploy_build.test_domain','like','%'.$this->map['domain_search'].'%'); |
| @@ -319,8 +320,12 @@ class ProjectController extends BaseController | @@ -319,8 +320,12 @@ class ProjectController extends BaseController | ||
| 319 | }); | 320 | }); |
| 320 | } | 321 | } |
| 321 | } | 322 | } |
| 322 | - if(isset($this->map['seo_plan'])){ | ||
| 323 | - $query = $query->where('gl_project_deploy_build.seo_plan','!=',0); | 323 | + if (isset($this->map['seo_plan'])) { |
| 324 | + $query = $query->where('gl_project_deploy_build.seo_plan', '!=', 0) | ||
| 325 | + ->where(function ($subQuery) { | ||
| 326 | + $subQuery->where('gl_project_deploy_build.plan', '=', 0) | ||
| 327 | + ->orWhere('gl_project_deploy_build.seo_plan', '!=', 9); | ||
| 328 | + }); | ||
| 324 | } | 329 | } |
| 325 | if(isset($this->map['site_status'])){ | 330 | if(isset($this->map['site_status'])){ |
| 326 | $query = $query->where('gl_project.site_status',$this->map['site_status']); | 331 | $query = $query->where('gl_project.site_status',$this->map['site_status']); |
| @@ -444,32 +449,45 @@ class ProjectController extends BaseController | @@ -444,32 +449,45 @@ class ProjectController extends BaseController | ||
| 444 | $item['type'] = $item['extend_type']; | 449 | $item['type'] = $item['extend_type']; |
| 445 | } | 450 | } |
| 446 | $manageModel = new ManageHr(); | 451 | $manageModel = new ManageHr(); |
| 447 | - $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); | ||
| 448 | - $item['build_leader'] = $manageModel->getName($item['leader_mid']); | ||
| 449 | - $item['build_manager'] = $manageModel->getName($item['manager_mid']); | ||
| 450 | - $item['build_designer'] = $manageModel->getName($item['designer_mid']); | ||
| 451 | - $item['build_tech'] = $manageModel->getName($item['tech_mid']); | ||
| 452 | - $item['optimize_manager'] = $manageModel->getName($item['optimize_manager_mid']); | ||
| 453 | - $item['optimize_optimist'] = $manageModel->getName($item['optimize_optimist_mid']); | ||
| 454 | - $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); | ||
| 455 | - $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); | ||
| 456 | - $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); | 452 | + //geo项目 |
| 453 | + if(($item['plan'] == 0) && ($item['seo_plan'] != 0)){ | ||
| 454 | + //geo项目负责人 | ||
| 455 | + $geoConfModel = new GeoConf(); | ||
| 456 | + $manage_id = $geoConfModel->getValue(['project_id'=>$item['id']],'manager_id'); | ||
| 457 | + $item['geo_manage_name'] = $manageModel->getName($manage_id); | ||
| 458 | + $geoArticleModel = new GeoArticle(); | ||
| 459 | + $item['geo_article_num'] = $geoArticleModel->counts(['project_id'=>$item['id']]);//文章数量 | ||
| 460 | + $geoLinkModel = new GeoLink(); | ||
| 461 | + $item['geo_link_num'] = $geoLinkModel->counts(['project_id'=>$item['id']]);//权威新闻数量 | ||
| 462 | + $questionResModel = new GeoQuestionResult(); | ||
| 463 | + $item['geo_qualify_num'] = $questionResModel->counts(['project_id'=>$item['id'],'hit'=>['!=',0],'platform'=>['in',['openai', 'gemini','google_ai_overview']]]);//排名 | ||
| 464 | + } | ||
| 465 | + $item['build_leader'] = $manageModel->getName($item['leader_mid']); | ||
| 466 | + $item['build_manager'] = $manageModel->getName($item['manager_mid']); | ||
| 467 | + $item['build_designer'] = $manageModel->getName($item['designer_mid']); | ||
| 468 | + $item['build_tech'] = $manageModel->getName($item['tech_mid']); | ||
| 469 | + $item['optimize_manager'] = $manageModel->getName($item['optimize_manager_mid']); | ||
| 470 | + $item['optimize_optimist'] = $manageModel->getName($item['optimize_optimist_mid']); | ||
| 471 | + $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); | ||
| 472 | + $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); | ||
| 473 | + $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); | ||
| 457 | $planMap = Project::planMap(); | 474 | $planMap = Project::planMap(); |
| 458 | $seoPlanMap = Project::seoMap(); | 475 | $seoPlanMap = Project::seoMap(); |
| 459 | $item['plan'] = $planMap[$item['plan']] ?? ''; | 476 | $item['plan'] = $planMap[$item['plan']] ?? ''; |
| 460 | $item['seo_plan'] = $seoPlanMap[$item['seo_plan']] ?? ''; | 477 | $item['seo_plan'] = $seoPlanMap[$item['seo_plan']] ?? ''; |
| 461 | - $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date'])); | ||
| 462 | - $item['autologin_code'] = getAutoLoginCode($item['id']); | ||
| 463 | - $domainModel = new DomainInfo(); | 478 | + $domainModel = new DomainInfoModel(); |
| 464 | $item['domain'] = !empty($item['domain']) ? $domainModel->getDomain($item['domain']) : ''; | 479 | $item['domain'] = !empty($item['domain']) ? $domainModel->getDomain($item['domain']) : ''; |
| 480 | + $item['uuid'] = TicketProject::where('table_id', $item['id'])->where('project_cate', 2)->value('uuid') ?? null; | ||
| 481 | + $item['friend_id'] = ProjectAssociation::where('project_id', $item['id'])->where('status', ProjectAssociation::STATUS_NORMAL)->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT)->value('friend_id') ?? null; | ||
| 482 | + $item['autologin_code'] = getAutoLoginCode($item['id']); | ||
| 483 | + $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date'])); | ||
| 465 | $item['product_num'] = $data['product'] ?? 0; | 484 | $item['product_num'] = $data['product'] ?? 0; |
| 466 | $item['keyword_num'] = $data['key'] ?? 0; | 485 | $item['keyword_num'] = $data['key'] ?? 0; |
| 467 | $item['article_num'] = ($data['blog'] ?? 0) + ($data['news'] ?? 0); | 486 | $item['article_num'] = ($data['blog'] ?? 0) + ($data['news'] ?? 0); |
| 468 | $item['task_finish_num'] = Task::getNumByProjectId($item['id'], Task::STATUS_DOWN); | 487 | $item['task_finish_num'] = Task::getNumByProjectId($item['id'], Task::STATUS_DOWN); |
| 469 | $item['task_pending_num'] = Task::getNumByProjectId($item['id'], [Task::STATUS_DONGING, Task::STATUS_WAIT]); | 488 | $item['task_pending_num'] = Task::getNumByProjectId($item['id'], [Task::STATUS_DONGING, Task::STATUS_WAIT]); |
| 470 | $item['collect_time'] = $item['is_upgrade'] ? UpdateLog::getProjectUpdate($item['id']) : ''; | 489 | $item['collect_time'] = $item['is_upgrade'] ? UpdateLog::getProjectUpdate($item['id']) : ''; |
| 471 | - $item['uuid'] = TicketProject::where('table_id', $item['id'])->where('project_cate', 2)->value('uuid') ?? null; | ||
| 472 | - $item['friend_id'] = ProjectAssociation::where('project_id', $item['id'])->where('status', ProjectAssociation::STATUS_NORMAL)->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT)->value('friend_id') ?? null; | 490 | + $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); |
| 473 | return $item; | 491 | return $item; |
| 474 | } | 492 | } |
| 475 | 493 | ||
| @@ -792,7 +810,6 @@ class ProjectController extends BaseController | @@ -792,7 +810,6 @@ class ProjectController extends BaseController | ||
| 792 | $order_by_sort = $request->input('order_by_sort', 'desc'); | 810 | $order_by_sort = $request->input('order_by_sort', 'desc'); |
| 793 | $start_time = $this->param['start_time'] ?? ''; | 811 | $start_time = $this->param['start_time'] ?? ''; |
| 794 | $end_time = $this->param['end_time'] ?? ''; | 812 | $end_time = $this->param['end_time'] ?? ''; |
| 795 | - | ||
| 796 | if(!$source_id && !$id){ | 813 | if(!$source_id && !$id){ |
| 797 | $this->response('参数异常',Code::SYSTEM_ERROR); | 814 | $this->response('参数异常',Code::SYSTEM_ERROR); |
| 798 | } | 815 | } |
| @@ -886,7 +903,6 @@ class ProjectController extends BaseController | @@ -886,7 +903,6 @@ class ProjectController extends BaseController | ||
| 886 | $param['yesterday_ip_count'] = $yesterday_count['ip_num'] ?? 0; | 903 | $param['yesterday_ip_count'] = $yesterday_count['ip_num'] ?? 0; |
| 887 | $param['today_ip_count'] = $today_count['ip_num'] ?? 0; | 904 | $param['today_ip_count'] = $today_count['ip_num'] ?? 0; |
| 888 | $param['inquiry_num'] = $today_count['inquiry_num'] ?? 0; | 905 | $param['inquiry_num'] = $today_count['inquiry_num'] ?? 0; |
| 889 | - | ||
| 890 | $list[] = $param; | 906 | $list[] = $param; |
| 891 | } | 907 | } |
| 892 | $data['list'] = $list; | 908 | $data['list'] = $list; |
| @@ -1177,7 +1193,6 @@ class ProjectController extends BaseController | @@ -1177,7 +1193,6 @@ class ProjectController extends BaseController | ||
| 1177 | 'id.required' => '项目id不能为空', | 1193 | 'id.required' => '项目id不能为空', |
| 1178 | 'site_status.required' => '状态不能为空', | 1194 | 'site_status.required' => '状态不能为空', |
| 1179 | ]); | 1195 | ]); |
| 1180 | - | ||
| 1181 | //获取项目数据 | 1196 | //获取项目数据 |
| 1182 | $projectModel = new Project(); | 1197 | $projectModel = new Project(); |
| 1183 | $projectInfo = $projectModel->read(['id'=>$this->param['id']],['project_type','serve_id','site_status','site_token']); | 1198 | $projectInfo = $projectModel->read(['id'=>$this->param['id']],['project_type','serve_id','site_status','site_token']); |
| @@ -1187,14 +1202,12 @@ class ProjectController extends BaseController | @@ -1187,14 +1202,12 @@ class ProjectController extends BaseController | ||
| 1187 | if($projectInfo['site_status'] == $this->param['site_status']){ | 1202 | if($projectInfo['site_status'] == $this->param['site_status']){ |
| 1188 | $this->response('success'); | 1203 | $this->response('success'); |
| 1189 | } | 1204 | } |
| 1190 | - | ||
| 1191 | //获取服务器数据 | 1205 | //获取服务器数据 |
| 1192 | $serverIpModel = new ServersIp(); | 1206 | $serverIpModel = new ServersIp(); |
| 1193 | $serversIpInfo = $serverIpModel->read(['id' => $projectInfo['serve_id']], ['servers_id']); | 1207 | $serversIpInfo = $serverIpModel->read(['id' => $projectInfo['serve_id']], ['servers_id']); |
| 1194 | if(!$serversIpInfo){ | 1208 | if(!$serversIpInfo){ |
| 1195 | $this->fail('获取项目所属服务器失败'); | 1209 | $this->fail('获取项目所属服务器失败'); |
| 1196 | } | 1210 | } |
| 1197 | - | ||
| 1198 | if($serversIpInfo['servers_id'] == ServerConfig::SELF_SITE_ID){ | 1211 | if($serversIpInfo['servers_id'] == ServerConfig::SELF_SITE_ID){ |
| 1199 | //自建站项目 | 1212 | //自建站项目 |
| 1200 | if($this->param['site_status'] == 1){ | 1213 | if($this->param['site_status'] == 1){ |
| @@ -1204,7 +1217,6 @@ class ProjectController extends BaseController | @@ -1204,7 +1217,6 @@ class ProjectController extends BaseController | ||
| 1204 | //开启站点 | 1217 | //开启站点 |
| 1205 | $site_token = str_replace('_expired','',$projectInfo['site_token']); | 1218 | $site_token = str_replace('_expired','',$projectInfo['site_token']); |
| 1206 | } | 1219 | } |
| 1207 | - | ||
| 1208 | $projectModel->edit(['site_status'=>$this->param['site_status'],'site_token'=>$site_token],['id'=>$this->param['id']]); | 1220 | $projectModel->edit(['site_status'=>$this->param['site_status'],'site_token'=>$site_token],['id'=>$this->param['id']]); |
| 1209 | }else{ | 1221 | }else{ |
| 1210 | //普通项目 | 1222 | //普通项目 |
| @@ -1214,7 +1226,6 @@ class ProjectController extends BaseController | @@ -1214,7 +1226,6 @@ class ProjectController extends BaseController | ||
| 1214 | if(!$domainInfo){ | 1226 | if(!$domainInfo){ |
| 1215 | $this->fail('获取域名数据失败'); | 1227 | $this->fail('获取域名数据失败'); |
| 1216 | } | 1228 | } |
| 1217 | - | ||
| 1218 | if($this->param['site_status'] == 1){ | 1229 | if($this->param['site_status'] == 1){ |
| 1219 | //关闭站点:通知C端 | 1230 | //关闭站点:通知C端 |
| 1220 | $re = curl_get('https://'.$domainInfo['domain'].'/api/stop_or_start_website'); | 1231 | $re = curl_get('https://'.$domainInfo['domain'].'/api/stop_or_start_website'); |
| @@ -1255,10 +1266,8 @@ class ProjectController extends BaseController | @@ -1255,10 +1266,8 @@ class ProjectController extends BaseController | ||
| 1255 | } | 1266 | } |
| 1256 | } | 1267 | } |
| 1257 | } | 1268 | } |
| 1258 | - | ||
| 1259 | $projectModel->edit(['site_status'=>$this->param['site_status']],['id'=>$this->param['id']]); | 1269 | $projectModel->edit(['site_status'=>$this->param['site_status']],['id'=>$this->param['id']]); |
| 1260 | } | 1270 | } |
| 1261 | - | ||
| 1262 | $this->response('success'); | 1271 | $this->response('success'); |
| 1263 | } | 1272 | } |
| 1264 | 1273 | ||
| @@ -1328,4 +1337,27 @@ class ProjectController extends BaseController | @@ -1328,4 +1337,27 @@ class ProjectController extends BaseController | ||
| 1328 | $data['videoFrequency'] =$videoModel->videoFrequency(); | 1337 | $data['videoFrequency'] =$videoModel->videoFrequency(); |
| 1329 | $this->response('success',Code::SUCCESS,$data); | 1338 | $this->response('success',Code::SUCCESS,$data); |
| 1330 | } | 1339 | } |
| 1340 | + | ||
| 1341 | + /** | ||
| 1342 | + * @remark :获取广告先投特批 | ||
| 1343 | + * @name :getSpAdsLists | ||
| 1344 | + * @author :lyh | ||
| 1345 | + * @method :post | ||
| 1346 | + * @time :2025/10/22 16:59 | ||
| 1347 | + */ | ||
| 1348 | + public function getSpAdsLists() | ||
| 1349 | + { | ||
| 1350 | + $params = $this->param; | ||
| 1351 | + $url = 'https://oa.cmer.com/api/sp_ads_lists'; | ||
| 1352 | + // 发送 GET 请求(附带 token) | ||
| 1353 | + $params['token'] = md5('qqs' . date('Y-m-d')); | ||
| 1354 | + $response = Http::get($url, $params); | ||
| 1355 | + // 判断请求是否成功 | ||
| 1356 | + if ($response->successful()) { | ||
| 1357 | + $data = $response->json(); // 自动解析 JSON | ||
| 1358 | + $this->response('success', Code::SUCCESS, $data); | ||
| 1359 | + } else { | ||
| 1360 | + $this->fail('拉取结果失败,请联系管理员'); | ||
| 1361 | + } | ||
| 1362 | + } | ||
| 1331 | } | 1363 | } |
| @@ -21,6 +21,9 @@ class AiBlogController extends BaseController | @@ -21,6 +21,9 @@ class AiBlogController extends BaseController | ||
| 21 | * @time :2025/2/14 13:59 | 21 | * @time :2025/2/14 13:59 |
| 22 | */ | 22 | */ |
| 23 | public function getAiBlog(AiBlog $aiBlog){ | 23 | public function getAiBlog(AiBlog $aiBlog){ |
| 24 | + if(isset($this->map['new_title']) && !empty($this->map['new_title'])){ | ||
| 25 | + $this->map['new_title'] = ['like', '%'.$this->map['new_title'].'%']; | ||
| 26 | + } | ||
| 24 | $lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','keyword','new_title','route','image','task_id','status','created_at','updated_at']); | 27 | $lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','keyword','new_title','route','image','task_id','status','created_at','updated_at']); |
| 25 | if(!empty($lists) && !empty($lists['list'])){ | 28 | if(!empty($lists) && !empty($lists['list'])){ |
| 26 | foreach ($lists['list'] as $k => $v){ | 29 | foreach ($lists['list'] as $k => $v){ |
| @@ -389,14 +389,17 @@ class FileController | @@ -389,14 +389,17 @@ class FileController | ||
| 389 | */ | 389 | */ |
| 390 | public function getFileList(){ | 390 | public function getFileList(){ |
| 391 | if(isset($this->cache['project_id']) && !empty($this->cache['project_id'])){ | 391 | if(isset($this->cache['project_id']) && !empty($this->cache['project_id'])){ |
| 392 | - $this->map['project_id'] = $this->cache['project_id']; | 392 | + $this->param['project_id'] = $this->cache['project_id']; |
| 393 | } | 393 | } |
| 394 | $fileModel = new File(); | 394 | $fileModel = new File(); |
| 395 | - $this->map['type'] = 'mp4'; | ||
| 396 | - $lists = $fileModel->list($this->map,'id',['id','hash','type','path','created_at','name']); | ||
| 397 | - foreach ($lists as $k => $v){ | 395 | + $this->param['type'] = 'mp4'; |
| 396 | + $page = $this->param['page'] ?? 1; | ||
| 397 | + $row = $this->param['row'] ?? 20; | ||
| 398 | + unset($this->param['page'],$this->param['row']); | ||
| 399 | + $lists = $fileModel->lists($this->param,$page,$row,'id',['id','hash','type','path','created_at','name']); | ||
| 400 | + foreach ($lists['list'] as $k => $v){ | ||
| 398 | $v['file_link'] = getFileUrl($v['path'],$this->cache['storage_type'] ?? 0,$this->cache['project_location'] ?? 0,$this->cache['file_cdn'] ?? 0); | 401 | $v['file_link'] = getFileUrl($v['path'],$this->cache['storage_type'] ?? 0,$this->cache['project_location'] ?? 0,$this->cache['file_cdn'] ?? 0); |
| 399 | - $lists[$k] = $v; | 402 | + $lists['list'][$k] = $v; |
| 400 | } | 403 | } |
| 401 | $this->response('success',Code::SUCCESS,$lists); | 404 | $this->response('success',Code::SUCCESS,$lists); |
| 402 | } | 405 | } |
app/Http/Logic/Aside/Geo/GeoConfirmLogic.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoConfirmLogic.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 11:36 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Logic\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Enums\Common\Code; | ||
| 13 | +use App\Http\Logic\Aside\BaseLogic; | ||
| 14 | +use App\Models\Geo\GeoConfirm; | ||
| 15 | +use App\Models\ProjectAssociation\ProjectAssociation; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * @remark :用户确认信息 | ||
| 19 | + * @name :GeoConfirmLogic | ||
| 20 | + * @author :lyh | ||
| 21 | + * @method :post | ||
| 22 | + * @time :2025/10/25 11:37 | ||
| 23 | + */ | ||
| 24 | +class GeoConfirmLogic extends BaseLogic | ||
| 25 | +{ | ||
| 26 | + public function __construct() | ||
| 27 | + { | ||
| 28 | + parent::__construct(); | ||
| 29 | + $this->param = $this->requestAll; | ||
| 30 | + $this->model = new GeoConfirm(); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * @remark :保存数据->并推送微信群客户确认 | ||
| 35 | + * @name :saveConfirmContent | ||
| 36 | + * @author :lyh | ||
| 37 | + * @method :post | ||
| 38 | + * @time :2025/10/25 11:41 | ||
| 39 | + */ | ||
| 40 | + public function saveConfirmContent($param) | ||
| 41 | + { | ||
| 42 | + try { | ||
| 43 | + $info = $this->model->read(['project_id' => $param['project_id']]); | ||
| 44 | + if($info === false){ | ||
| 45 | + $id = $this->model->addReturnId($param); | ||
| 46 | + }else{ | ||
| 47 | + $id = $param['id']; | ||
| 48 | + $this->model->edit($param,['id'=>$info['id']]); | ||
| 49 | + } | ||
| 50 | + $friend = ProjectAssociation::where(['project_id' => $param['project_id']])->first(); | ||
| 51 | + if (empty($friend)){ | ||
| 52 | + $this->fail('项目未绑定微信群, 推送消息失败!'); | ||
| 53 | + } | ||
| 54 | + GeoConfirm::sendConfirmMessage($id, $friend->friend_id); | ||
| 55 | + } catch (\Exception $e) { | ||
| 56 | + $this->fail('操作失败, error:' . $e->getMessage()); | ||
| 57 | + } | ||
| 58 | + return $this->success(['id'=>$id]); | ||
| 59 | + } | ||
| 60 | +} |
| @@ -4,109 +4,99 @@ | @@ -4,109 +4,99 @@ | ||
| 4 | * @name :GeoLogic.php | 4 | * @name :GeoLogic.php |
| 5 | * @author :lyh | 5 | * @author :lyh |
| 6 | * @method :post | 6 | * @method :post |
| 7 | - * @time :2025/7/2 17:51 | 7 | + * @time :2025/10/25 11:08 |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | namespace App\Http\Logic\Aside\Geo; | 10 | namespace App\Http\Logic\Aside\Geo; |
| 11 | 11 | ||
| 12 | +use App\Enums\Common\Code; | ||
| 12 | use App\Http\Logic\Aside\BaseLogic; | 13 | use App\Http\Logic\Aside\BaseLogic; |
| 13 | -use App\Models\Geo\GeoPlatform; | 14 | +use App\Models\Geo\GeoConf; |
| 14 | use App\Models\Geo\GeoQuestion; | 15 | use App\Models\Geo\GeoQuestion; |
| 16 | +use App\Models\Manage\ManageHr; | ||
| 17 | +use App\Models\Project\KeywordPrefix; | ||
| 15 | use App\Models\Project\Project; | 18 | use App\Models\Project\Project; |
| 16 | 19 | ||
| 20 | +/** | ||
| 21 | + * @remark :geo设置 | ||
| 22 | + * @name :GeoLogic | ||
| 23 | + * @author :lyh | ||
| 24 | + * @method :post | ||
| 25 | + * @time :2025/10/25 11:08 | ||
| 26 | + */ | ||
| 17 | class GeoLogic extends BaseLogic | 27 | class GeoLogic extends BaseLogic |
| 18 | { | 28 | { |
| 19 | public function __construct() | 29 | public function __construct() |
| 20 | { | 30 | { |
| 21 | parent::__construct(); | 31 | parent::__construct(); |
| 22 | $this->param = $this->requestAll; | 32 | $this->param = $this->requestAll; |
| 23 | - $this->model = new GeoQuestion(); | 33 | + $this->model = new GeoConf(); |
| 24 | } | 34 | } |
| 25 | 35 | ||
| 26 | /** | 36 | /** |
| 27 | - * @remark :设置geo状态 | ||
| 28 | - * @name :setGeoStatus | 37 | + * @remark :获取geo设置数据详情 |
| 38 | + * @name :getCongInfo | ||
| 29 | * @author :lyh | 39 | * @author :lyh |
| 30 | * @method :post | 40 | * @method :post |
| 31 | - * @time :2025/7/2 17:51 | 41 | + * @time :2025/10/25 11:10 |
| 32 | */ | 42 | */ |
| 33 | - public function setGeoStatus(){ | 43 | + public function getCongInfo($project_id) |
| 44 | + { | ||
| 34 | $projectModel = new Project(); | 45 | $projectModel = new Project(); |
| 35 | - $data = $projectModel->edit(['geo_status'=>$this->param['geo_status'],'geo_frequency'=>$this->param['geo_frequency']],['id'=>$this->param['project_id']]); | ||
| 36 | - $questionModel = new GeoQuestion(); | ||
| 37 | - $questionModel->edit(['status'=>$this->param['geo_status']],['project_id'=>$this->param['project_id']]); | ||
| 38 | - return $this->success($data); | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - /** | ||
| 42 | - * @remark :获取类型 | ||
| 43 | - * @name :getType | ||
| 44 | - * @author :lyh | ||
| 45 | - * @method :post | ||
| 46 | - * @time :2025/7/3 10:47 | ||
| 47 | - */ | ||
| 48 | - public function getType(){ | ||
| 49 | - $data['type'] = $this->model->brandType(); | ||
| 50 | - $data['frequency'] = $this->model->frequency; | ||
| 51 | - $geoPlatformModel = new GeoPlatform(); | ||
| 52 | - $data['platform'] = $geoPlatformModel->getList(); | ||
| 53 | - return $this->success($data); | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - /** | ||
| 57 | - * @remark :获取问题列表 | ||
| 58 | - * @name :getGeoQuestionList | ||
| 59 | - * @author :lyh | ||
| 60 | - * @method :post | ||
| 61 | - * @time :2025/7/3 9:12 | ||
| 62 | - */ | ||
| 63 | - public function getGeoQuestionList($map,$page,$row,$order,$field = ['*']){ | ||
| 64 | - $data = $this->model->lists($map,$page,$row,$order,$field); | ||
| 65 | - if(!empty($data) && !empty($data['list'])){ | ||
| 66 | - foreach ($data['list'] as $key => $item){ | ||
| 67 | - $item['type_name'] = $this->model->brandType()[$item['type']]; | ||
| 68 | - $data['list'][$key] = $item; | ||
| 69 | - } | 46 | + $project_geo_conf = $projectModel->read(['id' => $project_id],['title', 'version', 'geo_status', 'geo_qualify_num']); |
| 47 | + $geoConfModel = new GeoConf(); | ||
| 48 | + $geo_conf = $geoConfModel->read(['project_id' => $project_id]); | ||
| 49 | + if($geo_conf === false){//数据未初始化 | ||
| 50 | + $geo_conf = [ | ||
| 51 | + 'project_id' => $project_id, 'manager_id'=>0, 'company'=>$project_geo_conf['title'], 'brand'=>'', 'description'=>'' | ||
| 52 | + ]; | ||
| 70 | } | 53 | } |
| 71 | - return $this->success($data); | 54 | + //负责人集合 |
| 55 | + $geo_manage_list = $geoConfModel->geoManage(); | ||
| 56 | + // geo配置管理员,已经移除管理员列表,补充管理员信息 | ||
| 57 | + if ($geo_conf && $geo_conf['manager_id'] && empty($geo_manage_list[$geo_conf['manager_id']])) { | ||
| 58 | + $manage = ManageHr::where(['id' => $geo_conf['manager_id']])->pluck('name', 'id')->toArray(); | ||
| 59 | + $geo_manage_list = array_merge($geo_manage_list, $manage); | ||
| 60 | + } | ||
| 61 | + $result = [ | ||
| 62 | + 'project_geo_conf' => $project_geo_conf, | ||
| 63 | + 'geo_conf' => $geo_conf, | ||
| 64 | + 'geo_manage_list' => $geo_manage_list, | ||
| 65 | + 'geo_keyword' => [ | ||
| 66 | + 'prefix' => KeywordPrefix::getKeyword($project_id, KeywordPrefix::TYPE_GEO_PREFIX), | ||
| 67 | + 'suffix' => KeywordPrefix::getKeyword($project_id, KeywordPrefix::TYPE_GEO_SUFFIX), | ||
| 68 | + ], | ||
| 69 | + ]; | ||
| 70 | + return $this->success($result); | ||
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | /** | 73 | /** |
| 75 | - * @remark :保存数据 | ||
| 76 | - * @name :saveGeoQuestion | 74 | + * @remark :保存数据详情 |
| 75 | + * @name :saveCongInfo | ||
| 77 | * @author :lyh | 76 | * @author :lyh |
| 78 | * @method :post | 77 | * @method :post |
| 79 | - * @time :2025/7/3 9:47 | ||
| 80 | - * @param : question->提交的问题 | ||
| 81 | - * @param : url->提交的网址 | ||
| 82 | - * @param : keywords->提交的关键字 | ||
| 83 | - * @param : project_id->项目id | 78 | + * @time :2025/10/25 11:14 |
| 79 | + * @param->gl_geo_conf : project_id->项目id;manager_id->管理员id;company->公司名称;brand->品牌名;description->描述(必传) | ||
| 80 | + * @param :prefix->前缀;suffix->后缀(非必传) | ||
| 81 | + * @param->gl_project : geo_status->开启/关闭状态 geo_qualify_num->达标数量 | ||
| 84 | */ | 82 | */ |
| 85 | - public function saveGeoQuestion(){ | ||
| 86 | - //处理数据 | ||
| 87 | - $this->param['question'] = json_encode($this->param['question'] ?? [],true); | ||
| 88 | - $this->param['url'] = json_encode($this->param['url'] ?? [],true); | ||
| 89 | - $this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true); | ||
| 90 | - //执行时间设置为今天 | ||
| 91 | - if(isset($this->param['id']) && !empty($this->param['id'])){ | ||
| 92 | - $id = $this->param['id']; | ||
| 93 | - $this->model->edit($this->param,['id'=>$id]); | ||
| 94 | - }else{ | ||
| 95 | - $this->param['next_time'] = date('Y-m-d'); | ||
| 96 | - $id = $this->model->addReturnId($this->param); | 83 | + public function saveConfig($param) |
| 84 | + { | ||
| 85 | + $projectModel = new Project(); | ||
| 86 | + $projectModel->edit(['geo_status'=>$param['geo_status'],'geo_qualify_num'=>$param['geo_qualify_num']],['id'=>$param['project_id']]); | ||
| 87 | + try { | ||
| 88 | + unset($param['geo_status'],$param['geo_qualify_num']);//无需保存 | ||
| 89 | + $info = $this->model->read(['project_id' => $param['project_id']]); | ||
| 90 | + if($info === false){ | ||
| 91 | + $id = $this->model->addReturnId($param); | ||
| 92 | + }else{ | ||
| 93 | + $id = $param['id']; | ||
| 94 | + $this->model->edit($param,['id'=>$info['id']]); | ||
| 95 | + } | ||
| 96 | + } catch (\Exception $e) { | ||
| 97 | + $this->fail('配置保存失败, error:' . $e->getMessage()); | ||
| 97 | } | 98 | } |
| 98 | return $this->success(['id'=>$id]); | 99 | return $this->success(['id'=>$id]); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | - /** | ||
| 102 | - * @remark :删除数据 | ||
| 103 | - * @name :delGeoQuestion | ||
| 104 | - * @author :lyh | ||
| 105 | - * @method :post | ||
| 106 | - * @time :2025/7/3 10:13 | ||
| 107 | - */ | ||
| 108 | - public function delGeoQuestion(){ | ||
| 109 | - $data = $this->model->del(['id'=>['in',$this->param['ids']]]); | ||
| 110 | - return $this->success($data); | ||
| 111 | - } | ||
| 112 | } | 102 | } |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoQuestionLogic.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/7/2 17:51 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Logic\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Http\Logic\Aside\BaseLogic; | ||
| 13 | +use App\Models\Geo\GeoPlatform; | ||
| 14 | +use App\Models\Geo\GeoQuestion; | ||
| 15 | +use App\Models\Project\Project; | ||
| 16 | + | ||
| 17 | +class GeoQuestionLogic extends BaseLogic | ||
| 18 | +{ | ||
| 19 | + public function __construct() | ||
| 20 | + { | ||
| 21 | + parent::__construct(); | ||
| 22 | + $this->param = $this->requestAll; | ||
| 23 | + $this->model = new GeoQuestion(); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * @remark :设置geo状态 | ||
| 28 | + * @name :setGeoStatus | ||
| 29 | + * @author :lyh | ||
| 30 | + * @method :post | ||
| 31 | + * @time :2025/7/2 17:51 | ||
| 32 | + */ | ||
| 33 | + public function setGeoStatus(){ | ||
| 34 | + $projectModel = new Project(); | ||
| 35 | + $data = $projectModel->edit(['geo_status'=>$this->param['geo_status'],'geo_frequency'=>$this->param['geo_frequency']],['id'=>$this->param['project_id']]); | ||
| 36 | + $questionModel = new GeoQuestion(); | ||
| 37 | + $questionModel->edit(['status'=>$this->param['geo_status']],['project_id'=>$this->param['project_id']]); | ||
| 38 | + return $this->success($data); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * @remark :获取类型 | ||
| 43 | + * @name :getType | ||
| 44 | + * @author :lyh | ||
| 45 | + * @method :post | ||
| 46 | + * @time :2025/7/3 10:47 | ||
| 47 | + */ | ||
| 48 | + public function getType(){ | ||
| 49 | + $data['type'] = $this->model->brandType(); | ||
| 50 | + $data['frequency'] = $this->model->frequency; | ||
| 51 | + $geoPlatformModel = new GeoPlatform(); | ||
| 52 | + $data['platform'] = $geoPlatformModel->getList(); | ||
| 53 | + return $this->success($data); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * @remark :获取问题列表 | ||
| 58 | + * @name :getGeoQuestionList | ||
| 59 | + * @author :lyh | ||
| 60 | + * @method :post | ||
| 61 | + * @time :2025/7/3 9:12 | ||
| 62 | + */ | ||
| 63 | + public function getGeoQuestionList($map,$page,$row,$order,$field = ['*']){ | ||
| 64 | + $data = $this->model->lists($map,$page,$row,$order,$field); | ||
| 65 | + if(!empty($data) && !empty($data['list'])){ | ||
| 66 | + foreach ($data['list'] as $key => $item){ | ||
| 67 | + $item['type_name'] = $this->model->brandType()[$item['type']]; | ||
| 68 | + $data['list'][$key] = $item; | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + return $this->success($data); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * @remark :保存数据 | ||
| 76 | + * @name :saveGeoQuestion | ||
| 77 | + * @author :lyh | ||
| 78 | + * @method :post | ||
| 79 | + * @time :2025/7/3 9:47 | ||
| 80 | + * @param : question->提交的问题 | ||
| 81 | + * @param : url->提交的网址 | ||
| 82 | + * @param : keywords->提交的关键字 | ||
| 83 | + * @param : project_id->项目id | ||
| 84 | + */ | ||
| 85 | + public function saveGeoQuestion(){ | ||
| 86 | + //处理数据 | ||
| 87 | + $this->param['question'] = json_encode($this->param['question'] ?? [],true); | ||
| 88 | + $this->param['url'] = json_encode($this->param['url'] ?? [],true); | ||
| 89 | + $this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true); | ||
| 90 | + //执行时间设置为今天 | ||
| 91 | + if(isset($this->param['id']) && !empty($this->param['id'])){ | ||
| 92 | + $id = $this->param['id']; | ||
| 93 | + $this->model->edit($this->param,['id'=>$id]); | ||
| 94 | + }else{ | ||
| 95 | + $this->param['next_time'] = date('Y-m-d'); | ||
| 96 | + $id = $this->model->addReturnId($this->param); | ||
| 97 | + } | ||
| 98 | + return $this->success(['id'=>$id]); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * @remark :删除数据 | ||
| 103 | + * @name :delGeoQuestion | ||
| 104 | + * @author :lyh | ||
| 105 | + * @method :post | ||
| 106 | + * @time :2025/7/3 10:13 | ||
| 107 | + */ | ||
| 108 | + public function delGeoQuestion(){ | ||
| 109 | + $data = $this->model->del(['id'=>['in',$this->param['ids']]]); | ||
| 110 | + return $this->success($data); | ||
| 111 | + } | ||
| 112 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingsLogic.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 10:43 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Logic\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Http\Logic\Aside\BaseLogic; | ||
| 13 | +use App\Models\Geo\GeoWritings; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * @remark :文章任务 | ||
| 17 | + * @name :GeoWritingsLogic | ||
| 18 | + * @author :lyh | ||
| 19 | + * @method :post | ||
| 20 | + * @time :2025/10/25 10:44 | ||
| 21 | + */ | ||
| 22 | +class GeoWritingsLogic extends BaseLogic | ||
| 23 | +{ | ||
| 24 | + public function __construct() | ||
| 25 | + { | ||
| 26 | + parent::__construct(); | ||
| 27 | + $this->param = $this->requestAll; | ||
| 28 | + $this->model = new GeoWritings(); | ||
| 29 | + } | ||
| 30 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingsTaskLogic.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 10:45 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Logic\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use App\Http\Logic\Aside\BaseLogic; | ||
| 13 | +use App\Models\Geo\GeoWritings; | ||
| 14 | +use App\Models\Geo\GeoWritingsTask; | ||
| 15 | + | ||
| 16 | +class GeoWritingsTaskLogic extends BaseLogic | ||
| 17 | +{ | ||
| 18 | + public function __construct() | ||
| 19 | + { | ||
| 20 | + parent::__construct(); | ||
| 21 | + $this->param = $this->requestAll; | ||
| 22 | + $this->model = new GeoWritingsTask(); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * @remark : | ||
| 27 | + * @name :listWritingTask | ||
| 28 | + * @author :lyh | ||
| 29 | + * @method :post | ||
| 30 | + * @time :2025/10/25 15:13 | ||
| 31 | + */ | ||
| 32 | + public function listWritingTask($map,$page,$row,$order){ | ||
| 33 | + $data = $this->model->lists($map,$page,$row,$order); | ||
| 34 | + return $this->success($data); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * @remark :保存AI文章数据 | ||
| 39 | + * @name :saveWritingTask | ||
| 40 | + * @author :lyh | ||
| 41 | + * @method :post | ||
| 42 | + * @time :2025/10/25 14:41 | ||
| 43 | + * @param :project_id->项目ID;company->公司名称;brand->品牌词;keyword->关键词;prefix->前缀;suffix->后缀;event_title->事件标题; | ||
| 44 | + * event_content->事件内容;title->标题;description->描述;footer->结尾引用;img->图片;ai_model->ai_model | ||
| 45 | + */ | ||
| 46 | + public function saveWritingTask(){ | ||
| 47 | + try { | ||
| 48 | + if(isset($this->param['id']) &&!empty($this->param['id'])){ | ||
| 49 | + $id = $this->param['id']; | ||
| 50 | + $this->model->edit($this->param,['id'=>$id]); | ||
| 51 | + }else{ | ||
| 52 | + $id = $this->model->addReturnId($this->param); | ||
| 53 | + } | ||
| 54 | + }catch (\Exception $e){ | ||
| 55 | + $this->fail('保存数据失败,请联系管理员'.$e->getMessage()); | ||
| 56 | + } | ||
| 57 | + return $this->success(['id'=>$id]); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * @remark :删除数据 | ||
| 62 | + * @name :delWritingTask | ||
| 63 | + * @author :lyh | ||
| 64 | + * @method :post | ||
| 65 | + * @time :2025/10/25 15:05 | ||
| 66 | + */ | ||
| 67 | + public function delWritingTask() | ||
| 68 | + { | ||
| 69 | + $res = $this->model->del(['id'=>['in',$this->param['id']]]); | ||
| 70 | + if($res === false){ | ||
| 71 | + $this->fail('删除失败,请联系管理员'); | ||
| 72 | + } | ||
| 73 | + return $this->success(); | ||
| 74 | + } | ||
| 75 | +} |
| @@ -123,10 +123,6 @@ class ProjectLogic extends BaseLogic | @@ -123,10 +123,6 @@ class ProjectLogic extends BaseLogic | ||
| 123 | $info['collect_test_domain'] = $info['is_upgrade'] ? CollectLog::getCollectTestDomain($id) : ''; | 123 | $info['collect_test_domain'] = $info['is_upgrade'] ? CollectLog::getCollectTestDomain($id) : ''; |
| 124 | //获取项目所属行业 | 124 | //获取项目所属行业 |
| 125 | $info['deploy_optimize']['industry'] = ProjectIndustryRelated::where('project_id', $id)->pluck('industry_id')->toArray(); | 125 | $info['deploy_optimize']['industry'] = ProjectIndustryRelated::where('project_id', $id)->pluck('industry_id')->toArray(); |
| 126 | - $questionModel = new GeoQuestionResult(); | ||
| 127 | - $info['question_qualify_count'] = $questionModel->where('project_id', $id) | ||
| 128 | - ->where('hit','!=',0)->whereIn('platform',['openai', 'gemini','google_ai_overview']) | ||
| 129 | - ->count(); | ||
| 130 | return $this->success($info); | 126 | return $this->success($info); |
| 131 | } | 127 | } |
| 132 | 128 |
| @@ -34,9 +34,20 @@ class GeoQuestionResLogic extends BaseLogic | @@ -34,9 +34,20 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 34 | * @time :2025/7/8 17:16 | 34 | * @time :2025/7/8 17:16 |
| 35 | */ | 35 | */ |
| 36 | public function getCount(){ | 36 | public function getCount(){ |
| 37 | - $total = $this->model->counts(['project_id'=>$this->user['project_id']]); | ||
| 38 | - $type_1 = $this->model->counts(['type'=>$this->model::BRAND_TYPE,'project_id'=>$this->user['project_id']]); | ||
| 39 | - $type_2 = $this->model->counts(['type'=>$this->model::MARKETING_TYPE,'project_id'=>$this->user['project_id']]); | 37 | + $total = $this->model |
| 38 | + ->where('project_id', $this->user['project_id']) | ||
| 39 | + ->distinct('question') | ||
| 40 | + ->count('question'); | ||
| 41 | + $type_1 = $this->model | ||
| 42 | + ->where('type', $this->model::BRAND_TYPE) | ||
| 43 | + ->where('project_id', $this->user['project_id']) | ||
| 44 | + ->distinct('question') | ||
| 45 | + ->count('question'); | ||
| 46 | + $type_2 = $this->model | ||
| 47 | + ->where('type', $this->model::MARKETING_TYPE) | ||
| 48 | + ->where('project_id', $this->user['project_id']) | ||
| 49 | + ->distinct('question') | ||
| 50 | + ->count('question'); | ||
| 40 | return $this->success(['total'=>$total,'type_1'=>$type_1,'type_2'=>$type_2]); | 51 | return $this->success(['total'=>$total,'type_1'=>$type_1,'type_2'=>$type_2]); |
| 41 | } | 52 | } |
| 42 | 53 |
| @@ -5,6 +5,8 @@ namespace App\Http\Logic\Bside\HomeCount; | @@ -5,6 +5,8 @@ namespace App\Http\Logic\Bside\HomeCount; | ||
| 5 | 5 | ||
| 6 | use App\Helper\FormGlobalsoApi; | 6 | use App\Helper\FormGlobalsoApi; |
| 7 | use App\Http\Logic\Bside\BaseLogic; | 7 | use App\Http\Logic\Bside\BaseLogic; |
| 8 | +use App\Models\Geo\GeoCount; | ||
| 9 | +use App\Models\RankData\RankDataBmseo; | ||
| 8 | use App\Models\Template\BCustomTemplate; | 10 | use App\Models\Template\BCustomTemplate; |
| 9 | use App\Models\Visit\Visit; | 11 | use App\Models\Visit\Visit; |
| 10 | use App\Models\Visit\VisitItem; | 12 | use App\Models\Visit\VisitItem; |
| @@ -101,8 +103,13 @@ class CountLogic extends BaseLogic | @@ -101,8 +103,13 @@ class CountLogic extends BaseLogic | ||
| 101 | * @time :2023/5/24 14:03 | 103 | * @time :2023/5/24 14:03 |
| 102 | */ | 104 | */ |
| 103 | public function keyword_data_count(){ | 105 | public function keyword_data_count(){ |
| 106 | + $version = $this->project['version'] ?? ''; | ||
| 104 | $yesterday = date('Y-m-d'); | 107 | $yesterday = date('Y-m-d'); |
| 105 | - $rankDataModel = new RankDataModel(); | 108 | + if($this->user['project_seo_type'] == 1){ |
| 109 | + $rankDataModel = new RankDataBmseo(); | ||
| 110 | + }else{ | ||
| 111 | + $rankDataModel = new RankDataModel(); | ||
| 112 | + } | ||
| 106 | $param = [ | 113 | $param = [ |
| 107 | 'updated_date' => $yesterday, | 114 | 'updated_date' => $yesterday, |
| 108 | 'project_id' => $this->user['project_id'] | 115 | 'project_id' => $this->user['project_id'] |
| @@ -117,6 +124,13 @@ class CountLogic extends BaseLogic | @@ -117,6 +124,13 @@ class CountLogic extends BaseLogic | ||
| 117 | $data = []; | 124 | $data = []; |
| 118 | } | 125 | } |
| 119 | } | 126 | } |
| 127 | + if(!empty($version) && ($version == '7.5')){ | ||
| 128 | + $geoCountModel = new GeoCount(); | ||
| 129 | + $geoInfo = $geoCountModel->where('project_id',$this->user['project_id'])->where('date', '<=', date('Y-m-d'))->orderBy('date', 'desc')->first(); | ||
| 130 | + $geoInfo = $geoInfo ? $geoInfo->toArray() : []; | ||
| 131 | + $data['geo_qualify_total'] = $geoInfo['qualify_total'] ?? 0; | ||
| 132 | + $data['total_count'] = ($this->project['deploy_build']['keyword_num'] ?? 0) + ($this->project['geo_qualify_num'] ?? 0); | ||
| 133 | + } | ||
| 120 | return $this->success($data); | 134 | return $this->success($data); |
| 121 | } | 135 | } |
| 122 | 136 |
| @@ -93,7 +93,7 @@ class ProductLogic extends BaseLogic | @@ -93,7 +93,7 @@ class ProductLogic extends BaseLogic | ||
| 93 | $route = $param['route']; | 93 | $route = $param['route']; |
| 94 | $is_upgrade = $param['is_upgrade'] ?? 0;//1:5.0数据 0:6.0 | 94 | $is_upgrade = $param['is_upgrade'] ?? 0;//1:5.0数据 0:6.0 |
| 95 | $six_read = $param['six_read'] ?? 0;//是否按6.0显示 | 95 | $six_read = $param['six_read'] ?? 0;//是否按6.0显示 |
| 96 | - if($six_read == 0 && $is_upgrade == 1){ | 96 | + if($six_read == 1 && $is_upgrade == 1){ |
| 97 | unset($param['route']); | 97 | unset($param['route']); |
| 98 | }else{ | 98 | }else{ |
| 99 | $param['route'] = RouteMap::setRoute($param['route'], RouteMap::SOURCE_PRODUCT, $this->param['id'], $this->user['project_id']); | 99 | $param['route'] = RouteMap::setRoute($param['route'], RouteMap::SOURCE_PRODUCT, $this->param['id'], $this->user['project_id']); |
| @@ -35,6 +35,9 @@ class WebSettingReceivingLogic extends BaseLogic | @@ -35,6 +35,9 @@ class WebSettingReceivingLogic extends BaseLogic | ||
| 35 | */ | 35 | */ |
| 36 | public function setting_receiving_save(){ | 36 | public function setting_receiving_save(){ |
| 37 | $data = []; | 37 | $data = []; |
| 38 | + if(!isset($this->param['data']) || empty($this->param['data'])){ | ||
| 39 | + $this->fail('参数错误,请联系管理员'); | ||
| 40 | + } | ||
| 38 | foreach ($this->param['data'] as $v){ | 41 | foreach ($this->param['data'] as $v){ |
| 39 | if($v['type'] == 1){ | 42 | if($v['type'] == 1){ |
| 40 | // 使用正则表达式匹配中国大陆手机号 | 43 | // 使用正则表达式匹配中国大陆手机号 |
| @@ -286,6 +286,7 @@ class UserLoginLogic | @@ -286,6 +286,7 @@ class UserLoginLogic | ||
| 286 | $info['is_watermark'] = $project['is_watermark']; | 286 | $info['is_watermark'] = $project['is_watermark']; |
| 287 | $info['configuration'] = $project['deploy_build']['configuration']; | 287 | $info['configuration'] = $project['deploy_build']['configuration']; |
| 288 | $info['project_type'] = $project['type']; | 288 | $info['project_type'] = $project['type']; |
| 289 | + $info['version'] = $project['version'] ?? 6; | ||
| 289 | $info['project_seo_type'] = $project['project_type']; | 290 | $info['project_seo_type'] = $project['project_type']; |
| 290 | $info['storage_type'] = $project['storage_type']; | 291 | $info['storage_type'] = $project['storage_type']; |
| 291 | $info['open_export_product'] = $project['open_export_product']; | 292 | $info['open_export_product'] = $project['open_export_product']; |
| @@ -55,7 +55,7 @@ class LoginAuthMiddleware | @@ -55,7 +55,7 @@ class LoginAuthMiddleware | ||
| 55 | //操作权限设置 | 55 | //操作权限设置 |
| 56 | $projectRoleModel = new ProjectRoleModel(); | 56 | $projectRoleModel = new ProjectRoleModel(); |
| 57 | $role_info = $projectRoleModel->read(['id'=>$info['role_id']]); | 57 | $role_info = $projectRoleModel->read(['id'=>$info['role_id']]); |
| 58 | - if($role_info['status'] != 0){ | 58 | + if($role_info === false || $role_info['status'] != 0){ |
| 59 | return response(['code'=>Code::USER_LOGIN_ERROE,'message'=>'当前用户角色被禁用']); | 59 | return response(['code'=>Code::USER_LOGIN_ERROE,'message'=>'当前用户角色被禁用']); |
| 60 | } | 60 | } |
| 61 | return $role_info; | 61 | return $role_info; |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingsTaskRequest.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 14:21 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Http\Requests\Aside\Geo; | ||
| 11 | + | ||
| 12 | +use Illuminate\Foundation\Http\FormRequest; | ||
| 13 | + | ||
| 14 | +class GeoWritingsTaskRequest extends FormRequest | ||
| 15 | +{ | ||
| 16 | + /** | ||
| 17 | + * Determine if the user is authorized to make this request. | ||
| 18 | + * | ||
| 19 | + * @return bool | ||
| 20 | + */ | ||
| 21 | + public function authorize() | ||
| 22 | + { | ||
| 23 | + return true; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * Get the validation rules that apply to the request. | ||
| 28 | + * | ||
| 29 | + * @return array | ||
| 30 | + */ | ||
| 31 | + public function rules() | ||
| 32 | + { | ||
| 33 | + return [ | ||
| 34 | + 'project_id' => 'required', | ||
| 35 | + 'company' => 'required|string', | ||
| 36 | + 'brand' => 'required|string', | ||
| 37 | + 'keyword' => 'required|string', | ||
| 38 | + 'prefix' => 'required|string', | ||
| 39 | + 'suffix' => 'required|string', | ||
| 40 | + 'event_title' => 'required|string', | ||
| 41 | + 'event_content' => 'required|string', | ||
| 42 | + 'title' => 'required|string', | ||
| 43 | + 'description' => 'required|string', | ||
| 44 | + 'footer' => 'required|string', | ||
| 45 | + 'img' => 'required|string', | ||
| 46 | + 'ai_model' => 'required|string', | ||
| 47 | + ]; | ||
| 48 | + } | ||
| 49 | +} |
| @@ -26,7 +26,7 @@ class NewsRequest extends FormRequest | @@ -26,7 +26,7 @@ class NewsRequest extends FormRequest | ||
| 26 | return [ | 26 | return [ |
| 27 | 'name'=>'required|max:200', | 27 | 'name'=>'required|max:200', |
| 28 | 'url'=>'required', | 28 | 'url'=>'required', |
| 29 | -// 'seo_title' => 'max:70', | 29 | + 'seo_title' => 'max:70', |
| 30 | 'seo_keywords' => 'max:300', | 30 | 'seo_keywords' => 'max:300', |
| 31 | 'seo_description' => 'max:200', | 31 | 'seo_description' => 'max:200', |
| 32 | ]; | 32 | ]; |
| @@ -38,7 +38,7 @@ class NewsRequest extends FormRequest | @@ -38,7 +38,7 @@ class NewsRequest extends FormRequest | ||
| 38 | 'name.required'=>'请填写名称', | 38 | 'name.required'=>'请填写名称', |
| 39 | 'name.max'=>'名称超过最长长度200', | 39 | 'name.max'=>'名称超过最长长度200', |
| 40 | 'url.required'=>'链接不能为空', | 40 | 'url.required'=>'链接不能为空', |
| 41 | -// 'seo_title.max' => 'SEO标题不能超过70个字符', | 41 | + 'seo_title.max' => 'SEO标题不能超过70个字符', |
| 42 | 'seo_keywords.max' => 'SEO关键词不能超过300个字符', | 42 | 'seo_keywords.max' => 'SEO关键词不能超过300个字符', |
| 43 | 'seo_description.max' => 'SEO描述不能超过200个字符', | 43 | 'seo_description.max' => 'SEO描述不能超过200个字符', |
| 44 | ]; | 44 | ]; |
app/Models/Geo/GeoConf.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: zhl | ||
| 5 | + * Date: 2025/10/22 | ||
| 6 | + * Time: 17:01 | ||
| 7 | + */ | ||
| 8 | +namespace App\Models\Geo; | ||
| 9 | + | ||
| 10 | +use App\Models\Base; | ||
| 11 | +use App\Models\Manage\ManageHr; | ||
| 12 | +use Illuminate\Support\Facades\Cache; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * GEO 相关配置 | ||
| 16 | + * Class GeoConf | ||
| 17 | + * @package App\Models\Geo | ||
| 18 | + */ | ||
| 19 | +class GeoConf extends Base | ||
| 20 | +{ | ||
| 21 | + /** | ||
| 22 | + * @var string table | ||
| 23 | + */ | ||
| 24 | + protected $table = 'gl_project_geo_conf'; | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * GEO 负责人集合 | ||
| 29 | + * TODO 负责人:优化师 + 陶婵 + 艾媛媛 | ||
| 30 | + * @return array | ||
| 31 | + */ | ||
| 32 | + public function geoManage() | ||
| 33 | + { | ||
| 34 | + $key = 'geo_manage_list_' . date('Ymd'); | ||
| 35 | + $optimize = Cache::get($key); | ||
| 36 | + if (empty($optimize)) { | ||
| 37 | + $optimize = ManageHr::where(['status' => ManageHr::STATUS_ONE, 'entry_position' => 46])->pluck('name', 'id')->toArray(); | ||
| 38 | + $optimize[1] = '陶婵'; | ||
| 39 | + $optimize[875] = '艾媛媛'; | ||
| 40 | + ksort($optimize); | ||
| 41 | + Cache::put($key, $optimize, 3600); | ||
| 42 | + } | ||
| 43 | + return $optimize; | ||
| 44 | + } | ||
| 45 | +} |
app/Models/Geo/GeoConfirm.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: zhl | ||
| 5 | + * Date: 2025/10/22 | ||
| 6 | + * Time: 17:03 | ||
| 7 | + */ | ||
| 8 | +namespace App\Models\Geo; | ||
| 9 | + | ||
| 10 | +use App\Models\Base; | ||
| 11 | +use App\Models\Workchat\MessagePush; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * GEO 客户确认相关数据 | ||
| 15 | + * Class GeoConfirm | ||
| 16 | + * @package App\Models\Geo | ||
| 17 | + */ | ||
| 18 | +class GeoConfirm extends Base | ||
| 19 | +{ | ||
| 20 | + /** | ||
| 21 | + * @var string table | ||
| 22 | + */ | ||
| 23 | + protected $table = 'gl_project_geo_confirm'; | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 客户确认类型 | ||
| 27 | + */ | ||
| 28 | + const TYPE_TITLE = 1; | ||
| 29 | + const TYPE_KEYWORD = 2; | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 数据状态 | ||
| 33 | + */ | ||
| 34 | + const STATUS_INIT = 1; # 初始化数据,仅保存完成 | ||
| 35 | + const STATUS_RUNNING = 2; # 已推送客户,等待客户确认 | ||
| 36 | + const STATUS_FINISH = 3; # 客户已确认完成 | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 客户确认数据类型 | ||
| 40 | + * @return array | ||
| 41 | + */ | ||
| 42 | + public static function typeMapping() | ||
| 43 | + { | ||
| 44 | + return [ | ||
| 45 | + self::TYPE_TITLE => '确认标题', | ||
| 46 | + self::TYPE_KEYWORD => '确认关键词' | ||
| 47 | + ]; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 客户确认数据状态 | ||
| 52 | + * @return array | ||
| 53 | + */ | ||
| 54 | + public static function statusMapping() | ||
| 55 | + { | ||
| 56 | + return [ | ||
| 57 | + self::STATUS_INIT => '初始数据', | ||
| 58 | + self::STATUS_RUNNING => '数据确认中', | ||
| 59 | + self::STATUS_FINISH => '客户已确认' | ||
| 60 | + ]; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * 保存确认数据 | ||
| 66 | + * @param $project_id | ||
| 67 | + * @param $type | ||
| 68 | + * @param $confirm | ||
| 69 | + * @param $confirm_num | ||
| 70 | + * @param $confirm_ip | ||
| 71 | + * @return bool | ||
| 72 | + */ | ||
| 73 | + public static function saveConfirm($project_id, $type, $confirm, $confirm_num, $confirm_ip) | ||
| 74 | + { | ||
| 75 | + $data = self::where(compact('project_id', 'type'))->first(); | ||
| 76 | + if (empty($data)) | ||
| 77 | + return false; | ||
| 78 | + $data->confirm = $confirm; | ||
| 79 | + $data->confirm_ip = $confirm_ip; | ||
| 80 | + $data->confirm_num = $confirm_num; | ||
| 81 | + $data->confirm_at = now(); | ||
| 82 | + $data->status = self::STATUS_FINISH; | ||
| 83 | + $data->save(); | ||
| 84 | + return $data; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * 推送确认消息 | ||
| 89 | + * @param $id | ||
| 90 | + * @return bool | ||
| 91 | + */ | ||
| 92 | + public static function sendConfirmMessage($id, $friend_id) | ||
| 93 | + { | ||
| 94 | + $data = self::where(compact('id'))->first(); | ||
| 95 | + $project_id = $data->project_id; | ||
| 96 | + $content_type = 'Link'; | ||
| 97 | + $send_time = now(); | ||
| 98 | + $type = MessagePush::TYPE_GEO_CONFIRM; | ||
| 99 | + $token = uniqid().$friend_id; | ||
| 100 | + $created_at = $updated_at = now(); | ||
| 101 | + $content_array = [ | ||
| 102 | + 'title' => self::typeMapping()[$data->type], | ||
| 103 | + 'desc' => self::typeMapping()[$data->type], | ||
| 104 | + 'size' => 0, | ||
| 105 | + 'thumbSize' => 0, | ||
| 106 | + 'thumbUrl' => 'https://hub.globalso.com/logocm.png', | ||
| 107 | + 'url' => 'https://oa.quanqiusou.cn/public-geo-confirm?token=' . $token | ||
| 108 | + ]; | ||
| 109 | + $content = json_encode($content_array, JSON_UNESCAPED_UNICODE); | ||
| 110 | + MessagePush::insert(compact('project_id', 'friend_id', 'type', 'content_type', 'content', 'send_time', 'updated_at', 'created_at')); | ||
| 111 | + // 消息推送, 更新数据 | ||
| 112 | + $data->confirm = ''; | ||
| 113 | + $data->send_at = now(); | ||
| 114 | + $data->uniqid = $token; | ||
| 115 | + $data->status = self::STATUS_RUNNING; | ||
| 116 | + $data->save(); | ||
| 117 | + return $data; | ||
| 118 | + } | ||
| 119 | +} |
| @@ -35,7 +35,7 @@ class GeoPlatform extends Base | @@ -35,7 +35,7 @@ class GeoPlatform extends Base | ||
| 35 | public function getList(){ | 35 | public function getList(){ |
| 36 | // $data = Cache::get('geo_platform'); | 36 | // $data = Cache::get('geo_platform'); |
| 37 | // if(empty($data)){ | 37 | // if(empty($data)){ |
| 38 | - $data = $this->list(['status'=>$this::STATUS_ON],'id',['name','en_name','icon','sort'],'asc'); | 38 | + $data = $this->list(['status'=>$this::STATUS_ON],'sort',['name','en_name','icon','sort'],'desc'); |
| 39 | Cache::put('geo_platform',$data,'12 * 3600'); | 39 | Cache::put('geo_platform',$data,'12 * 3600'); |
| 40 | // } | 40 | // } |
| 41 | return $data; | 41 | return $data; |
app/Models/Geo/GeoWritings.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: zhl | ||
| 5 | + * Date: 2025/10/22 | ||
| 6 | + * Time: 17:25 | ||
| 7 | + */ | ||
| 8 | +namespace App\Models\Geo; | ||
| 9 | + | ||
| 10 | +use App\Models\Base; | ||
| 11 | +use App\Models\ProjectAssociation\ProjectAssociation; | ||
| 12 | +use App\Models\Workchat\MessagePush; | ||
| 13 | +use Illuminate\Support\Facades\Crypt; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * GEO 文章相关 | ||
| 17 | + * Class GeoWritings | ||
| 18 | + * @package App\Models\Geo | ||
| 19 | + */ | ||
| 20 | +class GeoWritings extends Base | ||
| 21 | +{ | ||
| 22 | + /** | ||
| 23 | + * @var string $table | ||
| 24 | + */ | ||
| 25 | + protected $table = 'gl_project_geo_writings'; | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 文章来源类型 | ||
| 29 | + */ | ||
| 30 | + const TYPE_AI_CREATE = 1; | ||
| 31 | + const TYPE_SUBMIT = 2; | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 文章状态类型 | ||
| 35 | + */ | ||
| 36 | + const STATUS_INIT = 1; # 文章仅保存完成,未推送给客户 | ||
| 37 | + const STATUS_RUNNING = 2; # 已推送客户,等待客户确认 | ||
| 38 | + const STATUS_FINISH = 3; # 客户已确认完成 | ||
| 39 | + const STATUS_AI_WAIT = 7; # 任务提交成功,等待AI生成 | ||
| 40 | + const STATUS_AI_RUNNING = 8; # AI生成中 | ||
| 41 | + | ||
| 42 | + const IS_DEL_FALSE = 0; | ||
| 43 | + const IS_DEL_TRUE = 1; | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * @return array | ||
| 47 | + */ | ||
| 48 | + public static function typeMapping() | ||
| 49 | + { | ||
| 50 | + return [ | ||
| 51 | + self::TYPE_AI_CREATE => 'AI生成文章', | ||
| 52 | + self::TYPE_SUBMIT => '上传已有文章' | ||
| 53 | + ]; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 状态隐私 | ||
| 58 | + * @return array | ||
| 59 | + */ | ||
| 60 | + public static function statusMapping() | ||
| 61 | + { | ||
| 62 | + return [ | ||
| 63 | + self::STATUS_INIT => '已就绪,待推送', | ||
| 64 | + self::STATUS_RUNNING => '已推送,待确认', | ||
| 65 | + self::STATUS_FINISH => '已确认', | ||
| 66 | + self::STATUS_AI_WAIT => '等待生成', | ||
| 67 | + self::STATUS_AI_RUNNING => '生成中', | ||
| 68 | + ]; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 推送确认消息 | ||
| 73 | + * TODO 通过项目ID,时间生成推送token,页面打开后, 回传token解码确定展示项目数据 | ||
| 74 | + * @param $project_id | ||
| 75 | + * @return bool | ||
| 76 | + * @throws \Exception | ||
| 77 | + */ | ||
| 78 | + public static function sendConfirmMessage($project_id) | ||
| 79 | + { | ||
| 80 | + $friend = ProjectAssociation::where(['project_id' => $project_id])->first(); | ||
| 81 | + if (empty($friend)) { | ||
| 82 | + throw new \Exception('项目未绑定微信群'); | ||
| 83 | + } | ||
| 84 | + $content_type = 'Link'; | ||
| 85 | + $send_time = now(); | ||
| 86 | + $type = MessagePush::TYPE_GEO_CONFIRM; | ||
| 87 | + $friend_id = $friend->friend_id; | ||
| 88 | + $created_at = $updated_at = now(); | ||
| 89 | + $param = [ | ||
| 90 | + 'project_id' => $project_id, | ||
| 91 | + 'send_at' => time() | ||
| 92 | + ]; | ||
| 93 | + $token = Crypt::encrypt($param); | ||
| 94 | + $content_array = [ | ||
| 95 | + 'title' => "确认核心文章", | ||
| 96 | + 'desc' => '确认核心文章', | ||
| 97 | + 'size' => 0, | ||
| 98 | + 'thumbSize' => 0, | ||
| 99 | + 'thumbUrl' => 'https://hub.globalso.com/logocm.png', | ||
| 100 | + 'url' => 'https://oa.quanqiusou.cn/public-geo-article-list?token=' . $token | ||
| 101 | + ]; | ||
| 102 | + $content = json_encode($content_array, JSON_UNESCAPED_UNICODE); | ||
| 103 | + MessagePush::insert(compact('project_id', 'friend_id', 'type', 'content_type', 'content', 'send_time', 'updated_at', 'created_at')); | ||
| 104 | + return true; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | +} |
app/Models/Geo/GeoWritingsTask.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoWritingsTask.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/25 10:47 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Models\Geo; | ||
| 11 | + | ||
| 12 | +use App\Models\Base; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * @remark :文章生成任务 | ||
| 16 | + * @name :GeoWritingsTask | ||
| 17 | + * @author :lyh | ||
| 18 | + * @method :post | ||
| 19 | + * @time :2025/10/25 10:48 | ||
| 20 | + */ | ||
| 21 | +class GeoWritingsTask extends Base | ||
| 22 | +{ | ||
| 23 | + protected $table = 'gl_project_geo_writings_task'; | ||
| 24 | +} |
| @@ -5,10 +5,10 @@ namespace App\Models\Inquiry; | @@ -5,10 +5,10 @@ namespace App\Models\Inquiry; | ||
| 5 | use App\Helper\Arr; | 5 | use App\Helper\Arr; |
| 6 | use App\Helper\FormGlobalsoApi; | 6 | use App\Helper\FormGlobalsoApi; |
| 7 | use App\Models\Base; | 7 | use App\Models\Base; |
| 8 | -use App\Utils\LogUtils; | ||
| 9 | use Illuminate\Database\Eloquent\SoftDeletes; | 8 | use Illuminate\Database\Eloquent\SoftDeletes; |
| 10 | use Illuminate\Support\Facades\DB; | 9 | use Illuminate\Support\Facades\DB; |
| 11 | use Illuminate\Support\Facades\Log; | 10 | use Illuminate\Support\Facades\Log; |
| 11 | +use Illuminate\Support\Str; | ||
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * Class InquiryFormData | 14 | * Class InquiryFormData |
| @@ -42,7 +42,7 @@ class InquiryFormData extends Base | @@ -42,7 +42,7 @@ class InquiryFormData extends Base | ||
| 42 | * @author zbj | 42 | * @author zbj |
| 43 | * @date 2023/12/4 | 43 | * @date 2023/12/4 |
| 44 | */ | 44 | */ |
| 45 | - public static function saveData($form_id, $domain, $ip, $country, $referer, $user_agent, $submit_at, $data, $traffic = 0){ | 45 | + public static function saveData($form_id, $domain, $ip, $country, $referer, $user_agent, $submit_at, $data, $project_id, $traffic = 0){ |
| 46 | if(!empty($data['email'])){ | 46 | if(!empty($data['email'])){ |
| 47 | $data['email'] = str_replace(' ', '', $data['email']); | 47 | $data['email'] = str_replace(' ', '', $data['email']); |
| 48 | } | 48 | } |
| @@ -96,6 +96,14 @@ class InquiryFormData extends Base | @@ -96,6 +96,14 @@ class InquiryFormData extends Base | ||
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | $res = (new FormGlobalsoApi())->submitInquiry($ip, $referer, $submit_at, $data, $traffic); | 98 | $res = (new FormGlobalsoApi())->submitInquiry($ip, $referer, $submit_at, $data, $traffic); |
| 99 | + //自定义推送 | ||
| 100 | + if($project_id == 3870) { //走这里发送的,关杰那边也要取消发送邮件 | ||
| 101 | + list($mobile, $email) = self::SpecialMailPhone($referer); | ||
| 102 | + Log::channel('inquiry')->info('自定义推送', [$mobile, $email]); | ||
| 103 | + $body = self::specialInquiryTemplate($data['name'], $data['email'], $data['phone'] ?? "", $data['message'], $domain, $ip, $country); | ||
| 104 | + (new FormGlobalsoApi())->customizeInquiryEmail($email, '询盘客户<' . $data['name'] . '>', $body, $ip, $referer, $submit_at); | ||
| 105 | + (new FormGlobalsoApi())->customizeInquirySms($mobile, $country, $domain); | ||
| 106 | + } | ||
| 99 | Log::channel('inquiry')->info('询盘发送邮件', [$data, $res]); | 107 | Log::channel('inquiry')->info('询盘发送邮件', [$data, $res]); |
| 100 | if(!$res){ | 108 | if(!$res){ |
| 101 | throw new \Exception('询盘发送邮件失败'); | 109 | throw new \Exception('询盘发送邮件失败'); |
| @@ -118,6 +126,123 @@ class InquiryFormData extends Base | @@ -118,6 +126,123 @@ class InquiryFormData extends Base | ||
| 118 | } | 126 | } |
| 119 | 127 | ||
| 120 | /** | 128 | /** |
| 129 | + * 获取推送邮箱和手机号 | ||
| 130 | + * 邮件地址和手机号 根据链接匹配,没匹配到随机取一个邮件和手机号 | ||
| 131 | + * @param $referer | ||
| 132 | + * @author zbj | ||
| 133 | + * @date 2025/10/25 | ||
| 134 | + */ | ||
| 135 | + public static function SpecialMailPhone($referer) | ||
| 136 | + { | ||
| 137 | + $mail_mobile_map = [ | ||
| 138 | + 'luchfitness' => [15262817624, 'Sales02@luchfitness.com'], | ||
| 139 | + 'modernsporting' => [13073258707,'sales@modernsporting.com'], | ||
| 140 | + 'liveupsports' => [18355892630,'sales@liveupsports.com'], | ||
| 141 | + 'topflor' => [13912296731,'alan@topflor.cn'], | ||
| 142 | + ]; | ||
| 143 | + $url_map = [ | ||
| 144 | + 'luchfitness' => [ | ||
| 145 | + '/supplier/nantong-luch-fitness-co-ltd', | ||
| 146 | + '/benches-machines-luch-fitness', | ||
| 147 | + '/free-weight-luch-fitness', | ||
| 148 | + '/functional-training-luch-fitness/s', | ||
| 149 | + '/studio-exercise-luch-fitness', | ||
| 150 | + '/commercial-gym-half-power-rack-for-strength-training-product', | ||
| 151 | + '/heavy-duty-fitness-flat-bench-for-home-commercial-gym-product', | ||
| 152 | + '/durable-gym-dumbbell-flat-bench-for-weight-training-product', | ||
| 153 | + '/rubber-colored-bumper-plate-for-olympic-weightlifting-product', | ||
| 154 | + '/urethane-competition-bumper-plate-for-strength-training-product', | ||
| 155 | + '/10-pair-dumbbell-storage-rack-for-commercial-gyms-product', | ||
| 156 | + '/tpu-coated-dumbbells-for-home-and-commercial-fitness-product', | ||
| 157 | + '/urethane-weight-plate-for-powerlifting-strength-gym-product', | ||
| 158 | + '/iphifun-cpu-weight-plate-for-professional-training-product', | ||
| 159 | + '/men-s-weightlifting-barbell-bar-for-strength-training-product', | ||
| 160 | + '/women-s-weightlifting-barbell-bar-for-olympic-lifts-product', | ||
| 161 | + '/steel-competition-kettlebell-for-functional-training-product', | ||
| 162 | + '/adjustable-strength-jump-plyo-boxes-for-gym-training-product', | ||
| 163 | + '/commercial-soft-plyo-box-for-functional-gym-training-product', | ||
| 164 | + '/power-training-weight-bull-bag-for-strength-workout-product', | ||
| 165 | + '/pu-leather-power-bag-for-functional-strength-training-product', | ||
| 166 | + '/abdominal-muscle-mat-for-core-and-sit-up-training-product', | ||
| 167 | + '/gymnastics-training-mat-for-fitness-and-yoga-workout-product', | ||
| 168 | + '/adjustable-bench-stepper-for-aerobic-and-strength-gym-product', | ||
| 169 | + '/rubber-body-pump-set-for-cardio-and-strength-training-product', | ||
| 170 | + '/balance-training-yoga-ball-for-core-stability-workout-product', | ||
| 171 | + '/pull-up-resistance-band-for-strength-and-stretching-product', | ||
| 172 | + ], | ||
| 173 | + 'modernsporting' => [ | ||
| 174 | + '/supplier/nantong-modern-sporting-industrial-co-ltd', | ||
| 175 | + '/barbell-bars-modern-sporting', | ||
| 176 | + '/storage-racks-modern-sporting', | ||
| 177 | + '/dumbbells-modern-sporting', | ||
| 178 | + '/rubber-plates-modern-sporting', | ||
| 179 | + '/training-handles-modern-sporting', | ||
| 180 | + '/md4137-201cm-weightlifting-beginner-bar-product', | ||
| 181 | + '/md4143-220cm-hybrid-training-bar-product', | ||
| 182 | + '/md4149-powder-coated-pentagon-bar-product', | ||
| 183 | + '/gym-home-10-pairs-dumbbell-rack-stand-md6242-product', | ||
| 184 | + '/10-pairs-dumbbell-rack-for-home-gym-workouts-md6247-product', | ||
| 185 | + '/10-pairs-dumbbell-storage-rack-for-gym-home-md6250-product', | ||
| 186 | + '/urethane-dumbbells-set-for-strength-training-md2117-product', | ||
| 187 | + '/md2123-rubber-coated-studio-dumbbells-product', | ||
| 188 | + '/md2135-12-side-tpu-coated-dumbbells-product', | ||
| 189 | + '/rubber-bumper-plates-for-weightlifting-gym-use-md1056-product', | ||
| 190 | + '/high-quality-rubber-bumper-plates-for-gym-lifting-md1057-product', | ||
| 191 | + '/md1058-competition-weight-plates-product', | ||
| 192 | + '/tricep-press-down-bar-for-cable-machines-strength-md5128-product', | ||
| 193 | + '/md5132-tricep-press-down-bar-product', | ||
| 194 | + '/md5132-tricep-press-down-bar-product', | ||
| 195 | + ], | ||
| 196 | + 'liveupsports' => [ | ||
| 197 | + '/supplier/nantong-liveup-sports-co-ltd', | ||
| 198 | + '/yoga-pilates-liveup-sports', | ||
| 199 | + '/training-equipment-liveup-sports', | ||
| 200 | + '/gym-racks-and-equipment-liveup-sports', | ||
| 201 | + '/20-25-30cm-pvc-customised-pilates-stability-exercise-ball-inflatable-soft-mini-pilates-small-yoga-bal-product', | ||
| 202 | + '/55-65-75cm-bloom-workout-fitness-exercise-balance-gym-abs-anti-burst-yoga-ball-anti-slip-swiss-pilates-ball-product', | ||
| 203 | + '/bodybuilding-fitness-exercise-custom-logo-gym-yoga-latex-hip-resistance-bands-loop-bands-set-product', | ||
| 204 | + '/bloom-2080x4-5cm-natural-latex-loop-yoga-elastic-stretch-long-resistance-bands-exercise-band-product', | ||
| 205 | + '/custom-logo-manufacturer-high-quality-eco-friendly-fitness-pilates-anti-slip-3-10mm-pu-rubber-tpe-cork-nbr-pvc-printed-yoga-mat-product', | ||
| 206 | + '/custom-professional-manufacture-cheap-solid-cast-iron-dumbbell-weights-rubber-hex-dumbbell-sets-5-100lb-product', | ||
| 207 | + '/professional-wholesale-custom-logo-free-weight-colored-rubber-bumper-gym-weight-barbell-plates-with-kg-mark-product', | ||
| 208 | + '/gym-equipment-free-weights-fitness-12-sided-weightlifting-exercise-barbell-weight-lifting-polyurethane-fixed-barbell-product', | ||
| 209 | + '/livepro-high-quality-steel-fitness-equipment-training-competition-gym-power-weightlifting-20kg-barbell-bar-product', | ||
| 210 | + '/livepro-gym-commercial-equipment-fitness-storage-system-professional-multifunctional-training-frame-gym-storage-rack-product', | ||
| 211 | + '/livepro-commercial-floor-mount-free-standing-cross-training-gym-rigs-multi-functional-training-rack-fitness-gym-rig-product', | ||
| 212 | + '/livepro-oem-odm-fitness-equipment-multi-functional-trainer-smith-machine-station-home-using-gym-full-frame-cage-squat-power-rack-product', | ||
| 213 | + ], | ||
| 214 | + 'topflor' => [ | ||
| 215 | + '/supplier/nantong-topflor-co-ltd', | ||
| 216 | + '/sports-flooring-topflor', | ||
| 217 | + '/healthcare-flooring-topflor', | ||
| 218 | + '/gym-flooring-topflor', | ||
| 219 | + '/sprint-track-turf-for-high-performance-indoor-and-outdoor-training-product', | ||
| 220 | + '/durable-gym-rubber-flooring-with-shock-absorption-and-slip-resistance-product', | ||
| 221 | + '/interlocking-gym-flooring-tilesinterlocking-gym-flooring-tiles-product', | ||
| 222 | + '/premium-hospital-vinyl-flooring-with-anti-bacterial-and-easy-clean-surface-product', | ||
| 223 | + '/high-performance-healthcare-flooring-for-safe-and-hygienic-environments-product', | ||
| 224 | + '/homogeneous-vinyl-flooring-with-high-durability-and-low-maintenance-product', | ||
| 225 | + '/clinic-vinyl-flooring-with-anti-bacterial-and-wear-resistant-properties-product', | ||
| 226 | + '/medical-pvc-flooring-with-anti-slip-hygienic-and-durable-features-product', | ||
| 227 | + '/professional-badminton-court-pvc-sports-flooring-with-high-grip-and-shock-absorption-product', | ||
| 228 | + '/indoor-basketball-sports-flooring-with-superior-ball-bounce-and-player-comfort-product', | ||
| 229 | + '/multi-sport-indoor-pvc-flooring-for-volleyball-handball-badminton-and-fitness-product', | ||
| 230 | + '/durable-multi-purpose-sports-flooring-for-schools-gyms-and-community-centers-product', | ||
| 231 | + '/high-performance-multi-use-indoor-sports-flooring-with-easy-maintenance-product', | ||
| 232 | + ], | ||
| 233 | + | ||
| 234 | + ]; | ||
| 235 | + foreach ($url_map as $k=>$urls) { | ||
| 236 | + foreach ($urls as $url) { | ||
| 237 | + if(Str::contains($referer, $url)){ | ||
| 238 | + return $mail_mobile_map[$k]; | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + } | ||
| 242 | + return $mail_mobile_map[array_rand($mail_mobile_map)]; | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + /** | ||
| 121 | * 特殊项目 邮件模版 | 246 | * 特殊项目 邮件模版 |
| 122 | * FIXME 后期有多个特殊项目,需要按照项目ID设置模板 | 247 | * FIXME 后期有多个特殊项目,需要按照项目ID设置模板 |
| 123 | * @param $name | 248 | * @param $name |
| @@ -128,7 +253,7 @@ class InquiryFormData extends Base | @@ -128,7 +253,7 @@ class InquiryFormData extends Base | ||
| 128 | * @param $country | 253 | * @param $country |
| 129 | * @return string | 254 | * @return string |
| 130 | */ | 255 | */ |
| 131 | - public static function specialInquiryTemplate($name, $email, $phone, $message, $domain, $country) | 256 | + public static function specialInquiryTemplate($name, $email, $phone, $message, $domain, $ip, $country) |
| 132 | { | 257 | { |
| 133 | $template = " | 258 | $template = " |
| 134 | 客户姓名:$name | 259 | 客户姓名:$name |
| @@ -139,7 +264,7 @@ class InquiryFormData extends Base | @@ -139,7 +264,7 @@ class InquiryFormData extends Base | ||
| 139 | $message | 264 | $message |
| 140 | -------------------------------------------------------------------- | 265 | -------------------------------------------------------------------- |
| 141 | 发送询盘网址: $domain | 266 | 发送询盘网址: $domain |
| 142 | -客户IP地址: [ip] | 267 | +客户IP地址: $ip |
| 143 | IP所在国家/地区: $country | 268 | IP所在国家/地区: $country |
| 144 | --------------------------------------------------------------------"; | 269 | --------------------------------------------------------------------"; |
| 145 | return $template; | 270 | return $template; |
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | namespace App\Models\Project; | 10 | namespace App\Models\Project; |
| 11 | 11 | ||
| 12 | use App\Models\Base; | 12 | use App\Models\Base; |
| 13 | +use Illuminate\Support\Facades\Cache; | ||
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| 15 | * @remark :关键字前缀/后缀 | 16 | * @remark :关键字前缀/后缀 |
| @@ -21,4 +22,68 @@ use App\Models\Base; | @@ -21,4 +22,68 @@ use App\Models\Base; | ||
| 21 | class KeywordPrefix extends Base | 22 | class KeywordPrefix extends Base |
| 22 | { | 23 | { |
| 23 | protected $table = 'gl_project_keyword_prefix'; | 24 | protected $table = 'gl_project_keyword_prefix'; |
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 前后缀类型 | ||
| 28 | + */ | ||
| 29 | + const TYPE_OPTIMIZE_PREFIX = 1; | ||
| 30 | + const TYPE_OPTIMIZE_SUFFIX = 2; | ||
| 31 | + const TYPE_GEO_PREFIX = 3; | ||
| 32 | + const TYPE_GEO_SUFFIX = 4; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 前后缀类型映射 | ||
| 36 | + * @return array | ||
| 37 | + */ | ||
| 38 | + public static function typeMapping() | ||
| 39 | + { | ||
| 40 | + return [ | ||
| 41 | + self::TYPE_OPTIMIZE_PREFIX => '优化关键词前缀', | ||
| 42 | + self::TYPE_OPTIMIZE_SUFFIX => '优化关键词后缀', | ||
| 43 | + self::TYPE_GEO_PREFIX => 'GEO前缀', | ||
| 44 | + self::TYPE_GEO_SUFFIX => 'GEO后缀', | ||
| 45 | + ]; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * 保存关键词前后缀 | ||
| 50 | + * @param $project_id | ||
| 51 | + * @param $type | ||
| 52 | + * @param $keyword | ||
| 53 | + * @param $remark | ||
| 54 | + * @return KeywordPrefix | ||
| 55 | + */ | ||
| 56 | + public static function saveKeyword($project_id, $type, $keyword, $remark) | ||
| 57 | + { | ||
| 58 | + $data = self::where(['project_id' => $project_id, 'keyword' => $keyword])->first(); | ||
| 59 | + if (empty($data)) { | ||
| 60 | + $data = new self(); | ||
| 61 | + $data->project_id = $project_id; | ||
| 62 | + $data->type = $type; | ||
| 63 | + $data->keyword = $keyword; | ||
| 64 | + } | ||
| 65 | + $data->remark = $remark; | ||
| 66 | + $data->save(); | ||
| 67 | + Cache::forget('project_keyword_ps_' . $project_id . '_' . $type); | ||
| 68 | + return $data; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 获取关键词前后缀 | ||
| 73 | + * @param $project_id | ||
| 74 | + * @param $type | ||
| 75 | + * @return array|mixed | ||
| 76 | + */ | ||
| 77 | + public static function getKeyword($project_id, $type) | ||
| 78 | + { | ||
| 79 | + $key = 'project_keyword_ps_' . $project_id . '_' . $type; | ||
| 80 | + $list = Cache::get($key); | ||
| 81 | + if (empty($list)) { | ||
| 82 | + $list = self::select(['id', 'type', 'keyword', 'remark'])->where(['type' => $type])->whereIn('project_id', [0, $project_id])->orderBy('project_id', 'asc')->get(); | ||
| 83 | + $list = $list->isEmpty() ? [] : $list->toArray(); | ||
| 84 | + if ($list) | ||
| 85 | + Cache::put($key, $list, 1800); | ||
| 86 | + } | ||
| 87 | + return $list; | ||
| 88 | + } | ||
| 24 | } | 89 | } |
| @@ -79,7 +79,9 @@ class Project extends Base | @@ -79,7 +79,9 @@ class Project extends Base | ||
| 79 | 3=>'2-4', | 79 | 3=>'2-4', |
| 80 | 4=>'3-5', | 80 | 4=>'3-5', |
| 81 | 5=>'5-7', | 81 | 5=>'5-7', |
| 82 | - 6=>'1/2' | 82 | + 6=>'1/2', |
| 83 | + 7=>'1/3', | ||
| 84 | + 8=>'1/1', | ||
| 83 | ]; | 85 | ]; |
| 84 | if($val){ | 86 | if($val){ |
| 85 | return $arr[$val] ?? ''; | 87 | return $arr[$val] ?? ''; |
| @@ -30,6 +30,7 @@ class MessagePush extends Base | @@ -30,6 +30,7 @@ class MessagePush extends Base | ||
| 30 | const TYPE_TICKET = 'Ticket'; | 30 | const TYPE_TICKET = 'Ticket'; |
| 31 | const TYPE_DOMAIN = 'domain'; | 31 | const TYPE_DOMAIN = 'domain'; |
| 32 | const TYPE_DOMAIN_V5 = 'domain_v5'; | 32 | const TYPE_DOMAIN_V5 = 'domain_v5'; |
| 33 | + const TYPE_GEO_CONFIRM = 'geo_confirm'; | ||
| 33 | //设置关联表名 | 34 | //设置关联表名 |
| 34 | /** | 35 | /** |
| 35 | * @var mixed | 36 | * @var mixed |
| @@ -283,7 +283,7 @@ class SyncSubmitTaskService | @@ -283,7 +283,7 @@ class SyncSubmitTaskService | ||
| 283 | 283 | ||
| 284 | $data['referer'] = $this->handle_referer($data['referer']); | 284 | $data['referer'] = $this->handle_referer($data['referer']); |
| 285 | 285 | ||
| 286 | - $id = InquiryFormData::saveData($form_id, $data['domain'], $data['ip'], $data['country'], $data['referer'], $data['user_agent'], $data['submit_at'], $data['data'], $traffic); | 286 | + $id = InquiryFormData::saveData($form_id, $data['domain'], $data['ip'], $data['country'], $data['referer'], $data['user_agent'], $data['submit_at'], $data['data'], $data['project_id'], $traffic); |
| 287 | 287 | ||
| 288 | 288 | ||
| 289 | //转化询盘 | 289 | //转化询盘 |
| @@ -318,6 +318,10 @@ class SyncSubmitTaskService | @@ -318,6 +318,10 @@ class SyncSubmitTaskService | ||
| 318 | */ | 318 | */ |
| 319 | public function visit($data, $date, $task_id, $traffic = 0) | 319 | public function visit($data, $date, $task_id, $traffic = 0) |
| 320 | { | 320 | { |
| 321 | + //特殊过滤 无锡动为储能 | ||
| 322 | + if($data['country'] == '新加坡' && $data['data']['referrer_url'] == 'https://www.google.com/' && $data['domain'] == 'www.dowellelectronic.com'){ | ||
| 323 | + throw new InquiryFilterException( '特殊过滤'); | ||
| 324 | + } | ||
| 321 | 325 | ||
| 322 | $visit_data = $data['data']; | 326 | $visit_data = $data['data']; |
| 323 | $referrer_url = ''; | 327 | $referrer_url = ''; |
| @@ -492,6 +496,11 @@ class SyncSubmitTaskService | @@ -492,6 +496,11 @@ class SyncSubmitTaskService | ||
| 492 | throw new InquiryFilterException( '全局过滤3'); | 496 | throw new InquiryFilterException( '全局过滤3'); |
| 493 | } | 497 | } |
| 494 | 498 | ||
| 499 | + //新加坡 并且 没有来源信息的访问信息屏蔽了 海龙 25/10/21 | ||
| 500 | + if($data['country'] == '新加坡' && empty($data['referer'])){ | ||
| 501 | + throw new InquiryFilterException( '全局过滤4'); | ||
| 502 | + } | ||
| 503 | + | ||
| 495 | //1913宁波市鄞州永鑫 ip荷兰 message 8-16 纯字母不含空格 | 504 | //1913宁波市鄞州永鑫 ip荷兰 message 8-16 纯字母不含空格 |
| 496 | if($project_id == 1913 && in_array($data['country']??'', ['荷兰', '俄罗斯']) | 505 | if($project_id == 1913 && in_array($data['country']??'', ['荷兰', '俄罗斯']) |
| 497 | && strlen($data['data']['message']??"") >= 8 | 506 | && strlen($data['data']['message']??"") >= 8 |
| @@ -107,4 +107,8 @@ Route::prefix('ticket_upload')->group(function () { | @@ -107,4 +107,8 @@ Route::prefix('ticket_upload')->group(function () { | ||
| 107 | Route::any('/saveLayoutDesign', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveLayoutDesign'])->name('ticket_upload.saveLayoutDesign'); | 107 | Route::any('/saveLayoutDesign', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveLayoutDesign'])->name('ticket_upload.saveLayoutDesign'); |
| 108 | Route::any('/getLayoutDesignInfo', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getLayoutDesignInfo'])->name('ticket_upload.getLayoutDesignInfo'); | 108 | Route::any('/getLayoutDesignInfo', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getLayoutDesignInfo'])->name('ticket_upload.getLayoutDesignInfo'); |
| 109 | }); | 109 | }); |
| 110 | +//geo设置 | ||
| 111 | +Route::prefix('geo')->group(function () { | ||
| 112 | + Route::any('/getConfirm', [\App\Http\Controllers\Api\GeoController::class, 'getConfirm'])->name('geo.getConfirm'); | ||
| 113 | +}); | ||
| 110 | 114 |
| @@ -207,6 +207,7 @@ Route::middleware(['aloginauth'])->group(function () { | @@ -207,6 +207,7 @@ Route::middleware(['aloginauth'])->group(function () { | ||
| 207 | Route::any('/saveSiteStatus', [Aside\Project\ProjectController::class, 'saveSiteStatus'])->name('admin.project_saveSiteStatus'); | 207 | Route::any('/saveSiteStatus', [Aside\Project\ProjectController::class, 'saveSiteStatus'])->name('admin.project_saveSiteStatus'); |
| 208 | Route::any('/updateTdk', [Aside\Project\ProjectController::class, 'updateTdk'])->name('admin.project_updateTdk');//更新项目tdk | 208 | Route::any('/updateTdk', [Aside\Project\ProjectController::class, 'updateTdk'])->name('admin.project_updateTdk');//更新项目tdk |
| 209 | Route::any('/videoSetting', [Aside\Project\ProjectController::class, 'videoSetting'])->name('admin.project_videoSetting');//项目管理AI.video设置 | 209 | Route::any('/videoSetting', [Aside\Project\ProjectController::class, 'videoSetting'])->name('admin.project_videoSetting');//项目管理AI.video设置 |
| 210 | + Route::any('/getSpAdsLists', [Aside\Project\ProjectController::class, 'getSpAdsLists'])->name('admin.project_getSpAdsLists');//项目管理广告投放 | ||
| 210 | //获取关键词前缀和后缀 | 211 | //获取关键词前缀和后缀 |
| 211 | Route::prefix('keyword')->group(function () { | 212 | Route::prefix('keyword')->group(function () { |
| 212 | Route::any('/getKeywordPrefix', [Aside\Project\KeywordPrefixController::class, 'getKeywordPrefix'])->name('admin.keyword_getKeywordPrefix'); | 213 | Route::any('/getKeywordPrefix', [Aside\Project\KeywordPrefixController::class, 'getKeywordPrefix'])->name('admin.keyword_getKeywordPrefix'); |
| @@ -585,6 +586,21 @@ Route::middleware(['aloginauth'])->group(function () { | @@ -585,6 +586,21 @@ Route::middleware(['aloginauth'])->group(function () { | ||
| 585 | Route::any('/downloadGeoLink', [Aside\Geo\GeoLinkController::class, 'downloadGeoLink'])->name('admin.geo_link_downloadGeoLink'); | 586 | Route::any('/downloadGeoLink', [Aside\Geo\GeoLinkController::class, 'downloadGeoLink'])->name('admin.geo_link_downloadGeoLink'); |
| 586 | Route::any('/daResultData', [Aside\Geo\GeoLinkController::class, 'daResultData'])->name('admin.geo_link_daResultData'); | 587 | Route::any('/daResultData', [Aside\Geo\GeoLinkController::class, 'daResultData'])->name('admin.geo_link_daResultData'); |
| 587 | }); | 588 | }); |
| 589 | + //geo信息详情设置 | ||
| 590 | + Route::prefix('conf')->group(function () { | ||
| 591 | + Route::any('/getConfig', [Aside\Geo\GeoController::class, 'getConfig'])->name('admin.geo_conf_getConfig'); | ||
| 592 | + Route::any('/saveConfig', [Aside\Geo\GeoController::class, 'saveConfig'])->name('admin.geo_conf_saveConfig'); | ||
| 593 | + }); | ||
| 594 | + //geo客户确认信息 | ||
| 595 | + Route::prefix('confirm')->group(function () { | ||
| 596 | + Route::any('/saveConfirmContent', [Aside\Geo\GeoConfirmController::class, 'saveConfirmContent'])->name('admin.geo_confirm_saveConfirmContent'); | ||
| 597 | + }); | ||
| 598 | + //geoai文章任务管理 | ||
| 599 | + Route::prefix('writing_task')->group(function () { | ||
| 600 | + Route::any('/', [Aside\Geo\GeoWritingTaskController::class, 'lists'])->name('admin.geo_writing_task_lists'); | ||
| 601 | + Route::any('/saveWritingTask', [Aside\Geo\GeoWritingTaskController::class, 'saveWritingTask'])->name('admin.geo_writing_task_saveWritingTask'); | ||
| 602 | + Route::any('/delWritingTask', [Aside\Geo\GeoWritingTaskController::class, 'delWritingTask'])->name('admin.geo_writing_task_delWritingTask'); | ||
| 603 | + }); | ||
| 588 | }); | 604 | }); |
| 589 | // 任务相关 | 605 | // 任务相关 |
| 590 | Route::prefix('task')->group(function () { | 606 | Route::prefix('task')->group(function () { |
| @@ -651,6 +667,8 @@ Route::middleware(['aloginauth'])->group(function () { | @@ -651,6 +667,8 @@ Route::middleware(['aloginauth'])->group(function () { | ||
| 651 | Route::any('/save', [Aside\Ticket\TicketUploadDataController::class,'save'])->name('ticket_upload_save'); | 667 | Route::any('/save', [Aside\Ticket\TicketUploadDataController::class,'save'])->name('ticket_upload_save'); |
| 652 | Route::any('/detail', [Aside\Ticket\TicketUploadDataController::class,'detail'])->name('ticket_upload_detail'); | 668 | Route::any('/detail', [Aside\Ticket\TicketUploadDataController::class,'detail'])->name('ticket_upload_detail'); |
| 653 | }); | 669 | }); |
| 670 | + | ||
| 671 | + | ||
| 654 | }); | 672 | }); |
| 655 | 673 | ||
| 656 | //无需登录验证的路由组 | 674 | //无需登录验证的路由组 |
-
请 注册 或 登录 后发表评论