作者 赵彬吉
@@ -350,16 +350,26 @@ class GeoQuestionRes extends Command @@ -350,16 +350,26 @@ class GeoQuestionRes extends Command
350 $lock_key = 'geo_task_generation_lock'; 350 $lock_key = 'geo_task_generation_lock';
351 $lock_ttl = 60; // 锁时间大于当前 锁功能执行时间 351 $lock_ttl = 60; // 锁时间大于当前 锁功能执行时间
352 // 尝试获取锁,非阻塞方式 352 // 尝试获取锁,非阻塞方式
353 - $lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');  
354 - if (empty($lock)){ 353 +// $lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
  354 + $lock = Redis::get($lock_key);
  355 + if ($lock)
355 return $task_id; 356 return $task_id;
356 - }  
357 - $project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->pluck('project_id')->unique()->values()->toArray(); 357 + Redis::setex($lock_key, $lock_ttl, 1);
  358 +
  359 + $project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
  360 + ->where(function ($query){
  361 + $query->where('next_time', '<=', date('Y-m-d'))
  362 + ->orWhereNull('next_time');
  363 + })
  364 + ->pluck('project_id')
  365 + ->unique()
  366 + ->values()
  367 + ->toArray();
358 if(FALSE == empty($project_ids)){ 368 if(FALSE == empty($project_ids)){
359 $ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN) 369 $ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
360 ->whereIn('project_id', $project_ids) 370 ->whereIn('project_id', $project_ids)
361 ->where(function ($query){ 371 ->where(function ($query){
362 - $query->where('next_time', '<=', date('Y-m-d')) 372 + $query->where('current_time', '<>', date('Y-m-d'))
363 ->orWhereNull('next_time'); 373 ->orWhereNull('next_time');
364 }) 374 })
365 ->orderBy('next_time', 'asc') 375 ->orderBy('next_time', 'asc')
@@ -58,9 +58,31 @@ class lyhDemo extends Command @@ -58,9 +58,31 @@ class lyhDemo extends Command
58 protected $description = '更新路由'; 58 protected $description = '更新路由';
59 59
60 public function handle(){ 60 public function handle(){
61 - return $this->_actionRoute(); 61 + return $this->_actionAiBolog();
62 } 62 }
63 63
  64 + /**
  65 + * @remark :修改ai_blog
  66 + * @name :_actionAiBolog
  67 + * @author :lyh
  68 + * @method :post
  69 + * @time :2025/11/21 13:52
  70 + */
  71 + public function _actionAiBolog()
  72 + {
  73 + $projectModel = new Project();
  74 + $lists = $projectModel->list(['delete_status' => 0,'id'=>1,'project_type'=>0,'extend_type'=>0,'type'=>['in',[1,2,3,4,6]]], 'id', ['id']);
  75 + foreach ($lists as $item) {
  76 + echo date('Y-m-d H:i:s') . '开始--项目的id:' . $item['id'] . PHP_EOL;
  77 + ProjectServer::useProject($item['id']);
  78 + $aiblog = new AiBlog();
  79 + $task_ids = $aiblog->selectField(['image'=>''],'id');
  80 + dd($task_ids);
  81 + DB::disconnect('custom_mysql');
  82 + }
  83 + }
  84 +
  85 +
64 public function _actionDa() 86 public function _actionDa()
65 { 87 {
66 $geoLinkModel = new GeoLink(); 88 $geoLinkModel = new GeoLink();
@@ -1642,5 +1642,16 @@ if (!function_exists('httpGetSsl')) { @@ -1642,5 +1642,16 @@ if (!function_exists('httpGetSsl')) {
1642 return $truncated; 1642 return $truncated;
1643 } 1643 }
1644 1644
1645 - 1645 + /**
  1646 + * @remark :写入日志
  1647 + * @name :outMessage
  1648 + * @author :lyh
  1649 + * @method :post
  1650 + * @time :2025/11/20 16:04
  1651 + */
  1652 + function outMessage($filename = 'lyh_info',$message = '')
  1653 + {
  1654 + @file_put_contents(storage_path('logs/'.$filename.'.log'), "错误信息: " . $message . PHP_EOL, FILE_APPEND);
  1655 + return true;
  1656 + }
1646 } 1657 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :ComController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/19 15:50
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Api;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Models\Geo\GeoLink;
  14 +
  15 +class ComController extends BaseController
  16 +{
  17 + /**
  18 + * @remark :获取geo链接
  19 + * @name :getGeoLink
  20 + * @author :lyh
  21 + * @method :post
  22 + * @time :2025/11/19 15:51
  23 + */
  24 + public function getGeoLink()
  25 + {
  26 + $this->request->validate([
  27 + 'project_id' => 'required',
  28 +
  29 + ], [
  30 + 'project_id.required' => 'project_id不能为空',
  31 + ]);
  32 + $geoLinkModel = new GeoLink();
  33 + $filed = ['id','project_id','url','da','type','created_at','updated_at'];
  34 + $lists = $geoLinkModel->lists($this->map,$this->page,$this->row,$filed);
  35 + $this->response('success',Code::SUCCESS,$lists);
  36 + }
  37 +}
@@ -8,9 +8,12 @@ @@ -8,9 +8,12 @@
8 namespace App\Http\Controllers\Api; 8 namespace App\Http\Controllers\Api;
9 9
10 use App\Enums\Common\Code; 10 use App\Enums\Common\Code;
  11 +use App\Models\Geo\GeoConf;
11 use App\Models\Geo\GeoConfirm; 12 use App\Models\Geo\GeoConfirm;
12 use App\Models\Geo\GeoWritings; 13 use App\Models\Geo\GeoWritings;
  14 +use App\Models\Manage\ManageHr;
13 use App\Models\Project\Project; 15 use App\Models\Project\Project;
  16 +use App\Services\DingService;
14 use Illuminate\Http\Request; 17 use Illuminate\Http\Request;
15 use Illuminate\Support\Facades\Crypt; 18 use Illuminate\Support\Facades\Crypt;
16 19
@@ -89,11 +92,28 @@ class GeoController extends BaseController @@ -89,11 +92,28 @@ class GeoController extends BaseController
89 if ($info['status'] == GeoWritings::STATUS_FINISH){ 92 if ($info['status'] == GeoWritings::STATUS_FINISH){
90 return $this->response('当前文章已确认,不可再次确认',Code::SYSTEM_ERROR); 93 return $this->response('当前文章已确认,不可再次确认',Code::SYSTEM_ERROR);
91 } 94 }
92 - $this->param['confirm_ip'] = $this->request->ip();  
93 - $this->param['confirm_at'] = date('Y-m-d H:i:s');  
94 - $this->param['content_length'] = strlen($this->param['content']);  
95 - $this->param['status'] = GeoWritings::STATUS_FINISH;  
96 - $geoWritingsModel->edit($this->param,['uniqid' => $token]); 95 + try {
  96 + $this->param['confirm_ip'] = $this->request->ip();
  97 + $this->param['confirm_at'] = date('Y-m-d H:i:s');
  98 + $this->param['content_length'] = strlen($this->param['content']);
  99 + $this->param['status'] = GeoWritings::STATUS_FINISH;
  100 + $geoWritingsModel->edit($this->param,['uniqid' => $token]);
  101 + $geoConfModel = new GeoConf();
  102 + $confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
  103 + $hrModel = new ManageHr();
  104 + $manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
  105 + $dingService = new DingService();
  106 + $dingService->handle([
  107 + 'keyword' => '项目数据确认',
  108 + 'msg' =>
  109 + 'cm:文章确认完成' . PHP_EOL .
  110 + '项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
  111 + '负责人:'.$manage_name . PHP_EOL,
  112 + 'isAtAll' => false, // 是否@所有人
  113 + ], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
  114 + }catch (\Exception $e){
  115 + $this->response('非法请求',Code::SYSTEM_ERROR);
  116 + }
97 $this->response('success',Code::SUCCESS); 117 $this->response('success',Code::SUCCESS);
98 } 118 }
99 119
@@ -138,10 +158,31 @@ class GeoController extends BaseController @@ -138,10 +158,31 @@ class GeoController extends BaseController
138 'confirm_num.max' => '客户确认数量不能为空', 158 'confirm_num.max' => '客户确认数量不能为空',
139 ]); 159 ]);
140 $geoConfirmModel = new GeoConfirm(); 160 $geoConfirmModel = new GeoConfirm();
141 - $this->param['status'] = $geoConfirmModel::STATUS_FINISH;  
142 - $this->param['confirm_ip'] = $this->request->ip();  
143 - $this->param['confirm_at'] = date('Y-m-d H:i:s');  
144 - $result = $geoConfirmModel->edit($this->param,['uniqid'=>$this->param['uniqid']]); 161 + $info = $geoConfirmModel->read(['uniqid'=>$this->param['uniqid']]);
  162 + if ($info === false){
  163 + $this->response('当前数据不存在已被删除',Code::SYSTEM_ERROR);
  164 + }
  165 + try {
  166 + $this->param['status'] = $geoConfirmModel::STATUS_FINISH;
  167 + $this->param['confirm_ip'] = $this->request->ip();
  168 + $this->param['confirm_at'] = date('Y-m-d H:i:s');
  169 + $result = $geoConfirmModel->edit($this->param,['id'=>$info['$info']]);
  170 + $geoConfModel = new GeoConf();
  171 + $confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
  172 + $hrModel = new ManageHr();
  173 + $manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
  174 + $dingService = new DingService();
  175 + $dingService->handle([
  176 + 'keyword' => '项目数据确认',
  177 + 'msg' =>
  178 + 'cm:'.(($info['type'] == 1) ? '标题确认' : '关键词确认'). PHP_EOL .
  179 + '项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
  180 + '负责人:'.$manage_name . PHP_EOL,
  181 + 'isAtAll' => false, // 是否@所有人
  182 + ], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
  183 + }catch (\Exception $e){
  184 + $this->response('非法请求',Code::SYSTEM_ERROR);
  185 + }
145 $this->response('success',Code::SUCCESS,$result); 186 $this->response('success',Code::SUCCESS,$result);
146 } 187 }
147 } 188 }
@@ -48,7 +48,7 @@ class PrivateController extends BaseController @@ -48,7 +48,7 @@ class PrivateController extends BaseController
48 public function optimizeProjectList(Request $request) 48 public function optimizeProjectList(Request $request)
49 { 49 {
50 $page_size = $request->input('page_size', 20); 50 $page_size = $request->input('page_size', 20);
51 - $field = ['gl_project.id', 'gl_project.company', 'gl_project.is_upgrade', 'b.start_date', 'd.domain', 'b.special', 'gl_project.from_order_id'];// 'f.industry_name', 51 + $field = ['gl_project.id', 'gl_project.company', 'gl_project.post_id' ,'gl_project.is_upgrade', 'b.start_date', 'd.domain', 'b.special', 'gl_project.from_order_id'];// 'f.industry_name',
52 $result = Project::select($field)->leftJoin('gl_project_deploy_optimize as b', 'gl_project.id', '=', 'b.project_id') 52 $result = Project::select($field)->leftJoin('gl_project_deploy_optimize as b', 'gl_project.id', '=', 'b.project_id')
53 ->leftJoin('gl_project_online_check as c', 'gl_project.id', '=', 'c.project_id') 53 ->leftJoin('gl_project_online_check as c', 'gl_project.id', '=', 'c.project_id')
54 ->leftJoin('gl_domain_info as d', 'gl_project.id', '=', 'd.project_id') 54 ->leftJoin('gl_domain_info as d', 'gl_project.id', '=', 'd.project_id')
  1 +<?php
  2 +
  3 +namespace App\Http\Controllers\Aside\AiRemove;
  4 +
  5 +use App\Enums\Common\Code;
  6 +use App\Http\Controllers\Aside\BaseController;
  7 +use App\Jobs\WordAi;
  8 +use App\Models\AiRemove\AiRemove;
  9 +use App\Models\Manage\Manage;
  10 +
  11 +class AiRemoveController extends BaseController
  12 +{
  13 + /**
  14 + * 获取去AI痕迹任务列表
  15 + * @author Akun
  16 + * @date 2025/11/20 11:35
  17 + */
  18 + public function getTaskLists()
  19 + {
  20 + $model = new AiRemove();
  21 + $lists = $model->lists($this->map, $this->page, $this->row, 'id', ['id', 'user_id', 'status', 'created_at', 'updated_at']);
  22 + if (!empty($lists)) {
  23 + $manage_model = new Manage();
  24 + foreach ($lists['list'] as $k => $v) {
  25 + $lists['list'][$k]['operator_name'] = $manage_model->getName($v['user_id']);
  26 + }
  27 + }
  28 +
  29 + $this->response('success', Code::SUCCESS, $lists);
  30 + }
  31 +
  32 + /**
  33 + * 获取去AI任务详情
  34 + * @author Akun
  35 + * @date 2025/11/20 11:47
  36 + */
  37 + public function taskInfo()
  38 + {
  39 + $this->request->validate([
  40 + 'id' => 'required'
  41 + ], [
  42 + 'id.required' => 'ID不能为空'
  43 + ]);
  44 + $model = new AiRemove();
  45 + $info = $model->read(['id' => $this->param['id']]);
  46 + $this->response('success', Code::SUCCESS, $info);
  47 + }
  48 +
  49 + /**
  50 + * 提交去AI痕迹任务
  51 + * @throws \App\Exceptions\AsideGlobalException
  52 + * @author Akun
  53 + * @date 2025/11/20 11:41
  54 + */
  55 + public function saveTask()
  56 + {
  57 + $this->request->validate([
  58 + 'origin_text' => 'required',
  59 + ], [
  60 + 'origin_text.required' => '需要去痕迹的内容不能为空'
  61 + ]);
  62 +
  63 + $data = [
  64 + 'user_id' => $this->uid,
  65 + 'origin_text' => $this->param['origin_text'],
  66 + 'status' => ['<', AiRemove::STATUS_FAL]
  67 + ];
  68 + $model = new AiRemove();
  69 + $task_info = $model->read($data);
  70 + if ($task_info) {
  71 + $this->fail('已提交过相同任务,请勿重复提交');
  72 + }
  73 +
  74 + $data['status'] = AiRemove::STATUS_UN;
  75 + $id = $model->addReturnId($data);
  76 + WordAi::dispatch(['id' => $id]);
  77 + $this->response('success');
  78 + }
  79 +}
@@ -13,8 +13,10 @@ use App\Models\Manage\Manage; @@ -13,8 +13,10 @@ use App\Models\Manage\Manage;
13 use App\Models\User\User; 13 use App\Models\User\User;
14 use App\Models\WebSetting\WebLanguage; 14 use App\Models\WebSetting\WebLanguage;
15 use App\Services\HumanizeAiTextService; 15 use App\Services\HumanizeAiTextService;
  16 +use App\Services\WordAiService;
16 use Illuminate\Support\Facades\Cache; 17 use Illuminate\Support\Facades\Cache;
17 use Illuminate\Support\Facades\Hash; 18 use Illuminate\Support\Facades\Hash;
  19 +use Illuminate\Support\Facades\Http;
18 20
19 /** 21 /**
20 * Class IndexController 22 * Class IndexController
@@ -190,6 +192,25 @@ class IndexController extends BaseController @@ -190,6 +192,25 @@ class IndexController extends BaseController
190 } 192 }
191 193
192 /** 194 /**
  195 + * @remark :去Ai痕迹
  196 + * @name :notWordAi
  197 + * @author :lyh
  198 + * @method :post
  199 + * @time :2025/11/19 17:57
  200 + */
  201 + public function notWordAiHumanizer()
  202 + {
  203 + $this->request->validate([
  204 + 'text'=>'required',
  205 + ],[
  206 + 'text.required' => '文本text不能为空',
  207 + ]);
  208 + $wordAiService = new WordAiService();
  209 + $data = $wordAiService->setApiAvoid($this->param['text']);
  210 + $this->response('success', Code::SUCCESS, $data);
  211 + }
  212 +
  213 + /**
193 * @remark :翻译 214 * @remark :翻译
194 * @name :stringTranslation 215 * @name :stringTranslation
195 * @author :lyh 216 * @author :lyh
@@ -210,7 +231,23 @@ class IndexController extends BaseController @@ -210,7 +231,23 @@ class IndexController extends BaseController
210 */ 231 */
211 public function prInfoDownload() 232 public function prInfoDownload()
212 { 233 {
213 - $url = 'http://crawl.scraper.waimaoq.com/export/issuewire?token=MT0CM7y4tdFTFTm';  
214 - $this->response('success', Code::SUCCESS, ['url'=>$url]); 234 + $url = 'http://crawl.scraper.waimaoq.com/export/issuewire';
  235 + $param = [
  236 + 'page' => $this->page,
  237 + 'page_size' => $this->row,
  238 + 'token' => 'MT0CM7y4tdFTFTm',
  239 + 'pr_id' => $this->param['pr_id'] ?? '',
  240 + 'release_time_start'=>$this->param['release_time_start'] ?? '',
  241 + 'release_time_end'=>$this->param['release_time_end'] ?? '',
  242 + 'headline'=>$this->param['headline'] ?? '',
  243 + ];
  244 + $param = array_filter($param);
  245 + $response = Http::withHeaders(['Accept' => 'application/json',])->get($url, $param);
  246 + if ($response->successful()) {
  247 + $result = $response->json();
  248 + $this->response('success', Code::SUCCESS, ['url' => $url, 'list' => $result, 'page' => $this->page, 'page_size' => $this->row]);
  249 + } else {
  250 + $this->response('请求失败', Code::SYSTEM_ERROR, ['status_code' => $response->status(), 'error' => $response->body()]);
  251 + }
215 } 252 }
216 } 253 }
@@ -10,6 +10,7 @@ use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest; @@ -10,6 +10,7 @@ use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest;
10 use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest; 10 use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest;
11 use App\Models\Manage\Manage; 11 use App\Models\Manage\Manage;
12 use App\Models\Manage\ManageHr; 12 use App\Models\Manage\ManageHr;
  13 +use App\Models\Ticket\TicketUploadData;
13 use App\Models\WorkOrder\TicketLog; 14 use App\Models\WorkOrder\TicketLog;
14 use App\Models\WorkOrder\TicketProject; 15 use App\Models\WorkOrder\TicketProject;
15 use App\Models\WorkOrder\Tickets; 16 use App\Models\WorkOrder\Tickets;
@@ -214,6 +215,24 @@ class AsideTicketController extends BaseController @@ -214,6 +215,24 @@ class AsideTicketController extends BaseController
214 return $query->where('id', 0); // 返回空结果 215 return $query->where('id', 0); // 返回空结果
215 } 216 }
216 }) 217 })
  218 + //待审核项目列表
  219 + ->when(!empty($this->param['pending_review']), function ($query) use ($validated) {
  220 + // 查找项目名称或公司名称
  221 + $ticketUploadModel = new TicketUploadData();
  222 + if(!isset($this->param['project_type']) || empty($this->param['project_type'])){
  223 + $projectIds = $ticketUploadModel->where('status', 0)->where('project_type',1)->distinct('project_id')->pluck('project_id')->toArray();
  224 + $projectV6Ids = $ticketUploadModel->where('status', 0)->where('project_type',2)->distinct('project_id')->pluck('project_id')->toArray();
  225 + return $query->whereIn('post_id', $projectIds)->orWhereIn('table_id', $projectV6Ids);
  226 + }else{
  227 + if($this->param['project_type'] == 2){
  228 + $projectV6Ids = $ticketUploadModel->where('status', 0)->where('project_type',2)->distinct('project_id')->pluck('project_id')->toArray();
  229 + return $query->whereIn('table_id', $projectV6Ids);
  230 + }elseif ($this->param['project_type'] == 1){
  231 + $projectIds = $ticketUploadModel->where('status', 0)->where('project_type',1)->distinct('project_id')->pluck('project_id')->toArray();
  232 + return $query->whereIn('post_id', $projectIds);
  233 + }
  234 + }
  235 + })
217 ->when(!empty($validated['search']), function ($query) use ($validated) { 236 ->when(!empty($validated['search']), function ($query) use ($validated) {
218 // 查找项目名称或公司名称 237 // 查找项目名称或公司名称
219 $search = $validated['search']; 238 $search = $validated['search'];
@@ -375,6 +394,8 @@ class AsideTicketController extends BaseController @@ -375,6 +394,8 @@ class AsideTicketController extends BaseController
375 } 394 }
376 if ($project->wechat_switch) 395 if ($project->wechat_switch)
377 $project->pushWechatGroupMsg(); 396 $project->pushWechatGroupMsg();
  397 + else
  398 + $this->response('请先点击开关,打开微信推送', Code::USER_MODEL_NOTFOUND_ERROE);
378 $this->response('success', Code::SUCCESS); 399 $this->response('success', Code::SUCCESS);
379 } 400 }
380 } 401 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :Extension3915ModuleController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/20 11:42
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Bside\ExtensionModule;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Bside\BaseController;
  14 +use App\Models\ExtentModule\ExtensionModuleField;
  15 +use App\Models\ExtentModule\ExtensionModuleValue;
  16 +use Illuminate\Support\Facades\Cache;
  17 +
  18 +class Extension3915ModuleController extends BaseController
  19 +{
  20 +
  21 + /**
  22 + * @remark :获取列表数据
  23 + * @name :lists
  24 + * @author :lyh
  25 + * @method :post
  26 + * @time :2025/11/20 14:38
  27 + */
  28 + public function lists(){
  29 + $this->request->validate([
  30 + 'module_id'=>'required',
  31 + ],[
  32 + 'module_id.required' => '模块id不能为空',
  33 + ]);
  34 + $searchParam = [
  35 + 'module_id'=>$this->param['module_id'],
  36 + ];
  37 + $resultData = Cache::get('extension_module_list_3915_'.$this->param['module_id']);
  38 + if(empty($resultData)){
  39 + $data = [];
  40 + $moduleValueModel = new ExtensionModuleValue();
  41 + if(isset($this->param['field_id']) && ($this->param['field_id'] != 0) && isset($this->param['value'])){
  42 + $uuidArr = $moduleValueModel->formatQuery(['field_id'=>$this->param['field_id'],'value'=>$this->param['value'],'module_id'=>$this->param['module_id']])->distinct()->pluck('uuid')->toArray();
  43 + if(!empty($uuidArr)){
  44 + $searchParam['uuid'] = ['in',$uuidArr];
  45 + }
  46 + }
  47 + if(isset($this->param['start_time']) && !empty($this->param['start_time']) && isset($this->param['end_time']) && !empty($this->param['end_time'])){
  48 + $searchParam['created_at'] = ['between',[$this->param['start_time'],$this->param['end_time']]];
  49 + }
  50 + $lists = $moduleValueModel->list($searchParam);
  51 + if(!empty($lists)){
  52 + foreach ($lists as $k => $v){
  53 + $data[$v['uuid']][$v['field_id']] = $v['value'];
  54 + $data[$v['uuid']]['created_at'] = $v['created_at'];
  55 + }
  56 + }
  57 + $resultData = [];
  58 + foreach ($data as $k => $v){
  59 + $v['uuid'] = $k;
  60 + $resultData[] = $v;
  61 + }
  62 + Cache::add('extension_module_list_3915_'.$this->param['module_id'],$resultData);
  63 + }
  64 + $resultData = $this->formatPaginate($resultData,$this->row,$this->page);
  65 + //执行分页
  66 + $this->response('success',Code::SUCCESS,$resultData);
  67 + }
  68 +
  69 + /**
  70 + * @remark :分页
  71 + * @name :simplePaginate
  72 + * @author :lyh
  73 + * @method :post
  74 + * @time :2025/11/20 14:50
  75 + */
  76 + public function formatPaginate($data, $size = 20, $page = 1)
  77 + {
  78 + $collection = collect($data);
  79 + $total = $collection->count();
  80 + $totalPage = max(1, ceil($total / $size));
  81 + // 确保页码在有效范围内
  82 + $page = max(1, min($page, $totalPage));
  83 + $list = $collection->forPage($page, $size)->values()->toArray();
  84 + return [
  85 + 'list' => $list,
  86 + 'page' => (int)$page,
  87 + 'size' => (string)$size,
  88 + 'total' => $total,
  89 + 'total_page' => $totalPage
  90 + ];
  91 + }
  92 +
  93 + /**
  94 + * @remark :导入数据
  95 + * @name :importData
  96 + * @author :lyh
  97 + * @method :post
  98 + * @time :2025/11/20 14:40
  99 + */
  100 + public function importData()
  101 + {
  102 + $this->request->validate([
  103 + 'module_id'=>'required',
  104 + ],[
  105 + 'module_id.required' => '模块id不能为空',
  106 + ]);
  107 + if($this->user['project_id'] != 3915){
  108 + $this->fail('当前项目不能调用当前方法');
  109 + }
  110 + $moduleFieldModel = new ExtensionModuleField();
  111 + $filedList = $moduleFieldModel->where(['module_id' => $this->param['module_id']])->pluck('field_name', 'id')->toArray();
  112 + if(empty($filedList)){
  113 + $this->response('请先设置字段,再添加数据',Code::SUCCESS);
  114 + }
  115 + $data = $this->param['data'];
  116 + $moduleValueModel = new ExtensionModuleValue();
  117 + $key_filedId = [];
  118 + $resultData = [];
  119 + foreach ($data as $k => $v){
  120 + foreach ($v as $k1 => $v1){
  121 + if($k == 0){
  122 + if(isset($filedList[$v1])){
  123 + $key_filedId[$k1] = $filedList[$v1];
  124 + }
  125 + continue;
  126 + }
  127 + $resultData[] = [
  128 + 'uuid'=>$k + 1,
  129 + 'module_id'=>$this->param['module_id'],
  130 + 'field_id'=>$key_filedId[$k1],
  131 + 'value'=>$v1 ?? '',
  132 + ];
  133 + }
  134 + }
  135 + if(!empty($resultData)){
  136 + //todo::优先截断表
  137 + $moduleValueModel->truncate();
  138 + $moduleValueModel->insertAll($resultData);
  139 + }
  140 + $this->response('success',Code::SUCCESS,$resultData);
  141 + }
  142 +}
@@ -207,11 +207,14 @@ class ImageController extends Controller @@ -207,11 +207,14 @@ class ImageController extends Controller
207 if($this->upload_location == 0){ 207 if($this->upload_location == 0){
208 $watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0); 208 $watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0);
209 $cosService = new CosService(); 209 $cosService = new CosService();
210 - $cosService->uploadFile($files,$this->path,$fileName,false,$watermarkOptions); 210 + $res = $cosService->uploadFile($files,$this->path,$fileName,false,$watermarkOptions);
211 }else{ 211 }else{
212 //TODO::上传亚马逊 212 //TODO::上传亚马逊
213 $amazonS3Service = new AmazonS3Service(); 213 $amazonS3Service = new AmazonS3Service();
214 - $amazonS3Service->uploadFiles($files,$this->path,$fileName); 214 + $res = $amazonS3Service->uploadFiles($files,$this->path,$fileName);
  215 + }
  216 + if($res === false){
  217 + $this->response('上传失败,请重新上传',Code::SYSTEM_ERROR);
215 } 218 }
216 $this->saveMysql($imageModel,$files->getSize(),$image_type,$fileName,$hash,$this->upload_location,$files->getMimeType(), $name); 219 $this->saveMysql($imageModel,$files->getSize(),$image_type,$fileName,$hash,$this->upload_location,$files->getMimeType(), $name);
217 $this->synchronizationImage($fileName,$this->upload_location); 220 $this->synchronizationImage($fileName,$this->upload_location);
@@ -354,11 +357,15 @@ class ImageController extends Controller @@ -354,11 +357,15 @@ class ImageController extends Controller
354 if($this->upload_location == 0){ 357 if($this->upload_location == 0){
355 $watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0); 358 $watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0);
356 $cosService = new CosService(); 359 $cosService = new CosService();
357 - $cosService->uploadFile($file,$this->path,$fileName,false,$watermarkOptions); 360 + $res = $cosService->uploadFile($file,$this->path,$fileName,false,$watermarkOptions);
358 }else{ 361 }else{
359 //TODO::上传亚马逊 362 //TODO::上传亚马逊
360 $amazonS3Service = new AmazonS3Service(); 363 $amazonS3Service = new AmazonS3Service();
361 - $amazonS3Service->uploadFiles($file,$this->path,$fileName); 364 + $res = $amazonS3Service->uploadFiles($file,$this->path,$fileName);
  365 + }
  366 + if($res === false){
  367 + outMessage('upload_images','图片上传失败'.$name);
  368 + continue;
362 } 369 }
363 $this->synchronizationImage($fileName,$this->upload_location); 370 $this->synchronizationImage($fileName,$this->upload_location);
364 $data[] = $this->responseData($this->path.'/'.$fileName,$name); 371 $data[] = $this->responseData($this->path.'/'.$fileName,$name);
@@ -700,6 +707,9 @@ class ImageController extends Controller @@ -700,6 +707,9 @@ class ImageController extends Controller
700 $info = $imageSetting->read(['project_id'=>$this->cache['project_id']]); 707 $info = $imageSetting->read(['project_id'=>$this->cache['project_id']]);
701 $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名 708 $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
702 if($is_image){ 709 if($is_image){
  710 + if(empty($data['image'])){
  711 + $this->response('开启图片水印需要先关闭水印功能,重新上传水印图片'.Code::SYSTEM_ERROR);
  712 + }
703 $param = [ 713 $param = [
704 'image/'.$domain.($data['image'] ?? ''),//图片 714 'image/'.$domain.($data['image'] ?? ''),//图片
705 'gravity/'.($data['gravity'] ?? 'SouthEast'), 715 'gravity/'.($data['gravity'] ?? 'SouthEast'),
@@ -755,11 +765,11 @@ class ImageController extends Controller @@ -755,11 +765,11 @@ class ImageController extends Controller
755 if($info === false){ 765 if($info === false){
756 $this->response('请先设置水印',Code::SYSTEM_ERROR); 766 $this->response('请先设置水印',Code::SYSTEM_ERROR);
757 } 767 }
758 - if($info['status'] == 1 && empty($info['image_data'])){ 768 + if($this->param['status'] == 1 && empty($info['image_data'])){
759 $this->response('请先设置水印',Code::SYSTEM_ERROR); 769 $this->response('请先设置水印',Code::SYSTEM_ERROR);
760 } 770 }
761 - if($info['status'] == 2 && empty($info['str_data'])){  
762 - $this->response('请先设置水印',Code::SYSTEM_ERROR); 771 + if($this->param['status'] == 2 && empty($info['str_data'])){
  772 + $this->response('请先设置文字水印',Code::SYSTEM_ERROR);
763 } 773 }
764 $imageSetting->edit(['status'=>$this->param['status']],['project_id'=>$this->cache['project_id']]); 774 $imageSetting->edit(['status'=>$this->param['status']],['project_id'=>$this->cache['project_id']]);
765 $this->response('success'); 775 $this->response('success');
@@ -92,11 +92,14 @@ class GeoArticleLogic extends BaseLogic @@ -92,11 +92,14 @@ class GeoArticleLogic extends BaseLogic
92 if(!empty($this->param['data'])){ 92 if(!empty($this->param['data'])){
93 $data = []; 93 $data = [];
94 foreach ($this->param['data'] as $item){ 94 foreach ($this->param['data'] as $item){
95 - $data[] = [  
96 - 'filename' => $item['filename'],  
97 - 'url'=> $item['url'],  
98 - 'project_id'=>$this->param['project_id']  
99 - ]; 95 + $info = $this->model->read(['url'=>$item['url'],'filename'=>$item['filename']],['id','url']);
  96 + if($info === false){
  97 + $data[] = [
  98 + 'filename' => $item['filename'],
  99 + 'url'=> $item['url'],
  100 + 'project_id'=>$this->param['project_id']
  101 + ];
  102 + }
100 } 103 }
101 $this->model->insertAll($data); 104 $this->model->insertAll($data);
102 } 105 }
@@ -9,10 +9,12 @@ @@ -9,10 +9,12 @@
9 9
10 namespace App\Http\Logic\Aside\Geo; 10 namespace App\Http\Logic\Aside\Geo;
11 11
12 -use App\Enums\Common\Code;  
13 use App\Http\Logic\Aside\BaseLogic; 12 use App\Http\Logic\Aside\BaseLogic;
  13 +use App\Models\Geo\GeoConf;
14 use App\Models\Geo\GeoConfirm; 14 use App\Models\Geo\GeoConfirm;
  15 +use App\Models\Manage\ManageHr;
15 use App\Models\ProjectAssociation\ProjectAssociation; 16 use App\Models\ProjectAssociation\ProjectAssociation;
  17 +use App\Services\DingService;
16 18
17 /** 19 /**
18 * @remark :用户确认信息 20 * @remark :用户确认信息
@@ -40,7 +42,7 @@ class GeoConfirmLogic extends BaseLogic @@ -40,7 +42,7 @@ class GeoConfirmLogic extends BaseLogic
40 public function saveConfirmContent($param) 42 public function saveConfirmContent($param)
41 { 43 {
42 try { 44 try {
43 - $wechat = $param['wechat'] ?? true; 45 + $wechat = $param['wechat'] ?? 1;
44 unset($param['wechat']); 46 unset($param['wechat']);
45 $info = $this->model->read(['project_id' => $param['project_id'],'type' => $param['type']]); 47 $info = $this->model->read(['project_id' => $param['project_id'],'type' => $param['type']]);
46 if($info === false){ 48 if($info === false){
@@ -92,6 +94,19 @@ class GeoConfirmLogic extends BaseLogic @@ -92,6 +94,19 @@ class GeoConfirmLogic extends BaseLogic
92 }else{ 94 }else{
93 $id = $info['id']; 95 $id = $info['id'];
94 $this->model->edit($this->param,['id'=>$info['id']]); 96 $this->model->edit($this->param,['id'=>$info['id']]);
  97 + $geoConfModel = new GeoConf();
  98 + $confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
  99 + $hrModel = new ManageHr();
  100 + $manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
  101 + $dingService = new DingService();
  102 + $dingService->handle([
  103 + 'keyword' => '项目数据确认',
  104 + 'msg' =>
  105 + 'cm:'.(($info['type'] == 1) ? '标题确认' : '关键词确认'). PHP_EOL .
  106 + '项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
  107 + '负责人:'.$manage_name . PHP_EOL,
  108 + 'isAtAll' => false, // 是否@所有人
  109 + ], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
95 } 110 }
96 return $this->success(['id'=>$id]); 111 return $this->success(['id'=>$id]);
97 } 112 }
@@ -85,10 +85,15 @@ class GeoQuestionLogic extends BaseLogic @@ -85,10 +85,15 @@ class GeoQuestionLogic extends BaseLogic
85 public function saveGeoQuestion(){ 85 public function saveGeoQuestion(){
86 //处理数据 86 //处理数据
87 $count = count($this->param['question']); 87 $count = count($this->param['question']);
  88 + $sum = $this->model->where('project_id',$this->param['project_id'])->sum('question_num') ?? 0;
  89 + if($sum >= 200 || $count >= 200){
  90 + $this->fail('当前问题数量大于最大数量200个问题,不允许保存');
  91 + }
88 $question = $this->param['question']; 92 $question = $this->param['question'];
89 $this->param['url'] = json_encode($this->param['url'] ?? [],true); 93 $this->param['url'] = json_encode($this->param['url'] ?? [],true);
90 $this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true); 94 $this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true);
91 if($count <= 20){ 95 if($count <= 20){
  96 + $this->param['question_num'] = $count;
92 if(isset($this->param['id']) && !empty($this->param['id'])){ 97 if(isset($this->param['id']) && !empty($this->param['id'])){
93 $id = $this->param['id']; 98 $id = $this->param['id'];
94 $this->model->edit($this->param,['id'=>$id]); 99 $this->model->edit($this->param,['id'=>$id]);
@@ -101,6 +106,7 @@ class GeoQuestionLogic extends BaseLogic @@ -101,6 +106,7 @@ class GeoQuestionLogic extends BaseLogic
101 $chunks = array_chunk($question, 20); 106 $chunks = array_chunk($question, 20);
102 if(isset($this->param['id']) && !empty($this->param['id'])){ 107 if(isset($this->param['id']) && !empty($this->param['id'])){
103 foreach ($chunks as $index => $chunk) { 108 foreach ($chunks as $index => $chunk) {
  109 + $this->param['question_num'] = count($chunk);
104 $this->param['question'] = json_encode($chunk ?? [],true); 110 $this->param['question'] = json_encode($chunk ?? [],true);
105 if($index == 0){ 111 if($index == 0){
106 $id = $this->param['id']; 112 $id = $this->param['id'];
@@ -65,9 +65,11 @@ class GeoWritingsLogic extends BaseLogic @@ -65,9 +65,11 @@ class GeoWritingsLogic extends BaseLogic
65 $this->param['status'] = GeoWritings::STATUS_INIT; 65 $this->param['status'] = GeoWritings::STATUS_INIT;
66 if(isset($this->param['id']) &&!empty($this->param['id'])){ 66 if(isset($this->param['id']) &&!empty($this->param['id'])){
67 $id = $this->param['id']; 67 $id = $this->param['id'];
  68 + $this->param['content_length'] = strlen($this->param['content'] ?? '');
68 $this->model->edit($this->param,['id'=>$id]); 69 $this->model->edit($this->param,['id'=>$id]);
69 }else{ 70 }else{
70 $this->param['type'] = GeoWritings::TYPE_SUBMIT; 71 $this->param['type'] = GeoWritings::TYPE_SUBMIT;
  72 + $this->param['content_length'] = strlen($this->param['content'] ?? '');
71 $this->param['uniqid'] = uniqid().$this->param['project_id']; 73 $this->param['uniqid'] = uniqid().$this->param['project_id'];
72 $id = $this->model->addReturnId($this->param); 74 $id = $this->model->addReturnId($this->param);
73 } 75 }
@@ -102,7 +104,7 @@ class GeoWritingsLogic extends BaseLogic @@ -102,7 +104,7 @@ class GeoWritingsLogic extends BaseLogic
102 */ 104 */
103 public function sendWechatMessage() 105 public function sendWechatMessage()
104 { 106 {
105 - $wechat = $this->param['wechat'] ?? true; 107 + $wechat = $this->param['wechat'] ?? 1;
106 $this->model->edit(['status'=>2],['status'=>1,'project_id'=>$this->param['project_id']]); 108 $this->model->edit(['status'=>2],['status'=>1,'project_id'=>$this->param['project_id']]);
107 $data = GeoWritings::sendConfirmMessage($this->param['project_id'],$wechat); 109 $data = GeoWritings::sendConfirmMessage($this->param['project_id'],$wechat);
108 if($data === false){ 110 if($data === false){
@@ -551,8 +551,11 @@ class InquiryForwardLogic extends BaseLogic @@ -551,8 +551,11 @@ class InquiryForwardLogic extends BaseLogic
551 551
552 $last_year_month = date('Y-m', strtotime($last_year_month . ' +1 month')); 552 $last_year_month = date('Y-m', strtotime($last_year_month . ' +1 month'));
553 } 553 }
554 - $data_month['total'] = $data_month_total; 554 + $data_month['合计'] = $data_month_total;
555 555
  556 + foreach ($data_month as $km => $vm) {
  557 + $data_month[$km]['月/年合计'] = array_sum($vm);
  558 + }
556 559
557 //周统计 560 //周统计
558 $last_week_day = date('Y-m-d', strtotime('-1 week')); 561 $last_week_day = date('Y-m-d', strtotime('-1 week'));
@@ -576,7 +579,11 @@ class InquiryForwardLogic extends BaseLogic @@ -576,7 +579,11 @@ class InquiryForwardLogic extends BaseLogic
576 579
577 $last_week_day = date('Y-m-d', strtotime($last_week_day . ' +1 day')); 580 $last_week_day = date('Y-m-d', strtotime($last_week_day . ' +1 day'));
578 } 581 }
579 - $data_week['total'] = $data_week_total; 582 + $data_week['合计'] = $data_week_total;
  583 +
  584 + foreach ($data_week as $kw => $vw) {
  585 + $data_week[$kw]['日/周合计'] = array_sum($vw);
  586 + }
580 587
581 $data = ['data_month' => $data_month, 'data_week' => $data_week]; 588 $data = ['data_month' => $data_month, 'data_week' => $data_week];
582 589
@@ -870,7 +870,12 @@ class ProductLogic extends BaseLogic @@ -870,7 +870,12 @@ class ProductLogic extends BaseLogic
870 $img_arr = explode('^v6sp$',$data[7]); 870 $img_arr = explode('^v6sp$',$data[7]);
871 foreach ($img_arr as $v_img){ 871 foreach ($img_arr as $v_img){
872 if($v_img){ 872 if($v_img){
873 - $one_img = check_remote_url_down($v_img,$project_id,$domain); 873 + if($project_id == 4847){
  874 + //4847项目特殊处理
  875 + $one_img = 'https://ecdn6.globalso.com/upload/p/4847/image_other/2025-11/'.$v_img;
  876 + }else{
  877 + $one_img = check_remote_url_down($v_img,$project_id,$domain);
  878 + }
874 if($one_img){ 879 if($one_img){
875 $one_gallery = [ 880 $one_gallery = [
876 'alt' => '', 881 'alt' => '',
@@ -113,6 +113,8 @@ class RankDataLogic extends BaseLogic @@ -113,6 +113,8 @@ class RankDataLogic extends BaseLogic
113 'remain_day' => $project['remain_day'], 113 'remain_day' => $project['remain_day'],
114 'seo_remain_day' => $project['seo_remain_day'], 114 'seo_remain_day' => $project['seo_remain_day'],
115 'g_top_plan' => $g_top_plan ?? [], 115 'g_top_plan' => $g_top_plan ?? [],
  116 + 'is_remain_today'=>$project['is_remain_today'] ?? 0,
  117 + 'bm_is_remain_today'=>$project['bm_is_remain_today'] ?? 0
116 ]; 118 ];
117 //小语种列表 119 //小语种列表
118 $quanqiusou_api = new QuanqiusouApi(); 120 $quanqiusou_api = new QuanqiusouApi();
@@ -38,7 +38,7 @@ class GeoWritingsTaskRequest extends FormRequest @@ -38,7 +38,7 @@ class GeoWritingsTaskRequest extends FormRequest
38 // 'prefix' => 'required|string', 38 // 'prefix' => 'required|string',
39 // 'suffix' => 'required|string', 39 // 'suffix' => 'required|string',
40 'event_title' => 'required|string', 40 'event_title' => 'required|string',
41 - 'event_content' => 'required|string', 41 +// 'event_content' => 'required|string',
42 'title' => 'required|string|max:120', 42 'title' => 'required|string|max:120',
43 'description' => 'required|string', 43 'description' => 'required|string',
44 ]; 44 ];
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :WordAi.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/20 11:22
  8 + */
  9 +
  10 +namespace App\Jobs;
  11 +
  12 +use App\Models\AiRemove\AiRemove;
  13 +use App\Services\WordAiService;
  14 +use Illuminate\Bus\Queueable;
  15 +use Illuminate\Contracts\Queue\ShouldQueue;
  16 +use Illuminate\Foundation\Bus\Dispatchable;
  17 +use Illuminate\Queue\InteractsWithQueue;
  18 +use Illuminate\Queue\SerializesModels;
  19 +
  20 +class WordAi implements ShouldQueue
  21 +{
  22 + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  23 +
  24 + protected $param;
  25 +
  26 + public function __construct($data)
  27 + {
  28 + $this->param = $data;
  29 + }
  30 + /**
  31 + * @remark :执行数据
  32 + * @name :handle
  33 + * @author :lyh
  34 + * @method :post
  35 + * @time :2025/11/20 11:24
  36 + */
  37 + public function handle()
  38 + {
  39 + $model = new AiRemove();
  40 + $info = $model->read(['id'=>$this->param['id']]);
  41 + if($info !== false && !empty($info['origin_text'])) {
  42 + $model->edit(['status'=>$model::STATUS_ING],['id'=>$info['id']]);
  43 + $wordAiService = new WordAiService();
  44 + $data = $wordAiService->setApiAvoid($info['origin_text']);
  45 + if(isset($data['status']) && $data['status'] == 'Success'){
  46 + //todo::更新当前任务状态,并记录返回的值
  47 + $model->edit(['target_text'=>$data['text'],'status'=>$model::STATUS_SUC],['id'=>$info['id']]);
  48 + }else{
  49 + //todo::更改执行次数,及错误结果
  50 + $model->edit(['error_msg'=>substr(json_encode($data,JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),0,255),'status'=>$model::STATUS_FAL],['id'=>$info['id']]);
  51 + sleep(10);
  52 + }
  53 + }
  54 + return true;
  55 + }
  56 +}
@@ -41,6 +41,7 @@ class APublicModel extends Base @@ -41,6 +41,7 @@ class APublicModel extends Base
41 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count(); 41 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
42 $newsNumber = DB::connection('custom_mysql')->table('gl_news') 42 $newsNumber = DB::connection('custom_mysql')->table('gl_news')
43 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count(); 43 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
  44 + $aiBlogNumber = DB::connection('custom_mysql')->table('gl_ai_blog')->where('project_id', $project_id)->count();
44 $keyNumber = DB::connection('custom_mysql')->table('gl_product_keyword') 45 $keyNumber = DB::connection('custom_mysql')->table('gl_product_keyword')
45 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count(); 46 ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
46 //获取项目的询盘数量 47 //获取项目的询盘数量
@@ -49,7 +50,7 @@ class APublicModel extends Base @@ -49,7 +50,7 @@ class APublicModel extends Base
49 if(!empty($countInfo)){ 50 if(!empty($countInfo)){
50 $inquiryNumber = $countInfo->inquiry_num ?? 0; 51 $inquiryNumber = $countInfo->inquiry_num ?? 0;
51 } 52 }
52 - $data = ['product'=>$productNumber,'blog'=>$blogNumber,'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber]; 53 + $data = ['product'=>$productNumber,'blog'=>($blogNumber + $aiBlogNumber),'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber];
53 Cache::add('product_blog_news_'.$project_id,$data,30 * 60); 54 Cache::add('product_blog_news_'.$project_id,$data,30 * 60);
54 } 55 }
55 }catch (\Exception $e){ 56 }catch (\Exception $e){
  1 +<?php
  2 +
  3 +namespace App\Models\AiRemove;
  4 +
  5 +use App\Models\Base;
  6 +
  7 +class AiRemove extends Base
  8 +{
  9 + protected $table = 'gl_ai_remove_task';
  10 +
  11 + const STATUS_UN = 0;
  12 + const STATUS_ING = 1;
  13 + const STATUS_SUC = 2;
  14 + const STATUS_FAL = 3;
  15 +}
@@ -106,7 +106,7 @@ class GeoConfirm extends Base @@ -106,7 +106,7 @@ class GeoConfirm extends Base
106 * @param $id 106 * @param $id
107 * @return bool 107 * @return bool
108 */ 108 */
109 - public static function sendConfirmMessage($id, $friend_id,$send = true) 109 + public static function sendConfirmMessage($id, $friend_id,$send = 1)
110 { 110 {
111 $data = self::where(compact('id'))->first(); 111 $data = self::where(compact('id'))->first();
112 $project_id = $data->project_id; 112 $project_id = $data->project_id;
@@ -127,7 +127,7 @@ class GeoConfirm extends Base @@ -127,7 +127,7 @@ class GeoConfirm extends Base
127 'url' => 'https://oa.quanqiusou.cn/public-geo-confirm?token=' . $token 127 'url' => 'https://oa.quanqiusou.cn/public-geo-confirm?token=' . $token
128 ]; 128 ];
129 $content = json_encode($content_array, JSON_UNESCAPED_UNICODE); 129 $content = json_encode($content_array, JSON_UNESCAPED_UNICODE);
130 - if($send == true){ 130 + if($send){
131 $data->send_at = now(); 131 $data->send_at = now();
132 $data->status = self::STATUS_RUNNING; 132 $data->status = self::STATUS_RUNNING;
133 MessagePush::insert(compact('project_id', 'friend_id', 'type', 'content_type', 'content', 'send_time', 'updated_at', 'created_at')); 133 MessagePush::insert(compact('project_id', 'friend_id', 'type', 'content_type', 'content', 'send_time', 'updated_at', 'created_at'));
@@ -77,7 +77,7 @@ class GeoWritings extends Base @@ -77,7 +77,7 @@ class GeoWritings extends Base
77 * @return bool 77 * @return bool
78 * @throws \Exception 78 * @throws \Exception
79 */ 79 */
80 - public static function sendConfirmMessage($project_id,$wechat = true) 80 + public static function sendConfirmMessage($project_id,$wechat = 1)
81 { 81 {
82 $friend = ProjectAssociation::where(['project_id' => $project_id])->first(); 82 $friend = ProjectAssociation::where(['project_id' => $project_id])->first();
83 if (empty($friend)) { 83 if (empty($friend)) {
@@ -24,7 +24,7 @@ class CosService @@ -24,7 +24,7 @@ class CosService
24 * @method :post 24 * @method :post
25 * @time :2023/7/19 15:28 25 * @time :2023/7/19 15:28
26 */ 26 */
27 - public function uploadFile(&$files,$path,$filename, $binary = false,$watermarkOptions = '') 27 + public function uploadFile(&$files, $path, $filename, $binary = false, $watermarkOptions = '')
28 { 28 {
29 $cos = config('filesystems.disks.cos'); 29 $cos = config('filesystems.disks.cos');
30 $cosClient = new Client([ 30 $cosClient = new Client([
@@ -34,7 +34,9 @@ class CosService @@ -34,7 +34,9 @@ class CosService
34 'secretKey' => $cos['credentials']['secretKey'], 34 'secretKey' => $cos['credentials']['secretKey'],
35 ], 35 ],
36 ]); 36 ]);
37 - $key = $path.'/'.$filename; 37 +
  38 + $key = $path . '/' . $filename;
  39 +
38 // 判断是否为 Base64 编码的图片流文件 40 // 判断是否为 Base64 编码的图片流文件
39 if (Str::startsWith($files, 'data:image')) { 41 if (Str::startsWith($files, 'data:image')) {
40 // 分离 Base64 头部和数据部分 42 // 分离 Base64 头部和数据部分
@@ -42,33 +44,56 @@ class CosService @@ -42,33 +44,56 @@ class CosService
42 // 解码 Base64 数据 44 // 解码 Base64 数据
43 $Body = base64_decode($base64Data); 45 $Body = base64_decode($base64Data);
44 if ($Body === false) { 46 if ($Body === false) {
45 - throw new \Exception("Base64 数据解码失败"); 47 + outMessage('upload_images',"解码失败");
  48 + return false;
46 } 49 }
47 } else { 50 } else {
48 // 如果不是 Base64 流文件,处理为普通文件上传 51 // 如果不是 Base64 流文件,处理为普通文件上传
49 - $Body = $binary ? $files : fopen($files->getRealPath(), 'r'); 52 + try {
  53 + $Body = $binary ? $files : fopen($files->getRealPath(), 'r');
  54 + // 检查文件是否有效
  55 + if (!$Body) {
  56 + outMessage('upload_images',"文件打开失败");
  57 + return false;
  58 + }
  59 + } catch (\Exception $e) {
  60 + outMessage('upload_images',"文件处理失败: " . $e->getMessage());
  61 + return false;
  62 + }
50 } 63 }
51 - $options = [  
52 - 'Bucket' => $cos['bucket'],  
53 - 'Key' => $key,  
54 - 'Body' => $Body,  
55 - ];  
56 - //水印  
57 - if ($watermarkOptions) {  
58 - $options['PicOperations'] = json_encode([  
59 - 'is_pic_info' => 1,  
60 - 'rules' => [  
61 - [  
62 - 'fileid' => $key, // 使用相同的文件名保存  
63 - 'rule' => $watermarkOptions, 64 + try {
  65 + $options = [
  66 + 'Bucket' => $cos['bucket'],
  67 + 'Key' => $key,
  68 + 'Body' => $Body,
  69 + ];
  70 + // 水印处理
  71 + if ($watermarkOptions) {
  72 + $options['PicOperations'] = json_encode([
  73 + 'is_pic_info' => 1,
  74 + 'rules' => [
  75 + [
  76 + 'fileid' => $key, // 使用相同的文件名保存
  77 + 'rule' => $watermarkOptions,
  78 + ]
64 ] 79 ]
65 - ]  
66 - ], true); 80 + ], true);
  81 + }
  82 + $cosClient->putObject($options);
  83 + } catch (\Exception $e) {
  84 + // 记录上传失败日志
  85 + outMessage('upload_images',$e->getMessage());
  86 + return false;
  87 + } finally {
  88 + // 确保非二进制模式下关闭文件资源
  89 + if (!$binary && is_resource($Body)) {
  90 + fclose($Body);
  91 + }
67 } 92 }
68 - $res = $cosClient->putObject($options);  
69 return $key; 93 return $key;
70 } 94 }
71 95
  96 +
72 /** 97 /**
73 * @param $image_name 98 * @param $image_name
74 * @remark :获取图片访问链接 99 * @remark :获取图片访问链接
@@ -31,7 +31,7 @@ class DingService @@ -31,7 +31,7 @@ class DingService
31 public function handle(array $body, $link = '') 31 public function handle(array $body, $link = '')
32 { 32 {
33 $link = $link ?: self::LINK; 33 $link = $link ?: self::LINK;
34 - $msgKey = mb_substr($body['msg'], 50); 34 + $msgKey = mb_substr($body['msg'], 100);
35 if (!$this->getData(RedisKey::DING_MSG . $msgKey)) { 35 if (!$this->getData(RedisKey::DING_MSG . $msgKey)) {
36 $arr = [ 36 $arr = [
37 'msgtype' => 'text', 37 'msgtype' => 'text',
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :WordAiService.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/19 17:40
  8 + */
  9 +
  10 +namespace App\Services;
  11 +
  12 +use Illuminate\Support\Facades\Http;
  13 +
  14 +class WordAiService
  15 +{
  16 + public $email = 'bill@ai.cc';
  17 +
  18 + public $key = '868545714b911ab135327793fcadf46e';
  19 +
  20 + public $url = 'https://wai.wordai.com/';
  21 +
  22 + /**
  23 + * @remark :ai检测(WordAi 避免检测到)
  24 + * @name :setApiAvoid
  25 + * @author :lyh
  26 + * @method :post
  27 + * @time :2025/11/19 17:43
  28 + */
  29 + public function setApiAvoid($input = '',$model = 'change_less')
  30 + {
  31 + $response = Http::timeout(600)->retry(3, 5000)
  32 + ->post($this->url.'/api/avoid', [
  33 + 'email' => $this->email,
  34 + 'key' => $this->key,
  35 + 'input' => $input,
  36 + 'mode' => $model
  37 + ]);
  38 + if ($response->successful()) {
  39 + $result = $response->json();
  40 + // 处理返回结果
  41 + return $result;
  42 + } else {
  43 + // 处理错误
  44 + return false;
  45 + }
  46 + }
  47 +
  48 +}
@@ -81,6 +81,7 @@ return [ @@ -81,6 +81,7 @@ return [
81 'cdn' => env('COS_CDN'), 81 'cdn' => env('COS_CDN'),
82 'cdn1' => env('COS_CDN1'), 82 'cdn1' => env('COS_CDN1'),
83 'cdn2' => env('COS_CDN2'), 83 'cdn2' => env('COS_CDN2'),
  84 + 'cdn3' => env('COS_CDN3'),
84 'timeout' => 60, 85 'timeout' => 60,
85 'connect_timeout' => 60, 86 'connect_timeout' => 60,
86 ], 87 ],
@@ -125,5 +125,7 @@ Route::prefix('geo')->group(function () { @@ -125,5 +125,7 @@ Route::prefix('geo')->group(function () {
125 Route::any('/getWritingsList', [\App\Http\Controllers\Api\GeoController::class, 'getWritingsList'])->name('geo.getWritingsList');//文章确认列表 125 Route::any('/getWritingsList', [\App\Http\Controllers\Api\GeoController::class, 'getWritingsList'])->name('geo.getWritingsList');//文章确认列表
126 Route::any('/confirmWritings', [\App\Http\Controllers\Api\GeoController::class, 'confirmWritings'])->name('geo.confirmWritings');//确认文章信息 126 Route::any('/confirmWritings', [\App\Http\Controllers\Api\GeoController::class, 'confirmWritings'])->name('geo.confirmWritings');//确认文章信息
127 }); 127 });
  128 +//获取geo外链数据
  129 +Route::any('/getGeoLink', [\App\Http\Controllers\Api\ComController::class, 'getGeoLink'])->name('geo.getGeoLink');
128 130
129 131
@@ -18,6 +18,7 @@ Route::middleware(['aloginauth'])->group(function () { @@ -18,6 +18,7 @@ Route::middleware(['aloginauth'])->group(function () {
18 Route::any('/getCountry', [Aside\Com\CNoticeController::class, 'getCountry'])->name('admin.getCountry'); 18 Route::any('/getCountry', [Aside\Com\CNoticeController::class, 'getCountry'])->name('admin.getCountry');
19 Route::any('/getDynamicPassword', [Aside\Com\IndexController::class, 'getDynamicPassword'])->name('admin.getDynamicPassword'); 19 Route::any('/getDynamicPassword', [Aside\Com\IndexController::class, 'getDynamicPassword'])->name('admin.getDynamicPassword');
20 Route::any('/notAiHumanizer', [Aside\Com\IndexController::class, 'notAiHumanizer'])->name('admin.notAiHumanizer'); 20 Route::any('/notAiHumanizer', [Aside\Com\IndexController::class, 'notAiHumanizer'])->name('admin.notAiHumanizer');
  21 + Route::any('/notWordAiHumanizer', [Aside\Com\IndexController::class, 'notWordAiHumanizer'])->name('admin.notWordAiHumanizer');
21 Route::any('/prInfoDownload', [Aside\Com\IndexController::class, 'prInfoDownload'])->name('admin.prInfoDownload');//pr报告下载 22 Route::any('/prInfoDownload', [Aside\Com\IndexController::class, 'prInfoDownload'])->name('admin.prInfoDownload');//pr报告下载
22 //会员相关 23 //会员相关
23 Route::prefix('user')->group(function () { 24 Route::prefix('user')->group(function () {
@@ -690,6 +691,12 @@ Route::middleware(['aloginauth'])->group(function () { @@ -690,6 +691,12 @@ Route::middleware(['aloginauth'])->group(function () {
690 Route::any('/del', [Aside\Manage\ManageEntryPositionController::class,'del'])->name('entry_position_del'); 691 Route::any('/del', [Aside\Manage\ManageEntryPositionController::class,'del'])->name('entry_position_del');
691 }); 692 });
692 693
  694 + //去AI痕迹管理
  695 + Route::prefix('ai_remove')->group(function () {
  696 + Route::any('/', [Aside\AiRemove\AiRemoveController::class, 'getTaskLists'])->name('admin.ai_remove_getTaskLists');
  697 + Route::any('/taskInfo', [Aside\AiRemove\AiRemoveController::class, 'taskInfo'])->name('admin.ai_remove_taskInfo');
  698 + Route::any('/saveTask', [Aside\AiRemove\AiRemoveController::class, 'saveTask'])->name('admin.ai_remove_saveTask');
  699 + });
693 }); 700 });
694 701
695 //无需登录验证的路由组 702 //无需登录验证的路由组
@@ -656,6 +656,9 @@ Route::middleware(['bloginauth'])->group(function () { @@ -656,6 +656,9 @@ Route::middleware(['bloginauth'])->group(function () {
656 //2205项目单独处理 656 //2205项目单独处理
657 Route::any('2205/get2205List', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'get2205List'])->name('extension_module_get2205List'); 657 Route::any('2205/get2205List', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'get2205List'])->name('extension_module_get2205List');
658 Route::any('2205/save2205Status', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'save2205Status'])->name('extension_module_save2205Status'); 658 Route::any('2205/save2205Status', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'save2205Status'])->name('extension_module_save2205Status');
  659 + //3915项目处理
  660 + Route::any('3915/lists', [\App\Http\Controllers\Bside\ExtensionModule\Extension3915ModuleController::class, 'lists'])->name('extension_module_3915_lists');
  661 + Route::any('3915/importData', [\App\Http\Controllers\Bside\ExtensionModule\Extension3915ModuleController::class, 'importData'])->name('extension_module_3915_importData');
659 }); 662 });
660 663
661 //自定义小语种文本信息 664 //自定义小语种文本信息