作者 刘锟

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

  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Tdk;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Helper\Common;
  7 +use App\Helper\Gpt;
  8 +use App\Models\Ai\AiCommand;
  9 +use App\Models\Domain\DomainInfo;
  10 +use App\Models\Mail\Mail;
  11 +use App\Models\Project\DeployBuild;
  12 +use App\Models\Project\DeployOptimize;
  13 +use App\Models\Project\ProjectUpdateTdk;
  14 +use App\Models\User\User;
  15 +use App\Models\WebSetting\WebLanguage;
  16 +use App\Services\ProjectServer;
  17 +use Illuminate\Console\Command;
  18 +use Illuminate\Support\Facades\Cache;
  19 +use Illuminate\Support\Facades\DB;
  20 +use Illuminate\Support\Facades\Redis;
  21 +use Illuminate\Support\Str;
  22 +
  23 +/**
  24 + * 指定跑某个项目
  25 + * Class InitProject
  26 + * @package App\Console\Commands
  27 + * @author zbj
  28 + * @date 2023/10/8
  29 + */
  30 +class UpdateSeoTdkByTaskId extends Command
  31 +{
  32 + /**
  33 + * The name and signature of the console command.
  34 + *
  35 + * @var string
  36 + */
  37 + protected $signature = 'update_seo_tdk_by {task_id}';
  38 +
  39 + /**
  40 + * The console command description.
  41 + *
  42 + * @var string
  43 + */
  44 + protected $description = '一键生成tdk';
  45 +
  46 + protected $project;
  47 +
  48 + /**
  49 + * Create a new command instance.
  50 + *
  51 + * @return void
  52 + */
  53 + public function __construct()
  54 + {
  55 + parent::__construct();
  56 + }
  57 +
  58 + /**
  59 + * '表' => [
  60 + * '指令key' => '表字段'
  61 + * ]
  62 + * @return array
  63 + * @author zbj
  64 + * @date 2023/11/3
  65 + */
  66 + protected $maps = [
  67 + 'gl_web_custom_template' => [
  68 + 'page_title' => 'title',
  69 + 'page_meta_keywords' => 'keywords',
  70 + 'page_meta_description' => 'description',
  71 + ],
  72 + 'gl_product' => [
  73 + 'product_title' => 'seo_mate.title',
  74 + 'product_meta_keywords' => 'seo_mate.keyword',
  75 + 'product_meta_description' => 'seo_mate.description',
  76 + ],
  77 + 'gl_product_category' => [
  78 + 'product_cat_title' => 'seo_title',
  79 + 'product_cat_meta_keywords' => 'seo_keywords',
  80 + 'product_cat_meta_description' => 'seo_des',
  81 + ],
  82 + 'gl_blog' => [
  83 + 'blog_title' => 'seo_title',
  84 + 'blog_meta_keywords' => 'seo_keywords',
  85 + 'blog_meta_description' => 'seo_description',
  86 + ],
  87 + 'gl_blog_category' => [
  88 + 'blog_cat_title' => 'seo_title',
  89 + 'blog_cat_meta_keywords' => 'seo_keywords',
  90 + 'blog_cat_meta_description' => 'seo_des',
  91 + ],
  92 + 'gl_news' => [
  93 + 'news_title' => 'seo_title',
  94 + 'news_meta_keywords' => 'seo_keywords',
  95 + 'news_meta_description' => 'seo_description',
  96 + ],
  97 + 'gl_news_category' => [
  98 + 'news_cat_title' => 'seo_title',
  99 + 'news_cat_meta_keywords' => 'seo_keywords',
  100 + 'news_cat_meta_description' => 'seo_des',
  101 + ],
  102 + 'gl_product_keyword' => [
  103 + 'tags_title' => 'seo_title',
  104 + 'tags_meta_keywords' => 'seo_keywords',
  105 + 'tags_meta_description' => 'seo_description',
  106 + 'tags_content_title' => 'keyword_title',
  107 + 'tags_content_description' => 'keyword_content',
  108 + ]
  109 + ];
  110 +
  111 + /**
  112 + * topic-对相应字段
  113 + * @var array
  114 + */
  115 + protected $topic_fields = [
  116 + 'gl_web_custom_template' => 'name',
  117 + 'gl_product' => 'title',
  118 + 'gl_product_category' => 'title',
  119 + 'gl_blog' => 'name',
  120 + 'gl_blog_category' => 'name',
  121 + 'gl_news' => 'name',
  122 + 'gl_news_category' => 'name',
  123 + 'gl_product_keyword' => 'title'
  124 + ];
  125 +
  126 + /**
  127 + * 使用核心关键词的key 数量
  128 + * @var array
  129 + */
  130 + protected $core_keyword_keys = [
  131 + 'page_meta_keywords' => 1,
  132 + 'blog_cat_meta_keywords' => 8,
  133 + 'news_cat_meta_keywords' => 8,
  134 + ];
  135 +
  136 + /**
  137 + * @return bool
  138 + */
  139 + public function handle()
  140 + {
  141 + $task_id = $this->argument('task_id');
  142 + $task = ProjectUpdateTdk::where('status', ProjectUpdateTdk::STATUS_PENDING)->where('id', $task_id)->first();
  143 + if (!$task) {
  144 + echo date('Y-m-d H:i:s') . ' 任务不存在: ' . $task_id . PHP_EOL;
  145 + }
  146 + $project_id = $task->project_id;
  147 +
  148 + echo date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
  149 + try {
  150 + $this->project = ProjectServer::useProject($project_id);
  151 + $this->seo_tdk($project_id, $task->id);
  152 + DB::disconnect('custom_mysql');
  153 + }catch (\Exception $e){
  154 + echo date('Y-m-d H:i:s') . 'line: '. $e->getLine() .' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
  155 + ProjectUpdateTdk::retry($task->id, $e->getMessage());
  156 + }
  157 + Cache::forget('project_deploy_optimize_info_' . $project_id);
  158 + echo date('Y-m-d H:i:s') . ' end project_id: ' . $project_id . PHP_EOL;
  159 + }
  160 + public function sendNotify($project_id, $route)
  161 + {
  162 + //获取当前项目的域名
  163 + $domainModel = new DomainInfo();
  164 + $domainInfo = $domainModel->read(['project_id'=>$project_id]);
  165 + if($domainInfo === false){
  166 + //获取测试域名
  167 + $deployBuildModel = new DeployBuild();
  168 + $buildInfo = $deployBuildModel->read(['project_id'=>$project_id]);
  169 + $this->param['domain'] = $buildInfo['test_domain'];
  170 + }else{
  171 + $this->param['domain'] = 'https://'.$domainInfo['domain'].'/';
  172 + }
  173 + $url = $this->param['domain'].'api/update_page/';
  174 + $param = [
  175 + 'project_id' => $project_id,
  176 + 'type' => 1,
  177 + 'route' => $route,
  178 + 'url' => [],
  179 + 'language'=> [],
  180 + ];
  181 + http_post($url, json_encode($param));
  182 + echo '更新中请稍后, 更新完成将会发送站内信通知更新结果!'. PHP_EOL;
  183 + }
  184 + public function seo_tdk($project_id, $task_id)
  185 + {
  186 + $notify_master = $notify_keyword = false;
  187 + //更新统计
  188 + $update = [];
  189 + $ai_commands = AiCommand::where('is_batch', 1)->select('key', 'scene', 'ai')->get()->toArray();
  190 + $ai_commands = Arr::setValueToKey($ai_commands, 'key');
  191 + foreach ($this->maps as $table => $map) {
  192 + $total_page = DB::connection('custom_mysql')->table($table)->count();
  193 + $update[$table] = ['total_page'=>$total_page, 'title'=>0, 'keyword'=>0, 'des'=>0,'keyword_title'=>0,'keyword_content'=>0];
  194 + echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL;
  195 + $list = DB::connection('custom_mysql')->table($table)
  196 + ->where(function ($query) use ($table, $map){
  197 + if($table == 'gl_product'){
  198 + foreach ($map as $field){
  199 + $field_arr = explode('.', $field);
  200 + $query->orWhereRaw('JSON_CONTAINS('.$field_arr[0].', "null", "$.'.$field_arr[1].'") OR JSON_EXTRACT('.$field_arr[0].', "$.'.$field_arr[1].'") = ""');
  201 + }
  202 + }else{
  203 + foreach ($map as $field){
  204 + $query->orWhereRaw($field . " IS NULL OR ".$field." = ''");
  205 + }
  206 + }
  207 + })->select('id')->get();
  208 + if (!empty($list)) {
  209 + $list = $list->toArray();
  210 + foreach ($list as $v) {
  211 + $v = (array)$v;
  212 +
  213 + //缓存 在处理的项目数据 id
  214 + $cache_key = "seo_tdk_{$project_id}_{$table}_{$v['id']}";
  215 + if(!Redis::setnx($cache_key, 1)){
  216 + continue;
  217 + }
  218 + Redis::expire($cache_key, 120);
  219 +
  220 + echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . ':id' . $v['id'] . PHP_EOL;
  221 + $v = DB::connection('custom_mysql')->table($table)->where('id', $v['id'])->first();
  222 + $v = (array)$v;
  223 + $data = [];
  224 + $json_field = '';
  225 + foreach ($map as $ai_key => $field) {
  226 + $field_arr = explode('.', $field);
  227 + if (count($field_arr) > 1) {
  228 + $json_field = $field_arr[0];
  229 + $value = json_decode($v[$field_arr[0]], true)[$field_arr[1]] ?? '';
  230 + } else {
  231 + $value = $v[$field] ?? '';
  232 + }
  233 + //已有值的 跳过
  234 + if ($value) {
  235 + echo $field.'已有值 跳过' . PHP_EOL;
  236 + continue;
  237 + }
  238 +
  239 + //AI生成
  240 + if (!empty($ai_commands[$ai_key]['ai'])) {
  241 + $prompt = $this->getPrompt($project_id, $ai_commands[$ai_key]['ai'], $table, $v);
  242 + if(!$prompt){
  243 + continue;
  244 + }
  245 + if (count($field_arr) > 1) {
  246 + if($field_arr[1] == 'title'){
  247 + $update[$table]['title']++;
  248 + }elseif ($field_arr[1] == 'keyword'){
  249 + $update[$table]['keyword']++;
  250 + }elseif ($field_arr[1] == 'description'){
  251 + $update[$table]['des']++;
  252 + }
  253 + $data[$field_arr[0]][$field_arr[1]] = $this->ai_send($prompt);
  254 + }else{
  255 + if($field == 'title' || $field == 'seo_title'){
  256 + $update[$table]['title']++;
  257 + }
  258 + if($field == 'keywords' || $field == 'seo_keywords'){
  259 + $update[$table]['keyword']++;
  260 + }
  261 + if($field == 'seo_description' || $field == 'description' || $field == 'seo_des'){
  262 + $update[$table]['des']++;
  263 + }
  264 + if($field == 'keyword_title'){
  265 + $update[$table]['keyword_title']++;
  266 + }
  267 + if($field == 'keyword_content'){
  268 + $update[$table]['keyword_content']++;
  269 + }
  270 + $data[$field] = $this->ai_send($prompt);
  271 + }
  272 + } else {
  273 + //直接使用topic
  274 + if (count($field_arr) > 1) {
  275 + $data[$field_arr[0]][$field_arr[1]] = $v[$this->topic_fields[$table]] ?? '';
  276 + //使用核心关键词
  277 + if(in_array($ai_key, array_keys($this->core_keyword_keys))){
  278 + $data[$field_arr[0]][$field_arr[1]] = $this->mainKeywords($project_id, $this->core_keyword_keys[$ai_key]);
  279 + if(!empty($data[$field_arr[0]][$field_arr[1]])){
  280 + if($field_arr[1] == 'title'){
  281 + $data[$table]['title']++;
  282 + }elseif ($field_arr[1] == 'keyword'){
  283 + $data[$table]['keyword']++;
  284 + }elseif ($field_arr[1] == 'description'){
  285 + $data[$table]['des']++;
  286 + }
  287 + }
  288 + }
  289 + }else{
  290 + $data[$field] = $v[$this->topic_fields[$table]] ?? '';
  291 + //使用核心关键词
  292 + if(in_array($ai_key, array_keys($this->core_keyword_keys))){
  293 + $data[$field] = $this->mainKeywords($project_id, $this->core_keyword_keys[$ai_key]);
  294 + if(!empty($data[$field])){
  295 + if($field == 'title' || $field == 'seo_title'){
  296 + $update[$table]['title']++;
  297 + }
  298 + if($field == 'keywords' || $field == 'seo_keywords'){
  299 + $update[$table]['keyword']++;
  300 + }
  301 + if($field == 'seo_description' || $field == 'description' || $field == 'seo_des'){
  302 + $update[$table]['des']++;
  303 + }
  304 + if($field == 'keyword_title'){
  305 + $update[$table]['keyword_title']++;
  306 + }
  307 + if($field == 'keyword_content'){
  308 + $update[$table]['keyword_content']++;
  309 + }
  310 + }
  311 + }
  312 + }
  313 + }
  314 + }
  315 + if(!$data){
  316 + continue;
  317 + }
  318 + if($json_field){
  319 + $old_data = json_decode($v[$field_arr[0]], true);
  320 + foreach ($old_data ?: [] as $kk=>$vv){
  321 + empty($data[$json_field][$kk]) && $data[$json_field][$kk] = $vv;
  322 + }
  323 + $data[$json_field] = json_encode($data[$json_field]);
  324 + }
  325 + DB::connection('custom_mysql')->table($table)->where(['id' => $v['id']])->update($data);
  326 + if($table == 'gl_product_keyword'){
  327 + $notify_keyword = true;
  328 + }else{
  329 + $notify_master = true;
  330 + }
  331 + }
  332 + }
  333 + }
  334 + ProjectUpdateTdk::finish($task_id, $update);
  335 +
  336 + //通知C端更新界面
  337 + $notify_master && $this->sendNotify($project_id, 1); //通知主站更新
  338 + $notify_keyword && $this->sendNotify($project_id, 4); //通知聚合页更新
  339 + }
  340 +
  341 + public function getPrompt($project_id, $prompt, $table, $data){
  342 + if(strpos($prompt, '{topic}') !== false){
  343 + $topic = $data[$this->topic_fields[$table]] ?? '';
  344 + if(!$topic){
  345 + echo 'topic为空 跳过' . PHP_EOL;
  346 + return false;
  347 + }
  348 + $prompt = str_replace('{topic}', $topic, $prompt);
  349 + }
  350 + if(strpos($prompt, '{keyword}') !== false) {
  351 + $keyword = $this->mainKeywords($project_id, 1);
  352 + if(!$keyword){
  353 + echo '核心关键词为空 跳过' . PHP_EOL;
  354 + return false;
  355 + }
  356 + $prompt = str_replace('{keyword}', $keyword, $prompt);
  357 + }
  358 + if(strpos($prompt, '{company name}') !== false) {
  359 + $company_name = $this->companyName($project_id);
  360 + if(!$company_name){
  361 + echo '公司英文全称为空 跳过' . PHP_EOL;
  362 + return false;
  363 + }
  364 + $prompt = str_replace('{company name}', $company_name, $prompt);
  365 + }
  366 + $prompt .= '.Please answer in ' . $this->getLang();
  367 + return $prompt;
  368 + }
  369 +
  370 +
  371 + public function getDeployOptimize($project_id){
  372 + $cache_key = 'project_deploy_optimize_info_' . $project_id;
  373 + $info = Cache::get($cache_key);
  374 + if(!$info){
  375 + $projectOptimizeModel = new DeployOptimize();
  376 + $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'main_keywords']);
  377 + Cache::put($cache_key, $info, 600);
  378 + }
  379 + return $info;
  380 + }
  381 +
  382 + /**
  383 + * @remark :获取公司英文名称
  384 + * @name :companyName
  385 + * @author :lyh
  386 + * @method :post
  387 + * @time :2023/10/30 11:22
  388 + */
  389 + public function companyName($project_id, $key = '')
  390 + {
  391 + $data = [
  392 + 'product_long_description',
  393 + ];
  394 + $info = $this->getDeployOptimize($project_id);
  395 + if (in_array($key, $data)) {
  396 + return $info['company_en_description'];
  397 + } else {
  398 + return $info['company_en_name'];
  399 + }
  400 + }
  401 +
  402 + /**
  403 + * @remark :获取公司核心关键词
  404 + * @name :mainKeywords
  405 + * @author :lyh
  406 + * @method :post
  407 + * @time :2023/10/30 11:22
  408 + */
  409 + public function mainKeywords($project_id, $num)
  410 + {
  411 + $str = '';
  412 + $info = $this->getDeployOptimize($project_id);
  413 + if (!empty($info['main_keywords'])) {
  414 + $main_keywords = explode("\r\n", $info['main_keywords']);
  415 + //随机取
  416 + shuffle($main_keywords);
  417 + $main_keywords = array_slice($main_keywords, 0, $num);
  418 + $str = implode(", ", $main_keywords);
  419 + }
  420 + return $str;
  421 + }
  422 +
  423 + public function getLang(){
  424 + $lang = WebLanguage::getLangById($this->project['main_lang_id']??1);
  425 + return $lang['english'] ?? 'English';
  426 + }
  427 +
  428 + /**
  429 + * @remark :AI发送
  430 + * @name :ai_send
  431 + * @author :lyh
  432 + * @method :post
  433 + * @time :2023/8/19 10:40
  434 + */
  435 + public function ai_send($prompt)
  436 + {
  437 + $text = Gpt::instance()->openai_chat_qqs($prompt);
  438 + $text = Common::deal_keywords($text);
  439 + $text = Common::deal_str($text);
  440 +
  441 + //包含这写字 重新生成
  442 + if(Str::contains(Str::lower($text), ['[your brand]', '[brand name]'])){
  443 + return $this->ai_send($prompt);
  444 + }
  445 +
  446 + return $text;
  447 + }
  448 +
  449 + /**
  450 + * @remark :发送站内信
  451 + * @name :send_message
  452 + * @author :lyh
  453 + * @method :post
  454 + * @time :2023/11/4 10:22
  455 + */
  456 + public function send_message($project_id){
  457 + $user = new User();
  458 + $userInfo = $user->read(['project_id'=>$project_id,'role_id'=>0]);
  459 + $data["title"] = "seo更新通知---完成";
  460 + $data["user_list"] = $userInfo['id'];
  461 + $data["content"] = "seo更新成功,更新完成时间".date('Y-m-d H:i:s');
  462 + $mail = new Mail();
  463 + return $mail->add($data);
  464 + }
  465 +}
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :OaNoticeController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/6/20 10:47
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Aside\Com;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Aside\BaseController;
  14 +use App\Http\Logic\Aside\Com\OaNoticeLogic;
  15 +use App\Models\Manage\Manage;
  16 +use App\Models\OaNotice\OaNotice;
  17 +use App\Models\Project\Project;
  18 +use Illuminate\Support\Facades\DB;
  19 +
  20 +class OaNoticeController extends BaseController
  21 +{
  22 + /**
  23 + * @remark :通知消息
  24 + * @name :lists
  25 + * @author :lyh
  26 + * @method :post
  27 + * @time :2024/6/20 10:49
  28 + */
  29 + public function lists(){
  30 + $oaNoticeModel = new OaNotice();
  31 + $query = $oaNoticeModel->sortOrder($oaNoticeModel,'created_at','desc');
  32 + $query = $this->searchMap($query);
  33 + $lists = $query->paginate($this->row, ['*'], 'page', $this->page)->toArray();
  34 + if(!empty($lists) && !empty($lists['list'])){
  35 + $projectModel = new Project();
  36 + foreach ($lists['list'] as $k => $v){
  37 + $project_str = trim($v['project_str'],',');
  38 + if(strtolower($v['project_str']) != 'all'){
  39 + $v['project_title'] = $projectModel->formatQuery(['id'=>['in',explode(',',$project_str)]])->pluck('title')->toArray();
  40 + }else{
  41 + $v['project_title'] = '所有';
  42 + }
  43 + $v['operator_name'] = (new Manage())->getName($v['operator_id']);
  44 + $lists['list'][$k] = $v;
  45 + }
  46 + }
  47 + $this->response('success',Code::SUCCESS,$lists);
  48 + }
  49 +
  50 +
  51 + /**
  52 + * @remark :参数搜索
  53 + * @name :searchMap
  54 + * @author :lyh
  55 + * @method :post
  56 + * @time :2024/6/20 11:09
  57 + */
  58 + public function searchMap(&$query){
  59 + if(isset($this->map['project_title']) && !empty($this->map['project_title'])){
  60 + $projectModel = new Project();
  61 + $project_id_arr = $projectModel->formatQuery(['title'=>['like','%'.$this->map['project_title'].'%']])->pluck('id')->toArray();
  62 + if(!empty($project_id_arr)){
  63 + $query->where(function ($subQuery) use ($project_id_arr) {
  64 + foreach ($project_id_arr as $v) {
  65 + $subQuery->orWhereRaw("FIND_IN_SET(?, project_str) > 0", [$v]);
  66 + }
  67 + });
  68 + }
  69 + }
  70 + if(isset($this->map['title']) && !empty($this->map['title'])){
  71 + $query->where('title','like','%'.$this->map['title'].'%');
  72 + }
  73 + if(isset($this->map['operator_id']) && !empty($this->map['operator_id'])){
  74 + $query->where('operator_id',$this->map['operator_id']);
  75 + }
  76 + if(isset($this->map['start_time']) && isset($this->map['end_time'])){
  77 + $query->whereBetween('end_time',[$this->map['start_time'],$this->map['end_time']]);
  78 + }
  79 + return $query;
  80 + }
  81 +
  82 + /**
  83 + * @remark :获取详情
  84 + * @name :info
  85 + * @author :lyh
  86 + * @method :post
  87 + * @time :2024/6/20 16:04
  88 + */
  89 + public function info(OaNoticeLogic $oaNoticeLogic){
  90 + $this->request->validate([
  91 + 'id'=>'required',
  92 + ],[
  93 + 'id.required' => 'ID不能为空',
  94 + ]);
  95 + $data = $oaNoticeLogic->infoOaNotice();
  96 + $this->response('success',Code::SUCCESS,$data);
  97 + }
  98 +
  99 + /**
  100 + * @remark :保存数据
  101 + * @name :save
  102 + * @author :lyh
  103 + * @method :post
  104 + * @time :2024/6/20 10:49
  105 + */
  106 + public function save(OaNoticeLogic $oaNoticeLogic){
  107 + $this->request->validate([
  108 + 'project_str'=>'required',
  109 + 'title'=>'required',
  110 + 'remark'=>'required',
  111 + 'start_time'=>'required',
  112 + 'end_time'=>'required',
  113 + ],[
  114 + 'project_str.required' => 'project_str不能为空',
  115 + 'title.required' => 'title不能为空',
  116 + 'remark.required' => 'remark不能为空',
  117 + 'start_time.required' => 'start_time不能为空',
  118 + 'end_time.required' => 'end_time不能为空',
  119 + ]);
  120 + $data = $oaNoticeLogic->saveOaNotice();
  121 + $this->response('success',Code::SUCCESS,$data);
  122 + }
  123 +
  124 + /**
  125 + * @remark :修改状态
  126 + * @name :status
  127 + * @author :lyh
  128 + * @method :post
  129 + * @time :2024/6/20 10:50
  130 + */
  131 + public function status(OaNoticeLogic $oaNoticeLogic){
  132 + $this->request->validate([
  133 + 'id'=>'required',
  134 + 'status'=>'required'
  135 + ],[
  136 + 'id.required' => 'ID不能为空',
  137 + 'status.required' => 'status不能为空'
  138 + ]);
  139 + $data = $oaNoticeLogic->statusOaNotice();
  140 + $this->response('success',Code::SUCCESS,$data);
  141 + }
  142 +}
@@ -229,6 +229,9 @@ class OptimizeController extends BaseController @@ -229,6 +229,9 @@ class OptimizeController extends BaseController
229 if(isset($this->map['special'])){ 229 if(isset($this->map['special'])){
230 $query = $query->whereRaw("FIND_IN_SET(?, gl_project_deploy_optimize.special) > 0", [$this->map['special']]); 230 $query = $query->whereRaw("FIND_IN_SET(?, gl_project_deploy_optimize.special) > 0", [$this->map['special']]);
231 } 231 }
  232 + if(isset($this->map['search'])){
  233 + $query = $query->where('gl_project_deploy_optimize.ai_video', 1);
  234 + }
232 if(isset($this->map['is_remain_today'])){ 235 if(isset($this->map['is_remain_today'])){
233 $query = $query->where('gl_project.is_remain_today',$this->map['is_remain_today']); 236 $query = $query->where('gl_project.is_remain_today',$this->map['is_remain_today']);
234 } 237 }
@@ -8,6 +8,7 @@ use App\Helper\Common; @@ -8,6 +8,7 @@ use App\Helper\Common;
8 use App\Http\Controllers\Bside\BaseController; 8 use App\Http\Controllers\Bside\BaseController;
9 use App\Jobs\PurchaserJob; 9 use App\Jobs\PurchaserJob;
10 use App\Models\CustomModule\CustomModule; 10 use App\Models\CustomModule\CustomModule;
  11 +use App\Models\OaNotice\OaNotice;
11 use App\Models\Project\DeployBuild; 12 use App\Models\Project\DeployBuild;
12 use App\Models\Project\Project; 13 use App\Models\Project\Project;
13 use App\Models\RouteMap\RouteMap; 14 use App\Models\RouteMap\RouteMap;
@@ -325,4 +326,21 @@ class ComController extends BaseController @@ -325,4 +326,21 @@ class ComController extends BaseController
325 $this->response('success',Code::SUCCESS,$data); 326 $this->response('success',Code::SUCCESS,$data);
326 } 327 }
327 328
  329 + /**
  330 + * @remark :获取通知信息
  331 + * @name :getNoticeInfo
  332 + * @author :lyh
  333 + * @method :post
  334 + * @time :2024/6/20 16:49
  335 + */
  336 + public function getNoticeInfo(){
  337 + $oaNoticeModel = new OaNotice();
  338 + $this->map['start_time'] = ['<=',date('Y-m-d H:i:s')];
  339 + $this->map['end_time'] = ['>=',date('Y-m-d H:i:s')];
  340 + $this->map['status'] = 0;
  341 + $this->map['project_str'] = ['like','%,'.$this->user['project_id'].',%'];
  342 + $lists = $oaNoticeModel->formatQuery($this->map)->orWhere('project_str', 'all')->select(['*'])->orderBy($this->order,'desc')->paginate($this->row, ['*'], 'page', $this->page);
  343 + $this->response('success',Code::SUCCESS,$lists);
  344 + }
  345 +
328 } 346 }
@@ -197,14 +197,11 @@ class ImageController extends Controller @@ -197,14 +197,11 @@ class ImageController extends Controller
197 if($image_hash !== false){ 197 if($image_hash !== false){
198 return $this->response('图片资源',Code::SUCCESS,$this->responseData($image_hash['path'], $name)); 198 return $this->response('图片资源',Code::SUCCESS,$this->responseData($image_hash['path'], $name));
199 } 199 }
200 - //保存路径  
201 - $url = $this->config['root'].$this->path;  
202 $image_type = $files->getClientOriginalExtension(); 200 $image_type = $files->getClientOriginalExtension();
203 if(strlen($image_type) > 7){ 201 if(strlen($image_type) > 7){
204 $this->response('不支持当前格式',Code::SYSTEM_ERROR); 202 $this->response('不支持当前格式',Code::SYSTEM_ERROR);
205 } 203 }
206 $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0); 204 $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0);
207 -  
208 //上传到cos 205 //上传到cos
209 if($this->upload_location == 0){ 206 if($this->upload_location == 0){
210 $cosService = new CosService(); 207 $cosService = new CosService();
@@ -321,36 +318,39 @@ class ImageController extends Controller @@ -321,36 +318,39 @@ class ImageController extends Controller
321 private function multi(&$files) { 318 private function multi(&$files) {
322 $data = []; 319 $data = [];
323 foreach ($files as $file) { 320 foreach ($files as $file) {
324 - $imageModel = new ImageModel();  
325 - $hash = hash_file('sha256', $file->getPathname());  
326 - $name = $file->getClientOriginalName();  
327 - //查看图片是否已上传  
328 - $param = ['hash'=>$hash,'refer'=>$this->param['refer'] ?? 0,'is_cos'=>(($this->upload_location == 0) ? 1 : 0)];  
329 - if(isset($this->cache['project_id']) && !empty($this->cache['project_id'])){  
330 - $param['project_id'] = $this->cache['project_id'];  
331 - }  
332 - $image_hash = $imageModel->read($param);  
333 - if($image_hash !== false){  
334 - $data[] = $this->responseData($image_hash['path'],$image_hash['name']);  
335 - continue;  
336 - }  
337 - $image_type = $file->getClientOriginalExtension();  
338 - $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0);  
339 - //同步数据到cos  
340 - if($this->upload_location == 0){  
341 - $cosService = new CosService();  
342 - $cosService->uploadFile($file,$this->path,$fileName);  
343 - }else{  
344 - //TODO::上传亚马逊  
345 - $amazonS3Service = new AmazonS3Service();  
346 - $amazonS3Service->uploadFiles($file,$this->path,$fileName); 321 + try {
  322 + $hash = hash_file('sha256', $file->getPathname());
  323 + $imageModel = new ImageModel();
  324 + //查看图片是否已上传
  325 + $param = ['hash'=>$hash,'refer'=>$this->param['refer'] ?? 0,'is_cos'=>(($this->upload_location == 0) ? 1 : 0)];
  326 + if(isset($this->cache['project_id']) && !empty($this->cache['project_id'])){
  327 + $param['project_id'] = $this->cache['project_id'];
  328 + }
  329 + $image_hash = $imageModel->read($param);
  330 + if($image_hash !== false){
  331 + $data[] = $this->responseData($image_hash['path'],$image_hash['name']);
  332 + continue;
  333 + }
  334 + $name = $file->getClientOriginalName();
  335 + $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0);
  336 + $image_type = $file->getClientOriginalExtension();
  337 + $this->saveMysql($imageModel,$file->getSize(),$image_type,$fileName,$hash,$this->upload_location,$file->getMimeType(),$name);
  338 + //同步数据到cos
  339 + if($this->upload_location == 0){
  340 + $cosService = new CosService();
  341 + $cosService->uploadFile($file,$this->path,$fileName);
  342 + }else{
  343 + //TODO::上传亚马逊
  344 + $amazonS3Service = new AmazonS3Service();
  345 + $amazonS3Service->uploadFiles($file,$this->path,$fileName);
  346 + }
  347 + $this->synchronizationImage($fileName,$this->upload_location);
  348 + $data[] = $this->responseData($this->path.'/'.$fileName,$name);
  349 + }catch (\Exception $e){
  350 + $this->response('图片资源',Code::SUCCESS,$data);
347 } 351 }
348 - //批量存储  
349 - $this->saveMysql($imageModel,$file->getSize(),$image_type,$fileName,$hash,$this->upload_location,$file->getMimeType(),$name);  
350 - $this->synchronizationImage($fileName,$this->upload_location);  
351 - $data[] = $this->responseData($this->path.'/'.$fileName,$name);  
352 } 352 }
353 - $this->response('图片资源',Code::SUCCESS,$data); 353 + $this->response('图片资源',Code::SUCCESS,$data);
354 } 354 }
355 355
356 /** 356 /**
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :OaNoticeLogic.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/6/20 10:48
  8 + */
  9 +
  10 +namespace App\Http\Logic\Aside\Com;
  11 +
  12 +use App\Http\Logic\Aside\BaseLogic;
  13 +use App\Models\Manage\Manage;
  14 +use App\Models\OaNotice\OaNotice;
  15 +use App\Models\Project\Project;
  16 +
  17 +class OaNoticeLogic extends BaseLogic
  18 +{
  19 + /**
  20 + * 初始数据
  21 + */
  22 + public function __construct()
  23 + {
  24 + parent::__construct();
  25 + $this->model = new OaNotice();
  26 + $this->param = $this->requestAll;
  27 + }
  28 +
  29 + /**
  30 + * @remark :保存数据
  31 + * @name :saveOaNotice
  32 + * @author :lyh
  33 + * @method :post
  34 + * @time :2024/6/20 15:03
  35 + */
  36 + public function saveOaNotice(){
  37 + $this->param['operator_id'] = $this->manager['id'];
  38 + $project_str = trim($this->param['project_str'],',');
  39 + if($project_str != 'all'){
  40 + $this->param['project_str'] = ','.$project_str.',';
  41 + }
  42 + if(isset($this->param['id']) && !empty($this->param['id'])){
  43 + $id = $this->param['id'];
  44 + $this->model->edit($this->param,['id'=>$id]);
  45 + }else{
  46 + $id = $this->model->addReturnId($this->param);
  47 + }
  48 + return $this->success(['id'=>$id]);
  49 + }
  50 +
  51 + /**
  52 + * @remark :修改状态
  53 + * @name :statusOaNotice
  54 + * @author :lyh
  55 + * @method :post
  56 + * @time :2024/6/20 15:44
  57 + */
  58 + public function statusOaNotice(){
  59 + $id = $this->param['id'];
  60 + $this->model->edit(['status'=>$this->param['status']],['id'=>$id]);
  61 + return $this->success(['id'=>$id]);
  62 + }
  63 +
  64 + /**
  65 + * @remark :获取详情
  66 + * @name :infoOaNotice
  67 + * @author :lyh
  68 + * @method :post
  69 + * @time :2024/6/20 16:04
  70 + */
  71 + public function infoOaNotice(){
  72 + $info = $this->model->read($this->param);
  73 + if($info == false){
  74 + $this->fail('当前数据不存在或已被删除');
  75 + }
  76 + $info['project_str'] = trim($info['project_str'],',');
  77 + if(strtolower($info['project_str']) != 'all'){
  78 + $projectModel = new Project();
  79 + $info['project_title'] = $projectModel->formatQuery(['id'=>['in',explode(',',$info['project_str'])]])->pluck('title')->toArray();
  80 + }else{
  81 + $info['project_title'] = '所有';
  82 + }
  83 + $info['operator_name'] = (new Manage())->getName($info['operator_id']);
  84 + return $this->success($info);
  85 + }
  86 +}
@@ -622,6 +622,7 @@ class ProjectLogic extends BaseLogic @@ -622,6 +622,7 @@ class ProjectLogic extends BaseLogic
622 $data['level'] = $this->model::levelMap(); 622 $data['level'] = $this->model::levelMap();
623 $data['type'] = $this->model::typeMap(); 623 $data['type'] = $this->model::typeMap();
624 $data['special'] = $this->model::specialMap(); 624 $data['special'] = $this->model::specialMap();
  625 + $data['search'] = $this->model::searchParam();
625 $data['plan'] = $this->model::planMap(); 626 $data['plan'] = $this->model::planMap();
626 return $this->success($data); 627 return $this->success($data);
627 } 628 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :OaNotice.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/6/20 10:44
  8 + */
  9 +
  10 +namespace App\Models\OaNotice;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +/**
  15 + * @remark :oa通知消息
  16 + * @name :OaNotice
  17 + * @author :lyh
  18 + * @method :post
  19 + * @time :2024/6/20 10:44
  20 + */
  21 +class OaNotice extends Base
  22 +{
  23 + protected $table = 'gl_oa_notice';
  24 +}
@@ -92,6 +92,13 @@ class Project extends Base @@ -92,6 +92,13 @@ class Project extends Base
92 ]; 92 ];
93 } 93 }
94 94
  95 + /**
  96 + * @remark :优化搜索参数
  97 + * @name :specialMap
  98 + * @author :lyh
  99 + * @method :post
  100 + * @time :2024/6/21 16:23
  101 + */
95 public static function specialMap() 102 public static function specialMap()
96 { 103 {
97 return [ 104 return [
@@ -109,10 +116,21 @@ class Project extends Base @@ -109,10 +116,21 @@ class Project extends Base
109 12 => 'AI', 116 12 => 'AI',
110 13 => 'AI站群', 117 13 => 'AI站群',
111 14 => '未达标', 118 14 => '未达标',
112 - 15 => 'AI视频'  
113 ]; 119 ];
114 } 120 }
115 121
  122 + /**
  123 + * @remark :新增搜索
  124 + * @name :searchParam
  125 + * @author :lyh
  126 + * @method :post
  127 + * @time :2024/6/21 16:23
  128 + */
  129 + public static function searchParam(){
  130 + return [
  131 + 1 => 'AI视频',
  132 + ];
  133 + }
116 134
117 /** 135 /**
118 * 项目部署服务器信息 136 * 项目部署服务器信息
@@ -414,6 +414,14 @@ Route::middleware(['aloginauth'])->group(function () { @@ -414,6 +414,14 @@ Route::middleware(['aloginauth'])->group(function () {
414 Route::any('/del', [Aside\Com\TutorialController::class, 'del'])->name('admin.tutorial_del'); 414 Route::any('/del', [Aside\Com\TutorialController::class, 'del'])->name('admin.tutorial_del');
415 }); 415 });
416 416
  417 + //oa通知
  418 + Route::prefix('oa_notice')->group(function () {
  419 + Route::any('/', [Aside\Com\OaNoticeController::class, 'lists'])->name('admin.oa_notice_lists');
  420 + Route::any('/save', [Aside\Com\OaNoticeController::class, 'save'])->name('admin.oa_notice_save');
  421 + Route::any('/status', [Aside\Com\OaNoticeController::class, 'status'])->name('admin.oa_notice_status');
  422 + Route::any('/info', [Aside\Com\OaNoticeController::class, 'info'])->name('admin.oa_notice_info');
  423 + });
  424 +
417 Route::any('/generate_aicc_token', [Aside\Com\IndexController::class, 'generateAiCCToken'])->name('admin.generate_aicc_token'); 425 Route::any('/generate_aicc_token', [Aside\Com\IndexController::class, 'generateAiCCToken'])->name('admin.generate_aicc_token');
418 Route::any('/getAutoToken', [Aside\Com\IndexController::class, 'getAutoToken'])->name('admin.getAutoToken'); 426 Route::any('/getAutoToken', [Aside\Com\IndexController::class, 'getAutoToken'])->name('admin.getAutoToken');
419 427
@@ -20,6 +20,7 @@ Route::middleware(['bloginauth'])->group(function () { @@ -20,6 +20,7 @@ Route::middleware(['bloginauth'])->group(function () {
20 Route::any('/generateToken', [\App\Http\Controllers\Bside\BCom\ComController::class, 'generateToken'])->name('generateToken'); 20 Route::any('/generateToken', [\App\Http\Controllers\Bside\BCom\ComController::class, 'generateToken'])->name('generateToken');
21 Route::any('/getLink', [\App\Http\Controllers\Bside\BCom\ComController::class, 'getLink'])->name('getLink'); 21 Route::any('/getLink', [\App\Http\Controllers\Bside\BCom\ComController::class, 'getLink'])->name('getLink');
22 Route::any('/getMobileProject', [\App\Http\Controllers\Bside\BCom\ComController::class, 'getMobileProject'])->name('getMobileProject'); 22 Route::any('/getMobileProject', [\App\Http\Controllers\Bside\BCom\ComController::class, 'getMobileProject'])->name('getMobileProject');
  23 + Route::any('/getNoticeInfo', [\App\Http\Controllers\Bside\BCom\ComController::class, 'getNoticeInfo'])->name('getNoticeInfo');
23 //黑格数据 24 //黑格数据
24 Route::prefix('suppliers')->group(function () { 25 Route::prefix('suppliers')->group(function () {
25 Route::any('/recommendedPurchaser', [\App\Http\Controllers\Bside\Suppliers\SuppliersController::class, 'recommendedPurchaser'])->name('suppliers_recommendedPurchaser'); 26 Route::any('/recommendedPurchaser', [\App\Http\Controllers\Bside\Suppliers\SuppliersController::class, 'recommendedPurchaser'])->name('suppliers_recommendedPurchaser');