作者 刘锟

Merge remote-tracking branch 'origin/master' into akun

正在显示 46 个修改的文件 包含 1217 行增加91 行删除
@@ -73,6 +73,7 @@ class AiBlogListTask extends Command @@ -73,6 +73,7 @@ class AiBlogListTask extends Command
73 $saveData = []; 73 $saveData = [];
74 $result = $aiBlogService->getAiBlogList($page,15); 74 $result = $aiBlogService->getAiBlogList($page,15);
75 if(!isset($result['status']) || $result['status'] != 200){ 75 if(!isset($result['status']) || $result['status'] != 200){
  76 + echo '请示失败。'.json_encode($result, JSON_UNESCAPED_UNICODE);
76 return true; 77 return true;
77 } 78 }
78 $total_page = $result['data']['total_page']; 79 $total_page = $result['data']['total_page'];
@@ -43,7 +43,7 @@ class RemainDay extends Command @@ -43,7 +43,7 @@ class RemainDay extends Command
43 * @var 暂停的项目 43 * @var 暂停的项目
44 */ 44 */
45 protected $ceaseProjectId = [ 45 protected $ceaseProjectId = [
46 - 354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250, 2193, 2399, 1685, 3931 46 + 354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250, 2193, 2399, 1685, 3931,2273,3647
47 ];//需要单独处理的项目 47 ];//需要单独处理的项目
48 /** 48 /**
49 * The console command description. 49 * The console command description.
@@ -12,6 +12,7 @@ use App\Helper\Gpt; @@ -12,6 +12,7 @@ use App\Helper\Gpt;
12 use App\Helper\Translate; 12 use App\Helper\Translate;
13 use App\Helper\Validate; 13 use App\Helper\Validate;
14 use App\Models\Ai\AiCommand; 14 use App\Models\Ai\AiCommand;
  15 +use App\Models\Inquiry\InquiryRelayDetailLog;
15 use App\Models\Inquiry\ReInquiryConfig; 16 use App\Models\Inquiry\ReInquiryConfig;
16 use App\Models\Inquiry\ReInquiryDetail; 17 use App\Models\Inquiry\ReInquiryDetail;
17 use App\Models\Inquiry\ReInquiryDetailLog; 18 use App\Models\Inquiry\ReInquiryDetailLog;
@@ -24,6 +25,7 @@ use App\Models\WebSetting\WebLanguage; @@ -24,6 +25,7 @@ use App\Models\WebSetting\WebLanguage;
24 use GuzzleHttp\Exception\ConnectException; 25 use GuzzleHttp\Exception\ConnectException;
25 use Illuminate\Console\Command; 26 use Illuminate\Console\Command;
26 use Illuminate\Support\Arr; 27 use Illuminate\Support\Arr;
  28 +use Illuminate\Support\Carbon;
27 use Illuminate\Support\Facades\Cache; 29 use Illuminate\Support\Facades\Cache;
28 use Illuminate\Support\Facades\DB; 30 use Illuminate\Support\Facades\DB;
29 use Illuminate\Support\Facades\Http; 31 use Illuminate\Support\Facades\Http;
@@ -433,7 +435,12 @@ class RelayInquiry extends Command @@ -433,7 +435,12 @@ class RelayInquiry extends Command
433 } 435 }
434 //是否有必选的渠道 渠道有一个及以上必选 就在组内随机一个 436 //是否有必选的渠道 渠道有一个及以上必选 就在组内随机一个
435 $require_agent_group = []; 437 $require_agent_group = [];
436 - foreach ($task['target'] as $item) { 438 + foreach ($task['target'] as $k=>$item) {
  439 + //没有广告费的 按频率来 x天一封 发过了先踢掉 优先级高于必选
  440 + if(!$this->checkFrequency($item)){
  441 + unset($item[$k]);
  442 + continue;
  443 + }
437 if (!empty($item['is_require'])) { 444 if (!empty($item['is_require'])) {
438 $require_agent_group[] = $item['agent_group']; 445 $require_agent_group[] = $item['agent_group'];
439 } 446 }
@@ -517,7 +524,7 @@ class RelayInquiry extends Command @@ -517,7 +524,7 @@ class RelayInquiry extends Command
517 524
518 $pre = 0; 525 $pre = 0;
519 $start_time = time(); 526 $start_time = time();
520 - $seconds = $this->delay_seconds($form->inquiry_date); 527 + $seconds = $this->delay_seconds($form->inquiry_date, $domain, $task);
521 $email = ''; 528 $email = '';
522 if($is_inquiry) { 529 if($is_inquiry) {
523 $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first(); 530 $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();
@@ -547,6 +554,31 @@ class RelayInquiry extends Command @@ -547,6 +554,31 @@ class RelayInquiry extends Command
547 return true; 554 return true;
548 } 555 }
549 556
  557 + public function checkFrequency($item)
  558 + {
  559 + //设置了频率的
  560 + if (!empty($item['frequency'])) {
  561 + $item['is_ad_fee'] = 0; //v5都没有
  562 + if($item['is_v6']){
  563 + $project = Project::getProjectByDomain($item['url']);
  564 + if($project && $project->deploy_build){
  565 + $item['is_ad_fee'] = $project->deploy_build->ads_price ? 1 : 0;
  566 + }
  567 + }
  568 + //没有广告费 是否X天内发送过
  569 + if(!$item['is_ad_fee']){
  570 + $inquiry_log = InquiryRelayDetailLog::where('type', InquiryRelayDetailLog::TYPE_INQUIRY)
  571 + ->where('start_at', '>', date('Y-m-d H:i:s', strtotime('- ' . $item['frequency'] . ' day')))
  572 + ->first();
  573 + if($inquiry_log){
  574 + $this->output('频率限制');
  575 + return false;
  576 + }
  577 + }
  578 + }
  579 + return true;
  580 + }
  581 +
550 public function relayShopDetail($task, $form) 582 public function relayShopDetail($task, $form)
551 { 583 {
552 $this->output('获取商城转发对象'); 584 $this->output('获取商城转发对象');
@@ -580,7 +612,7 @@ class RelayInquiry extends Command @@ -580,7 +612,7 @@ class RelayInquiry extends Command
580 $referrer = $this->getReferer($country_name, $lang); 612 $referrer = $this->getReferer($country_name, $lang);
581 613
582 $start_time = time(); 614 $start_time = time();
583 - $seconds = $this->delay_seconds($form->inquiry_date); 615 + $seconds = $this->delay_seconds($form->inquiry_date, $domain, $task);
584 $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first(); 616 $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();
585 if($exists){ 617 if($exists){
586 $this->output('转发站点邮件已存在'); 618 $this->output('转发站点邮件已存在');
@@ -616,7 +648,7 @@ class RelayInquiry extends Command @@ -616,7 +648,7 @@ class RelayInquiry extends Command
616 $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua); 648 $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
617 649
618 $start_time = time(); 650 $start_time = time();
619 - $seconds = $this->delay_seconds($form->inquiry_date); 651 + $seconds = $this->delay_seconds($form->inquiry_date, $postid, $task);
620 $exists = ReInquiryDetail::where('re_website', $postid)->where('email', $form->email)->first(); 652 $exists = ReInquiryDetail::where('re_website', $postid)->where('email', $form->email)->first();
621 if($exists){ 653 if($exists){
622 $this->output('转发站点邮件已存在'); 654 $this->output('转发站点邮件已存在');
@@ -796,7 +828,7 @@ class RelayInquiry extends Command @@ -796,7 +828,7 @@ class RelayInquiry extends Command
796 { 828 {
797 $cache_key = 'inquiry_ads_tasks'; 829 $cache_key = 'inquiry_ads_tasks';
798 $ads = Cache::get($cache_key, function () use ($cache_key) { 830 $ads = Cache::get($cache_key, function () use ($cache_key) {
799 - $ads = ReInquiryTask::where(['status' => ReInquiryTask::STATUS_OPEN])->get(['id', 'ad_id', 'num', 'target', 'is_replace_text', 'ai_param', 'shop_site', 'fob_pro']); 831 + $ads = ReInquiryTask::where(['status' => ReInquiryTask::STATUS_OPEN])->get(['id', 'ad_id', 'num', 'target', 'is_replace_text', 'ai_param', 'shop_site', 'fob_pro', 'second_push_rate']);
800 $array = []; 832 $array = [];
801 foreach ($ads as $key=>$val) { 833 foreach ($ads as $key=>$val) {
802 $ad_ids = explode(',', $val['ad_id']); 834 $ad_ids = explode(',', $val['ad_id']);
@@ -945,8 +977,36 @@ class RelayInquiry extends Command @@ -945,8 +977,36 @@ class RelayInquiry extends Command
945 * @author zbj 977 * @author zbj
946 * @date 2025/7/16 978 * @date 2025/7/16
947 */ 979 */
948 - public function delay_seconds($inquiry_date) 980 + public function delay_seconds($inquiry_date, $domain, $task)
949 { 981 {
  982 + $inquiry_date = Carbon::make($inquiry_date);
  983 + //当天的
  984 + if($inquiry_date->isToday()){
  985 + //广告投放日(周一、二、三、四) 第一封询盘100%及时推送
  986 + $is_timely = true; //是否及时推送
  987 + if(in_array($inquiry_date->weekday(), [1,2,3,4])) {
  988 + //是否今天的第一封询盘
  989 + $detail = ReInquiryDetail::where('re_website', $domain)->where('start_at', '>=', $inquiry_date->startOfDay()->toDatetimeString())->first();
  990 + if($detail){
  991 + $is_timely = false; //只有周一到周四的非第一封询盘 根据概率及时推送
  992 + }
  993 + }
  994 + //概率及时推送
  995 + if(!$is_timely && $task->second_push_rate != 100){
  996 + //按概率
  997 + $res = $this->get_rand([$task->second_push_rate, 100 - $task->second_push_rate]);
  998 + if($res == 1){
  999 + $this->output('非广告投放日第一封询盘 概率' . (100 - $task->second_push_rate) . '%延迟推送');
  1000 + //随机分配到未投放广告日期
  1001 + $now = Carbon::now();
  1002 + // 随机开始时间(本周四或现在)
  1003 + $startTime = max($now->timestamp, $now->startOfWeek(4)->timestamp);
  1004 +
  1005 + $random = mt_rand($startTime, $now->endOfWeek()->timestamp);
  1006 + return $random - $now->timestamp;
  1007 + }
  1008 + }
  1009 + }
950 $seconds = rand(300, 2 * 3600); // 默认 从5分钟-2小时后开始 1010 $seconds = rand(300, 2 * 3600); // 默认 从5分钟-2小时后开始
951 $time_diff = time() - strtotime($inquiry_date); //2小时前-24小时内的 当天发完 1011 $time_diff = time() - strtotime($inquiry_date); //2小时前-24小时内的 当天发完
952 if ($time_diff > 2 * 3600 && $time_diff <= 24 * 3600) { 1012 if ($time_diff > 2 * 3600 && $time_diff <= 24 * 3600) {
@@ -21,8 +21,11 @@ use App\Models\Project\Payment; @@ -21,8 +21,11 @@ use App\Models\Project\Payment;
21 use App\Models\Project\Project; 21 use App\Models\Project\Project;
22 use App\Models\Project\ProjectAiSetting; 22 use App\Models\Project\ProjectAiSetting;
23 use App\Models\Project\ProjectWhiteHatAffix; 23 use App\Models\Project\ProjectWhiteHatAffix;
  24 +use App\Models\RouteMap\RouteMap;
24 use App\Models\Template\BTemplateMain; 25 use App\Models\Template\BTemplateMain;
25 use App\Models\Template\TemplateTypeMain; 26 use App\Models\Template\TemplateTypeMain;
  27 +use App\Models\WebSetting\Translate;
  28 +use App\Models\WebSetting\TranslateData;
26 use App\Models\WebSetting\WebSetting; 29 use App\Models\WebSetting\WebSetting;
27 use App\Models\WorkOrder\TicketLog; 30 use App\Models\WorkOrder\TicketLog;
28 use App\Models\WorkOrder\Tickets; 31 use App\Models\WorkOrder\Tickets;
@@ -51,30 +54,7 @@ class lyhDemo extends Command @@ -51,30 +54,7 @@ class lyhDemo extends Command
51 protected $description = '更新路由'; 54 protected $description = '更新路由';
52 55
53 public function handle(){ 56 public function handle(){
54 - $projectModel = new Payment();  
55 - $lists = $projectModel->list(['renewal_record'=>['not like','"expire_at": null']]);  
56 - foreach ($lists as $item){  
57 - foreach ($item['renewal_record'] as $key => $val){  
58 - if(!isset($val['end_time']) && !empty($val['expire_at'])){  
59 - $val['end_time'] = $val['expire_at'];  
60 - }  
61 - $item['renewal_record'][$key] = $val;  
62 - }  
63 - $projectModel->edit(['renewal_record'=>json_encode($item['renewal_record'],true)],['id'=>$item['id']]);  
64 - }  
65 - return true;  
66 - }  
67 -  
68 - public function getExpectResult(){  
69 - $geo_service = new GeoService();  
70 - $question = 'Top AI Coffee Robot';  
71 - $answer = "Top AI Coffee Robot\" refers to advanced robotic systems that combine **precision automation, artificial intelligence, and specialty coffee expertise** to create high-quality beverages with minimal human intervention. Here's a breakdown of key features, leading examples, and benefits:\n\n### Core Features of Top AI Coffee Robots:\n1. **AI-Driven Customization** \n - Analyzes user preferences (strength, milk type, sweetness) via app profiles or voice commands. \n - Learns from feedback to refine future orders (e.g., \"less bitter than last time\"). \n2. **Robotic Precision Brewing** \n - Industrial arms handle grinding, tamping, steaming milk, and latte art with sub-millimeter accuracy. \n - Sensors monitor temperature, extraction time, and pressure for optimal flavor.";  
72 - $expect = "While I don't have specific information on the RobotAnno coffee machine, in general";  
73 - $str = "客户提出的问题:{$question},客户得到的回复:{$answer},客户需要预期:{$expect},请分析得到的回复和预期是否一致,仅回复我是或者否";  
74 - $data = $geo_service->getChatResult($str, 'gpt-4o-mini');  
75 - if(isset($data['text']) && $data['text'] == '是'){  
76 -  
77 - } 57 + return $this->translate_action();
78 } 58 }
79 59
80 /** 60 /**
@@ -257,9 +237,133 @@ class lyhDemo extends Command @@ -257,9 +237,133 @@ class lyhDemo extends Command
257 echo "字段 $field 小写替换出错:" . $e->getMessage() . PHP_EOL; 237 echo "字段 $field 小写替换出错:" . $e->getMessage() . PHP_EOL;
258 } 238 }
259 } 239 }
260 -  
261 echo '执行结束' . PHP_EOL; 240 echo '执行结束' . PHP_EOL;
  241 + DB::disconnect('custom_mysql');
  242 + }
262 243
  244 + public function translate_action()
  245 + {
  246 + ProjectServer::useProject(655);
  247 + $this->model = new Translate();
  248 + $lists = DB::connection('custom_mysql')->table('gl_translate_copy1')->where('url','!=','All')->get()->toArray();
  249 + foreach ($lists as $item) {
  250 + $item = (array)$item;
  251 + $sourceInfo = $this->getRouteSource($item['url']);
  252 + $info = $this->model->read(['language_id'=>$item['language_id'],'source_id'=>$sourceInfo['source_id'],'url'=>$item['url'],'project_id'=>655,'type'=>$item['type']]);
  253 + if($info === false){
  254 + $param = [
  255 + 'type'=>$item['type'] ?? 1,
  256 + 'project_id'=>655,
  257 + 'url'=>$item['url'],
  258 + 'language_id'=>$item['language_id'],
  259 + 'alias'=>$item['alias'],
  260 + 'source'=>$sourceInfo['source'],
  261 + 'source_id'=>$sourceInfo['source_id'],
  262 + 'is_list'=>$sourceInfo['is_list'],
  263 + 'is_custom'=>$sourceInfo['is_custom'],
  264 + 'page'=>$sendData['page'] ?? 0
  265 + ];
  266 + $id = $this->model->addReturnId($param);
  267 + TranslateData::insert(['trans_id'=>$id,'data'=>$item['data']]);
  268 + }else{
  269 + TranslateData::where(['trans_id'=>$info['id']])->update(['data'=>$item['data']]);
  270 + }
  271 + }
263 DB::disconnect('custom_mysql'); 272 DB::disconnect('custom_mysql');
264 } 273 }
  274 +
  275 + public function getRouteSource($route){
  276 + $routes = $route;
  277 + $data = ['source'=>0,'source_id'=>0,'is_list'=>0,'is_custom'=>0,'page'=>0];
  278 + if(strtolower($route) == 'all'){
  279 + return $data;
  280 + }
  281 + if($route == 'index' || $route == '/'){
  282 + $data['source'] = 1;
  283 + return $data;
  284 + }
  285 + $route = basename($route);
  286 + $page = 0;
  287 + if (is_numeric($route)) {
  288 + $arr = explode('/',$routes);
  289 + $page = $route;
  290 + $route = $arr[0];
  291 + }
  292 + $routeModel = new RouteMap();
  293 + $routeInfo = $routeModel->read(['route'=>$route]);
  294 + if($routeInfo === false){
  295 + if(in_array($route,['products','news','blog'])){
  296 + //固定路由
  297 + $data['page'] = $page;
  298 + $data['is_list'] = 1;
  299 + if($route == 'products'){
  300 + $data['source'] = 2;
  301 + }elseif ($route == 'news'){
  302 + $data['source'] = 4;
  303 + }else{
  304 + $data['source'] = 3;
  305 + }
  306 + return $data;
  307 + }
  308 + return $data;
  309 + }
  310 + $data = $this->resultData($routeInfo,$data);
  311 + $data['page'] = $page;
  312 + return $data;
  313 + }
  314 +
  315 + public function resultData($routeInfo,$data){
  316 + if($routeInfo['source'] == RouteMap::SOURCE_PAGE){
  317 + if($routeInfo['source_id']){
  318 + $data = ['source'=>9,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  319 + }
  320 + }
  321 + if($routeInfo['source'] == RouteMap::SOURCE_PRODUCT){
  322 + if($routeInfo['source_id']){
  323 + $data = ['source'=>2,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  324 + }
  325 + }
  326 + if($routeInfo['source'] == RouteMap::SOURCE_PRODUCT_CATE){
  327 + if($routeInfo['source_id']){
  328 + $data = ['source'=>2,'source_id'=>$routeInfo['source_id'],'is_list'=>1,'is_custom'=>0];
  329 + }
  330 + }
  331 + if($routeInfo['source'] == RouteMap::SOURCE_BLOG){
  332 + if($routeInfo['source_id']){
  333 + $data = ['source'=>3,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  334 + }
  335 + }
  336 + if($routeInfo['source'] == RouteMap::SOURCE_BLOG_CATE){
  337 + if($routeInfo['source_id']){
  338 + $data = ['source'=>3,'source_id'=>$routeInfo['source_id'],'is_list'=>1,'is_custom'=>0];
  339 + }
  340 + }
  341 + if($routeInfo['source'] == RouteMap::SOURCE_NEWS){
  342 + if($routeInfo['source_id']){
  343 + $data = ['source'=>4,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  344 + }
  345 + }
  346 + if($routeInfo['source'] == RouteMap::SOURCE_NEWS_CATE){
  347 + if($routeInfo['source_id']){
  348 + $data = ['source'=>4,'source_id'=>$routeInfo['source_id'],'is_list'=>1,'is_custom'=>0];
  349 + }
  350 + }
  351 + if($routeInfo['source'] == RouteMap::SOURCE_PRODUCT_KEYWORD){
  352 + if($routeInfo['source_id']){
  353 + $data = ['source'=>8,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  354 + }
  355 + }
  356 + if($routeInfo['source'] == RouteMap::SOURCE_MODULE){
  357 + if($routeInfo['source_id']){
  358 + $data = ['source'=>7,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>1];
  359 + }
  360 + }
  361 + if($routeInfo['source'] == RouteMap::SOURCE_MODULE_CATE){
  362 + if($routeInfo['source_id']){
  363 + $data = ['source'=>7,'source_id'=>$routeInfo['source_id'],'is_list'=>1,'is_custom'=>1];
  364 + }
  365 + }
  366 + return $data;
  367 + }
  368 +
265 } 369 }
@@ -97,7 +97,7 @@ class SyncSubmitTask extends Command @@ -97,7 +97,7 @@ class SyncSubmitTask extends Command
97 } 97 }
98 $task_info->save(); 98 $task_info->save();
99 Log::channel('inquiry')->error($task_id . '处理失败', [$e->getMessage(), $e->getFile(), $e->getLine()]); 99 Log::channel('inquiry')->error($task_id . '处理失败', [$e->getMessage(), $e->getFile(), $e->getLine()]);
100 - $this->output('任务失败:' . $e->getMessage()); 100 + $this->output('任务失败:' . $e->getMessage() . $e->getFile() . $e->getLine());
101 } 101 }
102 102
103 $use_time = time() - $time; 103 $use_time = time() - $time;
@@ -83,7 +83,7 @@ class UpdateKeyword extends Command @@ -83,7 +83,7 @@ class UpdateKeyword extends Command
83 if($info['update_method'] != 1){ 83 if($info['update_method'] != 1){
84 $idArr = shuffle($idArr); 84 $idArr = shuffle($idArr);
85 } 85 }
86 - if(!$idArr){ 86 + if(!is_array($idArr)){
87 return false; 87 return false;
88 } 88 }
89 $result = $this->splitArrayIntoParts($idArr,$number); 89 $result = $this->splitArrayIntoParts($idArr,$number);
@@ -245,4 +245,41 @@ class Arr extends \Illuminate\Support\Arr @@ -245,4 +245,41 @@ class Arr extends \Illuminate\Support\Arr
245 }, $arr)); 245 }, $arr));
246 return json_encode(array_values(array_unique(array_filter($array)))); 246 return json_encode(array_values(array_unique(array_filter($array))));
247 } 247 }
  248 +
  249 +
  250 + /**
  251 + * 数组转文本html数组
  252 + * @param $array
  253 + * @param $indentLevel
  254 + * @return array
  255 + * @author zbj
  256 + * @date 2025/9/26
  257 + */
  258 + public static function formatForHtml($array, $indentLevel = 0) {
  259 + $result = [];
  260 + $indent = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $indentLevel);
  261 +
  262 + foreach ($array as $key => $value) {
  263 + $isNumericKey = is_numeric($key);
  264 +
  265 + if (is_array($value)) {
  266 + if (!$isNumericKey) {
  267 + $result[] = "{$indent}{$key}:<br/>";
  268 + $nestedResult = self::formatForHtml($value, $indentLevel + 1);
  269 + } else {
  270 + $key && $result[] = '<br/>';
  271 + $nestedResult = self::formatForHtml($value, $indentLevel);
  272 + }
  273 + $result = array_merge($result, $nestedResult);
  274 + } else {
  275 + if ($isNumericKey) {
  276 + $result[] = "{$indent}{$value}<br/>";
  277 + } else {
  278 + $result[] = "{$indent}{$key}: {$value}<br/>";
  279 + }
  280 + }
  281 + }
  282 +
  283 + return $result;
  284 + }
248 } 285 }
@@ -1590,7 +1590,7 @@ if (!function_exists('httpGetSsl')) { @@ -1590,7 +1590,7 @@ if (!function_exists('httpGetSsl')) {
1590 } 1590 }
1591 1591
1592 /** 1592 /**
1593 - * @remark :截取自付出啊 1593 + * @remark :截取字符串
1594 * @name :truncate_words 1594 * @name :truncate_words
1595 * @author :lyh 1595 * @author :lyh
1596 * @method :post 1596 * @method :post
@@ -20,14 +20,83 @@ use Illuminate\Support\Facades\Cache; @@ -20,14 +20,83 @@ use Illuminate\Support\Facades\Cache;
20 */ 20 */
21 class BaseController extends Controller 21 class BaseController extends Controller
22 { 22 {
23 - public $param;  
24 - public $request; 23 + protected $param = [];//所有请求参数
  24 + protected $token = ''; //token
  25 + protected $request = [];//助手函数
  26 + protected $page = 1;//当前页
  27 + protected $row = 20;//每页条数
  28 + protected $header = [];//设置请求头参数
  29 + protected $order = 'created_at';
  30 + protected $order_type = 'desc';
  31 + protected $map = [];//处理后的参数
  32 +
25 33
26 public function __construct(Request $request) 34 public function __construct(Request $request)
27 { 35 {
28 $this->request = $request; 36 $this->request = $request;
29 $this->param = $this->request->all(); 37 $this->param = $this->request->all();
  38 + $this->getParam();
  39 + }
  40 +
  41 + /**
  42 + * @remark :请求参数处理
  43 + * @name :getParam
  44 + * @author :lyh
  45 + * @method :post
  46 + * @time :2023/6/17 16:34
  47 + */
  48 + public function getParam(){
  49 + foreach ($this->param as $k => $v){
  50 + if(is_array($v)){
  51 + $this->map[$k] = $v;
  52 + }else{
  53 + $this->getMap($k,$v);
  54 + }
  55 + }
30 } 56 }
  57 +
  58 + /**
  59 + * @remark :搜索参数处理
  60 + * @name :getMap
  61 + * @author :lyh
  62 + * @method :post
  63 + * @time :2023/8/28 10:22
  64 + */
  65 + public function getMap($k,$v){
  66 + switch ($k){
  67 + case "order":
  68 + $this->order = $v;
  69 + break;
  70 + case "order_type":
  71 + $this->order_type = $v;
  72 + break;
  73 + case 'page':
  74 + $this->page = $v;
  75 + break;
  76 + case 'row':
  77 + case 'size':
  78 + $this->row = $v;
  79 + break;
  80 + case "name":
  81 + $this->map['name'] = ['like','%'.$v.'%'];
  82 + break;
  83 + case "start_at":
  84 + $this->_btw[0] = $v;
  85 + $this->_btw[1] = date('Y-m-d H:i:s',time());
  86 + $this->map['created_at'] = ['between', $this->_btw];
  87 + break;
  88 + case "end_at":
  89 + $this->_btw[1] = $v;
  90 + $this->map['created_at'] = ['between', $this->_btw];
  91 + break;
  92 + default:
  93 + if (!empty($v) || $v == 0) {
  94 + $this->map[$k] = $v;
  95 + }
  96 + break;
  97 + }
  98 + }
  99 +
31 /** 100 /**
32 * @param array $data 101 * @param array $data
33 * @param string $message 102 * @param string $message
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :TicketUploadDataController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/9/25 09:40
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Api\WorkOrder;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Api\BaseController;
  14 +use App\Models\Blog\BlogCategory;
  15 +use App\Models\News\NewsCategory;
  16 +use App\Models\Product\Category;
  17 +use App\Models\Product\Keyword;
  18 +use App\Models\Ticket\TicketUploadData;
  19 +use App\Services\ProjectServer;
  20 +use Illuminate\Http\Request;
  21 +use Illuminate\Support\Facades\DB;
  22 +
  23 +/**
  24 + * @remark :上传产品/博客/新闻模块
  25 + * @name :TicketUploadDataController
  26 + * @author :lyh
  27 + * @method :post
  28 + * @time :2025/9/25 09:40
  29 + */
  30 +class TicketUploadDataController extends BaseController
  31 +{
  32 + public function __construct(Request $request)
  33 + {
  34 + parent::__construct($request);
  35 + $this->model = new TicketUploadData();
  36 + }
  37 +
  38 + /**
  39 + * @remark :已提交列表
  40 + * @name :lists
  41 + * @author :lyh
  42 + * @method :post
  43 + * @time :2025/9/25 10:28
  44 + */
  45 + public function lists()
  46 + {
  47 + $this->request->validate([
  48 + 'project_id' => 'required',
  49 + ], [
  50 + 'project_id.required' => 'project_id不能为空',
  51 + ]);
  52 + $data = $this->model->lists($this->map, $this->page, $this->row, $this->order);
  53 + ProjectServer::useProject($this->map['project_id']);
  54 + if(!empty($data) && !empty($data['list'])){
  55 + foreach ($data['list'] as &$item) {
  56 + $item = $this->getHandleFileImage($item);
  57 + $item['text']['cate_name'] = $this->cateText($item['type'],$item['text']['category_id'] ?? []);
  58 + }
  59 + }
  60 + DB::disconnect('custom_mysql');
  61 + $this->response('success', Code::SUCCESS, $data);
  62 + }
  63 +
  64 + /**
  65 + * @remark :处理数据
  66 + * @name :getHandleFileImage
  67 + * @author :lyh
  68 + * @method :post
  69 + * @time :2025/9/25 16:53
  70 + */
  71 + public function getHandleFileImage($v){
  72 + if($v['type'] == 1){
  73 + if(!empty($v['text']['image'])){
  74 + foreach ($v['text']['image'] as $gallery_k => $gallery_v){
  75 + $gallery_v['url'] = getImageUrl($gallery_v['url']);
  76 + $v['text']['image'][$gallery_k] = $gallery_v;
  77 + }
  78 + }
  79 + }else{
  80 + if(isset($v['text']['image']) && !empty($v['text']['image'])){
  81 + $v['text']['image'] = getImageUrl($v['text']['image']);
  82 + }
  83 + }
  84 + return $v;
  85 + }
  86 + /**
  87 + * @remark :获取分类名称
  88 + * @name :cateText
  89 + * @author :lyh
  90 + * @method :post
  91 + * @time :2025/9/29 17:18
  92 + */
  93 + public function cateText($type,$category_id,$keyword_id = [],$is_array = false)
  94 + {
  95 + if(empty($category_id)){
  96 + return '';
  97 + }else{
  98 + $filed = 'name';
  99 + if($type == 1){
  100 + $cateModel = new Category();
  101 + $filed = 'title';
  102 + }elseif ($type == 2){
  103 + $cateModel = new BlogCategory();
  104 + }else{
  105 + $cateModel = new NewsCategory();
  106 + }
  107 + if($is_array){
  108 + $cate_arr = $cateModel->whereIn('id', (array)$category_id)
  109 + ->pluck($filed, 'id')
  110 + ->toArray();
  111 + if($type == 1){
  112 + $keywodModel = new KeyWord();
  113 + $keywod_arr = $keywodModel->whereIn('id', (array)$keyword_id)
  114 + ->pluck($filed, 'id')
  115 + ->toArray();
  116 + return ['keywod_arr' => $keywod_arr, 'cate_arr' => $cate_arr];
  117 + }
  118 + return ['cate_arr' => $cate_arr];
  119 + }else{
  120 + $cateArr = $cateModel->selectField(['id'=>['in',$category_id]],$filed);
  121 + return implode(',',$cateArr);
  122 + }
  123 + }
  124 + }
  125 +
  126 +
  127 + /**
  128 + * @remark :获取数据详情
  129 + * @name :info
  130 + * @author :lyh
  131 + * @method :post
  132 + * @time :2025/9/25 10:35
  133 + */
  134 + public function info()
  135 + {
  136 + $this->request->validate([
  137 + 'id' => 'required',
  138 + ], [
  139 + 'id.required' => 'id不能为空',
  140 + ]);
  141 + $info = $this->model->read($this->param);
  142 + if($info === false){
  143 + $this->response('当前数据不存在或已被删除',Code::SYSTEM_ERROR);
  144 + }
  145 + ProjectServer::useProject($info['project_id']);
  146 + $info['text']['cate_name'] = $this->cateText($info['type'],$info['text']['category_id'] ?? [],$info['text']['keyword_id'] ?? [],true);
  147 + $info = $this->getHandleFileImage($info);
  148 + DB::disconnect('custom_mysql');
  149 + $this->response('success', Code::SUCCESS, $info);
  150 + }
  151 +
  152 + /**
  153 + * @remark :提交数据
  154 + * @name :save
  155 + * @author :lyh
  156 + * @method :post
  157 + * @time :2025/9/25 09:48
  158 + */
  159 + public function save()
  160 + {
  161 + $this->request->validate([
  162 + 'project_id' => 'required',
  163 + 'type' => 'required',
  164 + 'text' => 'required'
  165 + ], [
  166 + 'project_id.required' => 'project_id不能为空',
  167 + 'type.required' => '上传类型不能为空',
  168 + 'text' => '数据详情不为空'
  169 + ]);
  170 + //验证当前数据是否已提交
  171 + $this->param['text'] = json_encode($this->param['text'], true);
  172 + if(isset($this->param['id']) && !empty($this->param['id'])){
  173 + //执行编辑
  174 + $info = $this->model->read(['id'=>$this->param['id']]);
  175 + if($info['status'] == 0){
  176 + $this->model->edit($this->param,['id'=>$this->param['id']]);
  177 + }else{
  178 + $this->response('当前状态不允许编辑', Code::SYSTEM_ERROR);
  179 + }
  180 + $this->response('success');
  181 + }else{
  182 + $info = $this->model->read(['project_id' => $this->param['project_id'], 'type' => $this->param['type'], 'text' => $this->param['text'], 'status' => 0]);
  183 + if ($info === false) {
  184 + $id = $this->model->addReturnId($this->param);
  185 + } else {
  186 + $id = $info['id'];
  187 + }
  188 + $data = ['id' => $id];
  189 + $this->response('success', Code::SUCCESS, $data);
  190 + }
  191 + }
  192 +
  193 + /**
  194 + * @remark :根据项目获取分类
  195 + * @name :getProductCate
  196 + * @author :lyh
  197 + * @method :post
  198 + * @time :2025/9/25 15:41
  199 + */
  200 + public function getProductCate()
  201 + {
  202 + $this->request->validate([
  203 + 'project_id' => 'required',
  204 + 'type' => 'required',
  205 + 'search' => 'required'
  206 + ], [
  207 + 'project_id.required' => 'project_id不能为空',
  208 + 'type.required' => 'type不能为空',
  209 + 'search.required' => '搜索参数不能为空',
  210 + ]);
  211 + ProjectServer::useProject($this->param['project_id']);
  212 + if ($this->param['type'] == 1) {
  213 + //todo::搜索获取分类
  214 + $productCateModel = new Category();
  215 + $data = $productCateModel->lists(['title' => ['like','%' . $this->param['search'] . '%']], 1, 20,'id',['id','title as name']);
  216 + } else {
  217 + $keywordModel = new Keyword();
  218 + $data = $keywordModel->lists(['title' => ['like','%' . $this->param['search'] . '%']], 1, 20,'id',['id','title as name']);
  219 + }
  220 + DB::disconnect('custom_mysql');
  221 + $this->response('success', Code::SUCCESS, $data);
  222 + }
  223 +
  224 + /**
  225 + * @remark :获取博客分类
  226 + * @name :getBlogCate
  227 + * @author :lyh
  228 + * @method :post
  229 + * @time :2025/9/25 15:42
  230 + */
  231 + public function getBlogCate()
  232 + {
  233 + $this->request->validate([
  234 + 'project_id' => 'required',
  235 + 'search' => 'required'
  236 + ], [
  237 + 'project_id.required' => 'project_id不能为空',
  238 + 'search.required' => '搜索参数不能为空',
  239 + ]);
  240 + ProjectServer::useProject($this->param['project_id']);
  241 + $blogCateModel = new BlogCategory();
  242 + $data = $blogCateModel->lists(['name' => ['like' ,'%' . $this->param['search'] . '%']], 1, 20,'id',['id','name']);
  243 + DB::disconnect('custom_mysql');
  244 + $this->response('success', Code::SUCCESS, $data);
  245 + }
  246 +
  247 + /**
  248 + * @remark :获取新闻分类
  249 + * @name :getNewsCate
  250 + * @author :lyh
  251 + * @method :post
  252 + * @time :2025/9/25 15:43
  253 + */
  254 + public function getNewsCate()
  255 + {
  256 + $this->request->validate([
  257 + 'project_id' => 'required',
  258 + 'search' => 'required'
  259 + ], [
  260 + 'project_id.required' => 'project_id不能为空',
  261 + 'search.required' => '搜索参数不能为空',
  262 + ]);
  263 + ProjectServer::useProject($this->param['project_id']);
  264 + $newsCateModel = new NewsCategory();
  265 + $data = $newsCateModel->lists(['name' => ['like' , '%' . $this->param['search'] . '%']], 1, 20,'id',['id','name']);
  266 + DB::disconnect('custom_mysql');
  267 + $this->response('success', Code::SUCCESS, $data);
  268 + }
  269 +}
@@ -789,6 +789,8 @@ class ProjectController extends BaseController @@ -789,6 +789,8 @@ class ProjectController extends BaseController
789 $company = $this->param['company'] ?? ''; 789 $company = $this->param['company'] ?? '';
790 $order_by_field = $request->input('order_by_field', 'id'); 790 $order_by_field = $request->input('order_by_field', 'id');
791 $order_by_sort = $request->input('order_by_sort', 'desc'); 791 $order_by_sort = $request->input('order_by_sort', 'desc');
  792 + $start_time = $this->param['start_time'] ?? '';
  793 + $end_time = $this->param['end_time'] ?? '';
792 794
793 if(!$source_id && !$id){ 795 if(!$source_id && !$id){
794 $this->response('参数异常',Code::SYSTEM_ERROR); 796 $this->response('参数异常',Code::SYSTEM_ERROR);
@@ -815,7 +817,7 @@ class ProjectController extends BaseController @@ -815,7 +817,7 @@ class ProjectController extends BaseController
815 817
816 $data = Project::with(['deploy_build', 'deploy_optimize', 'online_check']) 818 $data = Project::with(['deploy_build', 'deploy_optimize', 'online_check'])
817 ->where('delete_status', 0) 819 ->where('delete_status', 0)
818 - ->where(function ($query) use ($channel_id, $type, $company, $id, $notice_order_id){ 820 + ->where(function ($query) use ($channel_id, $type, $company, $id, $notice_order_id, $start_time, $end_time){
819 if ($channel_id) { 821 if ($channel_id) {
820 $query->where('channel->channel_id', $channel_id); 822 $query->where('channel->channel_id', $channel_id);
821 } 823 }
@@ -831,6 +833,9 @@ class ProjectController extends BaseController @@ -831,6 +833,9 @@ class ProjectController extends BaseController
831 if ($notice_order_id) { 833 if ($notice_order_id) {
832 $query->whereIn('notice_order_id', $notice_order_id); 834 $query->whereIn('notice_order_id', $notice_order_id);
833 } 835 }
  836 + if ($start_time && $end_time ) {
  837 + $query->whereBetween('uptime', [$start_time, $end_time]);
  838 + }
834 })->orderBy($order_by_field, $order_by_sort)->paginate($size)->toArray(); 839 })->orderBy($order_by_field, $order_by_sort)->paginate($size)->toArray();
835 $list = []; 840 $list = [];
836 foreach ($data['list'] as $item){ 841 foreach ($data['list'] as $item){
@@ -65,17 +65,64 @@ class AdsController extends BaseController @@ -65,17 +65,64 @@ class AdsController extends BaseController
65 ->orderBy('id', 'desc') 65 ->orderBy('id', 'desc')
66 ->paginate($page_size) 66 ->paginate($page_size)
67 ->toArray(); 67 ->toArray();
  68 + $ids = array_column($result['list'], 'id');
  69 + $ad_ids = [];
  70 + foreach (array_column($result['list'], 'ad_id') as $ad_id){
  71 + foreach (explode(',', $ad_id) as $item){
  72 + $ad_ids[] = $item;
  73 + }
  74 + }
  75 +
  76 + $requiry_nums = ReInquiryDetail::select('task_id', DB::raw('COUNT(*) as count'))
  77 + ->whereIn('task_id', $ids)->where('status', ReInquiryDetail::STATUS_SUCCESS)
  78 + ->groupBy('task_id')->pluck('count', 'task_id')->toArray();
  79 +
  80 + $form_nums = ReInquiryForm::select('ad_id', DB::raw('COUNT(*) as count'))
  81 + ->whereIn('ad_id', $ad_ids)->groupBy('ad_id')->pluck('count', 'ad_id')->toArray();
  82 +
68 83
69 $relay_site_total = 0; 84 $relay_site_total = 0;
  85 + $fb_projects = ReInquiryCount::getFobProjects();
  86 +
  87 + $sites = ReInquiryTask::select('target', 'shop_site', 'fob_pro')->get()->toArray();
  88 + $targets = $shop_sites = $fob_pros = [];
  89 + foreach ($sites as $site){
  90 + foreach ($site['target'] as $v){
  91 + if(isset($targets[$v['url']])){
  92 + $targets[$v['url']] = $targets[$v['url']] + 1;
  93 + }else{
  94 + $targets[$v['url']] = 1;
  95 + }
  96 + }
  97 + foreach ($site['shop_site'] as $v){
  98 + if(isset($shop_sites[$v])){
  99 + $shop_sites[$v] = $shop_sites[$v] + 1;
  100 + }else{
  101 + $shop_sites[$v] = 1;
  102 + }
  103 + }
  104 + foreach ($site['fob_pro'] as $v){
  105 + if(isset($fob_pros[$v])){
  106 + $fob_pros[$v] = $fob_pros[$v] + 1;
  107 + }else{
  108 + $fob_pros[$v] = 1;
  109 + }
  110 + }
  111 + }
  112 +
70 foreach ($result['list'] as &$item){ 113 foreach ($result['list'] as &$item){
71 $relay_site_total += count($item['target']); 114 $relay_site_total += count($item['target']);
72 - $item['requiry_num'] = ReInquiryDetail::where('task_id', $item['id'])->where('status', ReInquiryDetail::STATUS_SUCCESS)->count();  
73 - $item['form_num'] = ReInquiryForm::whereIn('ad_id', explode(',', $item['ad_id']))->count(); 115 +// $item['requiry_num'] = ReInquiryDetail::where('task_id', $item['id'])->where('status', ReInquiryDetail::STATUS_SUCCESS)->count();
  116 +// $item['form_num'] = ReInquiryForm::whereIn('ad_id', explode(',', $item['ad_id']))->count();
  117 + $item['requiry_num'] = $requiry_nums[$item['id']] ?? 0;
  118 + $item['form_num'] = 0;
  119 + foreach (explode(',', $item['ad_id']) as $v){
  120 + $item['form_num'] += $form_nums[$v] ?? 0;
  121 + }
74 //关联网站是否有重复的 122 //关联网站是否有重复的
75 if($item['fob_pro']){ 123 if($item['fob_pro']){
76 - $fb_projects = ReInquiryCount::getFobProjects();  
77 foreach ($item['fob_pro'] as $k => $fob_pro){ 124 foreach ($item['fob_pro'] as $k => $fob_pro){
78 - $repeat = ReInquiryTask::where('fob_pro', 'like', '%"'.$fob_pro.'"%')->where('id', '<>', $item['id'])->first(); 125 + $repeat = $fob_pros[$fob_pro] > 1;
79 $fob_info = collect($fb_projects)->where('postid', $fob_pro)->first(); 126 $fob_info = collect($fb_projects)->where('postid', $fob_pro)->first();
80 $item['fob_pro_list'][$k] = [ 127 $item['fob_pro_list'][$k] = [
81 'is_repeat' => $repeat ? 1 : 0, 128 'is_repeat' => $repeat ? 1 : 0,
@@ -85,7 +132,7 @@ class AdsController extends BaseController @@ -85,7 +132,7 @@ class AdsController extends BaseController
85 } 132 }
86 if($item['shop_site']) { 133 if($item['shop_site']) {
87 foreach ($item['shop_site'] as $k => $site) { 134 foreach ($item['shop_site'] as $k => $site) {
88 - $repeat = ReInquiryTask::where('target', 'like', '%"' . $site . '"%')->where('id', '<>', $item['id'])->first(); 135 + $repeat = $shop_sites[$site] > 1;
89 $item['shop_site_list'][$k] = [ 136 $item['shop_site_list'][$k] = [
90 'is_repeat' => $repeat ? 1 : 0, 137 'is_repeat' => $repeat ? 1 : 0,
91 'url' => $site, 138 'url' => $site,
@@ -93,7 +140,7 @@ class AdsController extends BaseController @@ -93,7 +140,7 @@ class AdsController extends BaseController
93 } 140 }
94 } 141 }
95 foreach ($item['target'] as $k=>$target){ 142 foreach ($item['target'] as $k=>$target){
96 - $repeat = ReInquiryTask::where('target', 'like', '%"'.$target['url'].'"%')->where('id', '<>', $item['id'])->first(); 143 + $repeat = $targets[$target['url']] > 1;
97 $item['target'][$k]['is_repeat'] = $repeat ? 1 : 0; 144 $item['target'][$k]['is_repeat'] = $repeat ? 1 : 0;
98 $item['target'][$k]['is_ad_fee'] = 0; 145 $item['target'][$k]['is_ad_fee'] = 0;
99 if($item['target'][$k]['is_v6']){ 146 if($item['target'][$k]['is_v6']){
@@ -112,6 +159,15 @@ class AdsController extends BaseController @@ -112,6 +159,15 @@ class AdsController extends BaseController
112 } 159 }
113 $result['relay_site_total'] = $relay_site_total; 160 $result['relay_site_total'] = $relay_site_total;
114 $result['default_ai_param'] = ReInquiryConfig::getDefaultConfigCache(ReInquiryConfig::TYPE_AI_PARAM); 161 $result['default_ai_param'] = ReInquiryConfig::getDefaultConfigCache(ReInquiryConfig::TYPE_AI_PARAM);
  162 + $result['frequency_map'] = [
  163 + '1' => '一天一封询盘',
  164 + '2' => '两天一封询盘',
  165 + '3' => '三天一封询盘',
  166 + '4' => '四天一封询盘',
  167 + '5' => '五天一封询盘',
  168 + '6' => '六天一封询盘',
  169 + '0' => '不限制',
  170 + ];
115 171
116 return $this->response('success', Code::SUCCESS, $result); 172 return $this->response('success', Code::SUCCESS, $result);
117 } 173 }
@@ -134,6 +190,7 @@ class AdsController extends BaseController @@ -134,6 +190,7 @@ class AdsController extends BaseController
134 $status = intval($request->input('status')); 190 $status = intval($request->input('status'));
135 $is_replace_text = intval($request->input('is_replace_text')); 191 $is_replace_text = intval($request->input('is_replace_text'));
136 $ai_param = $request->input('ai_param'); 192 $ai_param = $request->input('ai_param');
  193 + $second_push_rate = $request->input('second_push_rate');
137 if (empty($title) || empty($ad_id)) 194 if (empty($title) || empty($ad_id))
138 return $this->response('请填写完整信息!', Code::USER_ERROR, []); 195 return $this->response('请填写完整信息!', Code::USER_ERROR, []);
139 196
@@ -152,7 +209,7 @@ class AdsController extends BaseController @@ -152,7 +209,7 @@ class AdsController extends BaseController
152 return $this->response('英文缩写参考不能为空!', Code::USER_ERROR, []); 209 return $this->response('英文缩写参考不能为空!', Code::USER_ERROR, []);
153 } 210 }
154 } 211 }
155 - $task = ReInquiryTask::createTask($id, $title, $industry, $ad_id, $ad_url, $ad_img, $num, $status, $is_replace_text, $ai_param, $is_show_fb_source); 212 + $task = ReInquiryTask::createTask($id, $title, $industry, $ad_id, $ad_url, $ad_img, $num, $status, $is_replace_text, $ai_param, $is_show_fb_source, $second_push_rate);
156 213
157 //是否显示FB标识 214 //是否显示FB标识
158 foreach ($task['target'] as $target){ 215 foreach ($task['target'] as $target){
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :TicketUploadDataController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/9/25 14:00
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Aside\Ticket;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Aside\BaseController;
  14 +use App\Http\Logic\Aside\Ticket\TicketUploadDataLogic;
  15 +use Illuminate\Http\Request;
  16 +
  17 +/**
  18 + * @remark :工单上传列表审核功能
  19 + * @name :TicketUploadDataController
  20 + * @author :lyh
  21 + * @method :post
  22 + * @time :2025/9/25 14:01
  23 + */
  24 +class TicketUploadDataController extends BaseController
  25 +{
  26 + public function __construct(Request $request)
  27 + {
  28 + parent::__construct($request);
  29 + $this->logic = new TicketUploadDataLogic();
  30 + }
  31 +
  32 + /**
  33 + * @remark :获取审核列表
  34 + * @name :lists
  35 + * @author :lyh
  36 + * @method :post
  37 + * @time :2025/9/25 14:02
  38 + */
  39 + public function lists(){
  40 + $this->request->validate([
  41 + 'project_id'=>'required'
  42 + ],[
  43 + 'project_id.required' => 'project_id不能为空',
  44 + ]);
  45 + if(isset($this->map['text']) && !empty($this->map['text'])){
  46 + $this->map['text'] = ['like','%'.$this->map['text'].'%'];
  47 + }
  48 + $data = $this->logic->getDataList($this->map,$this->page,$this->row,$this->order);
  49 + $this->response('success',Code::SUCCESS,$data);
  50 + }
  51 +
  52 + /**
  53 + * @remark :获取数据详情
  54 + * @name :detail
  55 + * @author :lyh
  56 + * @method :post
  57 + * @time :2025/9/26 09:29
  58 + */
  59 + public function detail(){
  60 + $this->request->validate([
  61 + 'id'=>'required'
  62 + ],[
  63 + 'id.required' => '主键ID不能为空',
  64 + ]);
  65 + $data = $this->logic->getDetail();
  66 + $this->response('success',Code::SUCCESS,$data);
  67 + }
  68 +
  69 + /**
  70 + * @remark :人工审核
  71 + * @name :save
  72 + * @author :lyh
  73 + * @method :post
  74 + * @time :2025/9/25 14:14
  75 + */
  76 + public function save()
  77 + {
  78 + $this->request->validate([
  79 + 'status'=>'required',
  80 + 'id'=>'required'
  81 + ],[
  82 + 'status.required' => '提交状态不能为空',
  83 + 'id.required' => '主键ID不能为空',
  84 + ]);
  85 + $data = $this->logic->saveData();
  86 + $this->response('success',Code::SUCCESS,$data);
  87 + }
  88 +}
@@ -82,8 +82,8 @@ class AiBlogController extends BaseController @@ -82,8 +82,8 @@ class AiBlogController extends BaseController
82 * @method :post 82 * @method :post
83 * @time :2023/7/5 14:33 83 * @time :2023/7/5 14:33
84 */ 84 */
85 - public function save(AiBlogLogic $aiBlogLogic){  
86 -// $aiBlogRequest->validated(); 85 + public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){
  86 + $aiBlogRequest->validated();
87 $aiBlogLogic->blogSave(); 87 $aiBlogLogic->blogSave();
88 $this->response('success'); 88 $this->response('success');
89 } 89 }
@@ -218,14 +218,8 @@ class BlogController extends BaseController @@ -218,14 +218,8 @@ class BlogController extends BaseController
218 public function edit_seo(BlogLogic $blogLogic){ 218 public function edit_seo(BlogLogic $blogLogic){
219 $this->request->validate([ 219 $this->request->validate([
220 'id'=>['required'], 220 'id'=>['required'],
221 - 'seo_title'=>['required'],  
222 - 'seo_description'=>['required'],  
223 - 'seo_keywords'=>['required'],  
224 ],[ 221 ],[
225 'id.required' => 'ID不能为空', 222 'id.required' => 'ID不能为空',
226 - 'seo_title.required' => 'seo_title不能为空',  
227 - 'seo_description.required' => 'seo_description不能为空',  
228 - 'seo_keywords.required' => 'seo_description不能为空',  
229 ]); 223 ]);
230 $blogLogic->edit_seo(); 224 $blogLogic->edit_seo();
231 $this->response('success'); 225 $this->response('success');
@@ -198,13 +198,19 @@ class CustomModuleContentController extends BaseController @@ -198,13 +198,19 @@ class CustomModuleContentController extends BaseController
198 */ 198 */
199 public function save(CustomModuleContentLogic $logic){ 199 public function save(CustomModuleContentLogic $logic){
200 $this->request->validate([ 200 $this->request->validate([
201 - 'name'=>['required'], 201 + 'name'=>['required','max:200'],
202 'route'=>['required'], 202 'route'=>['required'],
203 - 'module_id'=>['required'] 203 + 'module_id'=>['required'],
  204 +// 'seo_title'=>['max:70'],
  205 + 'seo_keywords'=>['max:300'],
  206 + 'seo_description'=>['max:200'],
204 ],[ 207 ],[
205 'name.required' => '分类名称不能为空', 208 'name.required' => '分类名称不能为空',
206 'route.required' => '分类路由不能为空', 209 'route.required' => '分类路由不能为空',
207 - 'module_id.required' => '所选模块id不能为空' 210 + 'module_id.required' => '所选模块id不能为空',
  211 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  212 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  213 + 'seo_description.max' => 'SEO描述不能超过200个字符',
208 ]); 214 ]);
209 $data = $logic->contentSave(); 215 $data = $logic->contentSave();
210 $this->response('success',Code::SUCCESS,$data); 216 $this->response('success',Code::SUCCESS,$data);
@@ -211,14 +211,8 @@ class NewsController extends BaseController @@ -211,14 +211,8 @@ class NewsController extends BaseController
211 public function edit_seo(NewsLogic $newsLogic){ 211 public function edit_seo(NewsLogic $newsLogic){
212 $this->request->validate([ 212 $this->request->validate([
213 'id'=>['required'], 213 'id'=>['required'],
214 - 'seo_title'=>['required'],  
215 - 'seo_description'=>['required'],  
216 - 'seo_keywords'=>['required'],  
217 ],[ 214 ],[
218 'id.required' => 'ID不能为空', 215 'id.required' => 'ID不能为空',
219 - 'seo_title.required' => 'seo_title不能为空',  
220 - 'seo_description.required' => 'seo_description不能为空',  
221 - 'seo_keywords.required' => 'seo_description不能为空',  
222 ]); 216 ]);
223 $newsLogic->edit_seo(); 217 $newsLogic->edit_seo();
224 $this->response('success'); 218 $this->response('success');
@@ -155,8 +155,8 @@ class RankDataController extends BaseController @@ -155,8 +155,8 @@ class RankDataController extends BaseController
155 'cnt_first' => '排名第一', 155 'cnt_first' => '排名第一',
156 'cnt_home' => '第一页', 156 'cnt_home' => '第一页',
157 'cnt_thirty' => '前三页', 157 'cnt_thirty' => '前三页',
158 - 'cnt_fifty' => '前五页',  
159 - 'cnt_hundred' => '前十页', 158 +// 'cnt_fifty' => '前五页',
  159 +// 'cnt_hundred' => '前十页',
160 'reach' => '是否达标', 160 'reach' => '是否达标',
161 ]; 161 ];
162 } 162 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :TicketUploadDataLogic.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/9/25 14:03
  8 + */
  9 +
  10 +namespace App\Http\Logic\Aside\Ticket;
  11 +
  12 +use App\Helper\Arr;
  13 +use App\Http\Logic\Aside\BaseLogic;
  14 +use App\Models\Blog\Blog;
  15 +use App\Models\Blog\BlogCategory;
  16 +use App\Models\News\News;
  17 +use App\Models\News\NewsCategory;
  18 +use App\Models\Product\Category;
  19 +use App\Models\Product\CategoryRelated;
  20 +use App\Models\Product\Keyword;
  21 +use App\Models\Product\KeywordRelated;
  22 +use App\Models\Product\Product;
  23 +use App\Models\RouteMap\RouteMap;
  24 +use App\Models\Ticket\TicketUploadData;
  25 +use App\Services\ProjectServer;
  26 +use Illuminate\Support\Facades\DB;
  27 +
  28 +class TicketUploadDataLogic extends BaseLogic
  29 +{
  30 + public function __construct()
  31 + {
  32 + parent::__construct();
  33 + $this->param = $this->requestAll;
  34 + $this->model = new TicketUploadData();
  35 + }
  36 +
  37 + /**
  38 + * @remark :获取审核列表
  39 + * @name :getDataList
  40 + * @author :lyh
  41 + * @method :post
  42 + * @time :2025/9/25 14:17
  43 + */
  44 + public function getDataList($map = [],$page = 1,$row = 20,$order = 'id'){
  45 + if(isset($this->map['text']) && !empty($this->map['text'])){
  46 + $this->map['text'] = ['like','%'.$this->map['text'].'%'];
  47 + }
  48 + ProjectServer::useProject($map['project_id']);
  49 + $data = $this->model->lists($map,$page,$row,$order);
  50 + if(!empty($data) && !empty($data['list'])){
  51 + foreach ($data['list'] as &$v){
  52 + $v = $this->getHandleFileImage($v);
  53 + $v['text']['cate_name'] = $this->cateText($v['type'],$v['text']['category_id'] ?? []);
  54 + }
  55 + }
  56 + DB::disconnect('custom_mysql');
  57 + return $this->success($data);
  58 + }
  59 +
  60 + /**
  61 + * @remark :处理数据
  62 + * @name :getHandleFileImage
  63 + * @author :lyh
  64 + * @method :post
  65 + * @time :2025/9/25 16:53
  66 + */
  67 + public function getHandleFileImage($v){
  68 + if($v['type'] == 1){
  69 + if(!empty($v['text']['image'])){
  70 + foreach ($v['text']['image'] as $gallery_k => $gallery_v){
  71 + $gallery_v['url'] = getImageUrl($gallery_v['url']);
  72 + $v['text']['image'][$gallery_k] = $gallery_v;
  73 + }
  74 + }
  75 + }else{
  76 + if(isset($v['text']['image']) && !empty($v['text']['image'])){
  77 + $v['text']['image'] = getImageUrl($v['text']['image']);
  78 + }
  79 + }
  80 + return $this->success($v);
  81 + }
  82 +
  83 + /**
  84 + * @remark :获取分类名称
  85 + * @name :cateText
  86 + * @author :lyh
  87 + * @method :post
  88 + * @time :2025/9/29 17:18
  89 + */
  90 + public function cateText($type,$category_id = [],$keyword_id = [],$is_array = false)
  91 + {
  92 + if(empty($category_id)){
  93 + return '';
  94 + }else{
  95 + $filed = 'name';
  96 + if($type == 1){
  97 + $cateModel = new Category();
  98 + $keywodModel = new KeyWord();
  99 + $filed = 'title';
  100 + }elseif ($type == 2){
  101 + $cateModel = new BlogCategory();
  102 + }else{
  103 + $cateModel = new NewsCategory();
  104 + }
  105 + if($is_array){
  106 + $cate_arr = $cateModel->whereIn('id', (array)$category_id)
  107 + ->pluck($filed, 'id')
  108 + ->toArray();
  109 + if($type == 1){
  110 + $keywod_arr = $keywodModel->whereIn('id', (array)$keyword_id)
  111 + ->pluck($filed, 'id')
  112 + ->toArray();
  113 + return ['keywod_arr' => $keywod_arr, 'cate_arr' => $cate_arr];
  114 + }
  115 + return ['cate_arr' => $cate_arr];
  116 + }else{
  117 + $cateArr = $cateModel->selectField(['id'=>['in',$category_id]],$filed);
  118 + return implode(',',$cateArr);
  119 + }
  120 + }
  121 + }
  122 +
  123 + /**
  124 + * @remark :获取当前数据详情
  125 + * @name :getDetail
  126 + * @author :lyh
  127 + * @method :post
  128 + * @time :2025/9/26 09:31
  129 + */
  130 + public function getDetail(){
  131 + $info = $this->model->read(['id'=>$this->param['id']]);
  132 + if($info === false){
  133 + $this->fail('当前数据不存在或已被删除');
  134 + }
  135 + ProjectServer::useProject($info['project_id']);
  136 + $info['text']['cate_name'] = $this->cateText($info['type'],$info['text']['category_id'] ?? [],$info['text']['keyword_id'] ?? [],true);
  137 + $info = $this->getHandleFileImage($info);
  138 + DB::disconnect('custom_mysql');
  139 + return $this->success($info);
  140 + }
  141 +
  142 + /**
  143 + * @remark :保存数据
  144 + * @name :saveData
  145 + * @author :lyh
  146 + * @method :post
  147 + * @time :2025/9/25 17:01
  148 + */
  149 + public function saveData()
  150 + {
  151 + //获取当前数据详情
  152 + $info = $this->model->read(['id'=>$this->param['id']]);
  153 + if($info === false){
  154 + $this->fail('当前数据不存在或已被删除');
  155 + }
  156 + //审核成功执行
  157 + if($this->param['status'] == 1){
  158 + ProjectServer::useProject($info['project_id']);
  159 + if($info['type'] == 1){
  160 + $this->saveProductData($info);
  161 + }elseif ($info['type'] == 2){
  162 + $this->saveBlogData($info);
  163 + }else{
  164 + $this->saveNewsData($info);
  165 + }
  166 + DB::disconnect('custom_mysql');
  167 + }
  168 + $data = $this->model->edit(['status'=>$this->param['status'],'operator_id'=>$this->manager['id'],'remark'=>$this->param['remark'] ?? ''],['id'=>$this->param['id']]);
  169 + return $this->success($data);
  170 + }
  171 +
  172 + /**
  173 + * @remark :保存数据详情
  174 + * @name :saveData
  175 + * @author :lyh
  176 + * @method :post
  177 + * @time :2025/9/25 14:17
  178 + */
  179 + public function saveProductData($info){
  180 + if(isset($info['text']['keyword_id']) && !empty($info['text']['keyword_id'])){
  181 + $keyword_id = ','.Arr::arrToSet($info['text']['keyword_id']).',';
  182 + }
  183 + if(isset($info['text']['category_id']) && !empty($info['text']['category_id'])) {
  184 + $category_id = ','.Arr::arrToSet($info['text']['category_id']).',';
  185 + }
  186 + if(isset($info['text']['image']) && !empty($info['text']['image'])){
  187 + foreach ($info['text']['image'] as $k => $v){
  188 + $v['url'] = str_replace_url($v['url']);
  189 + $info['text']['image'][$k] = $v;
  190 + }
  191 + $thumb = Arr::a2s($info['text']['image'][0] ?? []);
  192 + $info['text']['image'] = Arr::a2s($info['text']['image'] ?? []);
  193 + }else{
  194 + $thumb = $info['text']['image'] = Arr::a2s([]);
  195 + }
  196 + try {
  197 + $productModel = new Product();
  198 + $data = [
  199 + 'project_id' => $info['project_id'],
  200 + 'title' => $info['text']['title'],
  201 + 'thumb'=>$thumb,
  202 + 'gallery'=>$info['text']['image'] ?? [],
  203 + 'intro'=>$info['text']['remark'],
  204 + 'category_id'=>$category_id ?? '',
  205 + 'keyword_id'=>$keyword_id ?? '',
  206 + 'status'=>0,
  207 + ];
  208 + $id = $productModel->addReturnId($data);
  209 + CategoryRelated::saveRelated($id, $info['text']['category_id'] ?? []);//分类关联
  210 + KeywordRelated::saveRelated($id,$info['text']['keyword_id'] ?? []);//关键字关联
  211 + $route = RouteMap::setRoute($data['title'],RouteMap::SOURCE_PRODUCT,$id,$info['project_id']);
  212 + $this->model->edit(['route'=>$route],['id'=>$id]);
  213 + }catch (\Exception $e){
  214 + $this->fail('保存失败,请联系管理员');
  215 + }
  216 + return $this->success();
  217 + }
  218 +
  219 + /**
  220 + * @remark :保存blog数据
  221 + * @name :saveBlogData
  222 + * @author :lyh
  223 + * @method :post
  224 + * @time :2025/9/25 16:26
  225 + */
  226 + public function saveBlogData($info)
  227 + {
  228 + if(isset($info['text']['category_id']) && !empty($info['text']['category_id'])) {
  229 + $category_id = ','.Arr::arrToSet($info['text']['category_id']).',';
  230 + }
  231 + if(isset($info['text']['image'])){
  232 + $info['text']['image'] = str_replace_url($info['text']['image'] ?? '');
  233 + }
  234 + $data = [
  235 + 'project_id' => $info['project_id'],
  236 + 'name' => $info['text']['title'],
  237 + 'image'=>$info['text']['image'],
  238 + 'text'=>$info['text']['remark'],
  239 + 'category_id'=>$category_id ?? '',
  240 + 'status'=>0,
  241 + ];
  242 + try {
  243 + $blogModel = new Blog();
  244 + $id = $blogModel->addReturnId($data);
  245 + $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_BLOG,$id,$info['project_id']);
  246 + $this->model->edit(['url'=>$route],['id'=>$id]);
  247 + }catch (\Exception $e){
  248 + $this->fail('保存失败,请联系管理员');
  249 + }
  250 + return $this->success();
  251 + }
  252 +
  253 + /**
  254 + * @remark :保存新闻数据
  255 + * @name :saveNewsData
  256 + * @author :lyh
  257 + * @method :post
  258 + * @time :2025/9/25 16:34
  259 + */
  260 + public function saveNewsData($info)
  261 + {
  262 + if(isset($info['text']['category_id']) && !empty($info['text']['category_id'])) {
  263 + $category_id = ','.Arr::arrToSet($info['text']['category_id']).',';
  264 + }
  265 + if(isset($info['text']['image'])){
  266 + $info['text']['image'] = str_replace_url($info['text']['image'] ?? '');
  267 + }
  268 + $data = [
  269 + 'project_id' => $info['project_id'],
  270 + 'name' => $info['text']['title'],
  271 + 'image'=>$info['text']['image'],
  272 + 'text'=>$info['text']['remark'],
  273 + 'category_id'=>$category_id ?? '',
  274 + 'status'=>0,
  275 + ];
  276 + try {
  277 + $newsModel = new News();
  278 + $id = $newsModel->addReturnId($data);
  279 + $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_NEWS,$id,$info['project_id']);
  280 + $this->model->edit(['route'=>$route],['id'=>$id]);
  281 + }catch (\Exception $e){
  282 + $this->fail('保存失败,请联系管理员');
  283 + }
  284 + return $this->success();
  285 + }
  286 +}
@@ -58,6 +58,9 @@ class AiBlogLogic extends BaseLogic @@ -58,6 +58,9 @@ class AiBlogLogic extends BaseLogic
58 if(!empty($this->param['image'])){ 58 if(!empty($this->param['image'])){
59 $this->param['image'] = str_replace_url($this->param['image']); 59 $this->param['image'] = str_replace_url($this->param['image']);
60 } 60 }
  61 + if(!isset($this->param['seo_title']) || empty($this->param['seo_title'])){
  62 + $this->param['seo_title'] = truncate_text($this->param['new_title'],70);
  63 + }
61 $this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_AI_BLOG, $this->param['id'], $this->user['project_id']); 64 $this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_AI_BLOG, $this->param['id'], $this->user['project_id']);
62 $anchor = $this->param['anchor'] ?? []; 65 $anchor = $this->param['anchor'] ?? [];
63 $this->param['anchor'] = json_encode($anchor,true); 66 $this->param['anchor'] = json_encode($anchor,true);
@@ -153,7 +156,7 @@ class AiBlogLogic extends BaseLogic @@ -153,7 +156,7 @@ class AiBlogLogic extends BaseLogic
153 //删除路由映射 156 //删除路由映射
154 RouteMap::delRoute(RouteMap::SOURCE_AI_BLOG, $id, $this->user['project_id']); 157 RouteMap::delRoute(RouteMap::SOURCE_AI_BLOG, $id, $this->user['project_id']);
155 $this->model->del(['id'=>$id]); 158 $this->model->del(['id'=>$id]);
156 - $this->curlDelRoute(['old_route'=>$info['route']]); 159 + $this->curlDelRoute(['old_route'=>$info['route'],'path'=>'blog']);
157 } 160 }
158 Artisan::call('save_ai_blog_list', ['project_id' => $this->user['project_id']]); 161 Artisan::call('save_ai_blog_list', ['project_id' => $this->user['project_id']]);
159 }catch (\Exception $e){ 162 }catch (\Exception $e){
@@ -91,6 +91,7 @@ class AiVideoLogic extends BaseLogic @@ -91,6 +91,7 @@ class AiVideoLogic extends BaseLogic
91 //删除路由映射 91 //删除路由映射
92 RouteMap::delRoute(RouteMap::SOURCE_AI_VIDEO, $id, $this->user['project_id']); 92 RouteMap::delRoute(RouteMap::SOURCE_AI_VIDEO, $id, $this->user['project_id']);
93 $this->model->del(['id'=>$id]); 93 $this->model->del(['id'=>$id]);
  94 + $this->curlDelRoute(['old_route'=>$info['route'],'path'=>'video']);
94 } 95 }
95 }catch (\Exception $e){ 96 }catch (\Exception $e){
96 $this->fail('删除失败,请联系管理员'); 97 $this->fail('删除失败,请联系管理员');
@@ -30,6 +30,9 @@ class BlogCategoryLogic extends BaseLogic @@ -30,6 +30,9 @@ class BlogCategoryLogic extends BaseLogic
30 public function categorySave(){ 30 public function categorySave(){
31 //验证名称是否存在 31 //验证名称是否存在
32 $this->verifyParamName($this->param['name']); 32 $this->verifyParamName($this->param['name']);
  33 + if(!isset($this->param['seo_title']) || empty($this->param['seo_title'])){
  34 + $this->param['seo_title'] = truncate_text($this->param['name'],70);
  35 + }
33 DB::beginTransaction(); 36 DB::beginTransaction();
34 try { 37 try {
35 if(isset($this->param['id']) && !empty($this->param['id'])){ 38 if(isset($this->param['id']) && !empty($this->param['id'])){
@@ -201,6 +201,9 @@ class BlogLogic extends BaseLogic @@ -201,6 +201,9 @@ class BlogLogic extends BaseLogic
201 $this->fail('发布时间需大于当天'); 201 $this->fail('发布时间需大于当天');
202 } 202 }
203 } 203 }
  204 + if(!isset($param['seo_title']) || empty($param['seo_title'])){
  205 + $param['seo_title'] = truncate_text($param['name'],70);
  206 + }
204 return $this->success($param); 207 return $this->success($param);
205 } 208 }
206 209
@@ -234,6 +234,9 @@ class CustomModuleContentLogic extends BaseLogic @@ -234,6 +234,9 @@ class CustomModuleContentLogic extends BaseLogic
234 $param['video']['video_image'] = str_replace_url($param['video']['video_image']); 234 $param['video']['video_image'] = str_replace_url($param['video']['video_image']);
235 $param['video'] = Arr::a2s($param['video'] ?? []); 235 $param['video'] = Arr::a2s($param['video'] ?? []);
236 } 236 }
  237 + if(!isset($param['seo_title']) || empty($param['seo_title'])){
  238 + $param['seo_title'] = truncate_text($param['name'],70);
  239 + }
237 return $this->success($param); 240 return $this->success($param);
238 } 241 }
239 242
@@ -49,6 +49,7 @@ class GeoQuestionResLogic extends BaseLogic @@ -49,6 +49,7 @@ class GeoQuestionResLogic extends BaseLogic
49 public function getResultList($map = [],$page = 1,$row = 20,$order = 'created_at',$sort = 'desc'){ 49 public function getResultList($map = [],$page = 1,$row = 20,$order = 'created_at',$sort = 'desc'){
50 unset($map['sort']); 50 unset($map['sort']);
51 $map['project_id'] = $this->user['project_id']; 51 $map['project_id'] = $this->user['project_id'];
  52 + $map['hit'] = ['!=',0];
52 $filed = ['id','project_id','question_id','platform','is_match','question','en_question','keywords','url','label','cosine','created_at','updated_at']; 53 $filed = ['id','project_id','question_id','platform','is_match','question','en_question','keywords','url','label','cosine','created_at','updated_at'];
53 if(!empty($map['created_at'])){ 54 if(!empty($map['created_at'])){
54 $map['created_at'] = ['between',[$map['created_at'].' 00:00:00',$map['created_at'].' 23:59:59']]; 55 $map['created_at'] = ['between',[$map['created_at'].' 00:00:00',$map['created_at'].' 23:59:59']];
@@ -48,7 +48,7 @@ class CountLogic extends BaseLogic @@ -48,7 +48,7 @@ class CountLogic extends BaseLogic
48 $domain = parse_url($this->user['domain'], PHP_URL_HOST); // 直接取域名部分 48 $domain = parse_url($this->user['domain'], PHP_URL_HOST); // 直接取域名部分
49 $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$this->user['is_upgrade']); 49 $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$this->user['is_upgrade']);
50 if($inquiry_list !== false){ 50 if($inquiry_list !== false){
51 - if($inquiry_list['status'] != 400){ 51 + if(isset($inquiry_list['status']) && $inquiry_list['status'] != 400){
52 $info['inquiry_num'] = $inquiry_list['data']['count']; 52 $info['inquiry_num'] = $inquiry_list['data']['count'];
53 Cache::add('inquiry_num_'.$this->user['project_id'],$inquiry_list['data']['count'],3600); 53 Cache::add('inquiry_num_'.$this->user['project_id'],$inquiry_list['data']['count'],3600);
54 } 54 }
@@ -49,6 +49,9 @@ class NewsCategoryLogic extends BaseLogic @@ -49,6 +49,9 @@ class NewsCategoryLogic extends BaseLogic
49 if(isset($param['image']) && !empty($param['image'])){ 49 if(isset($param['image']) && !empty($param['image'])){
50 $param['image'] = str_replace_url($param['image']); 50 $param['image'] = str_replace_url($param['image']);
51 } 51 }
  52 + if(!isset($param['seo_title']) || empty($param['seo_title'])){
  53 + $param['seo_title'] = truncate_text($param['name'],70);
  54 + }
52 return $this->success($param); 55 return $this->success($param);
53 } 56 }
54 /** 57 /**
@@ -225,6 +225,9 @@ class NewsLogic extends BaseLogic @@ -225,6 +225,9 @@ class NewsLogic extends BaseLogic
225 if(isset($param['related_product_id'])){ 225 if(isset($param['related_product_id'])){
226 $param['related_product_id'] = implode(',',$param['related_product_id']); 226 $param['related_product_id'] = implode(',',$param['related_product_id']);
227 } 227 }
  228 + if(!isset($param['seo_title']) || empty($param['seo_title'])){
  229 + $param['seo_title'] = truncate_text($param['name'],70);
  230 + }
228 return $this->success($param); 231 return $this->success($param);
229 } 232 }
230 233
@@ -157,6 +157,9 @@ class CategoryLogic extends BaseLogic @@ -157,6 +157,9 @@ class CategoryLogic extends BaseLogic
157 }else{ 157 }else{
158 $param['cate_tak'] = json_encode([]);; 158 $param['cate_tak'] = json_encode([]);;
159 } 159 }
  160 + if(!isset($param['seo_title']) || empty($param['seo_title'])){
  161 + $param['seo_title'] = truncate_text($param['title'],70);
  162 + }
160 return $this->success($param); 163 return $this->success($param);
161 } 164 }
162 165
@@ -123,6 +123,8 @@ class KeywordLogic extends BaseLogic @@ -123,6 +123,8 @@ class KeywordLogic extends BaseLogic
123 } 123 }
124 if(!empty($param['seo_title'])){ 124 if(!empty($param['seo_title'])){
125 $param['seo_title'] = ucfirst($param['seo_title']); 125 $param['seo_title'] = ucfirst($param['seo_title']);
  126 + }else{
  127 + $param['seo_title'] = truncate_text($param['title'],70);
126 } 128 }
127 $param['first_word'] = $this->model->first_word($param['title']); 129 $param['first_word'] = $this->model->first_word($param['title']);
128 return $param; 130 return $param;
@@ -44,6 +44,9 @@ class ProductLogic extends BaseLogic @@ -44,6 +44,9 @@ class ProductLogic extends BaseLogic
44 if(isset($this->param['id']) && !empty($this->param['id'])){ 44 if(isset($this->param['id']) && !empty($this->param['id'])){
45 $data = $this->editProduct(); 45 $data = $this->editProduct();
46 }else{ 46 }else{
  47 + if(!isset($this->param['seo_title']) || empty($this->param['seo_title'])){
  48 + $this->param['seo_title'] = $this->param['title'];
  49 + }
47 $data = $this->addProduct(); 50 $data = $this->addProduct();
48 } 51 }
49 CategoryRelated::saveRelated($data['id'], $this->param['category_id'] ?? []);//分类关联 52 CategoryRelated::saveRelated($data['id'], $this->param['category_id'] ?? []);//分类关联
@@ -389,6 +392,9 @@ class ProductLogic extends BaseLogic @@ -389,6 +392,9 @@ class ProductLogic extends BaseLogic
389 $param['attr_id'] = Arr::arrToSet($param['attr_id'] ?? ''); 392 $param['attr_id'] = Arr::arrToSet($param['attr_id'] ?? '');
390 $param['describe'] = Arr::a2s($param['describe'] ?? []); 393 $param['describe'] = Arr::a2s($param['describe'] ?? []);
391 $param['describe_id'] = Arr::arrToSet($param['describe_id'] ?? ''); 394 $param['describe_id'] = Arr::arrToSet($param['describe_id'] ?? '');
  395 + if(!isset($param['seo_mate']['seo_title']) || empty($param['seo_mate']['seo_title'])){
  396 + $param['seo_mate']['seo_title'] = truncate_text($param['title'],70);
  397 + }
392 $param['seo_mate'] = Arr::a2s($param['seo_mate'] ?? []); 398 $param['seo_mate'] = Arr::a2s($param['seo_mate'] ?? []);
393 $param['related_product_id'] = Arr::arrToSet($param['related_product_id'] ?? ''); 399 $param['related_product_id'] = Arr::arrToSet($param['related_product_id'] ?? '');
394 if(isset($param['icon'])){ 400 if(isset($param['icon'])){
@@ -554,8 +554,8 @@ class RankDataLogic extends BaseLogic @@ -554,8 +554,8 @@ class RankDataLogic extends BaseLogic
554 $without_project_ids = []; //不用处理排名的项目 554 $without_project_ids = []; //不用处理排名的项目
555 $without_extension_project_ids = [658]; //是否达标只统计主词的 555 $without_extension_project_ids = [658]; //是否达标只统计主词的
556 $extension_project_ids = [354]; //扩展词也到达标的 556 $extension_project_ids = [354]; //扩展词也到达标的
557 - $compliance_project_ids = [2163,257,823,1750,497]; //直接达标处理的  
558 - $ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193,2399,1685, 3931];//暂停的项目 557 + $compliance_project_ids = [2163,257,823,1750,497,1006]; //直接达标处理的
  558 + $ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193,2399,1685, 3931,2273,3647];//暂停的项目
559 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目 559 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
560 //一个项目多个api_no 560 //一个项目多个api_no
561 $multiple_api_no_project_ids = [ 561 $multiple_api_no_project_ids = [
@@ -25,6 +25,9 @@ class AiBlogRequest extends FormRequest @@ -25,6 +25,9 @@ class AiBlogRequest extends FormRequest
25 { 25 {
26 return [ 26 return [
27 'new_title'=>'required', 27 'new_title'=>'required',
  28 +// 'seo_title'=>'max:70',
  29 + 'seo_keywords'=>'max:300',
  30 + 'seo_description'=>'max:200',
28 ]; 31 ];
29 } 32 }
30 33
@@ -32,6 +35,9 @@ class AiBlogRequest extends FormRequest @@ -32,6 +35,9 @@ class AiBlogRequest extends FormRequest
32 { 35 {
33 return [ 36 return [
34 'new_title.required' => '新标题不能为空', 37 'new_title.required' => '新标题不能为空',
  38 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  39 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  40 + 'seo_description.max' => 'SEO描述不能超过200个字符',
35 ]; 41 ];
36 } 42 }
37 } 43 }
@@ -24,7 +24,10 @@ class BlogCategoryRequest extends FormRequest @@ -24,7 +24,10 @@ class BlogCategoryRequest extends FormRequest
24 public function rules() 24 public function rules()
25 { 25 {
26 return [ 26 return [
27 - 'name'=>'required|max:100', 27 + 'name'=>'required|max:200',
  28 +// 'seo_title'=>'max:70',
  29 + 'seo_keywords'=>'max:300',
  30 + 'seo_des'=>'max:200',
28 ]; 31 ];
29 } 32 }
30 33
@@ -32,7 +35,10 @@ class BlogCategoryRequest extends FormRequest @@ -32,7 +35,10 @@ class BlogCategoryRequest extends FormRequest
32 { 35 {
33 return [ 36 return [
34 'name.required'=>'请填写名称', 37 'name.required'=>'请填写名称',
35 - 'name.max'=>'名称最大100字', 38 + 'name.max'=>'名称最大200字',
  39 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  40 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  41 + 'seo_des.max' => 'SEO描述不能超过200个字符',
36 ]; 42 ];
37 } 43 }
38 } 44 }
@@ -25,10 +25,11 @@ class BlogRequest extends FormRequest @@ -25,10 +25,11 @@ class BlogRequest extends FormRequest
25 { 25 {
26 return [ 26 return [
27 'name'=>'required|max:200', 27 'name'=>'required|max:200',
28 - 'seo_keywords'=>'max:500',  
29 'remark'=>'max:1000', 28 'remark'=>'max:1000',
30 'url'=>'required', 29 'url'=>'required',
31 -// 'text'=>'max:5000', 30 +// 'seo_title'=>'max:70',
  31 + 'seo_keywords'=>'max:300',
  32 + 'seo_description'=>'max:200',
32 ]; 33 ];
33 } 34 }
34 35
@@ -38,9 +39,10 @@ class BlogRequest extends FormRequest @@ -38,9 +39,10 @@ class BlogRequest extends FormRequest
38 'name.required'=>'请填写名称', 39 'name.required'=>'请填写名称',
39 'name.max'=>'名称超过最长长度200', 40 'name.max'=>'名称超过最长长度200',
40 'url.required'=>'链接不能为空', 41 'url.required'=>'链接不能为空',
41 - 'seo_keywords.max'=>'seo_keywords太长,请重新编辑', 42 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  43 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  44 + 'seo_description.max' => 'SEO描述不能超过200个字符',
42 'remark.max'=>'描述超过最长长度1000', 45 'remark.max'=>'描述超过最长长度1000',
43 -// 'text.max'=>'详情内容超过最大长度',  
44 ]; 46 ];
45 } 47 }
46 } 48 }
@@ -24,7 +24,10 @@ class NewsCategoryRequest extends FormRequest @@ -24,7 +24,10 @@ class NewsCategoryRequest extends FormRequest
24 public function rules() 24 public function rules()
25 { 25 {
26 return [ 26 return [
27 - 'name'=>'required|max:100', 27 + 'name'=>'required|max:200',
  28 +// 'seo_title'=>'max:70',
  29 + 'seo_keywords'=>'max:300',
  30 + 'seo_des'=>'max:200',
28 ]; 31 ];
29 } 32 }
30 33
@@ -33,6 +36,9 @@ class NewsCategoryRequest extends FormRequest @@ -33,6 +36,9 @@ class NewsCategoryRequest extends FormRequest
33 return [ 36 return [
34 'name.required'=>'请填写名称', 37 'name.required'=>'请填写名称',
35 'name.max'=>'名称最大100字', 38 'name.max'=>'名称最大100字',
  39 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  40 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  41 + 'seo_des.max' => 'SEO描述不能超过200个字符',
36 ]; 42 ];
37 } 43 }
38 } 44 }
@@ -25,8 +25,10 @@ class NewsRequest extends FormRequest @@ -25,8 +25,10 @@ class NewsRequest extends FormRequest
25 { 25 {
26 return [ 26 return [
27 'name'=>'required|max:200', 27 'name'=>'required|max:200',
28 -// 'remark'=>'max:2000',  
29 'url'=>'required', 28 'url'=>'required',
  29 +// 'seo_title' => 'max:70',
  30 + 'seo_keywords' => 'max:300',
  31 + 'seo_description' => 'max:200',
30 ]; 32 ];
31 } 33 }
32 34
@@ -36,7 +38,9 @@ class NewsRequest extends FormRequest @@ -36,7 +38,9 @@ class NewsRequest extends FormRequest
36 'name.required'=>'请填写名称', 38 'name.required'=>'请填写名称',
37 'name.max'=>'名称超过最长长度200', 39 'name.max'=>'名称超过最长长度200',
38 'url.required'=>'链接不能为空', 40 'url.required'=>'链接不能为空',
39 -// 'remark.max'=>'描述超过最长长度2000' 41 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  42 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  43 + 'seo_description.max' => 'SEO描述不能超过200个字符',
40 ]; 44 ];
41 } 45 }
42 } 46 }
@@ -32,9 +32,8 @@ class CategoryRequest extends FormRequest @@ -32,9 +32,8 @@ class CategoryRequest extends FormRequest
32 return [ 32 return [
33 'title'=>'required|max:200', 33 'title'=>'required|max:200',
34 'route'=>'required', 34 'route'=>'required',
35 -// 'image'=>'required',  
36 -// 'keywords'=>'max:50',  
37 -// 'describe'=>'max:200', 35 + 'seo_keywords'=>'max:300',
  36 + 'seo_des'=>'max:200',
38 ]; 37 ];
39 } 38 }
40 39
@@ -44,9 +43,8 @@ class CategoryRequest extends FormRequest @@ -44,9 +43,8 @@ class CategoryRequest extends FormRequest
44 'title.required' => '请输入分类名称', 43 'title.required' => '请输入分类名称',
45 'title.max' => '分类名称不能超过200个字符', 44 'title.max' => '分类名称不能超过200个字符',
46 'route.required' => '路由不能为空', 45 'route.required' => '路由不能为空',
47 -// 'image.required' => '请上传分类图片',  
48 -// 'keywords.max' => '分类关键词不能超过50个字符',  
49 -// 'describe.max' => '分类描述不能超过200个字符', 46 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  47 + 'seo_des.max' => 'SEO描述不能超过200个字符',
50 ]; 48 ];
51 } 49 }
52 50
@@ -31,9 +31,9 @@ class KeywordRequest extends FormRequest @@ -31,9 +31,9 @@ class KeywordRequest extends FormRequest
31 { 31 {
32 return [ 32 return [
33 'title'=>'required|max:200', 33 'title'=>'required|max:200',
34 - 'seo_title'=>'max:255',  
35 - 'seo_keywords'=>'max:500',  
36 - 'seo_description'=>'max:500', 34 +// 'seo_title'=>'max:70',
  35 + 'seo_keywords'=>'max:300',
  36 + 'seo_description'=>'max:200',
37 'related_news_ids'=>'array|max:2', 37 'related_news_ids'=>'array|max:2',
38 'related_blog_ids'=>'array|max:2', 38 'related_blog_ids'=>'array|max:2',
39 ]; 39 ];
@@ -44,9 +44,9 @@ class KeywordRequest extends FormRequest @@ -44,9 +44,9 @@ class KeywordRequest extends FormRequest
44 return [ 44 return [
45 'title.required' => '请输入关键词', 45 'title.required' => '请输入关键词',
46 'title.max' => '关键词不能超过200个字符', 46 'title.max' => '关键词不能超过200个字符',
47 - 'seo_title.max' => 'SEO标题不能超过255个字符',  
48 - 'seo_keywords.max' => 'SEO关键词不能超过500个字符',  
49 - 'seo_description.max' => 'SEO描述不能超过500个字符', 47 +// 'seo_title.max' => 'SEO标题不能超过70个字符',
  48 + 'seo_keywords.max' => 'SEO关键词不能超过300个字符',
  49 + 'seo_description.max' => 'SEO描述不能超过200个字符',
50 'related_news_ids.max' => '关联新闻不能超过两条', 50 'related_news_ids.max' => '关联新闻不能超过两条',
51 'related_blog_ids.max' => '关联博客不能超过两条', 51 'related_blog_ids.max' => '关联博客不能超过两条',
52 ]; 52 ];
@@ -38,6 +38,8 @@ class ProductRequest extends FormRequest @@ -38,6 +38,8 @@ class ProductRequest extends FormRequest
38 return [ 38 return [
39 'title' => 'required|max:200', 39 'title' => 'required|max:200',
40 'route' => 'required|max:200', 40 'route' => 'required|max:200',
  41 + 'seo_mate.keywords' => 'max:300',
  42 + 'seo_mate.description' => 'max:200',
41 'status' => ['required', Rule::in(array_keys(Product::statusMap()))], 43 'status' => ['required', Rule::in(array_keys(Product::statusMap()))],
42 ]; 44 ];
43 } 45 }
@@ -51,6 +53,9 @@ class ProductRequest extends FormRequest @@ -51,6 +53,9 @@ class ProductRequest extends FormRequest
51 'route.max' => '产品链接不能超过200个字符', 53 'route.max' => '产品链接不能超过200个字符',
52 'status.required' => '请选择产品状态', 54 'status.required' => '请选择产品状态',
53 'status.in' => '产品状态值异常', 55 'status.in' => '产品状态值异常',
  56 + // 可选的 seo_mate 子字段的提示
  57 + 'seo_mate.keywords.max' => 'SEO 关键字不能超过200个字符',
  58 + 'seo_mate.description.max' => 'SEO 描述不能超过200个字符',
54 ]; 59 ];
55 } 60 }
56 61
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 namespace App\Models\Inquiry; 3 namespace App\Models\Inquiry;
4 4
  5 +use App\Helper\Arr;
5 use App\Helper\FormGlobalsoApi; 6 use App\Helper\FormGlobalsoApi;
6 use App\Models\Base; 7 use App\Models\Base;
7 use App\Utils\LogUtils; 8 use App\Utils\LogUtils;
@@ -83,6 +84,12 @@ class InquiryFormData extends Base @@ -83,6 +84,12 @@ class InquiryFormData extends Base
83 $v = getImageUrl($v['path']); 84 $v = getImageUrl($v['path']);
84 $data[$k] = $v; 85 $data[$k] = $v;
85 } 86 }
  87 + if(is_string($v)){
  88 + $arr = json_decode($v, true);
  89 + if(is_array($arr)){
  90 + $v = implode('', Arr::formatForHtml($arr));
  91 + }
  92 + }
86 //其他字段补充到message里 93 //其他字段补充到message里
87 if(!in_array($k, ['name', 'email', 'message', 'phone', 'ip', 'date', 'cname', 'domain', 'edition', 'domain_host_url'])){ 94 if(!in_array($k, ['name', 'email', 'message', 'phone', 'ip', 'date', 'cname', 'domain', 'edition', 'domain_host_url'])){
88 $data['message'].= "<br/>" . $k .': ' . $v; 95 $data['message'].= "<br/>" . $k .': ' . $v;
@@ -110,6 +117,34 @@ class InquiryFormData extends Base @@ -110,6 +117,34 @@ class InquiryFormData extends Base
110 return $model->id; 117 return $model->id;
111 } 118 }
112 119
  120 + /**
  121 + * 特殊项目 邮件模版
  122 + * FIXME 后期有多个特殊项目,需要按照项目ID设置模板
  123 + * @param $name
  124 + * @param $email
  125 + * @param $phone
  126 + * @param $message
  127 + * @param $domain
  128 + * @param $country
  129 + * @return string
  130 + */
  131 + public static function specialInquiryTemplate($name, $email, $phone, $message, $domain, $country)
  132 + {
  133 + $template = "
  134 +客户姓名:$name
  135 +客户邮箱:$email
  136 +客户电话:$phone
  137 +--------------------------------------------------------------------
  138 +询盘内容:
  139 +$message
  140 +--------------------------------------------------------------------
  141 +发送询盘网址: $domain
  142 +客户IP地址: [ip]
  143 +IP所在国家/地区: $country
  144 +--------------------------------------------------------------------";
  145 + return $template;
  146 + }
  147 +
113 public function setDataAttribute($value) 148 public function setDataAttribute($value)
114 { 149 {
115 $this->attributes['data'] = json_encode($value); 150 $this->attributes['data'] = json_encode($value);
@@ -9,6 +9,7 @@ use App\Models\Base; @@ -9,6 +9,7 @@ use App\Models\Base;
9 use App\Models\Domain\DomainInfo; 9 use App\Models\Domain\DomainInfo;
10 use App\Models\Project\Project; 10 use App\Models\Project\Project;
11 use App\Models\Task\TaskOwner; 11 use App\Models\Task\TaskOwner;
  12 +use App\Services\DingService;
12 use App\Utils\HttpUtils; 13 use App\Utils\HttpUtils;
13 use Illuminate\Database\Eloquent\Model; 14 use Illuminate\Database\Eloquent\Model;
14 use Illuminate\Support\Facades\Cache; 15 use Illuminate\Support\Facades\Cache;
@@ -68,6 +69,18 @@ class ReInquiryCount extends Base @@ -68,6 +69,18 @@ class ReInquiryCount extends Base
68 $model->task_ids = $model->task_ids + [$task_id]; 69 $model->task_ids = $model->task_ids + [$task_id];
69 $model->num = $model->num + $num; 70 $model->num = $model->num + $num;
70 $model->save(); 71 $model->save();
  72 +
  73 + //数量首次达到100, 给钉钉推送消息
  74 + if($num > 0 && $model->num == 100){
  75 + (new DingService())->handle([
  76 + 'keyword' => '询盘数量通知',
  77 + 'msg' =>
  78 + '项目名称:' . $model->company . PHP_EOL .
  79 + '项目域名:' . $model->domain . PHP_EOL .
  80 + '询盘数量:' . $model->num,
  81 + 'isAtAll' => false, // 是否@所有人
  82 + ], 'https://oapi.dingtalk.com/robot/send?access_token=cd5733d3e6b810a501e3ea20df7c99ecb616aa6754fa048348837d088c1f5b2c');
  83 + }
71 } 84 }
72 85
73 public function setTaskIdsAttribute($value) 86 public function setTaskIdsAttribute($value)
@@ -105,7 +118,7 @@ class ReInquiryCount extends Base @@ -105,7 +118,7 @@ class ReInquiryCount extends Base
105 if(!$res){ 118 if(!$res){
106 $res = HttpUtils::get('https://fob.ai.cc/api/get_bind_project_list', []); 119 $res = HttpUtils::get('https://fob.ai.cc/api/get_bind_project_list', []);
107 $res = json_decode($res, true)['data'] ?? []; 120 $res = json_decode($res, true)['data'] ?? [];
108 - Cache::put($cache_key, $res, 120); 121 + Cache::put($cache_key, $res, 2 * 3600);
109 } 122 }
110 return $res; 123 return $res;
111 } 124 }
@@ -41,7 +41,7 @@ class ReInquiryTask extends Base @@ -41,7 +41,7 @@ class ReInquiryTask extends Base
41 * @param int $status 41 * @param int $status
42 * @return ReInquiryTask 42 * @return ReInquiryTask
43 */ 43 */
44 - public static function createTask($id, $title, $industry, $ad_id, $ad_url, $ad_img, $num, $status, $is_replace_text, $ai_param, $is_show_fb_source) 44 + public static function createTask($id, $title, $industry, $ad_id, $ad_url, $ad_img, $num, $status, $is_replace_text, $ai_param, $is_show_fb_source, $second_push_rate)
45 { 45 {
46 $self = self::where(['id' => $id])->first(); 46 $self = self::where(['id' => $id])->first();
47 if (empty($self)) 47 if (empty($self))
@@ -56,6 +56,7 @@ class ReInquiryTask extends Base @@ -56,6 +56,7 @@ class ReInquiryTask extends Base
56 $self->is_replace_text = $is_replace_text; 56 $self->is_replace_text = $is_replace_text;
57 $self->ai_param = $ai_param; 57 $self->ai_param = $ai_param;
58 $self->is_show_fb_source = $is_show_fb_source; 58 $self->is_show_fb_source = $is_show_fb_source;
  59 + $self->second_push_rate = $second_push_rate;
59 $self->save(); 60 $self->save();
60 return $self; 61 return $self;
61 } 62 }
@@ -73,6 +74,7 @@ class ReInquiryTask extends Base @@ -73,6 +74,7 @@ class ReInquiryTask extends Base
73 $item['agent_group'] = $item['agent_group'] ?? ''; 74 $item['agent_group'] = $item['agent_group'] ?? '';
74 $item['is_require'] = $item['is_require'] ?? 0; 75 $item['is_require'] = $item['is_require'] ?? 0;
75 $item['price'] = $item['price'] ?? 0; 76 $item['price'] = $item['price'] ?? 0;
  77 + $item['frequency'] = $item['frequency'] ?? '3'; //默认频率3天一次
76 } 78 }
77 return $value; 79 return $value;
78 } 80 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :TicketUploadData.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/9/25 09:33
  8 + */
  9 +
  10 +namespace App\Models\Ticket;
  11 +
  12 +use App\Helper\Arr;
  13 +use App\Models\Base;
  14 +
  15 +/**
  16 + * @remark :工单内上传数据
  17 + * @name :TicketUploadData
  18 + * @author :lyh
  19 + * @method :post
  20 + * @time :2025/9/25 09:34
  21 + */
  22 +class TicketUploadData extends Base
  23 +{
  24 + protected $table = 'gl_tickets_upload_data';
  25 +
  26 + public function getTextAttribute($value){
  27 + if(!empty($value)){
  28 + $value = Arr::s2a($value);
  29 + }
  30 + return $value;
  31 + }
  32 +}
@@ -94,3 +94,13 @@ Route::prefix('tickets')->group(function () { @@ -94,3 +94,13 @@ Route::prefix('tickets')->group(function () {
94 }); 94 });
95 Route::any('/get_project_records', [\App\Http\Controllers\Api\WorkOrder\TicketController::class, 'get_project_records'])->name('tickets.get_project_records'); 95 Route::any('/get_project_records', [\App\Http\Controllers\Api\WorkOrder\TicketController::class, 'get_project_records'])->name('tickets.get_project_records');
96 Route::get('/pushTicketByBot/{friend_id}', [\App\Http\Controllers\Api\WorkOrder\TicketController::class, 'pushTicketByBot'])->summary('企微群@机器人触发工单推送')->name('tickets.pushTicketByBot'); 96 Route::get('/pushTicketByBot/{friend_id}', [\App\Http\Controllers\Api\WorkOrder\TicketController::class, 'pushTicketByBot'])->summary('企微群@机器人触发工单推送')->name('tickets.pushTicketByBot');
  97 +//保存工单提交数据(产品,新闻,博客)详情
  98 +Route::prefix('ticket_upload')->group(function () {
  99 + Route::any('/', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'lists'])->name('ticket_upload.lists');
  100 + Route::any('/info', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'info'])->name('ticket_upload.info');
  101 + Route::any('/save', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'save'])->name('ticket_upload.save');
  102 + Route::any('/getProductCate', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getProductCate'])->name('ticket_upload.getProductCate');
  103 + Route::any('/getBlogCate', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getBlogCate'])->name('ticket_upload.getBlogCate');
  104 + Route::any('/getNewsCate', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getNewsCate'])->name('ticket_upload.getNewsCate');
  105 +});
  106 +
@@ -644,6 +644,12 @@ Route::middleware(['aloginauth'])->group(function () { @@ -644,6 +644,12 @@ Route::middleware(['aloginauth'])->group(function () {
644 Route::any('/monthManageList', [\App\Http\Controllers\Aside\Ticket\TicketController::class,'monthManageList'])->name('ticket_count_monthManageList');//月统计数据 644 Route::any('/monthManageList', [\App\Http\Controllers\Aside\Ticket\TicketController::class,'monthManageList'])->name('ticket_count_monthManageList');//月统计数据
645 Route::any('/manageTicketCount', [\App\Http\Controllers\Aside\Ticket\TicketController::class,'manageTicketCount'])->name('ticket_count_manageTicketCount'); 645 Route::any('/manageTicketCount', [\App\Http\Controllers\Aside\Ticket\TicketController::class,'manageTicketCount'])->name('ticket_count_manageTicketCount');
646 }); 646 });
  647 + //ticket
  648 + Route::prefix('ticket_upload')->group(function () {
  649 + Route::any('/', [Aside\Ticket\TicketUploadDataController::class,'lists'])->name('ticket_upload_lists');
  650 + Route::any('/save', [Aside\Ticket\TicketUploadDataController::class,'save'])->name('ticket_upload_save');
  651 + Route::any('/detail', [Aside\Ticket\TicketUploadDataController::class,'detail'])->name('ticket_upload_detail');
  652 + });
647 }); 653 });
648 654
649 //无需登录验证的路由组 655 //无需登录验证的路由组