正在显示
35 个修改的文件
包含
0 行增加
和
4841 行删除
.editorconfig
已删除
100644 → 0
| 1 | -root = true | ||
| 2 | - | ||
| 3 | -[*] | ||
| 4 | -charset = utf-8 | ||
| 5 | -end_of_line = lf | ||
| 6 | -insert_final_newline = true | ||
| 7 | -indent_style = space | ||
| 8 | -indent_size = 4 | ||
| 9 | -trim_trailing_whitespace = true | ||
| 10 | - | ||
| 11 | -[*.md] | ||
| 12 | -trim_trailing_whitespace = false | ||
| 13 | - | ||
| 14 | -[*.{yml,yaml}] | ||
| 15 | -indent_size = 2 | ||
| 16 | - | ||
| 17 | -[docker-compose.yml] | ||
| 18 | -indent_size = 4 |
.env.development
已删除
100644 → 0
| 1 | -APP_NAME=Laravel | ||
| 2 | -APP_ENV=development | ||
| 3 | -APP_KEY=base64:+ouoKlz2sFDOisnROMRpxT/u9xkZJVrXlzP4cfTqPow= | ||
| 4 | -APP_DEBUG=false | ||
| 5 | -APP_URL=http://localhost | ||
| 6 | - | ||
| 7 | -LOG_CHANNEL=stack | ||
| 8 | -LOG_DEPRECATIONS_CHANNEL=null | ||
| 9 | -LOG_LEVEL=debug | ||
| 10 | - | ||
| 11 | -DB_CONNECTION=mysql | ||
| 12 | -DB_HOST=127.0.0.1 | ||
| 13 | -DB_PORT=3306F | ||
| 14 | -DB_DATABASE=globalso | ||
| 15 | -DB_USERNAME=debian-sys-maint | ||
| 16 | -DB_PASSWORD=WtujxV73XIclQet0 | ||
| 17 | - | ||
| 18 | -BROADCAST_DRIVER=log | ||
| 19 | -CACHE_DRIVER=file | ||
| 20 | -FILESYSTEM_DRIVER=local | ||
| 21 | -QUEUE_CONNECTION=sync | ||
| 22 | -SESSION_DRIVER=file | ||
| 23 | -SESSION_LIFETIME=120 | ||
| 24 | - | ||
| 25 | -MEMCACHED_HOST=127.0.0.1 | ||
| 26 | - | ||
| 27 | -REDIS_HOST=127.0.0.1 | ||
| 28 | -REDIS_PASSWORD=null | ||
| 29 | -REDIS_PORT=6379 | ||
| 30 | - | ||
| 31 | -MAIL_MAILER=smtp | ||
| 32 | -MAIL_HOST=mailhog | ||
| 33 | -MAIL_PORT=1025 | ||
| 34 | -MAIL_USERNAME=null | ||
| 35 | -MAIL_PASSWORD=null | ||
| 36 | -MAIL_ENCRYPTION=null | ||
| 37 | -MAIL_FROM_ADDRESS=null | ||
| 38 | -MAIL_FROM_NAME="${APP_NAME}" | ||
| 39 | - | ||
| 40 | -AWS_ACCESS_KEY_ID= | ||
| 41 | -AWS_SECRET_ACCESS_KEY= | ||
| 42 | -AWS_DEFAULT_REGION=us-east-1 | ||
| 43 | -AWS_BUCKET= | ||
| 44 | -AWS_USE_PATH_STYLE_ENDPOINT=false | ||
| 45 | - | ||
| 46 | -PUSHER_APP_ID= | ||
| 47 | -PUSHER_APP_KEY= | ||
| 48 | -PUSHER_APP_SECRET= | ||
| 49 | -PUSHER_APP_CLUSTER=mt1 | ||
| 50 | - | ||
| 51 | -MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" | ||
| 52 | -MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" |
.env.production
已删除
100644 → 0
| 1 | -APP_NAME=Laravel | ||
| 2 | -APP_ENV=local | ||
| 3 | -APP_KEY=base64:+ouoKlz2sFDOisnROMRpxT/u9xkZJVrXlzP4cfTqPow= | ||
| 4 | -APP_DEBUG=false | ||
| 5 | -APP_URL=http://localhost | ||
| 6 | - | ||
| 7 | -LOG_CHANNEL=stack | ||
| 8 | -LOG_DEPRECATIONS_CHANNEL=null | ||
| 9 | -LOG_LEVEL=debug | ||
| 10 | - | ||
| 11 | -DB_CONNECTION=mysql | ||
| 12 | -DB_HOST=127.0.0.1 | ||
| 13 | -DB_PORT=3306 | ||
| 14 | -DB_DATABASE=globalso | ||
| 15 | -DB_USERNAME=debian-sys-maint | ||
| 16 | -DB_PASSWORD=WtujxV73XIclQet0 | ||
| 17 | - | ||
| 18 | -BROADCAST_DRIVER=log | ||
| 19 | -CACHE_DRIVER=file | ||
| 20 | -FILESYSTEM_DRIVER=local | ||
| 21 | -QUEUE_CONNECTION=sync | ||
| 22 | -SESSION_DRIVER=file | ||
| 23 | -SESSION_LIFETIME=120 | ||
| 24 | - | ||
| 25 | -MEMCACHED_HOST=127.0.0.1 | ||
| 26 | - | ||
| 27 | -REDIS_HOST=127.0.0.1 | ||
| 28 | -REDIS_PASSWORD=null | ||
| 29 | -REDIS_PORT=6379 | ||
| 30 | - | ||
| 31 | -MAIL_MAILER=smtp | ||
| 32 | -MAIL_HOST=mailhog | ||
| 33 | -MAIL_PORT=1025 | ||
| 34 | -MAIL_USERNAME=null | ||
| 35 | -MAIL_PASSWORD=null | ||
| 36 | -MAIL_ENCRYPTION=null | ||
| 37 | -MAIL_FROM_ADDRESS=null | ||
| 38 | -MAIL_FROM_NAME="${APP_NAME}" | ||
| 39 | - | ||
| 40 | -AWS_ACCESS_KEY_ID= | ||
| 41 | -AWS_SECRET_ACCESS_KEY= | ||
| 42 | -AWS_DEFAULT_REGION=us-east-1 | ||
| 43 | -AWS_BUCKET= | ||
| 44 | -AWS_USE_PATH_STYLE_ENDPOINT=false | ||
| 45 | - | ||
| 46 | -PUSHER_APP_ID= | ||
| 47 | -PUSHER_APP_KEY= | ||
| 48 | -PUSHER_APP_SECRET= | ||
| 49 | -PUSHER_APP_CLUSTER=mt1 | ||
| 50 | - | ||
| 51 | -MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" | ||
| 52 | -MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" |
.gitattributes
已删除
100644 → 0
.gitignore
已删除
100644 → 0
| 1 | -/node_modules | ||
| 2 | -/public/hot | ||
| 3 | -/public/storage | ||
| 4 | -/public/.user.ini | ||
| 5 | -/storage | ||
| 6 | -/vendor | ||
| 7 | -/uploads | ||
| 8 | -composer.lock | ||
| 9 | -.env | ||
| 10 | -.env.backup | ||
| 11 | -.phpunit.result.cache | ||
| 12 | -docker-compose.override.yml | ||
| 13 | -Homestead.json | ||
| 14 | -Homestead.yaml | ||
| 15 | -npm-debug.log | ||
| 16 | -yarn-error.log | ||
| 17 | -/.idea | ||
| 18 | -/.vscode | ||
| 19 | -composer.lock | ||
| 20 | -app/Console/Commands/Test/DataRecovery.php | ||
| 21 | -/public/upload | ||
| 22 | -/public/runtime | ||
| 23 | -public/nginx.htaccess | ||
| 24 | -public/.htaccess | ||
| 25 | -.gitignore |
.htaccess
已删除
100755 → 0
| 1 | - |
.styleci.yml
已删除
100644 → 0
404.html
已删除
100755 → 0
README.md
已删除
100644 → 0
| 1 | -# 基础框架 - 后端管理系统 | ||
| 2 | -## 路由 | ||
| 3 | -### 路由提供者Provider中预定义两个路由 | ||
| 4 | -- bside 代表B端用户访问路由 完整路由:{{url}}/a/xxx | ||
| 5 | -- aside 代表管理员访问路由 完整路由:{{url}}/b/xxx | ||
| 6 | - | ||
| 7 | -## 枚举 | ||
| 8 | -### 使用插件bensampo/laravel-enum 版本4 github地址:https://github.com/BenSampo/laravel-enum/blob/v4.2.0/README.md | ||
| 9 | -- 创建枚举类 : php artisan make:enum ”文件名“ | ||
| 10 | -- 给枚举类生成注释: php artisan enum:annotate "文件名" | ||
| 11 | -- 如有翻译本地化需求,在 resources/lang/zh-CN/enums.php文件中中文翻译,英文语言包不用写,会自动翻译键名 | ||
| 12 | -- 在验证器中使用 : '参数名' => ['required ', new EnumValue(CaptchaType::class)],(或者按照键名new EnumKey) | ||
| 13 | -- 可参考Enums/Common/Common.php枚举类 | ||
| 14 | - | ||
| 15 | -## 状态码 | ||
| 16 | -- 该系统所有状态码都定义在 App\Enums\Commom\Code枚举类中 | ||
| 17 | -- 大大类 和 大类不能变动 ,以大类为基准步长为100,根据业务自定义状态码 | ||
| 18 | - | ||
| 19 | -## 中间件 | ||
| 20 | -- 登录验证中间件 ”loginauth“ | ||
| 21 | -- Bside路由默认已经使用的中间件组为bside | ||
| 22 | -- Aside路由默认已经使用的中间件组为aside | ||
| 23 | - | ||
| 24 | -## 参数加密 | ||
| 25 | -- .env文件中有三个配置,其中iv必须是八位 | ||
| 26 | -- 参数加密不开启的时候,前端正常传入参数,是明文不安全 | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -## 控制器 | ||
| 30 | -- 各个端控制器目录:App\Http\Controllers\XXXside | ||
| 31 | -- BaseController基础控制器,需要被其他控制器继承 | ||
| 32 | -- 控制器中只需要干三件事情: | ||
| 33 | - 第一,验证参数(如果注入了自定义验证Request就可以省略$request->validate这一步) | ||
| 34 | - 第二,调用逻辑层Logic | ||
| 35 | - 第三,success返回---错误直接走异常处理 | ||
| 36 | - | ||
| 37 | -## 请求and响应 | ||
| 38 | -- 控制器方法注入请求Illuminate\Http\Request或者注入自定义请求表单 | ||
| 39 | -- 创建请求表单: php artisan make:request 文件名 | ||
| 40 | -- 请求表单中定义,用户是否有权限请求以及参数验证规则 | ||
| 41 | -- 控制器中调用request->validated() | ||
| 42 | -- 响应只能调用BaseController的success()方法 | ||
| 43 | -> 注意!全站返回不能编写自定义的message,只能通过Code码 | ||
| 44 | - | ||
| 45 | -## 逻辑层 | ||
| 46 | -- App\Http\Logic逻辑层只能被控制器调用 | ||
| 47 | -- 要继承基类BaseLogic,return 使用基类定义的方法 | ||
| 48 | -## 错误截获 | ||
| 49 | -- 自定义某端全局异常:App\Exceptions\XXXsideGlobalException,throw new XXXsideGlobalException($code); 注意也只能传入Code码 | ||
| 50 | - | ||
| 51 | -> 注意!.env文件APP_DEBUG控制是否显示详细错误信息,否则就按照本地化的错误码的message来显示 | ||
| 52 | - | ||
| 53 | -## 日志规范 | ||
| 54 | -- 配置文件logging.php中预定义了B端错误日志bside | ||
| 55 | -- 日志格式:logs -> bside(端)-> 2022-06(年月)-> 日期_级别.log (预定义了两个级别 errors和info) | ||
| 56 | -- errors错误日志会在异常抛出的时候自动记录,info手动调用 | ||
| 57 | -- 共工具类App\Utils\LogUtils 提供了两个方法errorBside,infoBside记录日志 | ||
| 58 | - | ||
| 59 | -## 数据迁移 | ||
| 60 | -- 每个版本的迭代如有数据结构修改,必须写到数据迁移里面 | ||
| 61 | -- 创建迁移 :php artisan make:migration create_users_table --create=users 或者 php artisan make:migration | ||
| 62 | - add_votes_to_users_table --table=users (--create是创建表 --table是编辑表) | ||
| 63 | -- 编写迁移脚本 | ||
| 64 | -- 执行迁移: php artisan migrate | ||
| 65 | - | ||
| 66 | -## 数据填充 | ||
| 67 | -- 每个版本的迭代如有数据预设置,必须写到数据填充里面 | ||
| 68 | -- 创建填充 : php artisan make:seeder 文件名 | ||
| 69 | -- 如果是简单的直接在seeder文件的run()方法中写insert | ||
| 70 | -- 如果较复杂需要编写模型工厂:php artisan make:factory UserFactory | ||
| 71 | -- 执行填充 : composer dump-autoload (用来重新生成composer映射) ,php artisan db:seed | ||
| 72 | - | ||
| 73 | -## Redis | ||
| 74 | -- 配置文件database.php中的redis | ||
| 75 | -- 所有使用到的键名需要在枚举类中定义:App\Enums\Common\RedisKey | ||
| 76 | -- 工具类App\Utils\RedisUtils中提供了获取redis实例的方法 | ||
| 77 | -- traits文件App\Traits\RedisTraits中,定义了常用的redis方法,使用的时候只需要: use RedisTrait; |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogAuthorId.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/5/26 15:57 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Com\Notify; | ||
| 14 | -use App\Models\Devops\ServerConfig; | ||
| 15 | -use App\Models\Devops\ServersIp; | ||
| 16 | -use App\Models\Domain\DomainInfo; | ||
| 17 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 18 | -use App\Models\Ai\AiBlogAuthor as AiBlogAuthorModel; | ||
| 19 | -use App\Models\Project\Project; | ||
| 20 | -use App\Services\AiBlogService; | ||
| 21 | -use App\Services\ProjectServer; | ||
| 22 | -use Illuminate\Console\Command; | ||
| 23 | -use Illuminate\Support\Facades\DB; | ||
| 24 | -use Illuminate\Support\Facades\Redis; | ||
| 25 | - | ||
| 26 | -class AiBlogAuthorId extends Command | ||
| 27 | -{ | ||
| 28 | - /** | ||
| 29 | - * The name and signature of the console command. | ||
| 30 | - * | ||
| 31 | - * @var string | ||
| 32 | - */ | ||
| 33 | - protected $signature = 'save_ai_blog_author_id'; | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | - * The console command description. | ||
| 37 | - * | ||
| 38 | - * @var string | ||
| 39 | - */ | ||
| 40 | - protected $description = '拉取对应作者的页面'; | ||
| 41 | - | ||
| 42 | - public $route = []; | ||
| 43 | - | ||
| 44 | - public function handle(){ | ||
| 45 | - while (true){ | ||
| 46 | - //获取任务id | ||
| 47 | - $task_id = $this->getTaskId(); | ||
| 48 | - if(empty($task_id)){ | ||
| 49 | - sleep(300); | ||
| 50 | - continue; | ||
| 51 | - } | ||
| 52 | - $this->_action($task_id); | ||
| 53 | - } | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - public function getTaskId() | ||
| 57 | - { | ||
| 58 | - $task_id = Redis::rpop('ai_blog_author_id'); | ||
| 59 | - if (empty($task_id)) { | ||
| 60 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 61 | - $ids = $aiBlogTaskModel->formatQuery(['status'=>$aiBlogTaskModel::STATUS_RUNNING, 'type'=>$aiBlogTaskModel::TYPE_AUTHOR_ID])->pluck('id'); | ||
| 62 | - if(!empty($ids)){ | ||
| 63 | - foreach ($ids as $id) { | ||
| 64 | - Redis::lpush('ai_blog_author_id', $id); | ||
| 65 | - } | ||
| 66 | - } | ||
| 67 | - $task_id = Redis::rpop('ai_blog_author_id'); | ||
| 68 | - } | ||
| 69 | - return $task_id; | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - /** | ||
| 73 | - * @remark :执行方法 | ||
| 74 | - * @name :_action | ||
| 75 | - * @author :lyh | ||
| 76 | - * @method :post | ||
| 77 | - * @time :2025/5/26 16:06 | ||
| 78 | - */ | ||
| 79 | - public function _action($task_id){ | ||
| 80 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 81 | - $item = $aiBlogTaskModel->read(['id'=>$task_id]); | ||
| 82 | - if($item === false){ | ||
| 83 | - echo '当前数据不存在.'.$item['id'].PHP_EOL; | ||
| 84 | - return true; | ||
| 85 | - } | ||
| 86 | - $aiBlogService = new AiBlogService($item['project_id']); | ||
| 87 | - ProjectServer::useProject($item['project_id']); | ||
| 88 | - $aiBlogService->author_id = $item['task_id']; | ||
| 89 | - $result = $aiBlogService->getAuthorDetail(); | ||
| 90 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 91 | - //当前作者的页面 | ||
| 92 | - $aiBlogAuthorModel = new AiBlogAuthorModel(); | ||
| 93 | - $authorInfo = $aiBlogAuthorModel->read(['author_id'=>$item['task_id']],['id','route']); | ||
| 94 | - if($authorInfo !== false && !empty($result['data']['section'])){ | ||
| 95 | - $this->route[] = $authorInfo['route']; | ||
| 96 | - $aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$item['task_id']]); | ||
| 97 | - } | ||
| 98 | - } | ||
| 99 | - DB::disconnect('custom_mysql'); | ||
| 100 | - $aiBlogTaskModel->edit(['status'=>2],['id'=>$task_id]); | ||
| 101 | - $this->sendCPost($item['project_id']); | ||
| 102 | - return true; | ||
| 103 | - } | ||
| 104 | - | ||
| 105 | - /** | ||
| 106 | - * @remark :通知C端 | ||
| 107 | - * @name :sendCPost | ||
| 108 | - * @author :lyh | ||
| 109 | - * @method :post | ||
| 110 | - * @time :2025/5/26 16:21 | ||
| 111 | - */ | ||
| 112 | - public function sendCPost($project_id){ | ||
| 113 | - //获取项目所在服务器 | ||
| 114 | - $project_model = new Project(); | ||
| 115 | - $project_info = $project_model->read(['id'=>$project_id],['serve_id','is_upgrade', 'main_lang_id']); | ||
| 116 | - if(!$project_info){ | ||
| 117 | - return false; | ||
| 118 | - } | ||
| 119 | - $serve_ip_model = new ServersIp(); | ||
| 120 | - $serve_ip_info = $serve_ip_model->read(['id'=>$project_info['serve_id']],['servers_id']); | ||
| 121 | - $servers_id = $serve_ip_info ? $serve_ip_info['servers_id'] : 0; | ||
| 122 | - if($servers_id == ServerConfig::SELF_SITE_ID){ | ||
| 123 | - //自建站服务器:如果项目已经上线,不请求C端接口,数据直接入库 | ||
| 124 | - $domain_model = new DomainInfo(); | ||
| 125 | - $domain_info = $domain_model->read(['project_id'=>$project_id],['domain']); | ||
| 126 | - if($domain_info){ | ||
| 127 | - //判断是否已有更新进行中 | ||
| 128 | - $notify_model = new Notify(); | ||
| 129 | - $data = [ | ||
| 130 | - 'project_id' => $project_id, | ||
| 131 | - 'type' => 1, | ||
| 132 | - 'route' => 3, | ||
| 133 | - 'server_id' => ServerConfig::SELF_SITE_ID, | ||
| 134 | - 'status' => ['!=',Notify::STATUS_FINISH_SITEMAP] | ||
| 135 | - ]; | ||
| 136 | - $notify = $notify_model->read($data,['id']); | ||
| 137 | - if(!$notify){ | ||
| 138 | - $domain = $domain_info['domain']; | ||
| 139 | - $data['data'] = Arr::a2s(['domain'=>$domain,'url'=>$this->route,'language'=>[]]); | ||
| 140 | - $data['status'] = Notify::STATUS_INIT; | ||
| 141 | - $data['is_pull_html_zip'] = Notify::IS_PULL_HTML_ZIP_FALSE; | ||
| 142 | - $data['sort'] = 1; | ||
| 143 | - $notify_model->add($data); | ||
| 144 | - } | ||
| 145 | - } | ||
| 146 | - }else{ | ||
| 147 | - $domainModel = new DomainInfo(); | ||
| 148 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 149 | - $c_url = $domain.'api/update_page/'; | ||
| 150 | - $param = [ | ||
| 151 | - 'project_id' => $project_id, | ||
| 152 | - 'type' => 1, | ||
| 153 | - 'route' => 3, | ||
| 154 | - 'url' => $this->route, | ||
| 155 | - 'language'=> [], | ||
| 156 | - 'is_sitemap' => 0 | ||
| 157 | - ]; | ||
| 158 | - $res = http_post($c_url, json_encode($param,true)); | ||
| 159 | - echo 'notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); | ||
| 160 | - } | ||
| 161 | - } | ||
| 162 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogAuthorTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/21 11:12 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiBlog; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 15 | -use App\Models\Project\ProjectAiSetting; | ||
| 16 | -use App\Models\RouteMap\RouteMap; | ||
| 17 | -use App\Services\AiBlogService; | ||
| 18 | -use App\Services\ProjectServer; | ||
| 19 | -use Illuminate\Console\Command; | ||
| 20 | -use Illuminate\Support\Facades\Cache; | ||
| 21 | -use Illuminate\Support\Facades\DB; | ||
| 22 | - | ||
| 23 | -class AiBlogAuthorTask extends Command | ||
| 24 | -{ | ||
| 25 | - /** | ||
| 26 | - * The name and signature of the console command. | ||
| 27 | - * | ||
| 28 | - * @var string | ||
| 29 | - */ | ||
| 30 | - protected $signature = 'save_ai_blog_author'; | ||
| 31 | - | ||
| 32 | - /** | ||
| 33 | - * The console command description. | ||
| 34 | - * | ||
| 35 | - * @var string | ||
| 36 | - */ | ||
| 37 | - protected $description = '查询ai_blog_author是否已经生成'; | ||
| 38 | - | ||
| 39 | - | ||
| 40 | - /** | ||
| 41 | - * @remark :获取作者 | ||
| 42 | - * @name :handle | ||
| 43 | - * @author :lyh | ||
| 44 | - * @method :post | ||
| 45 | - * @time :2025/2/21 11:30 | ||
| 46 | - */ | ||
| 47 | - public function handle(){ | ||
| 48 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 49 | - while (true){ | ||
| 50 | - $info = $aiBlogTaskModel->where('status',1)->where('type',1)->inRandomOrder()->first(); | ||
| 51 | - if(empty($info)){ | ||
| 52 | - sleep(300); | ||
| 53 | - continue; | ||
| 54 | - } | ||
| 55 | - $info = $info->toArray(); | ||
| 56 | - echo date('Y-m-d H:i:s').'开始->project_id:' . $info['project_id'] . PHP_EOL; | ||
| 57 | - //获取配置 | ||
| 58 | - $aiSettingInfo = $this->getSetting($info['project_id']); | ||
| 59 | - if(empty($aiSettingInfo)){ | ||
| 60 | - continue; | ||
| 61 | - } | ||
| 62 | - $aiBlogService = new AiBlogService(); | ||
| 63 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 64 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 65 | - $result = $aiBlogService->getAuthor(); | ||
| 66 | - if(!isset($result['status'])){ | ||
| 67 | - echo '错误:'.json_encode($result,true); | ||
| 68 | - continue; | ||
| 69 | - } | ||
| 70 | - if($result['status'] != 200){ | ||
| 71 | - sleep(10); | ||
| 72 | - continue; | ||
| 73 | - } | ||
| 74 | - if(empty($result['data'])){ | ||
| 75 | - echo '没有作者任务-'.PHP_EOL; | ||
| 76 | - continue; | ||
| 77 | - } | ||
| 78 | - //保存当前项目ai_blog数据 | ||
| 79 | - ProjectServer::useProject($info['project_id']); | ||
| 80 | - $this->saveAiBlogAuthor($result['data'] ?? [],$info['project_id']); | ||
| 81 | - RouteMap::setRoute('top-blog',RouteMap::SOURCE_AI_BLOG_LIST,0,$info['project_id']);//写一条列表页路由 | ||
| 82 | - RouteMap::setRoute('top-video',RouteMap::SOURCE_AI_VIDEO_LIST,0,$info['project_id']);//写一条列表页路由 | ||
| 83 | - DB::disconnect('custom_mysql'); | ||
| 84 | - //修改任务状态 | ||
| 85 | - $aiBlogTaskModel->edit(['status'=>2],['id'=>$info['id']]); | ||
| 86 | - echo date('Y-m-d H:i:s').'结束->任务id:' . $info['id'] . PHP_EOL; | ||
| 87 | - } | ||
| 88 | - return true; | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - /** | ||
| 93 | - * @remark :获取项目配置 | ||
| 94 | - * @name :getSetting | ||
| 95 | - * @author :lyh | ||
| 96 | - * @method :post | ||
| 97 | - * @time :2025/2/14 11:27 | ||
| 98 | - */ | ||
| 99 | - public function getSetting($project_id){ | ||
| 100 | - $ai_cache = Cache::get('ai_blog_'.$project_id); | ||
| 101 | - if($ai_cache){ | ||
| 102 | - return $ai_cache; | ||
| 103 | - } | ||
| 104 | - $projectAiSettingModel = new ProjectAiSetting(); | ||
| 105 | - $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); | ||
| 106 | - Cache::put('ai_blog_'.$project_id,$aiSettingInfo,3600); | ||
| 107 | - return $aiSettingInfo; | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - /** | ||
| 111 | - * @remark :保存数据 | ||
| 112 | - * @name :saveAiBlogAuthor | ||
| 113 | - * @author :lyh | ||
| 114 | - * @method :post | ||
| 115 | - * @time :2025/2/21 11:36 | ||
| 116 | - */ | ||
| 117 | - public function saveAiBlogAuthor($data,$project_id){ | ||
| 118 | - if(empty($data)){ | ||
| 119 | - return true; | ||
| 120 | - } | ||
| 121 | - $aiBlogAuthorModel = new AiBlogAuthor(); | ||
| 122 | - foreach ($data as $v){ | ||
| 123 | - $param = [ | ||
| 124 | - 'author_id'=>$v['id'], | ||
| 125 | - 'title'=>$v['title'], | ||
| 126 | - 'image'=>str_replace_url($v['picture']), | ||
| 127 | - 'description'=>$v['description'], | ||
| 128 | - ]; | ||
| 129 | - //查询当前数据是否存在 | ||
| 130 | - $info = $aiBlogAuthorModel->read(['author_id'=>$v['id']]); | ||
| 131 | - try { | ||
| 132 | - if($info === false){ | ||
| 133 | - echo '执行新增'.PHP_EOL; | ||
| 134 | - $id = $aiBlogAuthorModel->addReturnId($param); | ||
| 135 | - $param['route'] = RouteMap::setRoute($v['route'] ?? $v['title'], RouteMap::SOURCE_AI_BLOG_AUTHOR, $id, $project_id); | ||
| 136 | - $aiBlogAuthorModel->edit(['route'=>$param['route']],['id'=>$id]); | ||
| 137 | - }else{ | ||
| 138 | - $param['route'] = RouteMap::setRoute($v['route'] ?? $v['title'], RouteMap::SOURCE_AI_BLOG_AUTHOR, $info['id'], $project_id); | ||
| 139 | - $aiBlogAuthorModel->edit($param,['id'=>$info['id']]); | ||
| 140 | - echo '执行更新'.PHP_EOL; | ||
| 141 | - } | ||
| 142 | - $aiSettingInfo = $this->getSetting($project_id); | ||
| 143 | - $aiBlogService = new AiBlogService(); | ||
| 144 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 145 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 146 | - $aiBlogService->updateAuthorInfo(['author_id'=>$param['author_id'],'route'=>$param['route'],'title'=>$param['title'],'picture'=>$param['image'],'description'=>$param['description']]); | ||
| 147 | - }catch (\Exception $e){ | ||
| 148 | - echo 'error:'.$e->getMessage().PHP_EOL; | ||
| 149 | - continue; | ||
| 150 | - } | ||
| 151 | - } | ||
| 152 | - return true; | ||
| 153 | - } | ||
| 154 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\Ai; | ||
| 4 | - | ||
| 5 | -use App\Http\Logic\Aside\Project\ProjectLogic; | ||
| 6 | -use App\Models\Ai\AiBlog; | ||
| 7 | -use App\Models\Ai\AiBlogKeyword; | ||
| 8 | -use App\Models\Ai\AiBlogOpenLog; | ||
| 9 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 10 | -use App\Models\Project\Project; | ||
| 11 | -use App\Models\Project\ProjectKeyword; | ||
| 12 | -use App\Models\RankData\RankData; | ||
| 13 | -use App\Models\WebSetting\WebSetting; | ||
| 14 | -use App\Services\AiBlogService; | ||
| 15 | -use App\Services\DingService; | ||
| 16 | -use App\Services\ProjectServer; | ||
| 17 | -use Illuminate\Console\Command; | ||
| 18 | -use Illuminate\Support\Facades\DB; | ||
| 19 | -use Illuminate\Support\Facades\Log; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * 自动发布AI博客任务 | ||
| 23 | - * Class AiBlogAutoPublish | ||
| 24 | - * @package App\Console\Commands\Ai | ||
| 25 | - * @author zbj | ||
| 26 | - * @date 2025/3/6 | ||
| 27 | - */ | ||
| 28 | -class AiBlogAutoPublish extends Command | ||
| 29 | -{ | ||
| 30 | - /** | ||
| 31 | - * The name and signature of the console command. | ||
| 32 | - * | ||
| 33 | - * @var string | ||
| 34 | - */ | ||
| 35 | - protected $signature = 'ai_blog_auto_publish {action}'; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * The console command description. | ||
| 39 | - * | ||
| 40 | - * @var string | ||
| 41 | - */ | ||
| 42 | - protected $description = '自动发布AI Blog'; | ||
| 43 | - | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * @return bool | ||
| 47 | - * @author zbj | ||
| 48 | - * @date 2025/3/6 | ||
| 49 | - */ | ||
| 50 | - public function handle() | ||
| 51 | - { | ||
| 52 | - $action = $this->argument('action'); | ||
| 53 | - if($action == 'auto_publish'){ | ||
| 54 | - $this->auto_publish(); | ||
| 55 | - } | ||
| 56 | - if($action == 'auto_open'){ | ||
| 57 | - $this->auto_open(); | ||
| 58 | - } | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - public function auto_publish() | ||
| 62 | - { | ||
| 63 | - $this->output('开始自动发布博客文章'); | ||
| 64 | - $projects = Project::where('is_ai_blog', 1)->whereIn('type',[1,2,3,4,6])->where('delete_status',0)->where('site_status',0)->where('extend_type',0)->get(); | ||
| 65 | - foreach ($projects as $project) { | ||
| 66 | - try { | ||
| 67 | - $this->output("项目{$project->id}开始自动发布"); | ||
| 68 | - if(!$project->deploy_optimize['is_ai_blog_send']){ | ||
| 69 | - $this->output("项目{$project->id}未开启自动发布" . $project->deploy_optimize['start_date']); | ||
| 70 | - continue; | ||
| 71 | - } | ||
| 72 | - if(($project->deploy_optimize['start_date'] > date('Y-m-d')) || !$project->deploy_optimize['start_date']){ | ||
| 73 | - $this->output("项目{$project->id}未到推广时间" . $project->deploy_optimize['start_date']); | ||
| 74 | - continue; | ||
| 75 | - } | ||
| 76 | - $next_auto_date = AiBlogTaskModel::where('project_id', $project->id)->where('type', 2)->whereNotNull('next_auto_date')->orderBy('id', 'desc')->value('next_auto_date'); | ||
| 77 | - if($next_auto_date && $next_auto_date > date('Y-m-d')){ | ||
| 78 | - $this->output("项目{$project->id}未到执行时间" . $next_auto_date); | ||
| 79 | - continue; | ||
| 80 | - } | ||
| 81 | - $aiKeywordModel = new AiBlogKeyword(); | ||
| 82 | - $keywords = $aiKeywordModel->getValue(['project_id'=>$project->id],'keywords'); | ||
| 83 | - if(empty($keywords)){ | ||
| 84 | - //核心关键词+网站关键词+白帽关键词 | ||
| 85 | - $main_keywords = ProjectKeyword::where('project_id', $project->id)->value('main_keyword'); | ||
| 86 | - $main_keywords = explode("\r\n", $main_keywords); | ||
| 87 | - $seo_keywords = ProjectKeyword::where('project_id', $project->id)->value('seo_keywords'); | ||
| 88 | - $seo_keywords = explode("\r\n", $seo_keywords); | ||
| 89 | - ProjectServer::useProject($project->id); | ||
| 90 | - $site_keywords = WebSetting::where('project_id', $project->id)->value('keyword'); | ||
| 91 | - DB::disconnect('custom_mysql'); | ||
| 92 | - $site_keywords = explode(",", $site_keywords); | ||
| 93 | - $keywords = array_filter(array_merge($main_keywords, $site_keywords, $seo_keywords)); | ||
| 94 | - $keywords = array_map('trim', $keywords); | ||
| 95 | - }else{ | ||
| 96 | - $keywords = explode("\r\n", $keywords); | ||
| 97 | - $keywords = array_map('trim', $keywords); // 清理空格 | ||
| 98 | - $keywords = array_filter($keywords); // 移除空值 | ||
| 99 | - } | ||
| 100 | - if (empty($keywords)) { | ||
| 101 | - $this->output("项目{$project->id}未获取到关键词"); | ||
| 102 | - continue; | ||
| 103 | - } | ||
| 104 | - $last_task = AiBlogTaskModel::where('project_id', $project->id)->where('type', 2)->orderBy('id', 'desc')->first(); | ||
| 105 | - $compliance = RankData::where(['project_id' => $project->id, 'lang' => ''])->value('is_compliance'); | ||
| 106 | - $frequency = Project::typeBlogFrequency($project->deploy_optimize->send_ai_blog_frequency); | ||
| 107 | - $frequency = explode('-', $frequency); | ||
| 108 | - //1、之前测试那批项目,按照正常频率发送; | ||
| 109 | - //2、未达标的项目,开启AIblog, 并立即推送三篇; | ||
| 110 | - //3、其他项目等下下周 1 (2025-03-17)开始推送第一篇, 之后按照正频率发送; | ||
| 111 | - if (!$last_task) { | ||
| 112 | - if(strpos($frequency[0],'/')){ | ||
| 113 | - $frequency = [1,1];//默认每天执行 | ||
| 114 | - } | ||
| 115 | - if(!$compliance) { | ||
| 116 | - for ($i = 0; $i < 3; $i++) { | ||
| 117 | - $this->createTask($keywords, $project->id, $frequency); | ||
| 118 | - } | ||
| 119 | - }else{ | ||
| 120 | - if(date('Y-m-d') >= '2025-03-17'){ | ||
| 121 | - $this->createTask($keywords, $project->id, $frequency); | ||
| 122 | - } | ||
| 123 | - } | ||
| 124 | - } else { | ||
| 125 | - if(strpos($frequency[0],'/')){//一天2/3篇 | ||
| 126 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 127 | - $frequency = explode('/', $frequency[0]); | ||
| 128 | - //查询当前已发布几篇 | ||
| 129 | - $count = $aiBlogTaskModel->counts(['next_auto_date' => date('Y-m-d', strtotime('+1 day')),'project_id' => $project->id]); | ||
| 130 | - while ($count < ($frequency[1] ?? 2) && ($count <= 3)){ | ||
| 131 | - $this->createTask($keywords, $project->id, [1,1]); | ||
| 132 | - $count++; | ||
| 133 | - } | ||
| 134 | - }else{ | ||
| 135 | - $this->createTask($keywords, $project->id, $frequency); | ||
| 136 | - } | ||
| 137 | - } | ||
| 138 | - }catch (\Exception $e){ | ||
| 139 | - (new DingService())->handle([ | ||
| 140 | - 'keyword' => 'AI_BLOG自动发布失败', | ||
| 141 | - 'msg' => '项目ID:' . $project->id . PHP_EOL . | ||
| 142 | - '错误信息:' . $e->getMessage() . PHP_EOL . | ||
| 143 | - '错误文件:' . $e->getFile() . PHP_EOL . | ||
| 144 | - '错误行数:' . $e->getLine(), | ||
| 145 | - 'isAtAll' => true, // 是否@所有人 | ||
| 146 | - ]); | ||
| 147 | - $this->output("自动发布失败:" . $e->getMessage() . $e->getFile() . $e->getLine()); | ||
| 148 | - } | ||
| 149 | - sleep(5); | ||
| 150 | - } | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - public function createTask($keywords, $project_id, $frequency){ | ||
| 154 | - $keyword = $keywords[array_rand($keywords)]; | ||
| 155 | - $aiBlogService = new AiBlogService($project_id); | ||
| 156 | - $result = $aiBlogService->createTask($keyword); | ||
| 157 | - if ($result['status'] == 200) { | ||
| 158 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 159 | - $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequency[0] ?? 3, $frequency[1] ?? 6) . 'days')); //每3-6天自动发布 | ||
| 160 | - $aiBlogTaskModel->addReturnId(['project_id' => $project_id, 'type' => 2, 'task_id' => $result['data']['task_id'], 'status' => 1, 'next_auto_date' => $next_auto_date]); | ||
| 161 | - ProjectServer::useProject($project_id); | ||
| 162 | - $aiBlogModel = new AiBlog(); | ||
| 163 | - $start = strtotime('10:00:00'); | ||
| 164 | - $end = strtotime('16:00:00'); | ||
| 165 | - $randomTimestamp = mt_rand($start, $end); | ||
| 166 | - $created_at = date("Y-m-d H:i:s", $randomTimestamp); | ||
| 167 | - $aiBlogModel->addReturnId(['keyword' => $keyword, 'status' => 1, 'task_id' => $result['data']['task_id'], 'project_id' => $project_id, 'created_at' => $created_at]); | ||
| 168 | - DB::disconnect('custom_mysql'); | ||
| 169 | - $this->output("任务创建成功"); | ||
| 170 | - } else { | ||
| 171 | - $this->output('任务创建失败:' . json_encode($result)); | ||
| 172 | - } | ||
| 173 | - } | ||
| 174 | - | ||
| 175 | - /** | ||
| 176 | - * 上线的推广项目自动开启 | ||
| 177 | - * @author zbj | ||
| 178 | - * @date 2025/3/7 | ||
| 179 | - */ | ||
| 180 | - public function auto_open() | ||
| 181 | - { | ||
| 182 | - while (true) { | ||
| 183 | - $this->output('上线的推广项目自动开启'); | ||
| 184 | - | ||
| 185 | - $projects = Project::whereIn('type', [Project::TYPE_TWO, Project::TYPE_FOUR]) | ||
| 186 | - ->whereIn('id', function ($query) { | ||
| 187 | - //按推广时间 | ||
| 188 | - $query->select('project_id') | ||
| 189 | - ->from('gl_project_deploy_optimize') | ||
| 190 | - ->where('start_date', '<=', date('Y-m-d')) | ||
| 191 | - ->where('start_date', '<>', ''); | ||
| 192 | - }) | ||
| 193 | - ->where('is_ai_blog', 0) | ||
| 194 | - ->get(); | ||
| 195 | - | ||
| 196 | - foreach ($projects as $project) { | ||
| 197 | - try { | ||
| 198 | - //未开启过 自动开启 | ||
| 199 | - if (!AiBlogOpenLog::isOpened($project->id)) { | ||
| 200 | - //创建AI博客项目 | ||
| 201 | - $deploy_optimize = $project->deploy_optimize; | ||
| 202 | - (new ProjectLogic())->setAiBlog($project->id, $project->main_lang_id, 1, $project->company, $deploy_optimize->company_en_name, $deploy_optimize->company_en_description,$project->is_related_video ?? 0); | ||
| 203 | - | ||
| 204 | - //开启 | ||
| 205 | - $project->is_ai_blog = 1; | ||
| 206 | - | ||
| 207 | - //开启自动发布 | ||
| 208 | - $project->deploy_optimize->is_ai_blog_send = 1; | ||
| 209 | - $project->deploy_optimize->save(); | ||
| 210 | - | ||
| 211 | - $project->save(); | ||
| 212 | - | ||
| 213 | - //开启日志 | ||
| 214 | - AiBlogOpenLog::addLog($project->id); | ||
| 215 | - | ||
| 216 | - $this->output('自动开启项目:' . $project->id); | ||
| 217 | - } | ||
| 218 | - }catch (\Exception $e){ | ||
| 219 | - (new DingService())->handle([ | ||
| 220 | - 'keyword' => 'AI_BLOG自动开启失败', | ||
| 221 | - 'msg' => '项目ID:' . $project->id . PHP_EOL . | ||
| 222 | - '错误信息:' . $e->getMessage() . PHP_EOL . | ||
| 223 | - '错误文件:' . $e->getFile() . PHP_EOL . | ||
| 224 | - '错误行数:' . $e->getLine(), | ||
| 225 | - 'isAtAll' => true, // 是否@所有人 | ||
| 226 | - ]); | ||
| 227 | - $this->output("自动开启失败:" . $e->getMessage() . $e->getFile() . $e->getLine()); | ||
| 228 | - } | ||
| 229 | - } | ||
| 230 | - sleep(60); | ||
| 231 | - } | ||
| 232 | - } | ||
| 233 | - | ||
| 234 | - /** | ||
| 235 | - * 输出message | ||
| 236 | - * @param $message | ||
| 237 | - */ | ||
| 238 | - public function output($message) | ||
| 239 | - { | ||
| 240 | - Log::channel('ai_blog')->info($message); | ||
| 241 | - echo date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 242 | - } | ||
| 243 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/14 11:14 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiBlog; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Ai\AiBlogList; | ||
| 15 | -use App\Models\Domain\DomainInfo; | ||
| 16 | -use App\Models\Project\Project; | ||
| 17 | -use App\Models\Project\ProjectAiSetting; | ||
| 18 | -use App\Models\RouteMap\RouteMap; | ||
| 19 | -use App\Services\AiBlogService; | ||
| 20 | -use App\Services\ProjectServer; | ||
| 21 | -use Illuminate\Console\Command; | ||
| 22 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 23 | -use Illuminate\Support\Facades\Cache; | ||
| 24 | -use Illuminate\Support\Facades\DB; | ||
| 25 | -use function Symfony\Component\String\s; | ||
| 26 | - | ||
| 27 | -/*** | ||
| 28 | - * @remark :根据项目更新blog列表 | ||
| 29 | - * @name :AiBlogListProjectTask | ||
| 30 | - * @author :lyh | ||
| 31 | - * @method :post | ||
| 32 | - * @time :2025/3/6 9:45 | ||
| 33 | - */ | ||
| 34 | -class AiBlogListAllTask extends Command | ||
| 35 | -{ | ||
| 36 | - /** | ||
| 37 | - * The name and signature of the console command. | ||
| 38 | - * | ||
| 39 | - * @var string | ||
| 40 | - */ | ||
| 41 | - protected $signature = 'save_all_ai_blog_list'; | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * The console command description. | ||
| 45 | - * | ||
| 46 | - * @var string | ||
| 47 | - */ | ||
| 48 | - protected $description = '生成blog列表'; | ||
| 49 | - | ||
| 50 | - public function handle(){ | ||
| 51 | - $projectModel = new Project(); | ||
| 52 | - $lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'extend_type'=>0,'type'=>['in',[2,3,4,6]]], 'id', ['id']); | ||
| 53 | - foreach ($lists as $item){ | ||
| 54 | - echo '执行的项目的id'.$item['id'].PHP_EOL; | ||
| 55 | - $project_id = $item['id']; | ||
| 56 | - ProjectServer::useProject($project_id); | ||
| 57 | - $projectAiSettingModel = new ProjectAiSetting(); | ||
| 58 | - $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); | ||
| 59 | - if($aiSettingInfo === false){ | ||
| 60 | - echo '未加载到配置。'.PHP_EOL; | ||
| 61 | - continue; | ||
| 62 | - } | ||
| 63 | - $this->updateBlogList($aiSettingInfo); | ||
| 64 | - $this->curlDelRoute($project_id); | ||
| 65 | - DB::disconnect('custom_mysql'); | ||
| 66 | - } | ||
| 67 | - return true; | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - /** | ||
| 71 | - * @remark :更新列表页数据 | ||
| 72 | - * @name :updateBlogList | ||
| 73 | - * @author :lyh | ||
| 74 | - * @method :post | ||
| 75 | - * @time :2025/3/5 11:07 | ||
| 76 | - */ | ||
| 77 | - public function updateBlogList($aiSettingInfo){ | ||
| 78 | - $aiBlogService = new AiBlogService(); | ||
| 79 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 80 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 81 | - $page = 1; | ||
| 82 | - $saveData = []; | ||
| 83 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 84 | - if(!isset($result['status']) || $result['status'] != 200){ | ||
| 85 | - return true; | ||
| 86 | - } | ||
| 87 | - $total_page = $result['data']['total_page']; | ||
| 88 | - //组装数据保存 | ||
| 89 | - $saveData[] = [ | ||
| 90 | - 'route'=>$page, | ||
| 91 | - 'text'=>$result['data']['section'], | ||
| 92 | - ]; | ||
| 93 | - while ($total_page > $page){ | ||
| 94 | - $page++; | ||
| 95 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 96 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 97 | - $saveData[] = [ | ||
| 98 | - 'route'=>$page, | ||
| 99 | - 'text'=>$result['data']['section'], | ||
| 100 | - ]; | ||
| 101 | - } | ||
| 102 | - } | ||
| 103 | - $aiBlogListModel = new AiBlogList(); | ||
| 104 | - if(!empty($saveData)){ | ||
| 105 | - //写一条路由信息 | ||
| 106 | - $aiBlogListModel->truncate(); | ||
| 107 | - $aiBlogListModel->insertAll($saveData); | ||
| 108 | - } | ||
| 109 | - return true; | ||
| 110 | - } | ||
| 111 | - | ||
| 112 | - /** | ||
| 113 | - * @remark :通知C端生成界面 | ||
| 114 | - * @name :sendNotice | ||
| 115 | - * @author :lyh | ||
| 116 | - * @method :post | ||
| 117 | - * @time :2025/3/6 11:51 | ||
| 118 | - */ | ||
| 119 | - public function curlDelRoute($project_id){ | ||
| 120 | - $domainModel = new DomainInfo(); | ||
| 121 | - //获取项目域名 | ||
| 122 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 123 | - if(!empty($domain)){ | ||
| 124 | - $c_url = $domain.'api/update_page/'; | ||
| 125 | - $param = [ | ||
| 126 | - 'project_id' => $project_id, | ||
| 127 | - 'type' => 1, | ||
| 128 | - 'route' => 3, | ||
| 129 | - 'url' => ['top-blog'], | ||
| 130 | - 'language'=> [], | ||
| 131 | - 'is_sitemap' => 0 | ||
| 132 | - ]; | ||
| 133 | - http_post($c_url, json_encode($param)); | ||
| 134 | - } | ||
| 135 | - return true; | ||
| 136 | - } | ||
| 137 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/14 11:14 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiBlog; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Ai\AiBlogList; | ||
| 15 | -use App\Models\Domain\DomainInfo; | ||
| 16 | -use App\Models\Project\ProjectAiSetting; | ||
| 17 | -use App\Models\RouteMap\RouteMap; | ||
| 18 | -use App\Services\AiBlogService; | ||
| 19 | -use App\Services\ProjectServer; | ||
| 20 | -use Illuminate\Console\Command; | ||
| 21 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 22 | -use Illuminate\Support\Facades\Cache; | ||
| 23 | -use Illuminate\Support\Facades\DB; | ||
| 24 | -use function Symfony\Component\String\s; | ||
| 25 | - | ||
| 26 | -/*** | ||
| 27 | - * @remark :根据项目更新blog列表 | ||
| 28 | - * @name :AiBlogListProjectTask | ||
| 29 | - * @author :lyh | ||
| 30 | - * @method :post | ||
| 31 | - * @time :2025/3/6 9:45 | ||
| 32 | - */ | ||
| 33 | -class AiBlogListProjectTask extends Command | ||
| 34 | -{ | ||
| 35 | - /** | ||
| 36 | - * The name and signature of the console command. | ||
| 37 | - * | ||
| 38 | - * @var string | ||
| 39 | - */ | ||
| 40 | - protected $signature = 'save_ai_blog_list {project_id}'; | ||
| 41 | - | ||
| 42 | - /** | ||
| 43 | - * The console command description. | ||
| 44 | - * | ||
| 45 | - * @var string | ||
| 46 | - */ | ||
| 47 | - protected $description = '根据项目生成blog列表'; | ||
| 48 | - | ||
| 49 | - public function handle(){ | ||
| 50 | - $project_id = $this->argument('project_id'); | ||
| 51 | - @file_put_contents(storage_path('logs/lyh_error.log'), var_export('执行的项目id->'.$project_id, true) . PHP_EOL, FILE_APPEND); | ||
| 52 | - ProjectServer::useProject($project_id); | ||
| 53 | - $projectAiSettingModel = new ProjectAiSetting(); | ||
| 54 | - $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); | ||
| 55 | - $this->updateBlogList($aiSettingInfo); | ||
| 56 | - $this->curlDelRoute($project_id); | ||
| 57 | - DB::disconnect('custom_mysql'); | ||
| 58 | - return true; | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - /** | ||
| 62 | - * @remark :更新列表页数据 | ||
| 63 | - * @name :updateBlogList | ||
| 64 | - * @author :lyh | ||
| 65 | - * @method :post | ||
| 66 | - * @time :2025/3/5 11:07 | ||
| 67 | - */ | ||
| 68 | - public function updateBlogList($aiSettingInfo){ | ||
| 69 | - $aiBlogService = new AiBlogService(); | ||
| 70 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 71 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 72 | - $page = 1; | ||
| 73 | - $saveData = []; | ||
| 74 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 75 | - if(!isset($result['status']) || $result['status'] != 200){ | ||
| 76 | - echo '请示失败。'.json_encode($result, JSON_UNESCAPED_UNICODE); | ||
| 77 | - return true; | ||
| 78 | - } | ||
| 79 | - $total_page = $result['data']['total_page']; | ||
| 80 | - //组装数据保存 | ||
| 81 | - $saveData[] = [ | ||
| 82 | - 'route'=>$page, | ||
| 83 | - 'text'=>$result['data']['section'], | ||
| 84 | - ]; | ||
| 85 | - while ($total_page > $page){ | ||
| 86 | - $page++; | ||
| 87 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 88 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 89 | - $saveData[] = [ | ||
| 90 | - 'route'=>$page, | ||
| 91 | - 'text'=>$result['data']['section'], | ||
| 92 | - ]; | ||
| 93 | - } | ||
| 94 | - } | ||
| 95 | - $aiBlogListModel = new AiBlogList(); | ||
| 96 | - if(!empty($saveData)){ | ||
| 97 | - //写一条路由信息 | ||
| 98 | - $aiBlogListModel->truncate(); | ||
| 99 | - $aiBlogListModel->insertAll($saveData); | ||
| 100 | - } | ||
| 101 | - return true; | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | - /** | ||
| 105 | - * @remark :通知C端生成界面 | ||
| 106 | - * @name :sendNotice | ||
| 107 | - * @author :lyh | ||
| 108 | - * @method :post | ||
| 109 | - * @time :2025/3/6 11:51 | ||
| 110 | - */ | ||
| 111 | - public function curlDelRoute($project_id){ | ||
| 112 | - $domainModel = new DomainInfo(); | ||
| 113 | - //获取项目域名 | ||
| 114 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 115 | - if(!empty($domain)){ | ||
| 116 | - $c_url = $domain.'api/update_page/'; | ||
| 117 | - $param = [ | ||
| 118 | - 'project_id' => $project_id, | ||
| 119 | - 'type' => 1, | ||
| 120 | - 'route' => 3, | ||
| 121 | - 'url' => ['top-blog'], | ||
| 122 | - 'language'=> [], | ||
| 123 | - 'is_sitemap' => 0 | ||
| 124 | - ]; | ||
| 125 | - http_post($c_url, json_encode($param)); | ||
| 126 | - } | ||
| 127 | - return true; | ||
| 128 | - } | ||
| 129 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/14 11:14 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiBlog; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Ai\AiBlogList; | ||
| 15 | -use App\Models\Domain\DomainInfo; | ||
| 16 | -use App\Models\Project\ProjectAiSetting; | ||
| 17 | -use App\Models\RouteMap\RouteMap; | ||
| 18 | -use App\Services\AiBlogService; | ||
| 19 | -use App\Services\ProjectServer; | ||
| 20 | -use Illuminate\Console\Command; | ||
| 21 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 22 | -use Illuminate\Support\Facades\Cache; | ||
| 23 | -use Illuminate\Support\Facades\DB; | ||
| 24 | -use Illuminate\Support\Facades\Redis; | ||
| 25 | -use function Symfony\Component\String\s; | ||
| 26 | - | ||
| 27 | -/*** | ||
| 28 | - * @remark :根据项目更新blog列表 | ||
| 29 | - * @name :AiBlogListProjectTask | ||
| 30 | - * @author :lyh | ||
| 31 | - * @method :post | ||
| 32 | - * @time :2025/3/6 9:45 | ||
| 33 | - */ | ||
| 34 | -class AiBlogListTask extends Command | ||
| 35 | -{ | ||
| 36 | - /** | ||
| 37 | - * The name and signature of the console command. | ||
| 38 | - * | ||
| 39 | - * @var string | ||
| 40 | - */ | ||
| 41 | - protected $signature = 'save_ai_blog_list_task'; | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * The console command description. | ||
| 45 | - * | ||
| 46 | - * @var string | ||
| 47 | - */ | ||
| 48 | - protected $description = '生成blog列表页'; | ||
| 49 | - | ||
| 50 | - public function handle(){ | ||
| 51 | - while (true){ | ||
| 52 | - $task_id = $this->getTaskId(); | ||
| 53 | - if(empty($task_id)){ | ||
| 54 | - sleep(200); | ||
| 55 | - continue; | ||
| 56 | - } | ||
| 57 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 58 | - $info = $aiBlogTaskModel->read(['id'=>$task_id,'type'=>$aiBlogTaskModel::TYPE_LIST]); | ||
| 59 | - if($info === false){ | ||
| 60 | - echo date('Y-m-d H:i:s').',当前数据不存在或者已被删除。'.PHP_EOL; | ||
| 61 | - } | ||
| 62 | - $project_id = $info['project_id']; | ||
| 63 | - echo '执行的项目ID:'.$info['project_id'].PHP_EOL; | ||
| 64 | - ProjectServer::useProject($project_id); | ||
| 65 | - $projectAiSettingModel = new ProjectAiSetting(); | ||
| 66 | - $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); | ||
| 67 | - $res = $this->updateBlogList($aiSettingInfo); | ||
| 68 | - if($res){ | ||
| 69 | - $aiBlogTaskModel->edit(['status'=>2],['id'=>$task_id]); | ||
| 70 | - }else{ | ||
| 71 | - if($info['sort'] >= 5){ | ||
| 72 | - $aiBlogTaskModel->edit(['status'=>9],['id'=>$task_id]); | ||
| 73 | - }else{ | ||
| 74 | - $aiBlogTaskModel->edit(['status'=>9,'sort'=>($info['sort'] + 1)],['id'=>$task_id]); | ||
| 75 | - } | ||
| 76 | - } | ||
| 77 | - $this->curlDelRoute($project_id); | ||
| 78 | - DB::disconnect('custom_mysql'); | ||
| 79 | - } | ||
| 80 | - return true; | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - /** | ||
| 84 | - * @remark :更新列表页数据 | ||
| 85 | - * @name :updateBlogList | ||
| 86 | - * @author :lyh | ||
| 87 | - * @method :post | ||
| 88 | - * @time :2025/3/5 11:07 | ||
| 89 | - */ | ||
| 90 | - public function updateBlogList($aiSettingInfo){ | ||
| 91 | - $aiBlogService = new AiBlogService(); | ||
| 92 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 93 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 94 | - $page = 1; | ||
| 95 | - $saveData = []; | ||
| 96 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 97 | - if(!isset($result['status']) || $result['status'] != 200){ | ||
| 98 | - echo '请求失败。'.json_encode($result, JSON_UNESCAPED_UNICODE); | ||
| 99 | - return false; | ||
| 100 | - } | ||
| 101 | - $total_page = $result['data']['total_page']; | ||
| 102 | - //组装数据保存 | ||
| 103 | - $saveData[] = [ | ||
| 104 | - 'route'=>$page, | ||
| 105 | - 'text'=>$result['data']['section'], | ||
| 106 | - ]; | ||
| 107 | - while ($total_page > $page){ | ||
| 108 | - $page++; | ||
| 109 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 110 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 111 | - $saveData[] = [ | ||
| 112 | - 'route'=>$page, | ||
| 113 | - 'text'=>$result['data']['section'], | ||
| 114 | - ]; | ||
| 115 | - }else{ | ||
| 116 | - echo '请求失败。'.json_encode($result, JSON_UNESCAPED_UNICODE); | ||
| 117 | - return false; | ||
| 118 | - } | ||
| 119 | - } | ||
| 120 | - $aiBlogListModel = new AiBlogList(); | ||
| 121 | - if(!empty($saveData)){ | ||
| 122 | - //写一条路由信息 | ||
| 123 | - $aiBlogListModel->truncate(); | ||
| 124 | - $aiBlogListModel->insertAll($saveData); | ||
| 125 | - return true; | ||
| 126 | - } | ||
| 127 | - return true; | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - /** | ||
| 131 | - * @remark :通知C端生成界面 | ||
| 132 | - * @name :sendNotice | ||
| 133 | - * @author :lyh | ||
| 134 | - * @method :post | ||
| 135 | - * @time :2025/3/6 11:51 | ||
| 136 | - */ | ||
| 137 | - public function curlDelRoute($project_id){ | ||
| 138 | - $domainModel = new DomainInfo(); | ||
| 139 | - //获取项目域名 | ||
| 140 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 141 | - if(!empty($domain)){ | ||
| 142 | - $c_url = $domain.'api/update_page/'; | ||
| 143 | - $param = [ | ||
| 144 | - 'project_id' => $project_id, | ||
| 145 | - 'type' => 1, | ||
| 146 | - 'route' => 3, | ||
| 147 | - 'url' => ['top-blog'], | ||
| 148 | - 'language'=> [], | ||
| 149 | - 'is_sitemap' => 0 | ||
| 150 | - ]; | ||
| 151 | - http_post($c_url, json_encode($param)); | ||
| 152 | - } | ||
| 153 | - return true; | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - /** | ||
| 157 | - * 获取任务id | ||
| 158 | - * @param int $finish_at | ||
| 159 | - * @return mixed | ||
| 160 | - */ | ||
| 161 | - public function getTaskId($finish_at = 2) | ||
| 162 | - { | ||
| 163 | - $keys = 'ai_blog_list_task'; | ||
| 164 | - $task_id = Redis::rpop($keys); | ||
| 165 | - if (empty($task_id)) { | ||
| 166 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 167 | - $finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour')); | ||
| 168 | - $ids = $aiBlogTaskModel->formatQuery(['status'=>$aiBlogTaskModel::STATUS_RUNNING, 'type'=>$aiBlogTaskModel::TYPE_LIST, 'updated_at'=>['<=',$finish_at]])->pluck('id'); | ||
| 169 | - if(!empty($ids)){ | ||
| 170 | - foreach ($ids as $id) { | ||
| 171 | - Redis::lpush($keys, $id); | ||
| 172 | - } | ||
| 173 | - } | ||
| 174 | - $task_id = Redis::rpop($keys); | ||
| 175 | - } | ||
| 176 | - return $task_id; | ||
| 177 | - } | ||
| 178 | -} |
app/Console/Commands/Ai/AiBlogTask.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/14 11:14 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Ai\AiBlog; | ||
| 14 | -use App\Models\Ai\AiBlogAuthor; | ||
| 15 | -use App\Models\Ai\AiBlogList; | ||
| 16 | -use App\Models\Com\NoticeLog; | ||
| 17 | -use App\Models\Com\Notify; | ||
| 18 | -use App\Models\Devops\ServerConfig; | ||
| 19 | -use App\Models\Devops\ServersIp; | ||
| 20 | -use App\Models\Domain\DomainInfo; | ||
| 21 | -use App\Models\Project\Project; | ||
| 22 | -use App\Models\Project\ProjectAiSetting; | ||
| 23 | -use App\Models\RouteMap\RouteMap; | ||
| 24 | -use App\Services\AiBlogService; | ||
| 25 | -use App\Services\DingService; | ||
| 26 | -use App\Services\ProjectServer; | ||
| 27 | -use Illuminate\Console\Command; | ||
| 28 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 29 | -use Illuminate\Support\Facades\DB; | ||
| 30 | -use Illuminate\Support\Facades\Redis; | ||
| 31 | - | ||
| 32 | -class AiBlogTask extends Command | ||
| 33 | -{ | ||
| 34 | - /** | ||
| 35 | - * The name and signature of the console command. | ||
| 36 | - * | ||
| 37 | - * @var string | ||
| 38 | - */ | ||
| 39 | - protected $signature = 'save_ai_blog'; | ||
| 40 | - | ||
| 41 | - public $updateProject = [];//需更新的列表 | ||
| 42 | - public $projectSetting = []; | ||
| 43 | - public $routes = [];//需要更新的路由 | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * The console command description. | ||
| 47 | - * | ||
| 48 | - * @var string | ||
| 49 | - */ | ||
| 50 | - protected $description = '查询ai_blog是否已经生成'; | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | - * @return bool | ||
| 54 | - * @throws \Exception | ||
| 55 | - */ | ||
| 56 | - public function handle(){ | ||
| 57 | - while (true){ | ||
| 58 | - //获取任务id | ||
| 59 | - $task_id = $this->getTaskId(); | ||
| 60 | - if(empty($task_id)){ | ||
| 61 | - sleep(300); | ||
| 62 | - continue; | ||
| 63 | - } | ||
| 64 | - $this->sendRequest($task_id); | ||
| 65 | - } | ||
| 66 | - return true; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - /** | ||
| 70 | - * 请求方法 | ||
| 71 | - * @param $task_id | ||
| 72 | - * @return bool | ||
| 73 | - * @throws \Exception | ||
| 74 | - */ | ||
| 75 | - public function sendRequest($task_id){ | ||
| 76 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 77 | - $item = $aiBlogTaskModel->read(['id'=>$task_id]); | ||
| 78 | - $this->output('start:project ID: ' . $item['project_id'] . ',task ID: ' . $task_id); | ||
| 79 | - //获取配置 | ||
| 80 | - $aiSettingInfo = $this->getSetting($item['project_id']); | ||
| 81 | - $aiBlogService = new AiBlogService(); | ||
| 82 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 83 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 84 | - $aiBlogService->task_id = $item['task_id']; | ||
| 85 | - //拉取文章数据 | ||
| 86 | - $result = $aiBlogService->getDetail(); | ||
| 87 | - if(empty($result['status']) || ($result['status'] != 200)){ | ||
| 88 | - if($item['sort'] < 5){ | ||
| 89 | - $aiBlogTaskModel->edit(['sort'=>$item['sort'] + 1],['id'=>$item['id']]); | ||
| 90 | - }else{ | ||
| 91 | - $aiBlogTaskModel->edit(['status'=>9],['id'=>$item['id']]); | ||
| 92 | - // 钉钉通知 | ||
| 93 | - $dingService = new DingService(); | ||
| 94 | - $body = [ | ||
| 95 | - 'keyword' => 'AI_BLOG获取失败', | ||
| 96 | - 'msg' => '任务ID:' . $item['task_id'] . PHP_EOL . '返回信息:' . json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), | ||
| 97 | - 'isAtAll' => false, // 是否@所有人 | ||
| 98 | - ]; | ||
| 99 | - $dingService->handle($body); | ||
| 100 | - } | ||
| 101 | - $this->output('error: 数据获取失败,status:' . $result['status'] . ',message: ' . ($result['message'] ?? 'null')); | ||
| 102 | - return false; | ||
| 103 | - } | ||
| 104 | - //保存当前项目ai_blog数据 | ||
| 105 | - ProjectServer::useProject($item['project_id']); | ||
| 106 | - $aiBlogModel = new AiBlog(); | ||
| 107 | - $aiBlogInfo = $aiBlogModel->read(['task_id'=>$item['task_id']],['id','route']); | ||
| 108 | - if($aiBlogInfo === false){ | ||
| 109 | - // 钉钉通知 | ||
| 110 | - $dingService = new DingService(); | ||
| 111 | - $body = [ | ||
| 112 | - 'keyword' => 'AI_BLOG生成错误', | ||
| 113 | - 'msg' => '任务ID:' . $item['task_id'] . ', 子库获取数据失败, 检查子库数据是否被删除!', | ||
| 114 | - 'isAtAll' => false, // 是否@所有人 | ||
| 115 | - ]; | ||
| 116 | - $dingService->handle($body); | ||
| 117 | - $this->output('error: 子库获取数据失败, task id: ' . $task_id); | ||
| 118 | - $aiBlogTaskModel->edit(['status'=>9],['id'=>$item['id']]); | ||
| 119 | - DB::disconnect('custom_mysql'); | ||
| 120 | - return false; | ||
| 121 | - } | ||
| 122 | - //拿到返回的路由查看是否重复 | ||
| 123 | - $route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_BLOG, $aiBlogInfo['id'], $item['project_id']); | ||
| 124 | - if($route != $result['data']['url']){ | ||
| 125 | - $aiBlogService->updateDetail(['route'=>$route,'task_id'=>$item['task_id']]); | ||
| 126 | - } | ||
| 127 | - //需要更新的路由 | ||
| 128 | - if (!in_array($result['data']['author_id'], $this->updateProject[$item['project_id']] ?? [])) { | ||
| 129 | - $this->updateProject[$item['project_id']][] = $result['data']['author_id']; | ||
| 130 | - } | ||
| 131 | - if (!in_array($route, $this->routes[$item['project_id']] ?? [])) { | ||
| 132 | - $this->routes[$item['project_id']][] = $route; | ||
| 133 | - } | ||
| 134 | - $aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'],'seo_title'=>$result['data']['title'],'seo_keyword'=>$result['data']['keyword'],'seo_description'=>$result['data']['description'], 'route'=>$route ,'status'=>$aiBlogModel::STATUS_FINISH], ['task_id'=>$item['task_id']]); | ||
| 135 | - DB::disconnect('custom_mysql'); | ||
| 136 | - $aiBlogTaskModel->edit(['status'=>$aiBlogModel::STATUS_FINISH],['id'=>$item['id']]); | ||
| 137 | - $this->output('success: task id: ' . $task_id); | ||
| 138 | - return true; | ||
| 139 | - } | ||
| 140 | - | ||
| 141 | - /** | ||
| 142 | - * 获取任务id | ||
| 143 | - * @param int $finish_at | ||
| 144 | - * @return mixed | ||
| 145 | - */ | ||
| 146 | - public function getTaskId($finish_at = 2) | ||
| 147 | - { | ||
| 148 | - $task_id = Redis::rpop('ai_blog_task'); | ||
| 149 | - if (empty($task_id)) { | ||
| 150 | - if(!empty($this->updateProject)){ | ||
| 151 | - $this->updateProject($this->updateProject); | ||
| 152 | - $this->updateProject = []; | ||
| 153 | - } | ||
| 154 | - if(!empty($this->routes)){ | ||
| 155 | - $this->updateRoutes($this->routes); | ||
| 156 | - $this->routes = []; | ||
| 157 | - } | ||
| 158 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 159 | - $finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour')); | ||
| 160 | - $ids = $aiBlogTaskModel->formatQuery(['status'=>$aiBlogTaskModel::STATUS_RUNNING, 'type'=>$aiBlogTaskModel::TYPE_BLOG, 'updated_at'=>['<=',$finish_at]])->pluck('id'); | ||
| 161 | - if(!empty($ids)){ | ||
| 162 | - foreach ($ids as $id) { | ||
| 163 | - Redis::lpush('ai_blog_task', $id); | ||
| 164 | - } | ||
| 165 | - } | ||
| 166 | - $task_id = Redis::rpop('ai_blog_task'); | ||
| 167 | - } | ||
| 168 | - return $task_id; | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - /** | ||
| 172 | - * 更新项目作者页面及列表页 | ||
| 173 | - * @param $updateProject | ||
| 174 | - * @return bool | ||
| 175 | - */ | ||
| 176 | - public function updateProject($updateProject){ | ||
| 177 | - if(empty($updateProject)){ | ||
| 178 | - return true; | ||
| 179 | - } | ||
| 180 | - foreach ($updateProject as $project_id => $author){ | ||
| 181 | - ProjectServer::useProject($project_id); | ||
| 182 | - $aiSettingInfo = $this->getSetting($project_id); | ||
| 183 | - $this->output('sync: list start, project_id: ' . $project_id); | ||
| 184 | - $this->updateBlogList($aiSettingInfo,$project_id); | ||
| 185 | - $this->output('sync: list end'); | ||
| 186 | - //更新作者 | ||
| 187 | - $this->output('sync: author start, project_id: ' . $project_id); | ||
| 188 | - foreach ($author as $val){ | ||
| 189 | - $this->updateAiBlogAuthor($aiSettingInfo,$val,$project_id); | ||
| 190 | - } | ||
| 191 | - $this->output('sync: author end'); | ||
| 192 | - DB::disconnect('custom_mysql'); | ||
| 193 | - } | ||
| 194 | - | ||
| 195 | - return true; | ||
| 196 | - } | ||
| 197 | - | ||
| 198 | - /** | ||
| 199 | - * 获取项目配置 | ||
| 200 | - * @param $project_id | ||
| 201 | - * @return bool | ||
| 202 | - */ | ||
| 203 | - public function getSetting($project_id) | ||
| 204 | - { | ||
| 205 | - $project_setting = $this->projectSetting; | ||
| 206 | - if (FALSE == empty($project_setting[$project_id])){ | ||
| 207 | - return $project_setting[$project_id]; | ||
| 208 | - } | ||
| 209 | - $projectAiSettingModel = new ProjectAiSetting(); | ||
| 210 | - $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); | ||
| 211 | - $this->projectSetting[$project_id] = $aiSettingInfo; | ||
| 212 | - return $aiSettingInfo; | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - /** | ||
| 216 | - * 更新作者的页面 | ||
| 217 | - * @param $aiSettingInfo | ||
| 218 | - * @param $author_id | ||
| 219 | - * @return bool | ||
| 220 | - */ | ||
| 221 | - public function updateAiBlogAuthor($aiSettingInfo,$author_id,$project_id){ | ||
| 222 | - if(empty($author_id)){ | ||
| 223 | - return true; | ||
| 224 | - } | ||
| 225 | - $aiBlogService = new AiBlogService(); | ||
| 226 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 227 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 228 | - $aiBlogService->author_id = $author_id; | ||
| 229 | - $result = $aiBlogService->getAuthorDetail(); | ||
| 230 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 231 | - //当前作者的页面 | ||
| 232 | - $aiBlogAuthorModel = new AiBlogAuthor(); | ||
| 233 | - $authorInfo = $aiBlogAuthorModel->read(['author_id'=>$author_id],['id','route']); | ||
| 234 | - if($authorInfo !== false && !empty($result['data']['section'])){ | ||
| 235 | - //需要更新的路由 | ||
| 236 | - if (!in_array($authorInfo['route'], $this->routes[$project_id] ?? [])) { | ||
| 237 | - $this->routes[$project_id][] = $authorInfo['route']; | ||
| 238 | - } | ||
| 239 | - $aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$author_id]); | ||
| 240 | - } | ||
| 241 | - } | ||
| 242 | - return true; | ||
| 243 | - } | ||
| 244 | - | ||
| 245 | - /** | ||
| 246 | - * 更新列表页 | ||
| 247 | - * @param $aiSettingInfo | ||
| 248 | - * @return bool | ||
| 249 | - */ | ||
| 250 | - public function updateBlogList($aiSettingInfo,$project_id = 0){ | ||
| 251 | - $aiBlogService = new AiBlogService(); | ||
| 252 | - $aiBlogService->mch_id = $aiSettingInfo['mch_id']; | ||
| 253 | - $aiBlogService->key = $aiSettingInfo['key']; | ||
| 254 | - $page = 1; | ||
| 255 | - $saveData = []; | ||
| 256 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 257 | - if(!isset($result['status']) || $result['status'] != 200){ | ||
| 258 | - try { | ||
| 259 | - // 钉钉通知 | ||
| 260 | - $dingService = new DingService(); | ||
| 261 | - $body = [ | ||
| 262 | - 'keyword' => 'AI_BLOG列表页未生成拉取失败', | ||
| 263 | - 'msg' => '项目ID:' . $project_id . PHP_EOL . '返回信息:' . json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), | ||
| 264 | - 'isAtAll' => false, // 是否@所有人 | ||
| 265 | - ]; | ||
| 266 | - $dingService->handle($body); | ||
| 267 | - //写一条更新记录 | ||
| 268 | - $aiBlogTaskModel = new AiBlogTaskModel(); | ||
| 269 | - $aiBlogTaskModel->addReturnId(['project_id'=>$project_id,'task_id'=>$project_id,'status'=>$aiBlogTaskModel::STATUS_RUNNING,'type'=>$aiBlogTaskModel::TYPE_LIST]); | ||
| 270 | - }catch (\Exception $e){ | ||
| 271 | - $this->output('更新列表页失败同时通知失败--error:' . $e->getMessage()); | ||
| 272 | - } | ||
| 273 | - return true; | ||
| 274 | - } | ||
| 275 | - $total_page = $result['data']['total_page']; | ||
| 276 | - //组装数据保存 | ||
| 277 | - $saveData[] = [ | ||
| 278 | - 'route'=>$page, | ||
| 279 | - 'text'=>$result['data']['section'], | ||
| 280 | - ]; | ||
| 281 | - while ($total_page > $page){ | ||
| 282 | - $page++; | ||
| 283 | - $result = $aiBlogService->getAiBlogList($page,15); | ||
| 284 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 285 | - $saveData[] = [ | ||
| 286 | - 'route'=>$page, | ||
| 287 | - 'text'=>$result['data']['section'], | ||
| 288 | - ]; | ||
| 289 | - } | ||
| 290 | - } | ||
| 291 | - $aiBlogListModel = new AiBlogList(); | ||
| 292 | - if(!empty($saveData)){ | ||
| 293 | - //写一条路由信息 | ||
| 294 | - $aiBlogListModel->truncate(); | ||
| 295 | - $aiBlogListModel->insertAll($saveData); | ||
| 296 | - } | ||
| 297 | - return true; | ||
| 298 | - } | ||
| 299 | - | ||
| 300 | - /** | ||
| 301 | - * 通知C端生成界面 | ||
| 302 | - * @param $project_id | ||
| 303 | - * @return bool | ||
| 304 | - */ | ||
| 305 | - public function updateRoutes($routes){ | ||
| 306 | - $domainModel = new DomainInfo(); | ||
| 307 | - $project_model = new Project(); | ||
| 308 | - foreach ($routes as $project_id => $route){ | ||
| 309 | - if($project_id == 4339){ | ||
| 310 | - continue; | ||
| 311 | - } | ||
| 312 | - $route[] = 'top-blog'; | ||
| 313 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 314 | - if (empty($domain)) { | ||
| 315 | - $this->output('send: 域名不存在, project id: ' . $project_id); | ||
| 316 | - continue; | ||
| 317 | - } | ||
| 318 | - //判断是否是自建站服务器,如果是,不请求C端接口,数据直接入库 | ||
| 319 | - $project_info = $project_model->read(['id'=>$project_id],['serve_id']); | ||
| 320 | - if(!$project_info){ | ||
| 321 | - $this->output('send: 项目不存在, project id: ' . $project_id); | ||
| 322 | - continue; | ||
| 323 | - } | ||
| 324 | - $serve_ip_model = new ServersIp(); | ||
| 325 | - $serve_ip_info = $serve_ip_model->read(['id'=>$project_info['serve_id']],['servers_id']); | ||
| 326 | - $servers_id = $serve_ip_info ? $serve_ip_info['servers_id'] : 0; | ||
| 327 | - if($servers_id == ServerConfig::SELF_SITE_ID){ | ||
| 328 | - //判断是否已有更新进行中 | ||
| 329 | - $notify_model = new Notify(); | ||
| 330 | - $data = [ | ||
| 331 | - 'project_id' => $project_id, | ||
| 332 | - 'type' => Notify::TYPE_MASTER, | ||
| 333 | - 'route' => Notify::ROUTE_AI_BLOG, | ||
| 334 | - 'server_id' => ServerConfig::SELF_SITE_ID, | ||
| 335 | - 'status' => ['!=',Notify::STATUS_FINISH_SITEMAP] | ||
| 336 | - ]; | ||
| 337 | - $notify = $notify_model->read($data,['id']); | ||
| 338 | - if(!$notify){ | ||
| 339 | - $domain_array = parse_url($domain); | ||
| 340 | - $data['data'] = Arr::a2s(['domain'=>$domain_array['host'],'url'=>$route,'language'=>[]]); | ||
| 341 | - $data['status'] = Notify::STATUS_INIT; | ||
| 342 | - $data['sort'] = 2; | ||
| 343 | - $notify_model->add($data); | ||
| 344 | - } | ||
| 345 | - $this->output('send: 自建站项目, project id: ' . $project_id); | ||
| 346 | - }else{ | ||
| 347 | - $c_url = $domain.'api/update_page/'; | ||
| 348 | - $param = [ | ||
| 349 | - 'project_id' => $project_id, | ||
| 350 | - 'type' => 1, | ||
| 351 | - 'route' => 3, | ||
| 352 | - 'url' => $route, | ||
| 353 | - 'language'=> [], | ||
| 354 | - 'is_sitemap' => 0 | ||
| 355 | - ]; | ||
| 356 | - $res = http_post($c_url, json_encode($param,true)); | ||
| 357 | - if(empty($res)){ | ||
| 358 | - NoticeLog::createLog(NoticeLog::GENERATE_PAGE, ['c_url'=>$c_url,'c_params'=>$param],date('Y-m-d H:i:s',time()+300)); | ||
| 359 | - } | ||
| 360 | - $this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); | ||
| 361 | - } | ||
| 362 | - } | ||
| 363 | - return true; | ||
| 364 | - } | ||
| 365 | - | ||
| 366 | - /** | ||
| 367 | - * 输入日志 | ||
| 368 | - * @param $message | ||
| 369 | - * @return bool | ||
| 370 | - */ | ||
| 371 | - public function output($message) | ||
| 372 | - { | ||
| 373 | - $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 374 | - echo $message; | ||
| 375 | - file_put_contents(storage_path('logs/AiBlog/') . date('Ymd') . '.log', $message, FILE_APPEND); | ||
| 376 | - return true; | ||
| 377 | - } | ||
| 378 | -} |
app/Console/Commands/Ai/AiDomainTask.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiDomainTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/6/19 10:53 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Domain\DomainInfo; | ||
| 13 | -use Illuminate\Console\Command; | ||
| 14 | - | ||
| 15 | -/** | ||
| 16 | - * @remark :拉取项目Ai域名 | ||
| 17 | - * @name :AiDomainTask | ||
| 18 | - * @author :lyh | ||
| 19 | - * @method :post | ||
| 20 | - * @time :2025/6/19 10:54 | ||
| 21 | - */ | ||
| 22 | -class AiDomainTask extends Command | ||
| 23 | -{ | ||
| 24 | - /** | ||
| 25 | - * The name and signature of the console command. | ||
| 26 | - * | ||
| 27 | - * @var string | ||
| 28 | - */ | ||
| 29 | - protected $signature = 'ai_domain'; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * The console command description. | ||
| 33 | - * | ||
| 34 | - * @var string | ||
| 35 | - */ | ||
| 36 | - protected $description = '获取对应域名的ai复制站域名'; | ||
| 37 | - | ||
| 38 | - public $url = 'https://www.cmer.site/api/globalso_site'; | ||
| 39 | - | ||
| 40 | - /** | ||
| 41 | - * @remark :执行方法 | ||
| 42 | - * @name :handle | ||
| 43 | - * @author :lyh | ||
| 44 | - * @method :post | ||
| 45 | - * @time :2025/6/19 11:32 | ||
| 46 | - */ | ||
| 47 | - public function handle(){ | ||
| 48 | - $pageSize = 300; | ||
| 49 | - $page = 1; | ||
| 50 | - $res = http_get($this->url.'?pagesize='.$pageSize.'&page='.$page); | ||
| 51 | - if($res['status'] != 200){ | ||
| 52 | - echo date('Y-m-d H:i:s').'请求失败,状态码错误'.PHP_EOL; | ||
| 53 | - return false; | ||
| 54 | - } | ||
| 55 | - if(empty($res['data']['data'])){ | ||
| 56 | - echo date('Y-m-d H:i:s').'请求失败,未拉取到数据'.PHP_EOL; | ||
| 57 | - return false; | ||
| 58 | - } | ||
| 59 | - $data = $res['data']['data']; | ||
| 60 | - while($page <= $res['data']['last_page']){ | ||
| 61 | - $res = http_get($this->url.'?pagesize='.$pageSize.'&page='.$page); | ||
| 62 | - if($res['status'] != 200){ | ||
| 63 | - echo date('Y-m-d H:i:s').'第'.$page.'请求失败,未拉取到数据'.PHP_EOL; | ||
| 64 | - return false; | ||
| 65 | - } | ||
| 66 | - $data = array_values(array_merge($data,$res['data']['data'])); | ||
| 67 | - $page++; | ||
| 68 | - } | ||
| 69 | - //处理数据 | ||
| 70 | - $this->handleData($data); | ||
| 71 | - echo 'end'.PHP_EOL; | ||
| 72 | - return true; | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - /** | ||
| 76 | - * @remark :处理数据 | ||
| 77 | - * @name :handleData | ||
| 78 | - * @author :lyh | ||
| 79 | - * @method :post | ||
| 80 | - * @time :2025/6/19 11:21 | ||
| 81 | - */ | ||
| 82 | - public function handleData($data){ | ||
| 83 | - $domainInfoModel = new DomainInfo(); | ||
| 84 | - foreach ($data as $item){ | ||
| 85 | - $info = $domainInfoModel->read(['domain'=>$item['domain']],'id'); | ||
| 86 | - if($info === false){ | ||
| 87 | - $info = $domainInfoModel->read(['domain'=>$item['globalso_domain']],'id'); | ||
| 88 | - if($info !== false){ | ||
| 89 | - $domainInfoModel->edit(['ai_domain'=>$item['domain']],['id'=>$info['id']]); | ||
| 90 | - } | ||
| 91 | - }else{ | ||
| 92 | - $domainInfoModel->edit(['ai_domain'=>$item['globalso_domain']],['id'=>$info['id']]); | ||
| 93 | - } | ||
| 94 | - } | ||
| 95 | - return true; | ||
| 96 | - } | ||
| 97 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiVideoAutoPublish.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/8/1 15:19 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiVideo; | ||
| 13 | -use App\Models\AyrShare\AyrShare; | ||
| 14 | -use App\Models\Domain\DomainInfo; | ||
| 15 | -use App\Models\Product\Keyword; | ||
| 16 | -use App\Models\Product\Product; | ||
| 17 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 18 | -use App\Models\Project\AiVideoAutoLog; | ||
| 19 | -use App\Models\Project\DeployOptimize; | ||
| 20 | -use App\Models\Project\Project; | ||
| 21 | -use App\Services\AiVideoService; | ||
| 22 | -use App\Services\MidJourneyService; | ||
| 23 | -use App\Services\ProjectServer; | ||
| 24 | -use Illuminate\Console\Command; | ||
| 25 | -use Illuminate\Support\Facades\DB; | ||
| 26 | -use Illuminate\Support\Facades\Log; | ||
| 27 | -use App\Models\Project\AiVideoTask; | ||
| 28 | -use Illuminate\Support\Facades\Redis; | ||
| 29 | - | ||
| 30 | -/** | ||
| 31 | - * @remark :ai视频自动发布 | ||
| 32 | - * @name :AiVideoAutoPublish | ||
| 33 | - * @author :lyh | ||
| 34 | - * @method :post | ||
| 35 | - * @time :2025/8/1 15:19 | ||
| 36 | - */ | ||
| 37 | -class AiVideoAutoPublish extends Command | ||
| 38 | -{ | ||
| 39 | - /** | ||
| 40 | - * The name and signature of the console command. | ||
| 41 | - * | ||
| 42 | - * @var string | ||
| 43 | - */ | ||
| 44 | - protected $signature = 'ai_video_auto_publish {action}'; | ||
| 45 | - | ||
| 46 | - /** | ||
| 47 | - * The console command description. | ||
| 48 | - * | ||
| 49 | - * @var string | ||
| 50 | - */ | ||
| 51 | - protected $description = '自动发布AI Video'; | ||
| 52 | - | ||
| 53 | - public function handle(){ | ||
| 54 | - $action = $this->argument('action'); | ||
| 55 | - if($action == 'auto_publish'){ | ||
| 56 | - $this->auto_publish(); | ||
| 57 | - } | ||
| 58 | - if($action == 'auto_send_video'){ | ||
| 59 | - $this->auto_send_video(); | ||
| 60 | - } | ||
| 61 | - if($action == 'auto_save_video_task'){ | ||
| 62 | - $this->auto_save_video_task(); | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - | ||
| 66 | - /** | ||
| 67 | - * @remark :自动发布aiVideo组装数据(写入一条记录) | ||
| 68 | - * @name :auto_six_publish | ||
| 69 | - * @author :lyh | ||
| 70 | - * @method :post | ||
| 71 | - * @time :2025/8/1 15:22 | ||
| 72 | - */ | ||
| 73 | - public function auto_publish(){ | ||
| 74 | - $this->output('开始自动发布Video文章'); | ||
| 75 | - $projectModel = new Project(); | ||
| 76 | - $optimizeModel = new DeployOptimize(); | ||
| 77 | - $projectList = $projectModel->list(['is_ai_video'=>1,'type'=>['in',[1,2,3,4,6]],'delete_status'=>0,'site_status'=>0,'extend_type'=>0],'id',['id','project_type']); | ||
| 78 | - foreach ($projectList as $item){ | ||
| 79 | - $this->output("项目{$item['id']}开始自动发布"); | ||
| 80 | - //获取当前是否开启自动发布aiVideo | ||
| 81 | - $opInfo = $optimizeModel->read(['project_id'=>$item['id']],['is_ai_video_send','send_ai_video_frequency','start_date']); | ||
| 82 | - if($opInfo['is_ai_video_send'] != 1){ | ||
| 83 | - $this->output("项目{$item['id']}未开启自动发布" . $opInfo['start_date']); | ||
| 84 | - continue; | ||
| 85 | - } | ||
| 86 | - if(($opInfo['start_date'] > date('Y-m-d')) || empty($opInfo['start_date'])){ | ||
| 87 | - $this->output("项目{$item['id']}未到推广时间" . $opInfo['start_date']); | ||
| 88 | - continue; | ||
| 89 | - } | ||
| 90 | - $aiVideoTaskModel = new AiVideoTask(); | ||
| 91 | - $next_auto_date = $aiVideoTaskModel->formatQuery(['project_id'=>$item['id'],'next_auto_date'=>['!=',null]])->orderBy('id', 'desc')->value('next_auto_date'); | ||
| 92 | - if($next_auto_date && ($next_auto_date > date('Y-m-d'))){ | ||
| 93 | - $this->output("项目{$item['id']}未到执行时间" . $next_auto_date); | ||
| 94 | - continue; | ||
| 95 | - } | ||
| 96 | - if($item['project_type'] == 1){ | ||
| 97 | - //todo::页面上获取数据 | ||
| 98 | - $data = $this->getAiVideoParam($item['id']); | ||
| 99 | - }else{ | ||
| 100 | - //获取当前网站的标题 | ||
| 101 | - ProjectServer::useProject($item['id']); | ||
| 102 | - $data = $this->getVideoInfo(); | ||
| 103 | - DB::disconnect('custom_mysql'); | ||
| 104 | - } | ||
| 105 | - if(!empty($data)){ | ||
| 106 | - //写入一条零时生成视频记录 | ||
| 107 | - $aiVideoAutoLogModel = new AiVideoAutoLog(); | ||
| 108 | - $aiVideoAutoLogModel->addReturnId( | ||
| 109 | - ['project_id'=>$item['id'],'title'=>$data['title'],'remark'=>$data['remark'],'images'=>json_encode($data['images'],true),'date'=>date('Y-m-d')] | ||
| 110 | - ); | ||
| 111 | - } | ||
| 112 | - } | ||
| 113 | - return true; | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - /** | ||
| 117 | - * @remark :获取产品标题+产品描述 | ||
| 118 | - * @name :getProduct | ||
| 119 | - * @author :lyh | ||
| 120 | - * @method :post | ||
| 121 | - * @time :2025/8/1 16:09 | ||
| 122 | - */ | ||
| 123 | - public function getVideoInfo(){ | ||
| 124 | - $data = []; | ||
| 125 | - $random = rand(1, 2); | ||
| 126 | - if($random == 1){//取产品 | ||
| 127 | - $productModel = new Product(); | ||
| 128 | - $info = $productModel->formatQuery(['status'=>1,'title'=>['!=',null],'intro'=>['!=',null]])->select(['title','gallery','intro'])->inRandomOrder()->first(); | ||
| 129 | - if(empty($info)){ | ||
| 130 | - return $data; | ||
| 131 | - } | ||
| 132 | - $data['title'] = $info['title']; | ||
| 133 | - $data['remark'] = $info['intro']; | ||
| 134 | - $data['images'] = array_filter(array_map(function ($item) use ($data) { | ||
| 135 | - if (!empty($item['url'])) { | ||
| 136 | - return [ | ||
| 137 | - 'alt' => $item['title'] ?? $data['title'], | ||
| 138 | - 'url' => getImageUrl($item['url']), | ||
| 139 | - ]; | ||
| 140 | - } | ||
| 141 | - return null; | ||
| 142 | - }, $info['gallery'])); | ||
| 143 | - return $data; | ||
| 144 | - }else{ | ||
| 145 | - //聚合页获取当前关联产品的图片 | ||
| 146 | - $keywordModel = new Keyword(); | ||
| 147 | - $keywordInfo = $keywordModel->formatQuery(['keyword_title'=>['!=',null],'keyword_content'=>['!=',null]])->select(['keyword_title','keyword_content'])->inRandomOrder()->first(); | ||
| 148 | - if(empty($keywordInfo)){ | ||
| 149 | - return $data; | ||
| 150 | - } | ||
| 151 | - $data['title'] = $keywordInfo['keyword_title']; | ||
| 152 | - $data['remark'] = $keywordInfo['keyword_content']; | ||
| 153 | - $data['remark'] = strip_tags($keywordInfo['intro']); | ||
| 154 | - if(empty($data['remark'])){ | ||
| 155 | - $data['remark'] = $data['title']; | ||
| 156 | - } | ||
| 157 | - $data['images'] = []; | ||
| 158 | - $productModel = new Product(); | ||
| 159 | - $productList = $productModel->list(['keyword_id'=>['like','%,'.$keywordInfo['id'].',%']],'id',['gallery'],'desc',10); | ||
| 160 | - foreach ($productList as $info){ | ||
| 161 | - $images = array_filter(array_map(function ($item) use ($data) { | ||
| 162 | - if (!empty($item['url'])) { | ||
| 163 | - return [ | ||
| 164 | - 'alt' => $item['title'] ?? $data['title'], | ||
| 165 | - 'url' => getImageUrl($item['url']), | ||
| 166 | - ]; | ||
| 167 | - } | ||
| 168 | - return null; // 返回 null 让 array_filter 去除 | ||
| 169 | - }, $info['gallery'])); | ||
| 170 | - $data['images'] = array_merge($data['images'],$images); | ||
| 171 | - } | ||
| 172 | - return $data; | ||
| 173 | - } | ||
| 174 | - } | ||
| 175 | - | ||
| 176 | - /** | ||
| 177 | - * @remark :组装缺少图片数据-推送至发送平台 | ||
| 178 | - * @name :send_video | ||
| 179 | - * @author :lyh | ||
| 180 | - * @method :post | ||
| 181 | - * @time :2025/8/2 10:37 | ||
| 182 | - */ | ||
| 183 | - public function auto_send_video(){ | ||
| 184 | - $number = Redis::get('ai_video_image') ?? 0; | ||
| 185 | - $aiVideoAutoLogModel = new AiVideoAutoLog(); | ||
| 186 | - while (true){ | ||
| 187 | - if($number > 5){ | ||
| 188 | - echo date('Y-m-d H:i:s').':当前生成图片数量已达到最大限度。'.$number.PHP_EOL; | ||
| 189 | - sleep(300); | ||
| 190 | - continue; | ||
| 191 | - } | ||
| 192 | - $item = $aiVideoAutoLogModel->read(['status'=>0,'trigger_id'=>null]); | ||
| 193 | - if($item === false){ | ||
| 194 | - sleep(60); | ||
| 195 | - continue; | ||
| 196 | - } | ||
| 197 | - if(count($item['images']) < 6){ | ||
| 198 | - echo date('Y-m-d H:i:s').':提交生成图片。'.$item['project_id'].PHP_EOL; | ||
| 199 | - //需要生成图片 | ||
| 200 | - $content = "{$item['remark']},{$item['title']},4K,高清 --no logo --ar 16:9"; | ||
| 201 | - $midJourneyService = new MidJourneyService(); | ||
| 202 | - $result = $midJourneyService->imagine($content); | ||
| 203 | - if($result && !empty($result['trigger_id'])){ | ||
| 204 | - echo '提交的数据详情。'.json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES).$item['project_id'].PHP_EOL; | ||
| 205 | - Redis::incr('ai_video_image'); | ||
| 206 | - $aiVideoAutoLogModel->edit(['trigger_id'=>$result['trigger_id']],['id'=>$item['id']]); | ||
| 207 | - } | ||
| 208 | - }else{ | ||
| 209 | - //提交到待执行 | ||
| 210 | - $aiVideoAutoLogModel->edit(['status'=>1],['id'=>$item['id']]); | ||
| 211 | - } | ||
| 212 | - } | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - /** | ||
| 216 | - * @remark :状态为1的数据推送至生成视频任务表 | ||
| 217 | - * @name :auto_save_video_task | ||
| 218 | - * @author :lyh | ||
| 219 | - * @method :post | ||
| 220 | - * @time :2025/8/4 9:39 | ||
| 221 | - */ | ||
| 222 | - public function auto_save_video_task(){ | ||
| 223 | - $aiVideoAutoLogModel = new AiVideoAutoLog(); | ||
| 224 | - while (true){ | ||
| 225 | - //获取任务id | ||
| 226 | - $task_id = $this->getAutoTaskId(); | ||
| 227 | - if(empty($task_id)){ | ||
| 228 | - sleep(300); | ||
| 229 | - continue; | ||
| 230 | - } | ||
| 231 | - $info = $aiVideoAutoLogModel->read(['id'=>$task_id]); | ||
| 232 | - if($info === false){ | ||
| 233 | - $this->output(date('Y-m-d H:i:s').':当前数据不存在或已被删除'.$task_id); | ||
| 234 | - continue; | ||
| 235 | - } | ||
| 236 | - try { | ||
| 237 | - $aiVideoTaskModel = new AiVideoTask(); | ||
| 238 | - $aiVideoService = new AiVideoService($info['project_id']); | ||
| 239 | - $projectModel = new DeployOptimize(); | ||
| 240 | - $video_setting = $projectModel->getValue(['project_id'=>$info['project_id']],'video_setting'); | ||
| 241 | - $frequency_setting = $projectModel->getValue(['project_id'=>$info['project_id']],'send_ai_video_frequency'); | ||
| 242 | - $storage = $aiVideoTaskModel->videoSetting()[$video_setting ?? 1]; | ||
| 243 | - $frequency = $aiVideoTaskModel->videoFrequency()[$frequency_setting ?? 1]; | ||
| 244 | - $frequencyArr = explode('-',$frequency); | ||
| 245 | - if($storage == 'YOUTUBE'){ | ||
| 246 | - //查看是否有ayr账号 | ||
| 247 | - $ayrModel = new AyrShare(); | ||
| 248 | - $ayrInfo = $ayrModel->read(['project_id'=>$this->param['project_id'],'bind_platforms'=>['like','%"youtube"%'],'profile_key'=>['!=',null]]); | ||
| 249 | - if($ayrInfo !== false){ | ||
| 250 | - $ayrshare_profile_key = $ayrInfo['profile_key']; | ||
| 251 | - } | ||
| 252 | - } | ||
| 253 | - $result = $aiVideoService->createTask($info['title'],$info['remark'],array_slice($info['images'], 0, 8),[],$storage,$ayrshare_profile_key ?? ''); | ||
| 254 | - if($result['status'] == 200){ | ||
| 255 | - $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequencyArr[0] ?? 5,$frequencyArr[1] ?? 7) . 'days')); //每5-7天自动发布 | ||
| 256 | - $aiVideoTaskModel->addReturnId(['next_auto_date'=>$next_auto_date,'task_id'=>$result['data']['task_id'],'project_id'=>$info['project_id'],'storage'=>$storage]); | ||
| 257 | - ProjectServer::useProject($info['project_id']); | ||
| 258 | - $aiVideoModel = new AiVideo(); | ||
| 259 | - $aiVideoModel->addReturnId(['title'=>$info['title'],'task_id'=>$result['data']['task_id'],'description'=>$info['remark'],'project_id'=>$info['project_id'],'images'=>json_encode($info['images'],true),'anchor'=>json_encode([],true)]); | ||
| 260 | - DB::disconnect('custom_mysql'); | ||
| 261 | - $aiVideoAutoLogModel->edit(['status'=>2],['id'=>$info['id']]); | ||
| 262 | - }else{ | ||
| 263 | - $aiVideoAutoLogModel->edit(['status'=>3],['id'=>$info['id']]); | ||
| 264 | - } | ||
| 265 | - }catch (\Exception $e){ | ||
| 266 | - $this->output( date('Y-m-d H:i:s').':当前数据不存在或已被删除'.$task_id); | ||
| 267 | - continue; | ||
| 268 | - } | ||
| 269 | - } | ||
| 270 | - } | ||
| 271 | - | ||
| 272 | - /** | ||
| 273 | - * @remark :火锅自动发布任务id | ||
| 274 | - * @name :getAutoTaskId | ||
| 275 | - * @author :lyh | ||
| 276 | - * @method :post | ||
| 277 | - * @time :2025/8/4 9:44 | ||
| 278 | - */ | ||
| 279 | - public function getAutoTaskId() | ||
| 280 | - { | ||
| 281 | - $task_id = Redis::rpop('auto_ai_video_task'); | ||
| 282 | - if (empty($task_id)) { | ||
| 283 | - $aiVideoAutoLogModel = new AiVideoAutoLog(); | ||
| 284 | - $ids = $aiVideoAutoLogModel->formatQuery(['status'=>1])->pluck('id'); | ||
| 285 | - if(!empty($ids)){ | ||
| 286 | - foreach ($ids as $id) { | ||
| 287 | - Redis::lpush('auto_ai_video_task', $id); | ||
| 288 | - } | ||
| 289 | - } | ||
| 290 | - $task_id = Redis::rpop('auto_ai_video_task'); | ||
| 291 | - } | ||
| 292 | - return $task_id; | ||
| 293 | - } | ||
| 294 | - | ||
| 295 | - /** | ||
| 296 | - * @remark :页面获取 | ||
| 297 | - * @name :getAiVideoParam | ||
| 298 | - * @author :lyh | ||
| 299 | - * @method :post | ||
| 300 | - * @time :2025/8/1 16:25 | ||
| 301 | - */ | ||
| 302 | - public function getAiVideoParam($project_id) | ||
| 303 | - { | ||
| 304 | - //获取当前网站域名 | ||
| 305 | - $domainModel = new DomainInfo(); | ||
| 306 | - $domain = $domainModel->getValue(['project_id'=>$project_id],'domain'); | ||
| 307 | - if(empty($domain)){ | ||
| 308 | - return true; | ||
| 309 | - } | ||
| 310 | - $domain = str_replace('blog.', 'www.', $domain); | ||
| 311 | - //todo::看是否获取建站的产品数据 | ||
| 312 | - try { | ||
| 313 | - $sitemap_url = 'https://' . $domain . '/sitemap_post_tag.xml'; | ||
| 314 | - $sitemap_string = file_get_contents($sitemap_url); | ||
| 315 | - $xml = new \SimpleXMLElement($sitemap_string); | ||
| 316 | - $json = json_encode($xml); | ||
| 317 | - $array = json_decode($json, true); | ||
| 318 | - $urls = array_column($array['url'], 'loc'); | ||
| 319 | - $num = 0; | ||
| 320 | - if ($num >= 10) { | ||
| 321 | - return false; | ||
| 322 | - } | ||
| 323 | - AGAIN: | ||
| 324 | - $url = $urls[array_rand($urls)]; | ||
| 325 | - $dom = file_get_html($url); | ||
| 326 | - $h1 = $dom->find('.layout .global_section h1', 0); | ||
| 327 | - $title = $h1 ? trim($h1->plaintext) : ''; | ||
| 328 | - $p = $dom->find('.layout .global_section p', 0); | ||
| 329 | - $content = $p ? trim($p->plaintext) : ''; | ||
| 330 | - $img = $dom->find('.layout .global_section img'); | ||
| 331 | - $images = []; | ||
| 332 | - foreach ($img as $item) { | ||
| 333 | - if (empty($item->src) || empty($item->alt)){ | ||
| 334 | - continue; | ||
| 335 | - } | ||
| 336 | - array_push($images, ['url' => $item->src, 'alt' => $item->alt]); | ||
| 337 | - } | ||
| 338 | - if (empty($title) || empty($content) || empty($images)) { | ||
| 339 | - $num++; | ||
| 340 | - goto AGAIN; | ||
| 341 | - } | ||
| 342 | - return ['title'=>$title,'remark'=>$content,'images'=>$images]; | ||
| 343 | - } catch (\Exception $e) { | ||
| 344 | - $this->output('project_id: ' . $project_id . ', domain: ' . $domain . ', error: ' . $e->getMessage()); | ||
| 345 | - echo 'project_id: ' . $project_id . ', domain: ' . $domain . ', error: ' . $e->getMessage() . PHP_EOL; | ||
| 346 | - return []; | ||
| 347 | - } | ||
| 348 | - } | ||
| 349 | - | ||
| 350 | - /** | ||
| 351 | - * @remark :日志 | ||
| 352 | - * @name :output | ||
| 353 | - * @author :lyh | ||
| 354 | - * @method :post | ||
| 355 | - * @time :2025/8/1 15:28 | ||
| 356 | - */ | ||
| 357 | - public function output($message) | ||
| 358 | - { | ||
| 359 | - Log::channel('ai_video')->info($message); | ||
| 360 | - echo date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 361 | - } | ||
| 362 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiBlogTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/2/14 11:14 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Models\Ai\AiBlog; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Ai\AiBlogList; | ||
| 15 | -use App\Models\Ai\AiVideoList; | ||
| 16 | -use App\Models\Domain\DomainInfo; | ||
| 17 | -use App\Models\Project\ProjectAiSetting; | ||
| 18 | -use App\Models\RouteMap\RouteMap; | ||
| 19 | -use App\Services\AiBlogService; | ||
| 20 | -use App\Services\AiVideoService; | ||
| 21 | -use App\Services\ProjectServer; | ||
| 22 | -use Illuminate\Console\Command; | ||
| 23 | -use App\Models\Project\AiBlogTask as AiBlogTaskModel; | ||
| 24 | -use Illuminate\Support\Facades\Cache; | ||
| 25 | -use Illuminate\Support\Facades\DB; | ||
| 26 | -use function Symfony\Component\String\s; | ||
| 27 | - | ||
| 28 | -/*** | ||
| 29 | - * @remark :根据项目更新blog列表 | ||
| 30 | - * @name :AiBlogListProjectTask | ||
| 31 | - * @author :lyh | ||
| 32 | - * @method :post | ||
| 33 | - * @time :2025/3/6 9:45 | ||
| 34 | - */ | ||
| 35 | -class AiVideoListTask extends Command | ||
| 36 | -{ | ||
| 37 | - /** | ||
| 38 | - * The name and signature of the console command. | ||
| 39 | - * | ||
| 40 | - * @var string | ||
| 41 | - */ | ||
| 42 | - protected $signature = 'save_ai_video_list {project_id}'; | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * The console command description. | ||
| 46 | - * | ||
| 47 | - * @var string | ||
| 48 | - */ | ||
| 49 | - protected $description = '生成video列表'; | ||
| 50 | - | ||
| 51 | - public function handle(){ | ||
| 52 | - $project_id = $this->argument('project_id'); | ||
| 53 | - @file_put_contents(storage_path('logs/lyh_error.log'), var_export('执行的项目id->'.$project_id, true) . PHP_EOL, FILE_APPEND); | ||
| 54 | - ProjectServer::useProject($project_id); | ||
| 55 | - $this->updateBlogList($project_id); | ||
| 56 | - $this->curlDelRoute($project_id); | ||
| 57 | - DB::disconnect('custom_mysql'); | ||
| 58 | - return true; | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - /** | ||
| 62 | - * @remark :更新列表页数据 | ||
| 63 | - * @name :updateBlogList | ||
| 64 | - * @author :lyh | ||
| 65 | - * @method :post | ||
| 66 | - * @time :2025/3/5 11:07 | ||
| 67 | - */ | ||
| 68 | - public function updateBlogList($project_id){ | ||
| 69 | - $aiVideoService = new AiVideoService($project_id); | ||
| 70 | - $page = 1; | ||
| 71 | - $saveData = []; | ||
| 72 | - $result = $aiVideoService->getAiVideoList($page,15); | ||
| 73 | - if(!isset($result['status']) && $result['status'] != 200){ | ||
| 74 | - return true; | ||
| 75 | - } | ||
| 76 | - $total_page = $result['data']['total_page']; | ||
| 77 | - //组装数据保存 | ||
| 78 | - $saveData[] = [ | ||
| 79 | - 'route'=>$page, | ||
| 80 | - 'text'=>$result['data']['section'], | ||
| 81 | - ]; | ||
| 82 | - while ($total_page > $page){ | ||
| 83 | - $page++; | ||
| 84 | - $result = $aiVideoService->getAiVideoList($page,15); | ||
| 85 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 86 | - $saveData[] = [ | ||
| 87 | - 'route'=>$page, | ||
| 88 | - 'text'=>$result['data']['section'], | ||
| 89 | - ]; | ||
| 90 | - } | ||
| 91 | - } | ||
| 92 | - $aiVideoListModel = new AiVideoList(); | ||
| 93 | - if(!empty($saveData)){ | ||
| 94 | - //写一条路由信息 | ||
| 95 | - $aiVideoListModel->truncate(); | ||
| 96 | - $aiVideoListModel->insertAll($saveData); | ||
| 97 | - } | ||
| 98 | - return true; | ||
| 99 | - } | ||
| 100 | - | ||
| 101 | - /** | ||
| 102 | - * @remark :通知C端生成界面 | ||
| 103 | - * @name :sendNotice | ||
| 104 | - * @author :lyh | ||
| 105 | - * @method :post | ||
| 106 | - * @time :2025/3/6 11:51 | ||
| 107 | - */ | ||
| 108 | - public function curlDelRoute($project_id){ | ||
| 109 | - $domainModel = new DomainInfo(); | ||
| 110 | - //获取项目域名 | ||
| 111 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 112 | - if(!empty($domain)){ | ||
| 113 | - $c_url = $domain.'api/update_page/'; | ||
| 114 | - $param = [ | ||
| 115 | - 'project_id' => $project_id, | ||
| 116 | - 'type' => 1, | ||
| 117 | - 'route' => 3, | ||
| 118 | - 'url' => ['top-blog'], | ||
| 119 | - 'language'=> [], | ||
| 120 | - 'is_sitemap' => 0 | ||
| 121 | - ]; | ||
| 122 | - http_post($c_url, json_encode($param)); | ||
| 123 | - } | ||
| 124 | - return true; | ||
| 125 | - } | ||
| 126 | -} |
app/Console/Commands/Ai/AiVideoTask.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AiVideoTask.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/4/30 11:18 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\Ai; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Ai\AiBlogAuthor; | ||
| 14 | -use App\Models\Ai\AiVideo; | ||
| 15 | -use App\Models\Ai\AiVideoList; | ||
| 16 | -use App\Models\Com\Notify; | ||
| 17 | -use App\Models\Devops\ServerConfig; | ||
| 18 | -use App\Models\Devops\ServersIp; | ||
| 19 | -use App\Models\Domain\DomainInfo; | ||
| 20 | -use App\Models\Project\AiVideoTask as AiVideoTaskModel; | ||
| 21 | -use App\Models\Project\Project; | ||
| 22 | -use App\Models\RouteMap\RouteMap; | ||
| 23 | -use App\Services\AiBlogService; | ||
| 24 | -use App\Services\AiVideoService; | ||
| 25 | -use App\Services\DingService; | ||
| 26 | -use App\Services\ProjectServer; | ||
| 27 | -use Illuminate\Console\Command; | ||
| 28 | -use Illuminate\Support\Facades\DB; | ||
| 29 | -use Illuminate\Support\Facades\Redis; | ||
| 30 | - | ||
| 31 | -class AiVideoTask extends Command | ||
| 32 | -{ | ||
| 33 | - /** | ||
| 34 | - * The name and signature of the console command. | ||
| 35 | - * | ||
| 36 | - * @var string | ||
| 37 | - */ | ||
| 38 | - protected $signature = 'save_ai_video'; | ||
| 39 | - | ||
| 40 | - public $updateProject = [];//需更新的列表 | ||
| 41 | - public $routes = [];//需要更新的路由 | ||
| 42 | - /** | ||
| 43 | - * The console command description. | ||
| 44 | - * | ||
| 45 | - * @var string | ||
| 46 | - */ | ||
| 47 | - protected $description = '查询ai_video是否已经生成'; | ||
| 48 | - /** | ||
| 49 | - * @return bool | ||
| 50 | - * @throws \Exception | ||
| 51 | - */ | ||
| 52 | - public function handle(){ | ||
| 53 | - while (true){ | ||
| 54 | - //获取任务id | ||
| 55 | - $task_id = $this->getTaskId(); | ||
| 56 | - if(empty($task_id)){ | ||
| 57 | - sleep(300); | ||
| 58 | - continue; | ||
| 59 | - } | ||
| 60 | - $this->_action($task_id); | ||
| 61 | - } | ||
| 62 | - return true; | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - /** | ||
| 66 | - * 获取任务id | ||
| 67 | - * @param int $finish_at | ||
| 68 | - * @return mixed | ||
| 69 | - */ | ||
| 70 | - public function getTaskId($finish_at = 2) | ||
| 71 | - { | ||
| 72 | - $task_id = Redis::rpop('ai_video_task'); | ||
| 73 | - if (empty($task_id)) { | ||
| 74 | - if(!empty($this->updateProject)){ | ||
| 75 | - $this->updateProject($this->updateProject); | ||
| 76 | - $this->updateProject = []; | ||
| 77 | - } | ||
| 78 | - if(!empty($this->routes)){ | ||
| 79 | - $this->updateRoutes($this->routes); | ||
| 80 | - $this->routes = []; | ||
| 81 | - } | ||
| 82 | - $aiVideoTaskModel = new AiVideoTaskModel(); | ||
| 83 | - $finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour')); | ||
| 84 | - $ids = $aiVideoTaskModel->formatQuery(['status'=>$aiVideoTaskModel::STATUS_RUNNING,'updated_at'=>['<=',$finish_at]])->pluck('id'); | ||
| 85 | - if(!empty($ids)){ | ||
| 86 | - foreach ($ids as $id) { | ||
| 87 | - Redis::lpush('ai_video_task', $id); | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - $task_id = Redis::rpop('ai_video_task'); | ||
| 91 | - } | ||
| 92 | - return $task_id; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - /** | ||
| 96 | - * @remark :请求 | ||
| 97 | - * @name :sendRequest | ||
| 98 | - * @author :lyh | ||
| 99 | - * @method :post | ||
| 100 | - * @time :2025/4/30 11:31 | ||
| 101 | - */ | ||
| 102 | - public function _action($task_id){ | ||
| 103 | - $aiVideoTaskModel = new AiVideoTaskModel(); | ||
| 104 | - $item = $aiVideoTaskModel->read(['id'=>$task_id]); | ||
| 105 | - $this->output('ai_video->start:project ID: ' . $item['project_id'] . ',task ID: ' . $task_id); | ||
| 106 | - $aiVideoService = new AiVideoService($item['project_id']); | ||
| 107 | - $aiVideoService->task_id = $item['task_id']; | ||
| 108 | - //拉取文章数据 | ||
| 109 | - $result = $aiVideoService->getVideoDetail(); | ||
| 110 | - if(empty($result['status']) || ($result['status'] != 200)){ | ||
| 111 | - if($item['number'] < 5){ | ||
| 112 | - $aiVideoTaskModel->edit(['number'=>$item['number'] + 1],['id'=>$item['id']]); | ||
| 113 | - }else{ | ||
| 114 | - $aiVideoTaskModel->edit(['status'=>9],['id'=>$item['id']]); | ||
| 115 | - // 钉钉通知 | ||
| 116 | - $dingService = new DingService(); | ||
| 117 | - $body = [ | ||
| 118 | - 'keyword' => 'AI_VIDEO获取失败', | ||
| 119 | - 'msg' => '任务ID:' . $item['task_id'] . PHP_EOL . '返回信息:' . json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), | ||
| 120 | - 'isAtAll' => false, // 是否@所有人 | ||
| 121 | - ]; | ||
| 122 | - $dingService->handle($body); | ||
| 123 | - } | ||
| 124 | - $this->output('error: 数据获取失败,status:' . $result['status'] . ',message: ' . ($result['message'] ?? 'null')); | ||
| 125 | - return false; | ||
| 126 | - } | ||
| 127 | - //保存当前项目ai_blog数据 | ||
| 128 | - ProjectServer::useProject($item['project_id']); | ||
| 129 | - $aiVideoModel = new AiVideo(); | ||
| 130 | - $aiVideoInfo = $aiVideoModel->read(['task_id'=>$item['task_id']],['id','route']); | ||
| 131 | - if($aiVideoInfo === false){ | ||
| 132 | - // 钉钉通知 | ||
| 133 | - $dingService = new DingService(); | ||
| 134 | - $body = [ | ||
| 135 | - 'keyword' => 'AI_VIDEO生成错误', | ||
| 136 | - 'msg' => '任务ID:' . $item['task_id'] . ', 子库获取数据失败, 检查子库数据是否被删除!', | ||
| 137 | - 'isAtAll' => false, // 是否@所有人 | ||
| 138 | - ]; | ||
| 139 | - $dingService->handle($body); | ||
| 140 | - $this->output('error: 子库获取数据失败, task id: ' . $task_id); | ||
| 141 | - $aiVideoTaskModel->edit(['status'=>9],['id'=>$item['id']]); | ||
| 142 | - DB::disconnect('custom_mysql'); | ||
| 143 | - return false; | ||
| 144 | - } | ||
| 145 | - //拿到返回的路由查看是否重复 | ||
| 146 | - $route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_VIDEO, $aiVideoInfo['id'], $item['project_id']); | ||
| 147 | - if($route != $result['data']['url']){ | ||
| 148 | - $aiVideoService->updateDetail(['url'=>$route,'task_id'=>$item['task_id']]); | ||
| 149 | - } | ||
| 150 | - $saveData = [ | ||
| 151 | - 'title'=>$result['data']['title'], | ||
| 152 | - 'image'=>$result['data']['thumb'], | ||
| 153 | - 'video_url'=>$result['data']['video_url'], | ||
| 154 | - 'route'=>$route, | ||
| 155 | - 'author_id'=>$result['data']['author_id'], | ||
| 156 | - 'keyword'=>json_encode($result['data']['keyword'],true), | ||
| 157 | - 'content'=>$result['data']['content'], | ||
| 158 | - 'text'=>$result['data']['section'], | ||
| 159 | - 'status'=>$aiVideoTaskModel::STATUS_FINISH, | ||
| 160 | - 'seo_title'=>$result['data']['title'], | ||
| 161 | - 'seo_keyword'=>implode(',',$result['data']['keyword']), | ||
| 162 | - 'seo_description'=>$result['data']['description'] ?? '', | ||
| 163 | - ]; | ||
| 164 | - $aiVideoModel->edit($saveData,['task_id'=>$item['task_id']]); | ||
| 165 | - //需要更新的路由 | ||
| 166 | - if (!in_array($result['data']['author_id'], $this->updateProject[$item['project_id']] ?? [])) { | ||
| 167 | - $this->updateProject[$item['project_id']][] = $result['data']['author_id']; | ||
| 168 | - } | ||
| 169 | - if (!in_array($route, $this->routes[$item['project_id']] ?? [])) { | ||
| 170 | - $this->routes[$item['project_id']][] = $route; | ||
| 171 | - } | ||
| 172 | - DB::disconnect('custom_mysql'); | ||
| 173 | - $aiVideoTaskModel->edit(['status'=>$aiVideoTaskModel::STATUS_FINISH],['id'=>$item['id']]); | ||
| 174 | - $this->output('success: task id: ' . $task_id); | ||
| 175 | - return true; | ||
| 176 | - } | ||
| 177 | - | ||
| 178 | - /** | ||
| 179 | - * @remark :更新项目作者页面及列表页 | ||
| 180 | - * @name :updateProject | ||
| 181 | - * @author :lyh | ||
| 182 | - * @method :post | ||
| 183 | - * @time :2025/4/30 15:43 | ||
| 184 | - */ | ||
| 185 | - public function updateProject($updateProject){ | ||
| 186 | - if(empty($updateProject)){ | ||
| 187 | - return true; | ||
| 188 | - } | ||
| 189 | - foreach ($updateProject as $project_id => $author){ | ||
| 190 | - ProjectServer::useProject($project_id); | ||
| 191 | - $this->output('sync: list start, project_id: ' . $project_id); | ||
| 192 | - $this->updateBlogList($project_id); | ||
| 193 | - $this->output('sync: list end'); | ||
| 194 | - //更新作者 | ||
| 195 | - $this->output('sync: author start, project_id: ' . $project_id); | ||
| 196 | - foreach ($author as $val){ | ||
| 197 | - $this->updateAiBlogAuthor($val,$project_id); | ||
| 198 | - } | ||
| 199 | - $this->output('sync: author end'); | ||
| 200 | - DB::disconnect('custom_mysql'); | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - return true; | ||
| 204 | - } | ||
| 205 | - | ||
| 206 | - /** | ||
| 207 | - * @remark :更新作者页面 | ||
| 208 | - * @name :updateAiBlogAuthor | ||
| 209 | - * @author :lyh | ||
| 210 | - * @method :post | ||
| 211 | - * @time :2025/4/30 15:52 | ||
| 212 | - */ | ||
| 213 | - public function updateAiBlogAuthor($author_id,$project_id){ | ||
| 214 | - if(empty($author_id)){ | ||
| 215 | - return true; | ||
| 216 | - } | ||
| 217 | - $aiBlogService = new AiBlogService($project_id); | ||
| 218 | - $aiBlogService->author_id = $author_id; | ||
| 219 | - $result = $aiBlogService->getAuthorDetail(); | ||
| 220 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 221 | - //当前作者的页面 | ||
| 222 | - $aiBlogAuthorModel = new AiBlogAuthor(); | ||
| 223 | - $authorInfo = $aiBlogAuthorModel->read(['author_id'=>$author_id],['id','route']); | ||
| 224 | - if($authorInfo !== false && !empty($result['data']['section'])){ | ||
| 225 | - //需要更新的路由 | ||
| 226 | - if (!in_array($authorInfo['route'], $this->routes[$project_id] ?? [])) { | ||
| 227 | - $this->routes[$project_id][] = $authorInfo['route']; | ||
| 228 | - } | ||
| 229 | - $aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$author_id]); | ||
| 230 | - } | ||
| 231 | - } | ||
| 232 | - return true; | ||
| 233 | - } | ||
| 234 | - | ||
| 235 | - /** | ||
| 236 | - * @remark :更新 | ||
| 237 | - * @name :updateBlogList | ||
| 238 | - * @author :lyh | ||
| 239 | - * @method :post | ||
| 240 | - * @time :2025/4/30 15:45 | ||
| 241 | - */ | ||
| 242 | - public function updateBlogList($project_id){ | ||
| 243 | - $aiVideoService = new AiVideoService($project_id); | ||
| 244 | - $page = 1; | ||
| 245 | - $saveData = []; | ||
| 246 | - $result = $aiVideoService->getAiVideoList($page,15); | ||
| 247 | - if(!isset($result['status']) && $result['status'] != 200){ | ||
| 248 | - return true; | ||
| 249 | - } | ||
| 250 | - $total_page = $result['data']['total_page']; | ||
| 251 | - //组装数据保存 | ||
| 252 | - $saveData[] = [ | ||
| 253 | - 'route'=>$page, | ||
| 254 | - 'text'=>$result['data']['section'], | ||
| 255 | - ]; | ||
| 256 | - while ($total_page > $page){ | ||
| 257 | - $page++; | ||
| 258 | - $result = $aiVideoService->getAiVideoList($page,15); | ||
| 259 | - if(isset($result['status']) && $result['status'] == 200){ | ||
| 260 | - $saveData[] = [ | ||
| 261 | - 'route'=>$page, | ||
| 262 | - 'text'=>$result['data']['section'], | ||
| 263 | - ]; | ||
| 264 | - } | ||
| 265 | - } | ||
| 266 | - $aiVideoListModel = new AiVideoList(); | ||
| 267 | - if(!empty($saveData)){ | ||
| 268 | - //写一条路由信息 | ||
| 269 | - RouteMap::setRoute('top-video',RouteMap::SOURCE_AI_VIDEO_LIST,0,$project_id);//写一条列表页路由 | ||
| 270 | - $aiVideoListModel->truncate(); | ||
| 271 | - $aiVideoListModel->insertAll($saveData); | ||
| 272 | - } | ||
| 273 | - return true; | ||
| 274 | - } | ||
| 275 | - /** | ||
| 276 | - * 输入日志 | ||
| 277 | - * @param $message | ||
| 278 | - * @return bool | ||
| 279 | - */ | ||
| 280 | - public function output($message) | ||
| 281 | - { | ||
| 282 | - $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 283 | - echo $message; | ||
| 284 | - return true; | ||
| 285 | - } | ||
| 286 | - | ||
| 287 | - /** | ||
| 288 | - * 通知C端生成界面 | ||
| 289 | - * @param $project_id | ||
| 290 | - * @return bool | ||
| 291 | - */ | ||
| 292 | - public function updateRoutes($routes){ | ||
| 293 | - $domainModel = new DomainInfo(); | ||
| 294 | - $project_model = new Project(); | ||
| 295 | - foreach ($routes as $project_id => $route){ | ||
| 296 | - $route[] = 'top-video'; | ||
| 297 | - $domain = $domainModel->getProjectIdDomain($project_id); | ||
| 298 | - if (empty($domain)) { | ||
| 299 | - $this->output('send: 域名不存在, project id: ' . $project_id); | ||
| 300 | - continue; | ||
| 301 | - } | ||
| 302 | - //判断是否是自建站服务器,如果是,不请求C端接口,数据直接入库 | ||
| 303 | - $project_info = $project_model->read(['id'=>$project_id],['serve_id']); | ||
| 304 | - if(!$project_info){ | ||
| 305 | - $this->output('send: 项目不存在, project id: ' . $project_id); | ||
| 306 | - continue; | ||
| 307 | - } | ||
| 308 | - $serve_ip_model = new ServersIp(); | ||
| 309 | - $serve_ip_info = $serve_ip_model->read(['id'=>$project_info['serve_id']],['servers_id']); | ||
| 310 | - $servers_id = $serve_ip_info ? $serve_ip_info['servers_id'] : 0; | ||
| 311 | - if($servers_id == ServerConfig::SELF_SITE_ID){ | ||
| 312 | - //判断是否已有更新进行中 | ||
| 313 | - $notify_model = new Notify(); | ||
| 314 | - $data = [ | ||
| 315 | - 'project_id' => $project_id, | ||
| 316 | - 'type' => Notify::TYPE_MASTER, | ||
| 317 | - 'route' => Notify::ROUTE_AI_BLOG, | ||
| 318 | - 'server_id' => ServerConfig::SELF_SITE_ID, | ||
| 319 | - 'status' => ['!=',Notify::STATUS_FINISH_SITEMAP] | ||
| 320 | - ]; | ||
| 321 | - $notify = $notify_model->read($data,['id']); | ||
| 322 | - if(!$notify){ | ||
| 323 | - $domain_array = parse_url($domain); | ||
| 324 | - $data['data'] = Arr::a2s(['domain'=>$domain_array['host'],'url'=>$route,'language'=>[]]); | ||
| 325 | - $data['status'] = Notify::STATUS_INIT; | ||
| 326 | - $data['sort'] = 2; | ||
| 327 | - $notify_model->add($data); | ||
| 328 | - } | ||
| 329 | - $this->output('send: 自建站项目, project id: ' . $project_id); | ||
| 330 | - }else{ | ||
| 331 | - $c_url = $domain.'api/update_page/'; | ||
| 332 | - $param = [ | ||
| 333 | - 'project_id' => $project_id, | ||
| 334 | - 'type' => 1, | ||
| 335 | - 'route' => 3, | ||
| 336 | - 'url' => $route, | ||
| 337 | - 'language'=> [], | ||
| 338 | - 'is_sitemap' => 0 | ||
| 339 | - ]; | ||
| 340 | - $res = http_post($c_url, json_encode($param,true)); | ||
| 341 | - $this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); | ||
| 342 | - } | ||
| 343 | - } | ||
| 344 | - return true; | ||
| 345 | - } | ||
| 346 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AuthorityScore.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/7/1 16:43 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\AuthorityScore; | ||
| 11 | - | ||
| 12 | -use App\Models\AuthorityScore\AuthorityScore as AuthorityScoreModel; | ||
| 13 | -use App\Models\Domain\DomainInfo; | ||
| 14 | -use App\Models\Project\Project; | ||
| 15 | -use Illuminate\Console\Command; | ||
| 16 | - | ||
| 17 | -class AuthorityScore extends Command | ||
| 18 | -{ | ||
| 19 | - /** | ||
| 20 | - * The name and signature of the console command. | ||
| 21 | - * | ||
| 22 | - * @var string | ||
| 23 | - */ | ||
| 24 | - protected $signature = 'authority_score'; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * The console command description. | ||
| 28 | - * | ||
| 29 | - * @var string | ||
| 30 | - */ | ||
| 31 | - protected $description = '白帽外链数据详情,每月统计一次'; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * @remark :执行方法 | ||
| 35 | - * @name :handle | ||
| 36 | - * @author :lyh | ||
| 37 | - * @method :post | ||
| 38 | - * @time :2025/7/1 16:46 | ||
| 39 | - */ | ||
| 40 | - public function handle(){ | ||
| 41 | - $projectModel = new Project(); | ||
| 42 | - $projectIdArr = $projectModel->selectField(['project_type'=>1,'delete_status' => 0,'extend_type'=>0,'type'=>2],'id'); | ||
| 43 | - $domainModel = new DomainInfo(); | ||
| 44 | - $url = 'https://www.cmer.site/api/domain/organic?domain='; | ||
| 45 | - foreach ($projectIdArr as $item){ | ||
| 46 | - $domainInfo = $domainModel->read(['project_id'=>$item],['domain']); | ||
| 47 | - if($domainInfo === false){ | ||
| 48 | - continue; | ||
| 49 | - } | ||
| 50 | - echo '执行的项目id'.$item.PHP_EOL; | ||
| 51 | - $urls = $url.$domainInfo['domain']; | ||
| 52 | - echo $urls.PHP_EOL; | ||
| 53 | - $data = http_get($urls); | ||
| 54 | - if(!empty($data) && !empty($data['data'])){ | ||
| 55 | - echo json_encode($data).PHP_EOL; | ||
| 56 | - $data = $data['data']; | ||
| 57 | - $this->saveHandleData($data,$item); | ||
| 58 | - } | ||
| 59 | - } | ||
| 60 | - return true; | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - /** | ||
| 64 | - * @remark :保存数据 | ||
| 65 | - * @name :handleData | ||
| 66 | - * @author :lyh | ||
| 67 | - * @method :post | ||
| 68 | - * @time :2025/7/1 17:23 | ||
| 69 | - */ | ||
| 70 | - public function saveHandleData($data,$project_id){ | ||
| 71 | - $authorityScoreModel = new AuthorityScoreModel(); | ||
| 72 | - return $authorityScoreModel->addReturnId([ | ||
| 73 | - 'project_id'=>$project_id, | ||
| 74 | - 'ascore'=>(int)($data['ascore'] ?? 0), | ||
| 75 | - 'total'=>(int)($data['total'] ?? 0), | ||
| 76 | - 'domains_num'=>(int)($data['domains_num'] ?? 0), | ||
| 77 | - 'rank'=>(int)($data['Rank'] ?? 0), | ||
| 78 | - 'organic_keywords'=>(int)($data['Organic_Keywords'] ?? 0), | ||
| 79 | - 'organic_traffic'=>(int)($data['Organic_Traffic'] ?? 0), | ||
| 80 | - 'date'=>date('Y-m-d') | ||
| 81 | - ]); | ||
| 82 | - } | ||
| 83 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\AyrShare; | ||
| 4 | - | ||
| 5 | -use App\Helper\AyrShare as AyrShareHelper; | ||
| 6 | -use App\Models\AyrShare\AyrShare as AyrShareModel; | ||
| 7 | -use Illuminate\Console\Command; | ||
| 8 | - | ||
| 9 | -class ShareConfig extends Command | ||
| 10 | -{ | ||
| 11 | - public $error = 0; | ||
| 12 | - /** | ||
| 13 | - * The name and signature of the console command. | ||
| 14 | - * | ||
| 15 | - * @var string | ||
| 16 | - */ | ||
| 17 | - protected $signature = 'share_config'; | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * The console command description. | ||
| 21 | - * | ||
| 22 | - * @var string | ||
| 23 | - */ | ||
| 24 | - protected $description = '更新用户Ayr_share配置'; | ||
| 25 | - /** | ||
| 26 | - * @name :(定时执行更新用户配置)handle | ||
| 27 | - * @author :lyh | ||
| 28 | - * @method :post | ||
| 29 | - * @time :2023/5/12 14:48 | ||
| 30 | - */ | ||
| 31 | - public function handle() | ||
| 32 | - { | ||
| 33 | - $ayrShareModel = new AyrShareModel(); | ||
| 34 | - //更新用户配置 | ||
| 35 | - $lists = $ayrShareModel->lists($this->map,$this->page,$this->row,'id',['id','profile_key','bind_plat_from']); | ||
| 36 | - foreach ($lists['list'] as $k => $v){ | ||
| 37 | - if(empty($v['profile_key'])){ | ||
| 38 | - continue; | ||
| 39 | - } | ||
| 40 | - //获取当前用户配置 | ||
| 41 | - $ayrShareHelper = new AyrShareHelper(); | ||
| 42 | - $share_info = $ayrShareHelper->get_profiles_users($v['profile_key']); | ||
| 43 | - if(!isset($share_info['activeSocialAccounts'])){ | ||
| 44 | - $ayrShareModel->edit(['bind_plat_from'=>''],['id'=>$v['id']]); | ||
| 45 | - continue; | ||
| 46 | - } | ||
| 47 | - $str = json_encode($share_info['activeSocialAccounts']); | ||
| 48 | - if($str != $v['bind_plat_from']){ | ||
| 49 | - $rs = $ayrShareModel->edit(['bind_plat_from'=>$str],['id'=>$v['id']]); | ||
| 50 | - if($rs === false){ | ||
| 51 | - $this->error++; | ||
| 52 | - } | ||
| 53 | - } | ||
| 54 | - } | ||
| 55 | - echo $this->error; | ||
| 56 | - } | ||
| 57 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\AyrShare; | ||
| 4 | -use App\Helper\AyrShare as AyrShareHelper; | ||
| 5 | -use App\Models\Ai\AiVideo; | ||
| 6 | -use App\Models\AyrShare\AyrRelease as AyrReleaseModel; | ||
| 7 | -use App\Models\Project\AiVideoTask; | ||
| 8 | -use App\Services\ProjectServer; | ||
| 9 | -use Carbon\Carbon; | ||
| 10 | -use App\Models\AyrShare\AyrShare as AyrShareModel; | ||
| 11 | -use Illuminate\Console\Command; | ||
| 12 | -use Illuminate\Support\Facades\DB; | ||
| 13 | - | ||
| 14 | -class ShareUser extends Command | ||
| 15 | -{ | ||
| 16 | - public $error = 0; | ||
| 17 | - /** | ||
| 18 | - * The name and signature of the console command. | ||
| 19 | - * | ||
| 20 | - * @var string | ||
| 21 | - */ | ||
| 22 | - protected $signature = 'share_user'; | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * The console command description. | ||
| 26 | - * | ||
| 27 | - * @var string | ||
| 28 | - */ | ||
| 29 | - protected $description = '用户一周内无记录清除Ayr_share'; | ||
| 30 | - /** | ||
| 31 | - * @name :(定时执行)handle | ||
| 32 | - * @author :lyh | ||
| 33 | - * @method :post | ||
| 34 | - * @time :2023/5/12 14:48 | ||
| 35 | - */ | ||
| 36 | - public function handle() | ||
| 37 | - { | ||
| 38 | - $this->output('start'); | ||
| 39 | - $this->user_operator_record(); | ||
| 40 | - return true; | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * @name : 检测用户是否无操作记录 | ||
| 45 | - * @author :lyh | ||
| 46 | - * @method :post | ||
| 47 | - * @time :2023/5/12 14:55 | ||
| 48 | - */ | ||
| 49 | - protected function user_operator_record(){ | ||
| 50 | - //获取所有ayr_share用户 | ||
| 51 | - $ayr_share_model = new AyrShareModel(); | ||
| 52 | - $ayr_release = new AyrReleaseModel(); | ||
| 53 | - $ayr_share_list = $ayr_share_model->list(['profile_key'=>['!=','']]); | ||
| 54 | - foreach ($ayr_share_list as $v){ | ||
| 55 | - $this->output('执行数据的邮箱--'.$v['title']); | ||
| 56 | - $time = Carbon::now()->modify('-1 days')->toDateString(); | ||
| 57 | - //创建时间小于7天前的当前时间 | ||
| 58 | - if($v['created_at'] > $time){ | ||
| 59 | - $this->output('创建时间小于7天跳过--'.$v['title']); | ||
| 60 | - continue; | ||
| 61 | - } | ||
| 62 | - //查询当前用户是否有未推送的博文 | ||
| 63 | - $release_info = $this->release_info($ayr_release,$v); | ||
| 64 | - //有推文时,直接跳出循环 | ||
| 65 | - if($release_info !== false){ | ||
| 66 | - $this->output('有未推送的推文直接跳过--'.$v['title']); | ||
| 67 | - continue; | ||
| 68 | - } | ||
| 69 | - //查询7天是否发送博文 | ||
| 70 | - $release_info = $this->release_seven_info($ayr_release,$v); | ||
| 71 | - //有发送博文,则跳出循环 | ||
| 72 | - if($release_info !== false){ | ||
| 73 | - $this->output('7天内有推文跳过--'.$v['title']); | ||
| 74 | - continue; | ||
| 75 | - } | ||
| 76 | - $aiVideoInfo = $this->aiVideoInfo($v['project_id'] ?? 0); | ||
| 77 | - if($aiVideoInfo !== false){ | ||
| 78 | - $this->output('7天内有ai视频推送跳过--'.$v['title']); | ||
| 79 | - continue; | ||
| 80 | - } | ||
| 81 | - //删除用户第三方配置 | ||
| 82 | - if(!empty($v['profile_key'])){ | ||
| 83 | - $res = $this->del_profiles($v); | ||
| 84 | - if($res === false){ | ||
| 85 | - continue; | ||
| 86 | - } | ||
| 87 | - } | ||
| 88 | - //更新数据库 | ||
| 89 | - $this->save_ayr_share($ayr_share_model,$v); | ||
| 90 | - } | ||
| 91 | - return $this->error; | ||
| 92 | - } | ||
| 93 | - | ||
| 94 | - /** | ||
| 95 | - * @name :(删除第三方配置)del_profiles | ||
| 96 | - * @author :lyh | ||
| 97 | - * @method :post | ||
| 98 | - * @time :2023/6/14 16:10 | ||
| 99 | - */ | ||
| 100 | - public function del_profiles($v){ | ||
| 101 | - $ayr_share_helper = new AyrShareHelper(); | ||
| 102 | - $data_profiles = [ | ||
| 103 | - 'title'=>$v['title'], | ||
| 104 | - 'profileKey'=>$v['profile_key'] | ||
| 105 | - ]; | ||
| 106 | - $res = $ayr_share_helper->deleted_profiles($data_profiles); | ||
| 107 | - if($res['status'] == 'fail'){ | ||
| 108 | - $this->output('第三方删除失败'.json_encode($data_profiles,true)); | ||
| 109 | - return false; | ||
| 110 | - } | ||
| 111 | - return true; | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - /** | ||
| 115 | - * @name :(更新数据库)save_ayr_share | ||
| 116 | - * @author :lyh | ||
| 117 | - * @method :post | ||
| 118 | - * @time :2023/6/14 16:14 | ||
| 119 | - */ | ||
| 120 | - public function save_ayr_share(&$ayr_share_model,$v){ | ||
| 121 | - | ||
| 122 | - //更新数据库 | ||
| 123 | - $data = [ | ||
| 124 | - 'title'=>'', | ||
| 125 | - 'bind_platforms'=>'', | ||
| 126 | - 'profile_key'=>'', | ||
| 127 | - 'ref_id'=>'', | ||
| 128 | - ]; | ||
| 129 | - $res = $ayr_share_model->edit($data,['id'=>$v['id']]); | ||
| 130 | - if($res == false){ | ||
| 131 | - echo '更新数据库失败'; | ||
| 132 | - return true; | ||
| 133 | - } | ||
| 134 | - return true; | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - /** | ||
| 138 | - * @name :(查询是否有定时发送报文)info | ||
| 139 | - * @author :lyh | ||
| 140 | - * @method :post | ||
| 141 | - * @time :2023/6/14 16:17 | ||
| 142 | - */ | ||
| 143 | - public function release_info(&$ayr_release,$v){ | ||
| 144 | - //查询当前用户是否有未推送的博文 | ||
| 145 | - $release_info = $ayr_release->read(['schedule_date'=>['>',date('Y-m-d H:i:s',time())],'share_id'=>$v['id']]); | ||
| 146 | - return $release_info; | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - /** | ||
| 150 | - * @param $ayr_release | ||
| 151 | - * @name :7天内无发送记录release_seven_info | ||
| 152 | - * @author :lyh | ||
| 153 | - * @method :post | ||
| 154 | - * @time :2023/6/14 16:28 | ||
| 155 | - */ | ||
| 156 | - public function release_seven_info(&$ayr_release,$v){ | ||
| 157 | - //查看用户是否在一周内有发送博客 | ||
| 158 | - $start_at = Carbon::now()->modify('-7 days')->toDateString(); | ||
| 159 | - $end_at = Carbon::now()->toDateString(); | ||
| 160 | - $release_info = $ayr_release->read(['created_at'=>['between',[$start_at,$end_at]],'share_id'=>$v['id']]); | ||
| 161 | - return $release_info; | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - /** | ||
| 165 | - * @remark :7天内是否推送了ai视频 | ||
| 166 | - * @name :aiVidoe | ||
| 167 | - * @author :lyh | ||
| 168 | - * @method :post | ||
| 169 | - * @time :2025/9/22 17:13 | ||
| 170 | - */ | ||
| 171 | - public function aiVideoInfo($project_id) | ||
| 172 | - { | ||
| 173 | - if($project_id == 0){ | ||
| 174 | - return false; | ||
| 175 | - } | ||
| 176 | - $start_at = Carbon::now()->modify('-7 days')->toDateString(); | ||
| 177 | - $end_at = Carbon::now()->toDateString(); | ||
| 178 | - $aiVideoModel = new AiVideoTask(); | ||
| 179 | - $videoInfo = $aiVideoModel->read(['project_id'=>$project_id,'next_auto_date'=>null,'created_at'=>['between',[$start_at,$end_at]]]); | ||
| 180 | - return $videoInfo; | ||
| 181 | - } | ||
| 182 | - | ||
| 183 | - /** | ||
| 184 | - * 输入日志 | ||
| 185 | - * @param $message | ||
| 186 | - * @return bool | ||
| 187 | - */ | ||
| 188 | - public function output($message) | ||
| 189 | - { | ||
| 190 | - $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 191 | - echo $message; | ||
| 192 | - file_put_contents(storage_path('logs/share_user/') . date('Ymd') . '.log', $message, FILE_APPEND); | ||
| 193 | - return true; | ||
| 194 | - } | ||
| 195 | -} |
app/Console/Commands/CmdSignal.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Illuminate\Console\Command; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * TODO:: 如果想要在终止 任务时不让数据丢失或者异常,请使用此类 | ||
| 10 | - * @author:dc | ||
| 11 | - * @time 2023/8/21 11:03 | ||
| 12 | - * Class CmdSignal | ||
| 13 | - * @package App\Console\Commands | ||
| 14 | - */ | ||
| 15 | -trait CmdSignal | ||
| 16 | -{ | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * 是否停止 | ||
| 20 | - * @var bool | ||
| 21 | - */ | ||
| 22 | - public $isStop = false; | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 超时未退出,强制退出 暂时未实现 | ||
| 26 | - * @var int | ||
| 27 | - */ | ||
| 28 | - public $stopTimeOut = 30; | ||
| 29 | - | ||
| 30 | - | ||
| 31 | - public $debugLogFile = null; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * 调试输出 | ||
| 35 | - * @param $msg | ||
| 36 | - * @author:dc | ||
| 37 | - * @time 2023/8/21 11:22 | ||
| 38 | - */ | ||
| 39 | - public function debug_echo($msg){ | ||
| 40 | - if($this->debugLogFile){ | ||
| 41 | - @file_put_contents($this->debugLogFile,date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL,FILE_APPEND); | ||
| 42 | - }else{ | ||
| 43 | - echo date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL; | ||
| 44 | - } | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * @return bool | ||
| 49 | - */ | ||
| 50 | - public function handle() | ||
| 51 | - { | ||
| 52 | - | ||
| 53 | - if($this->isRunning()){ | ||
| 54 | - $this->debug_echo('脚本已运行,请无重复运行'); | ||
| 55 | - return 1; | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - $this->debug_echo('已启动脚本'); | ||
| 59 | - | ||
| 60 | - // 启动时 | ||
| 61 | - if(method_exists($this,'init')){ | ||
| 62 | - $this->init(); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | -// 注册信号处理程序 | ||
| 66 | -// SIGHUP:终端控制进程时终止或挂起进程 | ||
| 67 | -//SIGINT:中断进程(通常由CTRL+C发出) | ||
| 68 | -//SIGQUIT:退出进程并生成核心转储 | ||
| 69 | -//SIGILL:非法指令 | ||
| 70 | -//SIGABRT:由调试程序触发的异常终止信号 | ||
| 71 | -//SIGFPE:浮点异常 | ||
| 72 | -//SIGKILL:无条件终止进程 | ||
| 73 | -//SIGSEGV:无效的内存引用 | ||
| 74 | -//SIGPIPE:写入已关闭的FIFO或套接字时产生的信号 | ||
| 75 | -//SIGTERM:要求终止进程的信号 | ||
| 76 | -//SIGUSR1:用户定义的信号1 | ||
| 77 | -//SIGUSR2:用户定义的信号2 | ||
| 78 | - $handler = function ($signal){ | ||
| 79 | - // 可以处理其他程序 | ||
| 80 | - $this->isStop = true; | ||
| 81 | - }; | ||
| 82 | - pcntl_signal(SIGTERM, $handler); | ||
| 83 | - pcntl_signal(SIGINT, $handler); | ||
| 84 | -// pcntl_signal(SIGHUP, $handler); | ||
| 85 | - | ||
| 86 | - // 检查是否接收到信号 | ||
| 87 | - pcntl_signal_dispatch(); | ||
| 88 | - | ||
| 89 | - $tryNum = 0; | ||
| 90 | -// 无限循环,模拟进程运行 | ||
| 91 | - while (true) { | ||
| 92 | - // 做一些工作... 异常超过5次就重启下进程 | ||
| 93 | - if($this->isStop || $tryNum>5){ | ||
| 94 | - break; | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - try { | ||
| 98 | - $this->start(); | ||
| 99 | - }catch (\Throwable $e){ | ||
| 100 | - $tryNum++; | ||
| 101 | - // 保证此程序正常 | ||
| 102 | - $this->debug_echo('异常消息:'.$e->getMessage()); | ||
| 103 | - $this->debug_echo('异常文件:'.$e->getFile().':'.$e->getLine()); | ||
| 104 | - $this->debug_echo($e->getTraceAsString()); | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - $this->debug_echo('已退出程序'); | ||
| 111 | - | ||
| 112 | - | ||
| 113 | - return Command::SUCCESS; | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - | ||
| 117 | - /** | ||
| 118 | - * 获取进程启动名称 | ||
| 119 | - * @return mixed | ||
| 120 | - * @throws \Exception | ||
| 121 | - * @author:dc | ||
| 122 | - * @time 2023/8/21 11:43 | ||
| 123 | - */ | ||
| 124 | - public function getSignature(){ | ||
| 125 | - if(empty($this->signature)){ | ||
| 126 | - throw new \Exception('无法获取到启动命令'); | ||
| 127 | - } | ||
| 128 | - return $this->signature; | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - /** | ||
| 132 | - * 是否已运行 | ||
| 133 | - * @param int $max 最大运行多少进程 | ||
| 134 | - * @return bool | ||
| 135 | - * @throws \Exception | ||
| 136 | - * @author:dc | ||
| 137 | - * @time 2023/8/21 11:54 | ||
| 138 | - */ | ||
| 139 | - public function isRunning($max=1):bool { | ||
| 140 | - | ||
| 141 | - $ps = "ps -ef | grep \"artisan ".$this->getSignature()."\" | grep -v grep | wc -l"; | ||
| 142 | - | ||
| 143 | - $num = exec($ps); | ||
| 144 | - | ||
| 145 | - if(property_exists($this,'maxRunNumber')){ | ||
| 146 | - $max = $this->maxRunNumber; | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - if($num>$max){ | ||
| 150 | - return true; | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - return false; | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - | ||
| 157 | - | ||
| 158 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :CropImage.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/5/8 9:19 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\CropImage; | ||
| 11 | - | ||
| 12 | -use App\Enums\Common\Code; | ||
| 13 | -use App\Models\Domain\DomainInfo; | ||
| 14 | -use App\Models\File\Image; | ||
| 15 | -use App\Models\WebSetting\AggregationSetting; | ||
| 16 | -use App\Models\WebSetting\WebSettingImage; | ||
| 17 | -use App\Services\CosService; | ||
| 18 | -use App\Services\ProjectServer; | ||
| 19 | -use Illuminate\Console\Command; | ||
| 20 | -use Illuminate\Support\Facades\DB; | ||
| 21 | - | ||
| 22 | -class CropImage extends Command | ||
| 23 | -{ | ||
| 24 | - /** | ||
| 25 | - * The name and signature of the console command. | ||
| 26 | - * | ||
| 27 | - * @var string | ||
| 28 | - */ | ||
| 29 | - protected $signature = 'crop_image {project_id}'; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * The console command description. | ||
| 33 | - * | ||
| 34 | - * @var string | ||
| 35 | - */ | ||
| 36 | - protected $description = '裁剪图片'; | ||
| 37 | - | ||
| 38 | - public function handle(){ | ||
| 39 | - echo '测试裁剪->cs-crop:'.PHP_EOL; | ||
| 40 | - $project_id = $this->argument('project_id'); | ||
| 41 | - ProjectServer::useProject($project_id); | ||
| 42 | - $data = $this->_keywordAction($project_id); | ||
| 43 | - $this->_aiAction($project_id,$data[0] ?? []); | ||
| 44 | - DB::disconnect('custom_mysql'); | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * @remark :执行的方法 | ||
| 49 | - * @name :_action | ||
| 50 | - * @author :lyh | ||
| 51 | - * @method :post | ||
| 52 | - * @time :2025/5/8 9:21 | ||
| 53 | - */ | ||
| 54 | - public function _keywordAction($project_id){ | ||
| 55 | - $resData = []; | ||
| 56 | - //聚合页裁剪 | ||
| 57 | - $data = $this->getKeywordImage($project_id); | ||
| 58 | - $cosService = new CosService(); | ||
| 59 | - if(!empty($data)){ | ||
| 60 | - foreach ($data as $val){ | ||
| 61 | - //处理图片为相对路径 | ||
| 62 | - $image = str_replace_url($val); | ||
| 63 | - $height = $cosService->getImageHeight($image); | ||
| 64 | - if(empty($height)){ | ||
| 65 | - echo '未获取到图片高度。'.PHP_EOL; | ||
| 66 | - continue; | ||
| 67 | - } | ||
| 68 | - echo '返回的图片高度:'.$height.PHP_EOL; | ||
| 69 | - if($height > 220){ | ||
| 70 | - $result = $cosService->cropCosImage($image); | ||
| 71 | - if(empty($result)){ | ||
| 72 | - continue; | ||
| 73 | - } | ||
| 74 | - $resData[] = $result['path']; | ||
| 75 | - $this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']); | ||
| 76 | - }else{ | ||
| 77 | - $resData[] = $image; | ||
| 78 | - } | ||
| 79 | - } | ||
| 80 | - } | ||
| 81 | - $this->saveAggregationSetting($project_id,$resData); | ||
| 82 | - return $resData; | ||
| 83 | - } | ||
| 84 | - | ||
| 85 | - /** | ||
| 86 | - * @remark :ai执行方法 | ||
| 87 | - * @name :_aiAction | ||
| 88 | - * @author :lyh | ||
| 89 | - * @method :post | ||
| 90 | - * @time :2025/5/8 16:12 | ||
| 91 | - */ | ||
| 92 | - public function _aiAction($project_id,$keywordImage){ | ||
| 93 | - $cosService = new CosService(); | ||
| 94 | - //ai_blog裁剪 | ||
| 95 | - $ai_image = $this->getAiBlogImage($project_id,$keywordImage ?? []); | ||
| 96 | - if(empty($ai_image)){ | ||
| 97 | - echo '当前图片不需要裁剪。'.PHP_EOL; | ||
| 98 | - return true; | ||
| 99 | - } | ||
| 100 | - $height = $cosService->getImageHeight($ai_image); | ||
| 101 | - if(empty($height)){ | ||
| 102 | - echo '未获取到AI_BLOG图片高度。'.PHP_EOL; | ||
| 103 | - return true; | ||
| 104 | - } | ||
| 105 | - echo '返回的图片高度:'.$height.PHP_EOL; | ||
| 106 | - if($height > 220){ | ||
| 107 | - $result = $cosService->cropCosImage($ai_image); | ||
| 108 | - if(empty($result)){ | ||
| 109 | - return true; | ||
| 110 | - } | ||
| 111 | - $this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']); | ||
| 112 | - $webSettingImageModel = new WebSettingImage(); | ||
| 113 | - $webSettingImageModel->edit(['image'=>$result['path']],['project_id' => $project_id, 'type' => 4]); | ||
| 114 | - } | ||
| 115 | - return true; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - /** | ||
| 119 | - * @remark :保存数据 | ||
| 120 | - * @name :saveAggregationSetting | ||
| 121 | - * @author :lyh | ||
| 122 | - * @method :post | ||
| 123 | - * @time :2025/5/8 16:24 | ||
| 124 | - */ | ||
| 125 | - public function saveAggregationSetting($project_id,$data){ | ||
| 126 | - if(empty($data)){ | ||
| 127 | - return true; | ||
| 128 | - } | ||
| 129 | - //存全路径 | ||
| 130 | - foreach ($data as $key => $val){ | ||
| 131 | - $val = getImageUrl($val); | ||
| 132 | - $data[$key] = $val; | ||
| 133 | - } | ||
| 134 | - $aggregationSettingModel = new AggregationSetting(); | ||
| 135 | - $info = $aggregationSettingModel->read(['project_id'=>$project_id]); | ||
| 136 | - if($info === false){ | ||
| 137 | - $aggregationSettingModel->addReturnId(['project_id'=>$project_id,'top_banner'=>json_encode($data,true)]); | ||
| 138 | - }else{ | ||
| 139 | - $aggregationSettingModel->edit(['top_banner'=>json_encode($data,true)],['id'=>$info['id']]); | ||
| 140 | - } | ||
| 141 | - return true; | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - /** | ||
| 145 | - * @remark :获取aiBlog图片 | ||
| 146 | - * @name :getAiBlogImage | ||
| 147 | - * @author :lyh | ||
| 148 | - * @method :post | ||
| 149 | - * @time :2025/5/8 10:42 | ||
| 150 | - */ | ||
| 151 | - public function getAiBlogImage($project_id,$keywordImage){ | ||
| 152 | - // AI博客banner type:1:产品,2:博客,3:新闻,4:AIBlog | ||
| 153 | - $webSettingImageModel = new WebSettingImage(); | ||
| 154 | - $aiBlogInfo = $webSettingImageModel->read(['project_id' => $project_id, 'type' => 4],['image']); | ||
| 155 | - if($aiBlogInfo === false && !empty($keywordImage)){ | ||
| 156 | - $webSettingImageModel->addReturnId(['project_id'=>$project_id,'image'=>$keywordImage,'type'=>4]); | ||
| 157 | - return ''; | ||
| 158 | - } | ||
| 159 | - if(empty($aiBlogInfo['image']) && !empty($keywordImage)){ | ||
| 160 | - $webSettingImageModel->edit(['image'=>$keywordImage],['id'=>$aiBlogInfo['id']]); | ||
| 161 | - return ''; | ||
| 162 | - } | ||
| 163 | - $ai_image = str_replace_url($aiBlogInfo['image']); | ||
| 164 | - return $ai_image; | ||
| 165 | - } | ||
| 166 | - | ||
| 167 | - /** | ||
| 168 | - * @remark :获取聚合页图片 | ||
| 169 | - * @name :getImage | ||
| 170 | - * @author :lyh | ||
| 171 | - * @method :post | ||
| 172 | - * @time :2025/5/8 9:21 | ||
| 173 | - */ | ||
| 174 | - public function getKeywordImage($project_id){ | ||
| 175 | - $data = []; | ||
| 176 | - // 聚合页banner | ||
| 177 | - $aggregationSettingModel = new AggregationSetting(); | ||
| 178 | - $aggregationSettingInfo = $aggregationSettingModel->read(['project_id' => $project_id],['id','top_banner']); | ||
| 179 | - if($aggregationSettingInfo !== false && !empty($aggregationSettingInfo['top_banner'])){ | ||
| 180 | - foreach ($aggregationSettingInfo['top_banner'] as $val){ | ||
| 181 | - if($val != 'jpg' && $val != 'png' && $val != 'webp'){ | ||
| 182 | - $data[] = $val; | ||
| 183 | - } | ||
| 184 | - } | ||
| 185 | - } | ||
| 186 | - if(empty($data)){ | ||
| 187 | - //重页面上获取首页banner | ||
| 188 | - $data = $this->getDomImage($project_id); | ||
| 189 | - } | ||
| 190 | - return $data; | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | - /** | ||
| 194 | - * @remark :页面上获取图片 | ||
| 195 | - * @name :getDomImage | ||
| 196 | - * @author :lyh | ||
| 197 | - * @method :post | ||
| 198 | - * @time :2025/5/8 10:32 | ||
| 199 | - */ | ||
| 200 | - public function getDomImage($project_id){ | ||
| 201 | - $data = []; | ||
| 202 | - echo '获取首页banner:' . $project_id . PHP_EOL; | ||
| 203 | - $domainModel = new DomainInfo(); | ||
| 204 | - $domainInfo = $domainModel->read(['project_id' => $project_id, 'status' => 1]); | ||
| 205 | - if ($domainInfo !== false) { | ||
| 206 | - $dom = @file_get_html('https://' . $domainInfo['domain'] . '/'); | ||
| 207 | - if (empty($dom)) { | ||
| 208 | - $this->output('获取HTML失败: ' . $project_id); | ||
| 209 | - }else{ | ||
| 210 | - $banner_dom = $dom->find('main .section-banner-wrap-block img', 0); | ||
| 211 | - $data[] = $banner_dom ? $banner_dom->src : ''; | ||
| 212 | - $dom->clear(); | ||
| 213 | - unset($dom); | ||
| 214 | - } | ||
| 215 | - }else{ | ||
| 216 | - $this->output('域名不存在: ' . $project_id); | ||
| 217 | - } | ||
| 218 | - return $data; | ||
| 219 | - } | ||
| 220 | - | ||
| 221 | - /** | ||
| 222 | - * @remark :写入数据库 | ||
| 223 | - * @name :saveMysql | ||
| 224 | - * @author :lyh | ||
| 225 | - * @method :post | ||
| 226 | - * @time :2025/5/8 14:59 | ||
| 227 | - */ | ||
| 228 | - public function saveMysql($project_id,$size,$image_type,$path,$mime = ''){ | ||
| 229 | - $hash = md5($path); | ||
| 230 | - $imageModel = new Image(); | ||
| 231 | - $info = $imageModel->read(['hash'=>$hash,'project_id'=>$project_id]); | ||
| 232 | - $data = [ | ||
| 233 | - 'path' => $path, | ||
| 234 | - 'size' => $size, | ||
| 235 | - 'hash' => $hash, | ||
| 236 | - 'type' => $image_type, | ||
| 237 | - 'refer'=> 0, | ||
| 238 | - 'mime' => $mime, | ||
| 239 | - 'project_id'=>$project_id, | ||
| 240 | - 'name'=>basename($path), | ||
| 241 | - 'en_name'=>basename($path) | ||
| 242 | - ]; | ||
| 243 | - if($info === false){ | ||
| 244 | - $imageModel->addReturnId($data); | ||
| 245 | - }else{ | ||
| 246 | - $imageModel->edit($data,['id'=>$info['id']]); | ||
| 247 | - } | ||
| 248 | - return true; | ||
| 249 | - } | ||
| 250 | - | ||
| 251 | - /** | ||
| 252 | - * @remark :记录日志 | ||
| 253 | - * @name :output | ||
| 254 | - * @author :lyh | ||
| 255 | - * @method :post | ||
| 256 | - * @time :2025/5/8 9:57 | ||
| 257 | - */ | ||
| 258 | - public function output($message, $log_file = 'logs/crop_image.log') | ||
| 259 | - { | ||
| 260 | - $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 261 | - echo $message; | ||
| 262 | - file_put_contents(storage_path($log_file), $message, FILE_APPEND); | ||
| 263 | - return true; | ||
| 264 | - } | ||
| 265 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :AfterDayCount.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2025/3/26 15:28 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DayCount; | ||
| 11 | - | ||
| 12 | -use App\Models\ASide\APublicModel; | ||
| 13 | -use App\Models\Channel\Channel; | ||
| 14 | -use App\Models\Manage\ManageHr; | ||
| 15 | -use App\Models\Project\Project; | ||
| 16 | -use App\Models\RankData\RankDataLog; | ||
| 17 | -use Carbon\Carbon; | ||
| 18 | -use App\Models\HomeCount\AfterCount as AfterCountModel; | ||
| 19 | -use Illuminate\Console\Command; | ||
| 20 | - | ||
| 21 | -class AfterDayCount extends Command | ||
| 22 | -{ | ||
| 23 | - /** | ||
| 24 | - * The name and signature of the console command. | ||
| 25 | - * | ||
| 26 | - * @var string | ||
| 27 | - */ | ||
| 28 | - protected $signature = 'after_count'; | ||
| 29 | - | ||
| 30 | - protected $managerHrModel; | ||
| 31 | - | ||
| 32 | - public $after_manager = [ | ||
| 33 | - 1 => ['许璐','王袁袁'], | ||
| 34 | - 2 => ['陈思蓓'], | ||
| 35 | - 3 => ['张国英'] | ||
| 36 | - ]; | ||
| 37 | - | ||
| 38 | - /** | ||
| 39 | - * The console command description. | ||
| 40 | - * | ||
| 41 | - * @var string | ||
| 42 | - */ | ||
| 43 | - protected $description = '统计昨日售后数据'; | ||
| 44 | - | ||
| 45 | - public function handle(){ | ||
| 46 | - echo date('Y-m-d H:i:s').'统计start->'.PHP_EOL; | ||
| 47 | - $saveData = $this->_action(); | ||
| 48 | - $afterModel = new AfterCountModel(); | ||
| 49 | - //保存数据 | ||
| 50 | - $afterModel->insertAll($saveData); | ||
| 51 | - echo date('Y-m-d H:i:s').'->统计end'.PHP_EOL; | ||
| 52 | - return true; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - /** | ||
| 56 | - * @remark :执行方法 | ||
| 57 | - * @name :_action | ||
| 58 | - * @author :lyh | ||
| 59 | - * @method :post | ||
| 60 | - * @time :2025/3/26 15:29 | ||
| 61 | - */ | ||
| 62 | - public function _action(){ | ||
| 63 | - $this->managerHrModel = new ManageHr(); | ||
| 64 | - $projectModel = new Project(); | ||
| 65 | - $rankDataLogModel = new RankDataLog(); | ||
| 66 | - $date = date('Y-m-d'); | ||
| 67 | - $saveData = []; | ||
| 68 | -// $projectIdArr = $rankDataLogModel->selectField(['is_compliance'=>1,'lang'=>'','date'=>date('Y-m-d', strtotime('-3 months'))],'project_id');//3个月前达标的项目id | ||
| 69 | - foreach ($this->after_manager as $key => $valM){ | ||
| 70 | - $idArr = $this->managerHrModel->selectField(['name'=>['in',$valM]],'id'); | ||
| 71 | - echo '对应优化师id:'.json_encode($idArr).PHP_EOL; | ||
| 72 | - $project_count = $projectModel->where('gl_project.extend_type',0) | ||
| 73 | - ->where('gl_project.delete_status',0) | ||
| 74 | - ->where('gl_project.old_project_id',0) | ||
| 75 | - ->where('gl_project_deploy_optimize.start_date','<=',$date) | ||
| 76 | - ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr) | ||
| 77 | - ->whereIn('gl_project.type',[2,4,6]) | ||
| 78 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 79 | - ->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0") | ||
| 80 | - ->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0") | ||
| 81 | - ->count(); | ||
| 82 | - $qualified_count = $projectModel->where('gl_project.extend_type',0) | ||
| 83 | - ->where('gl_project.delete_status',0) | ||
| 84 | - ->where('gl_project.old_project_id',0) | ||
| 85 | - ->where('gl_project_deploy_optimize.start_date','<=',$date) | ||
| 86 | - ->where('gl_project.is_remain_today',1) | ||
| 87 | - ->where('gl_project_deploy_build.plan','!=',0) | ||
| 88 | - ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr) | ||
| 89 | - ->whereIn('gl_project.type',[2,4,6]) | ||
| 90 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 91 | - ->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id') | ||
| 92 | - ->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0") | ||
| 93 | - ->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0") | ||
| 94 | - ->count(); | ||
| 95 | - $rate = number_format($qualified_count / $project_count, 2); | ||
| 96 | - $threeMonthsAgo = date('Y-m', strtotime('-3 months')); | ||
| 97 | - echo '3个月前的时间:'.$threeMonthsAgo.PHP_EOL; | ||
| 98 | - $three_project_count = $projectModel->where('gl_project.extend_type',0) | ||
| 99 | - ->where('gl_project.delete_status',0) | ||
| 100 | - ->where('gl_project.old_project_id',0) | ||
| 101 | - ->where('gl_project_deploy_optimize.start_date','>=',$threeMonthsAgo.'-01') | ||
| 102 | - ->where('gl_project_deploy_optimize.start_date','<=',$threeMonthsAgo.'-31') | ||
| 103 | - ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr) | ||
| 104 | - ->whereIn('gl_project.type',[2,4,6]) | ||
| 105 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 106 | - ->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0") | ||
| 107 | - ->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0") | ||
| 108 | - ->count(); | ||
| 109 | - $three_qualified_count = $projectModel->where('gl_project.extend_type',0) | ||
| 110 | - ->where('gl_project.delete_status',0) | ||
| 111 | - ->where('gl_project.old_project_id',0) | ||
| 112 | - ->where('gl_project.is_remain_today',1) | ||
| 113 | - ->where('gl_project_deploy_optimize.start_date','>=',$threeMonthsAgo.'-01') | ||
| 114 | - ->where('gl_project_deploy_optimize.start_date','<=',$threeMonthsAgo.'-31') | ||
| 115 | - ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr) | ||
| 116 | - ->whereIn('gl_project.type',[2,4,6]) | ||
| 117 | - ->where('gl_project_deploy_build.plan','!=',0) | ||
| 118 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 119 | - ->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id') | ||
| 120 | - ->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0") | ||
| 121 | - ->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0") | ||
| 122 | - ->count(); | ||
| 123 | - if($three_project_count != 0){ | ||
| 124 | - $three_rate = number_format($three_qualified_count / $three_project_count, 2); | ||
| 125 | - }else{ | ||
| 126 | - $three_rate = 0; | ||
| 127 | - } | ||
| 128 | - $data = $projectModel->where('gl_project.extend_type',0) | ||
| 129 | - ->where('gl_project.delete_status',0) | ||
| 130 | - ->where('gl_project.old_project_id',0) | ||
| 131 | - ->where('gl_project_deploy_optimize.start_date','>=',$threeMonthsAgo.'-01') | ||
| 132 | - ->where('gl_project_deploy_optimize.start_date','<=',$threeMonthsAgo.'-31') | ||
| 133 | - ->where('gl_project.is_remain_today',1) | ||
| 134 | - ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr) | ||
| 135 | - ->whereIn('gl_project.type',[2,4,6]) | ||
| 136 | - ->leftJoin('gl_project_payment', 'gl_project.id', '=', 'gl_project_payment.project_id') | ||
| 137 | - ->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id') | ||
| 138 | - ->leftJoin('gl_domain_info', 'gl_project.id', '=', 'gl_domain_info.project_id') | ||
| 139 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 140 | - ->leftJoin('gl_project_online_check', 'gl_project.id', '=', 'gl_project_online_check.project_id') | ||
| 141 | - ->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0") | ||
| 142 | - ->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0") | ||
| 143 | - ->select($this->selectParam())->get()->toArray(); | ||
| 144 | - foreach ($data as $k=>$val){ | ||
| 145 | - $this->handleParam($val); | ||
| 146 | - $data[$k] = $val; | ||
| 147 | - } | ||
| 148 | - $saveData[] = [ | ||
| 149 | - 'date'=>date('Y-m-d'), | ||
| 150 | - 'type'=> $key, | ||
| 151 | - 'project_count'=>$project_count, | ||
| 152 | - 'qualified_count'=>$qualified_count, | ||
| 153 | - 'rate'=>$rate, | ||
| 154 | - 'three_project_count'=>$three_project_count, | ||
| 155 | - 'three_qualified_count'=>$three_qualified_count, | ||
| 156 | - 'three_rate'=>$three_rate, | ||
| 157 | - 'data' => json_encode($data,true) | ||
| 158 | - ]; | ||
| 159 | - } | ||
| 160 | - return $saveData; | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - | ||
| 164 | - public function selectParam(){ | ||
| 165 | - $select = [ | ||
| 166 | - 'gl_project.id AS id', | ||
| 167 | - 'gl_project.title AS title', | ||
| 168 | - 'gl_project.level AS level', | ||
| 169 | - 'gl_project.channel AS channel', | ||
| 170 | - 'gl_project.company AS company', | ||
| 171 | - 'gl_project.type AS type', | ||
| 172 | - 'gl_project.created_at AS created_at', | ||
| 173 | - 'gl_project.is_language AS is_language', | ||
| 174 | - 'gl_project.cooperate_date AS cooperate_date', | ||
| 175 | - 'gl_project.finish_remain_day AS finish_remain_day', | ||
| 176 | - 'gl_project.is_remain_today AS is_remain_today', | ||
| 177 | - 'gl_project.remain_day AS remain_day', | ||
| 178 | - 'gl_project.seo_remain_day AS seo_remain_day', | ||
| 179 | - 'gl_project.robots AS robots', | ||
| 180 | - 'gl_project.is_minor_languages AS is_minor_languages', | ||
| 181 | - 'gl_project.is_translate AS is_translate', | ||
| 182 | - 'gl_project.is_translate_tag AS is_translate_tag', | ||
| 183 | - 'gl_project.is_upgrade AS is_upgrade', | ||
| 184 | - 'gl_project.site_status AS site_status', | ||
| 185 | - 'gl_project_online_check.id AS online_check_id', | ||
| 186 | - 'gl_project_online_check.question AS question', | ||
| 187 | - 'gl_project_online_check.go_question AS go_question', | ||
| 188 | - 'gl_project_online_check.optimist_status AS optimist_status', | ||
| 189 | - 'gl_project_online_check.qa_status AS qa_status', | ||
| 190 | - 'gl_project_online_check.updated_at AS online_updated_at', | ||
| 191 | - 'gl_project_payment.amount AS amount', | ||
| 192 | - 'gl_project_deploy_build.dept_id AS dept_id', | ||
| 193 | - 'gl_project_deploy_build.keyword_num AS key', | ||
| 194 | - 'gl_project_deploy_build.service_duration AS day', | ||
| 195 | - 'gl_project_deploy_build.leader_mid AS leader_mid', | ||
| 196 | - 'gl_project_deploy_build.manager_mid AS manager_mid', | ||
| 197 | - 'gl_project_deploy_build.designer_mid AS designer_mid', | ||
| 198 | - 'gl_project_deploy_build.tech_mid AS tech_mid', | ||
| 199 | - 'gl_project_deploy_build.test_domain AS test_domain', | ||
| 200 | - 'gl_project_deploy_build.plan AS plan', | ||
| 201 | - 'gl_project_deploy_build.seo_plan AS seo_plan', | ||
| 202 | - 'gl_project_deploy_optimize.dept_id AS optimize_dept_id', | ||
| 203 | - 'gl_project_deploy_optimize.manager_mid AS optimize_manager_mid', | ||
| 204 | - 'gl_project_deploy_optimize.optimist_mid AS optimize_optimist_mid', | ||
| 205 | - 'gl_project_deploy_optimize.assist_mid AS optimize_assist_mid', | ||
| 206 | - 'gl_project_deploy_optimize.tech_mid AS optimize_tech_mid', | ||
| 207 | - 'gl_project_deploy_optimize.design_mid AS design_mid', | ||
| 208 | - 'gl_project_deploy_optimize.tech_leader AS tech_leader', | ||
| 209 | - 'gl_project_deploy_optimize.quality_mid AS quality_mid', | ||
| 210 | - 'gl_project_deploy_optimize.design_mid AS design_mid', | ||
| 211 | - 'gl_project_deploy_optimize.start_date AS start_date', | ||
| 212 | - 'gl_project_deploy_optimize.backlink AS backlink', | ||
| 213 | - 'gl_project_deploy_optimize.ai_video AS ai_video', | ||
| 214 | - 'gl_project_deploy_optimize.api_no AS api_no', | ||
| 215 | - 'gl_project_deploy_optimize.first_compliance_time AS first_compliance_time', | ||
| 216 | - 'gl_domain_info.amp_status AS amp_status', | ||
| 217 | - 'gl_domain_info.domain AS domain', | ||
| 218 | - ]; | ||
| 219 | - return $select; | ||
| 220 | - } | ||
| 221 | - | ||
| 222 | - public function handleParam(&$item){ | ||
| 223 | - $data = APublicModel::getNumByProjectId($item['id']); | ||
| 224 | - $manageModel = new ManageHr(); | ||
| 225 | - $plan = Project::planMap(); | ||
| 226 | - $seo_plan = Project::seoMap(); | ||
| 227 | - $item['plan'] = $plan[$item['plan']] ?? $seo_plan[1]; | ||
| 228 | - $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); | ||
| 229 | - $item['build_leader'] = $manageModel->getName($item['leader_mid']); | ||
| 230 | - $item['build_manager'] = $manageModel->getName($item['manager_mid']); | ||
| 231 | - $item['build_designer'] = $manageModel->getName($item['designer_mid']); | ||
| 232 | - $item['build_tech'] = $manageModel->getName($item['tech_mid']); | ||
| 233 | - $item['optimize_manager'] = $manageModel->getName($item['optimize_manager_mid']); | ||
| 234 | - $item['optimize_optimist'] = $manageModel->getName($item['optimize_optimist_mid']); | ||
| 235 | - $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); | ||
| 236 | - $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); | ||
| 237 | - $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); | ||
| 238 | - $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date'])); | ||
| 239 | - $item['autologin_code'] = getAutoLoginCode($item['id']); | ||
| 240 | - $item['domain'] = 'https://'.$item['domain'].'/'; | ||
| 241 | - if(!empty($item['domain']) && $item['amp_status'] == 1){ | ||
| 242 | - $item['amp_domain'] = str_replace('www','m',$item['domain']); | ||
| 243 | - } | ||
| 244 | - $item['product_num'] = $data['product'] ?? 0; | ||
| 245 | - $item['keyword_num'] = $item['key'] ?? 0; | ||
| 246 | - $item['inquiry_num'] = $data['inquiry'] ?? 0; | ||
| 247 | - $item['autologin_code'] = getAutoLoginCode($item['id']); | ||
| 248 | - return $item; | ||
| 249 | - } | ||
| 250 | -} |
app/Console/Commands/DayCount/Count.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\DayCount; | ||
| 4 | - | ||
| 5 | -use App\Helper\FormGlobalsoApi; | ||
| 6 | -use App\Models\Domain\DomainInfo; | ||
| 7 | -use App\Models\Inquiry\InquiryFormData; | ||
| 8 | -use App\Models\Project\Project; | ||
| 9 | -use App\Services\ProjectServer; | ||
| 10 | -use Carbon\Carbon; | ||
| 11 | -use Illuminate\Console\Command; | ||
| 12 | -use Illuminate\Support\Facades\DB; | ||
| 13 | -use Illuminate\Support\Facades\Log; | ||
| 14 | - | ||
| 15 | -class Count extends Command | ||
| 16 | -{ | ||
| 17 | - const STATUS_ERROR = 400; | ||
| 18 | - public $error = 0; | ||
| 19 | - /** | ||
| 20 | - * The name and signature of the console command. | ||
| 21 | - * | ||
| 22 | - * @var string | ||
| 23 | - */ | ||
| 24 | - protected $signature = 'count'; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * The console command description. | ||
| 28 | - * | ||
| 29 | - * @var string | ||
| 30 | - */ | ||
| 31 | - protected $description = '统计昨日数据'; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * @name :(定时执行生成昨日数据统计)handle | ||
| 35 | - * @author :lyh | ||
| 36 | - * @method :post | ||
| 37 | - * @time :2023/5/12 14:48 | ||
| 38 | - */ | ||
| 39 | - public function handle() | ||
| 40 | - { | ||
| 41 | - $list = DB::table('gl_project')->where('gl_project.extend_type',0)->where('gl_project.delete_status',0) | ||
| 42 | - ->whereIn('gl_project.type',[1,2,3,4,6]) | ||
| 43 | - ->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id') | ||
| 44 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 45 | - ->select($this->selectParam())->get(); | ||
| 46 | - try { | ||
| 47 | - if(!empty($list)){ | ||
| 48 | - $list = $list->toArray(); | ||
| 49 | - $yesterday = Carbon::yesterday()->toDateString(); | ||
| 50 | - $domainInfo = new DomainInfo(); | ||
| 51 | - foreach ($list as $v){ | ||
| 52 | - $v = (array)$v; | ||
| 53 | - echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL; | ||
| 54 | - if($v['type'] == Project::TYPE_ZERO){ | ||
| 55 | - continue; | ||
| 56 | - } | ||
| 57 | - if(!empty($v['domain'])){ | ||
| 58 | - $info = $domainInfo->read(['id'=>$v['domain']]); | ||
| 59 | - if($info !== false){ | ||
| 60 | - $v['test_domain'] = $info['domain']; | ||
| 61 | - } | ||
| 62 | - } | ||
| 63 | - $arr = []; | ||
| 64 | - //统计时间 | ||
| 65 | - $arr['date'] = $yesterday; | ||
| 66 | - ProjectServer::useProject($v['id']); | ||
| 67 | - //pv统计 | ||
| 68 | - $arr['pv_num'] = $this->pv_num($yesterday); | ||
| 69 | - //ip统计 | ||
| 70 | - $arr['ip_num'] = $this->ip_num($yesterday); | ||
| 71 | - DB::disconnect('custom_mysql'); | ||
| 72 | - //服务达标天数 | ||
| 73 | - $arr['compliance_day'] = $v['finish_remain_day']; | ||
| 74 | - //剩余服务时常 | ||
| 75 | - $arr['service_day'] = ($v['remain_day'] - 1) < 0 ? 0: $v['remain_day'] - 1; | ||
| 76 | - //项目id | ||
| 77 | - $arr['project_id'] = $v['project_id']; | ||
| 78 | - $arr['created_at'] = date('Y-m-d H:i:s'); | ||
| 79 | - $arr['updated_at'] = date('Y-m-d H:i:s'); | ||
| 80 | - //询盘统计 | ||
| 81 | - $arr = $this->inquiry($arr,$v['test_domain'], $v['id'] , $v['is_upgrade'] ?? 0); | ||
| 82 | - //查询当天数据是否存在 存在则更新 | ||
| 83 | - $countModel = new \App\Models\HomeCount\Count(); | ||
| 84 | - $info = $countModel->read(['date'=>$arr['date'],'project_id'=>$v['id']]); | ||
| 85 | - if($info === false){ | ||
| 86 | - DB::table('gl_count')->insert($arr); | ||
| 87 | - }else{ | ||
| 88 | - $countModel->edit($arr,['id'=>$info['id']]); | ||
| 89 | - } | ||
| 90 | - Log::channel('day_count')->error('日期:'.$arr['created_at'].'success: ' .$v['test_domain']); | ||
| 91 | - } | ||
| 92 | - } | ||
| 93 | - }catch (\Exception $e){ | ||
| 94 | - Log::channel('day_count')->error('day_count:->error ' . $e->getMessage()); | ||
| 95 | - } | ||
| 96 | - Log::channel('day_count')->error('success:end'); | ||
| 97 | - echo $this->error; | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - /** | ||
| 101 | - * @name :(统计pv)pv_num | ||
| 102 | - * @author :lyh | ||
| 103 | - * @method :post | ||
| 104 | - * @time :2023/6/14 15:40 | ||
| 105 | - */ | ||
| 106 | - public function pv_num($yesterday){ | ||
| 107 | - $pv = DB::connection('custom_mysql')->table('gl_customer_visit_item')->whereDate('updated_date', $yesterday)->count(); | ||
| 108 | - return $pv; | ||
| 109 | - } | ||
| 110 | - | ||
| 111 | - /** | ||
| 112 | - * @name :(统计ip)ip_num | ||
| 113 | - * @author :lyh | ||
| 114 | - * @method :post | ||
| 115 | - * @time :2023/6/14 15:40 | ||
| 116 | - */ | ||
| 117 | - public function ip_num($yesterday){ | ||
| 118 | - $ip = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $yesterday)->count(); | ||
| 119 | - return $ip; | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - /** | ||
| 123 | - * @param $arr | ||
| 124 | - * @param $domain | ||
| 125 | - * @name :(询盘统计)inquiry | ||
| 126 | - * @author :lyh | ||
| 127 | - * @method :post | ||
| 128 | - * @time :2023/6/14 15:44 | ||
| 129 | - */ | ||
| 130 | - public function inquiry($arr,$domain,$project_id,$is_upgrade = 0){ | ||
| 131 | - $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$is_upgrade); | ||
| 132 | - if($inquiry_list == false){ | ||
| 133 | - return $arr; | ||
| 134 | - } | ||
| 135 | - if($inquiry_list['status'] == self::STATUS_ERROR){ | ||
| 136 | - $arr['inquiry_num'] = 0; | ||
| 137 | - $countryArr = []; | ||
| 138 | - }else{ | ||
| 139 | - $arr['inquiry_num'] = $inquiry_list['data']['count']; | ||
| 140 | - //询盘国家统计 | ||
| 141 | - $countryArr = $inquiry_list['data']['country']; | ||
| 142 | - } | ||
| 143 | - //加上其他询盘 | ||
| 144 | - ProjectServer::useProject($project_id); | ||
| 145 | - $arr['inquiry_num'] += InquiryFormData::getCount(); | ||
| 146 | - $countryData = InquiryFormData::getCountryCount(); | ||
| 147 | - foreach ($countryData as $v1){ | ||
| 148 | - if(isset($countryArr[$v1['country']])){ | ||
| 149 | - $countryArr[$v1['country']] += $v1['count']; | ||
| 150 | - }else{ | ||
| 151 | - $countryArr[$v1['country']] = $v1['count']; | ||
| 152 | - } | ||
| 153 | - } | ||
| 154 | - arsort($countryArr); | ||
| 155 | - $top20 = array_slice($countryArr, 0, 20, true); | ||
| 156 | - $arr['country'] = json_encode($top20); | ||
| 157 | - return $arr; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - /** | ||
| 161 | - * @name :(查询参数设置)selectParam | ||
| 162 | - * @author :lyh | ||
| 163 | - * @method :post | ||
| 164 | - * @time :2023/6/14 15:00 | ||
| 165 | - */ | ||
| 166 | - public function selectParam(){ | ||
| 167 | - $select = [ | ||
| 168 | - 'gl_project.id AS id', | ||
| 169 | - 'gl_project.type AS type', | ||
| 170 | - 'gl_project.extend_type AS extend_type', | ||
| 171 | - 'gl_project.is_upgrade AS is_upgrade', | ||
| 172 | - 'gl_project.remain_day AS remain_day', | ||
| 173 | - 'gl_project.finish_remain_day AS finish_remain_day', | ||
| 174 | - 'gl_project_deploy_build.test_domain AS test_domain', | ||
| 175 | - 'gl_project_deploy_optimize.domain AS domain', | ||
| 176 | - 'gl_project_deploy_build.project_id AS project_id', | ||
| 177 | - 'gl_project.cooperate_date AS cooperate_date', | ||
| 178 | - 'gl_project_deploy_build.service_duration AS service_duration', | ||
| 179 | - ]; | ||
| 180 | - return $select; | ||
| 181 | - } | ||
| 182 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :CountProject.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2024/1/8 9:03 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DayCount; | ||
| 11 | - | ||
| 12 | -use App\Helper\FormGlobalsoApi; | ||
| 13 | -use App\Models\Inquiry\InquiryFormData; | ||
| 14 | -use App\Models\Project\Project; | ||
| 15 | -use App\Services\ProjectServer; | ||
| 16 | -use Illuminate\Console\Command; | ||
| 17 | -use Illuminate\Support\Facades\DB; | ||
| 18 | -use App\Models\HomeCount\Count; | ||
| 19 | - | ||
| 20 | -class CountAll extends Command | ||
| 21 | -{ | ||
| 22 | - const STATUS_ERROR = 400; | ||
| 23 | - public $error = 0; | ||
| 24 | - /** | ||
| 25 | - * The name and signature of the console command. | ||
| 26 | - * | ||
| 27 | - * @var string | ||
| 28 | - */ | ||
| 29 | - protected $signature = 'count_all'; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * The console command description. | ||
| 33 | - * | ||
| 34 | - * @var string | ||
| 35 | - */ | ||
| 36 | - protected $description = '所有项目统计'; | ||
| 37 | - | ||
| 38 | - public function handle(){ | ||
| 39 | - $projectModel = new Project(); | ||
| 40 | - $list = $projectModel->list(['delete_status'=>0,'type'=>['in',[1,2,3,4,6]]]); | ||
| 41 | - foreach ($list as $v) { | ||
| 42 | - echo date('Y-m-d H:i:s') . '项目id:'.$v['id'] . PHP_EOL; | ||
| 43 | - ProjectServer::useProject($v['id']); | ||
| 44 | - $this->count($v['id']); | ||
| 45 | - DB::disconnect('custom_mysql'); | ||
| 46 | - } | ||
| 47 | - return true; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - /** | ||
| 51 | - * @remark :日统计记录 | ||
| 52 | - * @name :count | ||
| 53 | - * @author :lyh | ||
| 54 | - * @method :post | ||
| 55 | - * @time :2024/1/8 9:05 | ||
| 56 | - */ | ||
| 57 | - public function count($project_id){ | ||
| 58 | - $list = DB::connection('custom_mysql')->table('gl_customer_visit')->select('updated_date') | ||
| 59 | - ->groupBy('updated_date')->get()->toArray(); | ||
| 60 | - $project = new Project(); | ||
| 61 | - $projectInfo = $project->read(['id'=>$project_id]); | ||
| 62 | - if(!empty($list)){ | ||
| 63 | - $arr = []; | ||
| 64 | - foreach ($list as $k=>$v){ | ||
| 65 | - $v = (array)$v; | ||
| 66 | - if($v['updated_date'] == date('Y-m-d')){ | ||
| 67 | - continue; | ||
| 68 | - } | ||
| 69 | - echo date('Y-m-d H:i:s') . '时间:'.$v['updated_date'] . PHP_EOL; | ||
| 70 | - $count = new Count(); | ||
| 71 | - $arr['project_id'] = $project_id; | ||
| 72 | - $arr['date'] = $v['updated_date']; | ||
| 73 | - $arr['pv_num'] = $this->pv_num($v['updated_date']); | ||
| 74 | - $arr['ip_num'] = $this->ip_num($v['updated_date']); | ||
| 75 | - $arr['inquiry_num'] = $this->inquiry_num($v['updated_date']); | ||
| 76 | - //服务达标天数 | ||
| 77 | - $arr['compliance_day'] = $projectInfo['finish_remain_day']; | ||
| 78 | - //剩余服务时常 | ||
| 79 | - $arr['service_day'] = $projectInfo['remain_day']; | ||
| 80 | - $arr['country'] = json_encode([]); | ||
| 81 | - //查询当天数据是否存在 存在则更新 | ||
| 82 | - $info = $count->read(['date'=>$v['updated_date'],'project_id'=>$project_id]); | ||
| 83 | - if($info === false){ | ||
| 84 | - $arr['created_at'] = $v['updated_date'].' 01:00:00'; | ||
| 85 | - $arr['updated_at'] = $v['updated_date'].' 01:00:00'; | ||
| 86 | - $count->insert($arr); | ||
| 87 | - }else{ | ||
| 88 | - $count->edit($arr,['id'=>$info['id']]); | ||
| 89 | - } | ||
| 90 | - } | ||
| 91 | - } | ||
| 92 | - echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - /** | ||
| 96 | - * @param $arr | ||
| 97 | - * @param $domain | ||
| 98 | - * @name :(询盘统计)inquiry | ||
| 99 | - * @author :lyh | ||
| 100 | - * @method :post | ||
| 101 | - * @time :2023/6/14 15:44 | ||
| 102 | - */ | ||
| 103 | - public function inquiry($arr,$domain,$project_id,$is_upgrade = 0){ | ||
| 104 | - $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$is_upgrade); | ||
| 105 | - if($inquiry_list == false){ | ||
| 106 | - return $arr; | ||
| 107 | - } | ||
| 108 | - if($inquiry_list['status'] == self::STATUS_ERROR){ | ||
| 109 | - $arr['inquiry_num'] = 0; | ||
| 110 | - $countryArr = []; | ||
| 111 | - }else{ | ||
| 112 | - $arr['inquiry_num'] = $inquiry_list['data']['count']; | ||
| 113 | - //询盘国家统计 | ||
| 114 | - $countryArr = $inquiry_list['data']['country']; | ||
| 115 | - } | ||
| 116 | - //加上其他询盘 | ||
| 117 | - ProjectServer::useProject($project_id); | ||
| 118 | - $arr['inquiry_num'] += InquiryFormData::getCount(); | ||
| 119 | - $countryData = InquiryFormData::getCountryCount(); | ||
| 120 | - foreach ($countryData as $v1){ | ||
| 121 | - if(isset($countryArr[$v1['country']])){ | ||
| 122 | - $countryArr[$v1['country']] += $v1['count']; | ||
| 123 | - }else{ | ||
| 124 | - $countryArr[$v1['country']] = $v1['count']; | ||
| 125 | - } | ||
| 126 | - } | ||
| 127 | - arsort($countryArr); | ||
| 128 | - $top20 = array_slice($countryArr, 0, 20, true); | ||
| 129 | - $arr['country'] = json_encode($top20); | ||
| 130 | - return $arr; | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - /** | ||
| 134 | - * @remark :询盘数量 | ||
| 135 | - * @name :inquiry_num | ||
| 136 | - * @author :lyh | ||
| 137 | - * @method :post | ||
| 138 | - * @time :2024/1/8 9:24 | ||
| 139 | - */ | ||
| 140 | - public function inquiry_num($day){ | ||
| 141 | - $count = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->where('is_inquiry',1)->count(); | ||
| 142 | - return $count; | ||
| 143 | - } | ||
| 144 | - | ||
| 145 | - /** | ||
| 146 | - * @name :(统计pv)pv_num | ||
| 147 | - * @author :lyh | ||
| 148 | - * @method :post | ||
| 149 | - * @time :2023/6/14 15:40 | ||
| 150 | - */ | ||
| 151 | - public function pv_num($day){ | ||
| 152 | - //$pv = DB::connection('custom_mysql')->table('gl_customer_visit_item')->whereDate('updated_date', $day)->count(); | ||
| 153 | - $pv = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->sum('depth'); | ||
| 154 | - return $pv; | ||
| 155 | - } | ||
| 156 | - | ||
| 157 | - /** | ||
| 158 | - * @name :(统计ip)ip_num | ||
| 159 | - * @author :lyh | ||
| 160 | - * @method :post | ||
| 161 | - * @time :2023/6/14 15:40 | ||
| 162 | - */ | ||
| 163 | - public function ip_num($day){ | ||
| 164 | - $ip = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->count(); | ||
| 165 | - return $ip; | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | - | ||
| 169 | - | ||
| 170 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\DayCount; | ||
| 4 | - | ||
| 5 | -use App\Helper\FormGlobalsoApi; | ||
| 6 | -use App\Models\Domain\DomainInfo; | ||
| 7 | -use App\Models\Inquiry\InquiryFormData; | ||
| 8 | -use App\Models\Project\Project; | ||
| 9 | -use App\Services\ProjectServer; | ||
| 10 | -use Illuminate\Console\Command; | ||
| 11 | -use Illuminate\Support\Facades\DB; | ||
| 12 | -use Illuminate\Support\Facades\Log; | ||
| 13 | - | ||
| 14 | -class CountDate extends Command | ||
| 15 | -{ | ||
| 16 | - const STATUS_ERROR = 400; | ||
| 17 | - public $error = 0; | ||
| 18 | - /** | ||
| 19 | - * The name and signature of the console command. | ||
| 20 | - * | ||
| 21 | - * @var string | ||
| 22 | - */ | ||
| 23 | - protected $signature = 'count_data {date}'; | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * The console command description. | ||
| 27 | - * | ||
| 28 | - * @var string | ||
| 29 | - */ | ||
| 30 | - protected $description = '按时间统计所有项目记录'; | ||
| 31 | - | ||
| 32 | - /** | ||
| 33 | - * @name :(定时执行生成昨日数据统计)handle | ||
| 34 | - * @author :lyh | ||
| 35 | - * @method :post | ||
| 36 | - * @time :2023/5/12 14:48 | ||
| 37 | - */ | ||
| 38 | - public function handle() | ||
| 39 | - { | ||
| 40 | - $date = $this->argument('date'); | ||
| 41 | - $list = DB::table('gl_project')->where('gl_project.extend_type','=',0) | ||
| 42 | - ->whereIn('gl_project.type',[1,2,3,4,6]) | ||
| 43 | - ->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id') | ||
| 44 | - ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') | ||
| 45 | - ->select($this->selectParam())->get(); | ||
| 46 | - try { | ||
| 47 | - if(!empty($list)){ | ||
| 48 | - $list = $list->toArray(); | ||
| 49 | -// $yesterday = Carbon::yesterday()->toDateString(); | ||
| 50 | - $yesterday = $date; | ||
| 51 | - $domainInfo = new DomainInfo(); | ||
| 52 | - foreach ($list as $v){ | ||
| 53 | - $v = (array)$v; | ||
| 54 | - echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL; | ||
| 55 | - if($v['type'] == Project::TYPE_ZERO){ | ||
| 56 | - continue; | ||
| 57 | - } | ||
| 58 | - if(!empty($v['domain'])){ | ||
| 59 | - $info = $domainInfo->read(['id'=>$v['domain']]); | ||
| 60 | - if($info !== false){ | ||
| 61 | - $v['test_domain'] = $info['domain']; | ||
| 62 | - } | ||
| 63 | - } | ||
| 64 | - $arr = []; | ||
| 65 | - //统计时间 | ||
| 66 | - $arr['date'] = $yesterday; | ||
| 67 | - ProjectServer::useProject($v['id']); | ||
| 68 | - //pv统计 | ||
| 69 | - $arr['pv_num'] = $this->pv_num($yesterday); | ||
| 70 | - //ip统计 | ||
| 71 | - $arr['ip_num'] = $this->ip_num($yesterday); | ||
| 72 | - DB::disconnect('custom_mysql'); | ||
| 73 | - //服务达标天数 | ||
| 74 | - $arr['compliance_day'] = $v['finish_remain_day']; | ||
| 75 | - //剩余服务时常 | ||
| 76 | - $arr['service_day'] = ($v['remain_day'] - 1) < 0 ? 0: $v['remain_day'] - 1; | ||
| 77 | - //项目id | ||
| 78 | - $arr['project_id'] = $v['project_id']; | ||
| 79 | - $arr['created_at'] = date('Y-m-d H:i:s'); | ||
| 80 | - $arr['updated_at'] = date('Y-m-d H:i:s'); | ||
| 81 | - //询盘统计 | ||
| 82 | - $arr = $this->inquiry($arr,$v['test_domain'], $v['id'],$v['is_upgrade'] ?? 0); | ||
| 83 | - if($arr === false){ | ||
| 84 | - continue; | ||
| 85 | - } | ||
| 86 | - //查询当天数据是否存在 存在则更新 | ||
| 87 | - $countModel = new \App\Models\HomeCount\Count(); | ||
| 88 | - $info = $countModel->read(['date'=>$arr['date'],'project_id'=>$v['id']]); | ||
| 89 | - if($info === false){ | ||
| 90 | - DB::table('gl_count')->insert($arr); | ||
| 91 | - }else{ | ||
| 92 | - $countModel->edit($arr,['id'=>$info['id']]); | ||
| 93 | - } | ||
| 94 | - Log::channel('day_count')->error('日期:'.$arr['created_at'].'success: ' .$v['test_domain']); | ||
| 95 | - } | ||
| 96 | - } | ||
| 97 | - }catch (\Exception $e){ | ||
| 98 | - Log::channel('day_count')->error('day_count:->error ' . $e->getMessage()); | ||
| 99 | - } | ||
| 100 | - Log::channel('day_count')->error('success:end'); | ||
| 101 | - echo $this->error; | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | - /** | ||
| 105 | - * @name :(统计pv)pv_num | ||
| 106 | - * @author :lyh | ||
| 107 | - * @method :post | ||
| 108 | - * @time :2023/6/14 15:40 | ||
| 109 | - */ | ||
| 110 | - public function pv_num($yesterday){ | ||
| 111 | - $pv = DB::connection('custom_mysql')->table('gl_customer_visit_item')->whereDate('updated_date', $yesterday)->count(); | ||
| 112 | - return $pv; | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - /** | ||
| 116 | - * @name :(统计ip)ip_num | ||
| 117 | - * @author :lyh | ||
| 118 | - * @method :post | ||
| 119 | - * @time :2023/6/14 15:40 | ||
| 120 | - */ | ||
| 121 | - public function ip_num($yesterday){ | ||
| 122 | - $ip = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $yesterday)->count(); | ||
| 123 | - return $ip; | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - /** | ||
| 127 | - * @param $arr | ||
| 128 | - * @param $domain | ||
| 129 | - * @name :(询盘统计)inquiry | ||
| 130 | - * @author :lyh | ||
| 131 | - * @method :post | ||
| 132 | - * @time :2023/6/14 15:44 | ||
| 133 | - */ | ||
| 134 | - public function inquiry($arr,$domain,$project_id,$is_upgrade = 0){ | ||
| 135 | - $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$is_upgrade); | ||
| 136 | - if($inquiry_list == false){ | ||
| 137 | - return $arr; | ||
| 138 | - } | ||
| 139 | - if($inquiry_list['status'] == self::STATUS_ERROR){ | ||
| 140 | - $arr['inquiry_num'] = 0; | ||
| 141 | - $countryArr = []; | ||
| 142 | - }else{ | ||
| 143 | - $arr['inquiry_num'] = $inquiry_list['data']['count']; | ||
| 144 | - //询盘国家统计 | ||
| 145 | - $countryArr = $inquiry_list['data']['country']; | ||
| 146 | - } | ||
| 147 | - //加上其他询盘 | ||
| 148 | - ProjectServer::useProject($project_id); | ||
| 149 | - $arr['inquiry_num'] += InquiryFormData::getCount(); | ||
| 150 | - $countryData = InquiryFormData::getCountryCount(); | ||
| 151 | - foreach ($countryData as $v1){ | ||
| 152 | - if(isset($countryArr[$v1['country']])){ | ||
| 153 | - $countryArr[$v1['country']] += $v1['count']; | ||
| 154 | - }else{ | ||
| 155 | - $countryArr[$v1['country']] = $v1['count']; | ||
| 156 | - } | ||
| 157 | - } | ||
| 158 | - arsort($countryArr); | ||
| 159 | - $top20 = array_slice($countryArr, 0, 20, true); | ||
| 160 | - $arr['country'] = json_encode($top20); | ||
| 161 | - return $arr; | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - /** | ||
| 165 | - * @name :(查询参数设置)selectParam | ||
| 166 | - * @author :lyh | ||
| 167 | - * @method :post | ||
| 168 | - * @time :2023/6/14 15:00 | ||
| 169 | - */ | ||
| 170 | - public function selectParam(){ | ||
| 171 | - $select = [ | ||
| 172 | - 'gl_project.id AS id', | ||
| 173 | - 'gl_project.type AS type', | ||
| 174 | - 'gl_project.extend_type AS extend_type', | ||
| 175 | - 'gl_project.is_upgrade AS is_upgrade', | ||
| 176 | - 'gl_project.remain_day AS remain_day', | ||
| 177 | - 'gl_project.finish_remain_day AS finish_remain_day', | ||
| 178 | - 'gl_project_deploy_build.test_domain AS test_domain', | ||
| 179 | - 'gl_project_deploy_optimize.domain AS domain', | ||
| 180 | - 'gl_project_deploy_build.project_id AS project_id', | ||
| 181 | - 'gl_project.cooperate_date AS cooperate_date', | ||
| 182 | - 'gl_project_deploy_build.service_duration AS service_duration', | ||
| 183 | - ]; | ||
| 184 | - return $select; | ||
| 185 | - } | ||
| 186 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :CountProject.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2024/1/8 9:03 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DayCount; | ||
| 11 | - | ||
| 12 | -use App\Helper\FormGlobalsoApi; | ||
| 13 | -use App\Models\Domain\DomainInfo; | ||
| 14 | -use App\Models\Inquiry\InquiryFormData; | ||
| 15 | -use App\Models\Project\DeployOptimize; | ||
| 16 | -use App\Models\Project\Project; | ||
| 17 | -use App\Services\ProjectServer; | ||
| 18 | -use Illuminate\Console\Command; | ||
| 19 | -use Illuminate\Support\Facades\DB; | ||
| 20 | -use App\Models\HomeCount\Count; | ||
| 21 | - | ||
| 22 | -class CountProject extends Command | ||
| 23 | -{ | ||
| 24 | - const STATUS_ERROR = 400; | ||
| 25 | - public $error = 0; | ||
| 26 | - /** | ||
| 27 | - * The name and signature of the console command. | ||
| 28 | - * | ||
| 29 | - * @var string | ||
| 30 | - */ | ||
| 31 | - protected $signature = 'count_project {project_id}'; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * The console command description. | ||
| 35 | - * | ||
| 36 | - * @var string | ||
| 37 | - */ | ||
| 38 | - protected $description = '按项目统计日记录'; | ||
| 39 | - | ||
| 40 | - public function handle(){ | ||
| 41 | - $project_id = $this->argument('project_id'); | ||
| 42 | - ProjectServer::useProject($project_id); | ||
| 43 | - $this->count($project_id); | ||
| 44 | - DB::disconnect('custom_mysql'); | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * @remark :日统计记录 | ||
| 49 | - * @name :count | ||
| 50 | - * @author :lyh | ||
| 51 | - * @method :post | ||
| 52 | - * @time :2024/1/8 9:05 | ||
| 53 | - */ | ||
| 54 | - public function count($project_id,$is_upgrade = 0){ | ||
| 55 | - $list = DB::connection('custom_mysql')->table('gl_customer_visit')->select('updated_date') | ||
| 56 | - ->groupBy('updated_date')->get()->toArray(); | ||
| 57 | - $project = new Project(); | ||
| 58 | - $projectInfo = $project->read(['id'=>$project_id]); | ||
| 59 | - $projectOptimizeModel = new DeployOptimize(); | ||
| 60 | - $optimizeInfo = $projectOptimizeModel->read(['project_id'=>$project_id]); | ||
| 61 | - $domain = ''; | ||
| 62 | - if(!empty($optimizeInfo['domain'])){ | ||
| 63 | - $domainInfoModel = new DomainInfo(); | ||
| 64 | - $domainInfo = $domainInfoModel->read(['id'=>$optimizeInfo['domain']]); | ||
| 65 | - if($domainInfo !== false){ | ||
| 66 | - $domain = $domainInfo['domain']; | ||
| 67 | - } | ||
| 68 | - } | ||
| 69 | - if(empty($domain)){ | ||
| 70 | - return false; | ||
| 71 | - } | ||
| 72 | - if(!empty($list)){ | ||
| 73 | - $arr = []; | ||
| 74 | - foreach ($list as $k=>$v){ | ||
| 75 | - $v = (array)$v; | ||
| 76 | - if($v['updated_date'] == date('Y-m-d')){ | ||
| 77 | - continue; | ||
| 78 | - } | ||
| 79 | - echo date('Y-m-d H:i:s') . '时间:'.$v['updated_date'] . PHP_EOL; | ||
| 80 | - $count = new Count(); | ||
| 81 | - $arr['project_id'] = $project_id; | ||
| 82 | - $arr['date'] = $v['updated_date']; | ||
| 83 | - $arr['pv_num'] = $this->pv_num($v['updated_date']); | ||
| 84 | - $arr['ip_num'] = $this->ip_num($v['updated_date']); | ||
| 85 | - //服务达标天数 | ||
| 86 | - $arr['compliance_day'] = $projectInfo['finish_remain_day']; | ||
| 87 | - //剩余服务时常 | ||
| 88 | - $arr['service_day'] = $projectInfo['remain_day']; | ||
| 89 | - $arr = $this->inquiry($arr,$domain, $project_id,$projectInfo['is_upgrade'] ?? 0); | ||
| 90 | - if($arr === false){ | ||
| 91 | - continue; | ||
| 92 | - } | ||
| 93 | - //查询当天数据是否存在 存在则更新 | ||
| 94 | - $info = $count->read(['date'=>$v['updated_date'],'project_id'=>$project_id]); | ||
| 95 | - if($info === false){ | ||
| 96 | - $arr['created_at'] = $v['updated_date'].' 01:00:00'; | ||
| 97 | - $arr['updated_at'] = $v['updated_date'].' 01:00:00'; | ||
| 98 | - $count->insert($arr); | ||
| 99 | - }else{ | ||
| 100 | - $count->edit($arr,['id'=>$info['id']]); | ||
| 101 | - } | ||
| 102 | - } | ||
| 103 | - } | ||
| 104 | - echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - /** | ||
| 108 | - * @remark :询盘数量 | ||
| 109 | - * @name :inquiry_num | ||
| 110 | - * @author :lyh | ||
| 111 | - * @method :post | ||
| 112 | - * @time :2024/1/8 9:24 | ||
| 113 | - */ | ||
| 114 | - public function inquiry_num($day){ | ||
| 115 | - $count = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->where('is_inquiry',1)->count(); | ||
| 116 | - return $count; | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - /** | ||
| 120 | - * @name :(统计pv)pv_num | ||
| 121 | - * @author :lyh | ||
| 122 | - * @method :post | ||
| 123 | - * @time :2023/6/14 15:40 | ||
| 124 | - */ | ||
| 125 | - public function pv_num($day){ | ||
| 126 | - $pv = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->sum('depth'); | ||
| 127 | - return $pv; | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - /** | ||
| 131 | - * @name :(统计ip)ip_num | ||
| 132 | - * @author :lyh | ||
| 133 | - * @method :post | ||
| 134 | - * @time :2023/6/14 15:40 | ||
| 135 | - */ | ||
| 136 | - public function ip_num($day){ | ||
| 137 | - $ip = DB::connection('custom_mysql')->table('gl_customer_visit')->whereDate('updated_date', $day)->count(); | ||
| 138 | - return $ip; | ||
| 139 | - } | ||
| 140 | - | ||
| 141 | - /** | ||
| 142 | - * @param $arr | ||
| 143 | - * @param $domain | ||
| 144 | - * @name :(询盘统计)inquiry | ||
| 145 | - * @author :lyh | ||
| 146 | - * @method :post | ||
| 147 | - * @time :2023/6/14 15:44 | ||
| 148 | - */ | ||
| 149 | - public function inquiry($arr,$domain,$project_id,$is_upgrade = 0){ | ||
| 150 | - $inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$is_upgrade); | ||
| 151 | - if($inquiry_list == false){ | ||
| 152 | - return $arr; | ||
| 153 | - } | ||
| 154 | -// echo date('Y-m-d H:i:s') . '拉取询盘状态:' .json_encode($inquiry_list) . PHP_EOL; | ||
| 155 | - if($inquiry_list['status'] == self::STATUS_ERROR){ | ||
| 156 | - $arr['inquiry_num'] = 0; | ||
| 157 | - $countryArr = []; | ||
| 158 | - }else{ | ||
| 159 | - $arr['inquiry_num'] = $inquiry_list['data']['count']; | ||
| 160 | - //询盘国家统计 | ||
| 161 | - $countryArr = $inquiry_list['data']['country']; | ||
| 162 | - } | ||
| 163 | - //加上其他询盘 | ||
| 164 | - ProjectServer::useProject($project_id); | ||
| 165 | - $arr['inquiry_num'] += InquiryFormData::getCount(); | ||
| 166 | - $countryData = InquiryFormData::getCountryCount(); | ||
| 167 | - foreach ($countryData as $v1){ | ||
| 168 | - if(isset($countryArr[$v1['country']])){ | ||
| 169 | - $countryArr[$v1['country']] += $v1['count']; | ||
| 170 | - }else{ | ||
| 171 | - $countryArr[$v1['country']] = $v1['count']; | ||
| 172 | - } | ||
| 173 | - } | ||
| 174 | - arsort($countryArr); | ||
| 175 | - $top20 = array_slice($countryArr, 0, 20, true); | ||
| 176 | - $arr['country'] = json_encode($top20); | ||
| 177 | - return $arr; | ||
| 178 | - } | ||
| 179 | - | ||
| 180 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\DayCount; | ||
| 4 | - | ||
| 5 | -use App\Models\Inquiry\InquiryCount as InquiryCountModel; | ||
| 6 | -use App\Models\Inquiry\InquiryInfo; | ||
| 7 | -use Carbon\Carbon; | ||
| 8 | -use Illuminate\Console\Command; | ||
| 9 | -use Illuminate\Support\Facades\Log; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * @remark : | ||
| 13 | - * @class :InquiryCount.php | ||
| 14 | - * @author :lyh | ||
| 15 | - * @time :2023/7/14 16:20 | ||
| 16 | - */ | ||
| 17 | -class InquiryCount extends Command | ||
| 18 | -{ | ||
| 19 | - /** | ||
| 20 | - * The name and signature of the console command. | ||
| 21 | - * | ||
| 22 | - * @var string | ||
| 23 | - */ | ||
| 24 | - protected $signature = 'inquiry_count'; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * The console command description. | ||
| 28 | - * | ||
| 29 | - * @var string | ||
| 30 | - */ | ||
| 31 | - protected $description = '每天统计询盘数量'; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * @var :根据状态统计 | ||
| 35 | - */ | ||
| 36 | - public $status = [ | ||
| 37 | - 1=>'站群询盘', | ||
| 38 | - 2=>'ai站群询盘', | ||
| 39 | - 3=>'amp自建平台', | ||
| 40 | - 4=>'fb询盘', | ||
| 41 | - 5=>'fb广告', | ||
| 42 | - 6=>'广告采集建站', | ||
| 43 | - 7=>'黄金平台询盘', | ||
| 44 | - 8=>'内部统计', | ||
| 45 | - 9=>'GlobalImporter', | ||
| 46 | - 10=>'whatsapp', | ||
| 47 | - 11=>'Skype', | ||
| 48 | - 12=>'建站客户', | ||
| 49 | - 13=>'ChinaCn', | ||
| 50 | - 14=>'EC21', | ||
| 51 | - 15=>'邮件群发' | ||
| 52 | - ]; | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * @remark :统计 | ||
| 56 | - * @name :handle | ||
| 57 | - * @author :lyh | ||
| 58 | - * @method :post | ||
| 59 | - * @time :2023/7/14 16:21 | ||
| 60 | - */ | ||
| 61 | - public function handle(){ | ||
| 62 | - $data = []; | ||
| 63 | - //获取昨天的时间 | ||
| 64 | - $yesterday = Carbon::yesterday()->toDateString(); | ||
| 65 | - $inquiryInfoModel = new InquiryInfo(); | ||
| 66 | - try { | ||
| 67 | - foreach ($this->status as $k=>$v){ | ||
| 68 | - $total = $inquiryInfoModel->formatQuery(['created_at'=>['between',[$yesterday.' 00:00:00',$yesterday.' 23:59:59']]])->count(); | ||
| 69 | - $untreated = $inquiryInfoModel->formatQuery(['created_at'=>['between',[$yesterday.' 00:00:00',$yesterday.' 23:59:59']],'status'=>1])->count(); | ||
| 70 | - $invalid = $inquiryInfoModel->formatQuery(['created_at'=>['between',[$yesterday.' 00:00:00',$yesterday.' 23:59:59']],'status'=>0])->count(); | ||
| 71 | - $data[] = [ | ||
| 72 | - 'type'=>$k, | ||
| 73 | - 'day'=>$yesterday, | ||
| 74 | - 'total'=>$total ?? 0, | ||
| 75 | - 'untreated'=>$untreated ?? 0, | ||
| 76 | - 'invalid'=>$invalid ?? 0 | ||
| 77 | - ]; | ||
| 78 | - } | ||
| 79 | - $inquiryCount = new InquiryCountModel(); | ||
| 80 | - $inquiryCount->insert($data); | ||
| 81 | - }catch (\Exception $e){ | ||
| 82 | - Log::error('inquiry_count : error'); | ||
| 83 | - } | ||
| 84 | - return true; | ||
| 85 | - } | ||
| 86 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace App\Console\Commands\DayCount; | ||
| 4 | - | ||
| 5 | -use App\Models\Inquiry\InquiryInfo; | ||
| 6 | -use Illuminate\Console\Command; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * @remark : | ||
| 10 | - * @class :InquiryDelay.php | ||
| 11 | - * @author :lyh | ||
| 12 | - * @time :2023/7/14 10:16 | ||
| 13 | - */ | ||
| 14 | -class InquiryDelay extends Command | ||
| 15 | -{ | ||
| 16 | - /** | ||
| 17 | - * The name and signature of the console command. | ||
| 18 | - * | ||
| 19 | - * @var string | ||
| 20 | - */ | ||
| 21 | - protected $signature = 'inquiry_delay'; | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * The console command description. | ||
| 25 | - * | ||
| 26 | - * @var string | ||
| 27 | - */ | ||
| 28 | - protected $description = '延时询盘转发(暂时弃用)'; | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * @remark :延时询盘转发 | ||
| 32 | - * @name :handle | ||
| 33 | - * @author :lyh | ||
| 34 | - * @method :post | ||
| 35 | - * @time :2023/7/14 10:17 | ||
| 36 | - */ | ||
| 37 | - public function handle() | ||
| 38 | - { | ||
| 39 | -// $inquiryInfoModel = new InquiryInfo(); | ||
| 40 | -// $param = $inquiryInfoModel->formatQuery(['status'=>$inquiryInfoModel::STATUS_FOUR])->orderBy('send_time','asc')->first(); | ||
| 41 | -// if(!empty($param)){ | ||
| 42 | -// $time = date('Y-m-d H:i:s'); | ||
| 43 | -// if($time >= $param['send_time']){ | ||
| 44 | -// $data = []; | ||
| 45 | -// //TODO::处理转发的url | ||
| 46 | -// $arr_url = explode(',',$param['forward_url']); | ||
| 47 | -// foreach ($arr_url as $v){ | ||
| 48 | -// $data['url'] = $v; | ||
| 49 | -// $this->inquiryForward($data); | ||
| 50 | -// } | ||
| 51 | -// $inquiryInfoModel->edit(['status'=>$inquiryInfoModel::STATUS_THREE],['id'=>$param['id']]); | ||
| 52 | -// } | ||
| 53 | -// } | ||
| 54 | - return true; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - /** | ||
| 58 | - * @remark :询盘转发 | ||
| 59 | - * @name :inquiryForward | ||
| 60 | - * @author :lyh | ||
| 61 | - * @method :post | ||
| 62 | - * @time :2023/7/13 14:39 | ||
| 63 | - */ | ||
| 64 | - public function inquiryForward($post_data){ | ||
| 65 | - $url = 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f'; | ||
| 66 | - $post_data_new = []; | ||
| 67 | - $post_data_new['refer'] = $post_data['url']; | ||
| 68 | - $post_data_new['name'] = $post_data['name']; | ||
| 69 | - $post_data_new['email'] = $post_data['email']; | ||
| 70 | - $post_data_new['phone'] = $post_data['phone']; | ||
| 71 | - $post_data_new['ip'] = $post_data['ip']; | ||
| 72 | - $post_data_new['message'] = $post_data['message']; | ||
| 73 | - $post_data_new['submit_time'] = date('Y-m-d H:i:s',time()+20); | ||
| 74 | - $token = md5($post_data_new['refer'].$post_data_new['name'].$post_data_new['ip'].date("Y-m-d",time())); | ||
| 75 | - $post_data_new['token'] = $token; | ||
| 76 | - $header = array( | ||
| 77 | - 'CLIENT-IP: '.$post_data['ip'], | ||
| 78 | - 'X-FORWARDED-FOR: '.$post_data['ip'] | ||
| 79 | - ); | ||
| 80 | - return http_post($url,$post_data_new,$header); | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :DeleteProductCategory.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2024/5/16 14:59 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DeleteCategory; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Blog\Blog; | ||
| 14 | -use App\Models\Blog\BlogCategory; | ||
| 15 | -use App\Models\Com\NoticeLog; | ||
| 16 | -use App\Models\Project\Project; | ||
| 17 | -use App\Services\ProjectServer; | ||
| 18 | -use Illuminate\Console\Command; | ||
| 19 | -use Illuminate\Support\Facades\DB; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * @remark :删除分类 | ||
| 23 | - * @name :DeleteProductCategory | ||
| 24 | - * @author :lyh | ||
| 25 | - * @method :post | ||
| 26 | - * @time :2024/5/16 15:00 | ||
| 27 | - */ | ||
| 28 | -class DeleteBlogCategory extends Command | ||
| 29 | -{ | ||
| 30 | - /** | ||
| 31 | - * The name and signature of the console command. | ||
| 32 | - * | ||
| 33 | - * @var string | ||
| 34 | - */ | ||
| 35 | - protected $signature = 'delete_blog_category'; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * The console command description. | ||
| 39 | - * | ||
| 40 | - * @var string | ||
| 41 | - */ | ||
| 42 | - protected $description = '删除博客分类'; | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * Create a new command instance. | ||
| 46 | - * | ||
| 47 | - * @return void | ||
| 48 | - */ | ||
| 49 | - public function __construct() | ||
| 50 | - { | ||
| 51 | - parent::__construct(); | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * @remark :批量处理 | ||
| 56 | - * @name :handle | ||
| 57 | - * @author :lyh | ||
| 58 | - * @method :post | ||
| 59 | - * @time :2024/5/16 15:02 | ||
| 60 | - */ | ||
| 61 | - public function handle(){ | ||
| 62 | - while (true){ | ||
| 63 | - $noticeLogModel = new NoticeLog(); | ||
| 64 | - $list = $noticeLogModel->list(['status'=>NoticeLog::STATUS_PENDING,'type'=>NoticeLog::DELETE_BLOG_CATEGORY],'id',['*'],'asc',100); | ||
| 65 | - if(empty($list)){ | ||
| 66 | - sleep(10); | ||
| 67 | - continue; | ||
| 68 | - } | ||
| 69 | - foreach ($list as $item){ | ||
| 70 | - echo 'start:' . $item['id'] . PHP_EOL; | ||
| 71 | - try { | ||
| 72 | - $projectModel = new Project(); | ||
| 73 | - $projectInfo = $projectModel->read(['id'=>$item['data']['project_id']]); | ||
| 74 | - if($projectInfo === false){ | ||
| 75 | - continue; | ||
| 76 | - } | ||
| 77 | - ProjectServer::useProject($projectInfo['id']); | ||
| 78 | - $this->updateCategory(); | ||
| 79 | - DB::disconnect('custom_mysql'); | ||
| 80 | - $noticeLogModel->edit(['status'=>NoticeLog::STATUS_SUCCESS],['id'=>$item['id']]); | ||
| 81 | - echo 'success:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; | ||
| 82 | - }catch (\Exception $e){ | ||
| 83 | - echo 'error:' . $item['id'] . $e->getMessage() . '执行时间:'.date('Y-m-d H:i:s') . PHP_EOL; | ||
| 84 | - errorLog('delete_blog_category删除失败'.date('Y-m-d H:i:s'), $item, $e); | ||
| 85 | - } | ||
| 86 | - } | ||
| 87 | - return true; | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - /** | ||
| 92 | - * @remark :更新分类 | ||
| 93 | - * @name :updateProductCategory | ||
| 94 | - * @author :lyh | ||
| 95 | - * @method :post | ||
| 96 | - * @time :2024/5/16 15:38 | ||
| 97 | - */ | ||
| 98 | - public function updateCategory(){ | ||
| 99 | - $page = 1; | ||
| 100 | - $blogModel = new Blog(); | ||
| 101 | - while (true){ | ||
| 102 | - $blogList = $blogModel->lists(['status'=>1],$page,1000,'id',['id','category_id']); | ||
| 103 | - if(empty($blogList) || empty($blogList['list'])){ | ||
| 104 | - return false; | ||
| 105 | - } | ||
| 106 | - foreach ($blogList['list'] as $v){ | ||
| 107 | - $category_id_arr = Arr::setToArr(trim($v['category_id'],',')); | ||
| 108 | - if(empty($category_id_arr)){ | ||
| 109 | - continue; | ||
| 110 | - } | ||
| 111 | - $categoryModel = new BlogCategory(); | ||
| 112 | - foreach ($category_id_arr as $k=>$cate_id){ | ||
| 113 | - $cateInfo = $categoryModel->read(['id'=>$cate_id],['id']); | ||
| 114 | - if($cateInfo == false){ | ||
| 115 | - //删除关联表 | ||
| 116 | - unset($category_id_arr[$k]); | ||
| 117 | - } | ||
| 118 | - } | ||
| 119 | - $str = !empty($category_id_arr) ? ','.Arr::arrToSet($category_id_arr).',' : ''; | ||
| 120 | - $blogModel->edit(['category_id'=>$str],['id'=>$v['id']]); | ||
| 121 | - } | ||
| 122 | - $page++; | ||
| 123 | - } | ||
| 124 | - return true; | ||
| 125 | - } | ||
| 126 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :DeleteProductCategory.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2024/5/16 14:59 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DeleteCategory; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Com\NoticeLog; | ||
| 14 | -use App\Models\CustomModule\CustomModuleCategory; | ||
| 15 | -use App\Models\CustomModule\CustomModuleContent; | ||
| 16 | -use App\Models\Project\Project; | ||
| 17 | -use App\Services\ProjectServer; | ||
| 18 | -use Illuminate\Console\Command; | ||
| 19 | -use Illuminate\Support\Facades\DB; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * @remark :删除分类 | ||
| 23 | - * @name :DeleteProductCategory | ||
| 24 | - * @author :lyh | ||
| 25 | - * @method :post | ||
| 26 | - * @time :2024/5/16 15:00 | ||
| 27 | - */ | ||
| 28 | -class DeleteCustomCategory extends Command | ||
| 29 | -{ | ||
| 30 | - /** | ||
| 31 | - * The name and signature of the console command. | ||
| 32 | - * | ||
| 33 | - * @var string | ||
| 34 | - */ | ||
| 35 | - protected $signature = 'delete_custom_category'; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * The console command description. | ||
| 39 | - * | ||
| 40 | - * @var string | ||
| 41 | - */ | ||
| 42 | - protected $description = '删除扩展模块分类'; | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * Create a new command instance. | ||
| 46 | - * | ||
| 47 | - * @return void | ||
| 48 | - */ | ||
| 49 | - public function __construct() | ||
| 50 | - { | ||
| 51 | - parent::__construct(); | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * @remark :批量处理 | ||
| 56 | - * @name :handle | ||
| 57 | - * @author :lyh | ||
| 58 | - * @method :post | ||
| 59 | - * @time :2024/5/16 15:02 | ||
| 60 | - */ | ||
| 61 | - public function handle(){ | ||
| 62 | - while (true){ | ||
| 63 | - $noticeLogModel = new NoticeLog(); | ||
| 64 | - $list = $noticeLogModel->list(['status'=>NoticeLog::STATUS_PENDING,'type'=>NoticeLog::DELETE_CUSTOM_CATEGORY],'id',['*'],'asc',100); | ||
| 65 | - if(empty($list)){ | ||
| 66 | - sleep(10); | ||
| 67 | - continue; | ||
| 68 | - } | ||
| 69 | - foreach ($list as $item){ | ||
| 70 | - echo 'start:' . $item['id'] . PHP_EOL; | ||
| 71 | - try { | ||
| 72 | - $projectModel = new Project(); | ||
| 73 | - $projectInfo = $projectModel->read(['id'=>$item['data']['project_id']]); | ||
| 74 | - if($projectInfo === false){ | ||
| 75 | - continue; | ||
| 76 | - } | ||
| 77 | - ProjectServer::useProject($projectInfo['id']); | ||
| 78 | - $this->updateCategory(); | ||
| 79 | - DB::disconnect('custom_mysql'); | ||
| 80 | - $noticeLogModel->edit(['status'=>NoticeLog::STATUS_SUCCESS],['id'=>$item['id']]); | ||
| 81 | - echo 'success:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; | ||
| 82 | - }catch (\Exception $e){ | ||
| 83 | - echo 'error:' . $item['id'] . $e->getMessage() . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; | ||
| 84 | - errorLog('delete_custom_category删除失败', $item, $e); | ||
| 85 | - } | ||
| 86 | - } | ||
| 87 | - return true; | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - /** | ||
| 92 | - * @remark :更新分类 | ||
| 93 | - * @name :updateProductCategory | ||
| 94 | - * @author :lyh | ||
| 95 | - * @method :post | ||
| 96 | - * @time :2024/5/16 15:38 | ||
| 97 | - */ | ||
| 98 | - public function updateCategory(){ | ||
| 99 | - $page = 1; | ||
| 100 | - $customModel = new CustomModuleContent(); | ||
| 101 | - while (true){ | ||
| 102 | - $customList = $customModel->lists(['status'=>0],$page,1000,'id',['id','category_id']); | ||
| 103 | - if(empty($customList) || empty($customList['list'])){ | ||
| 104 | - return false; | ||
| 105 | - } | ||
| 106 | - foreach ($customList['list'] as $v){ | ||
| 107 | - $category_id_arr = $v['category_id']; | ||
| 108 | - if(empty($category_id_arr)){ | ||
| 109 | - continue; | ||
| 110 | - } | ||
| 111 | - $categoryModel = new CustomModuleCategory(); | ||
| 112 | - foreach ($category_id_arr as $k=>$cate_id){ | ||
| 113 | - $cateInfo = $categoryModel->read(['id'=>$cate_id],['id']); | ||
| 114 | - if($cateInfo == false){ | ||
| 115 | - //删除关联表 | ||
| 116 | - unset($category_id_arr[$k]); | ||
| 117 | - } | ||
| 118 | - } | ||
| 119 | - $str = !empty($category_id_arr) ? ','.Arr::arrToSet($category_id_arr).',' : ''; | ||
| 120 | - $customModel->edit(['category_id'=>$str],['id'=>$v['id']]); | ||
| 121 | - } | ||
| 122 | - $page++; | ||
| 123 | - } | ||
| 124 | - return true; | ||
| 125 | - } | ||
| 126 | -} |
| 1 | -<?php | ||
| 2 | -/** | ||
| 3 | - * @remark : | ||
| 4 | - * @name :DeleteProductCategory.php | ||
| 5 | - * @author :lyh | ||
| 6 | - * @method :post | ||
| 7 | - * @time :2024/5/16 14:59 | ||
| 8 | - */ | ||
| 9 | - | ||
| 10 | -namespace App\Console\Commands\DeleteCategory; | ||
| 11 | - | ||
| 12 | -use App\Helper\Arr; | ||
| 13 | -use App\Models\Com\NoticeLog; | ||
| 14 | -use App\Models\News\News; | ||
| 15 | -use App\Models\News\NewsCategory; | ||
| 16 | -use App\Models\Project\Project; | ||
| 17 | -use App\Services\ProjectServer; | ||
| 18 | -use Illuminate\Console\Command; | ||
| 19 | -use Illuminate\Support\Facades\DB; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * @remark :删除分类 | ||
| 23 | - * @name :DeleteProductCategory | ||
| 24 | - * @author :lyh | ||
| 25 | - * @method :post | ||
| 26 | - * @time :2024/5/16 15:00 | ||
| 27 | - */ | ||
| 28 | -class DeleteNewsCategory extends Command | ||
| 29 | -{ | ||
| 30 | - /** | ||
| 31 | - * The name and signature of the console command. | ||
| 32 | - * | ||
| 33 | - * @var string | ||
| 34 | - */ | ||
| 35 | - protected $signature = 'delete_news_category'; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * The console command description. | ||
| 39 | - * | ||
| 40 | - * @var string | ||
| 41 | - */ | ||
| 42 | - protected $description = '删除新闻分类'; | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * Create a new command instance. | ||
| 46 | - * | ||
| 47 | - * @return void | ||
| 48 | - */ | ||
| 49 | - public function __construct() | ||
| 50 | - { | ||
| 51 | - parent::__construct(); | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * @remark :批量处理 | ||
| 56 | - * @name :handle | ||
| 57 | - * @author :lyh | ||
| 58 | - * @method :post | ||
| 59 | - * @time :2024/5/16 15:02 | ||
| 60 | - */ | ||
| 61 | - public function handle(){ | ||
| 62 | - while (true){ | ||
| 63 | - $noticeLogModel = new NoticeLog(); | ||
| 64 | - $list = $noticeLogModel->list(['status'=>NoticeLog::STATUS_PENDING,'type'=>NoticeLog::DELETE_NEWS_CATEGORY],'id',['*'],'asc',100); | ||
| 65 | - if(empty($list)){ | ||
| 66 | - sleep(10); | ||
| 67 | - continue; | ||
| 68 | - } | ||
| 69 | - foreach ($list as $item){ | ||
| 70 | - echo 'start:' . $item['id'] . PHP_EOL; | ||
| 71 | - try { | ||
| 72 | - $projectModel = new Project(); | ||
| 73 | - $projectInfo = $projectModel->read(['id'=>$item['data']['project_id']]); | ||
| 74 | - if($projectInfo === false){ | ||
| 75 | - continue; | ||
| 76 | - } | ||
| 77 | - ProjectServer::useProject($projectInfo['id']); | ||
| 78 | - $this->updateCategory(); | ||
| 79 | - DB::disconnect('custom_mysql'); | ||
| 80 | - $noticeLogModel->edit(['status'=>NoticeLog::STATUS_SUCCESS],['id'=>$item['id']]); | ||
| 81 | - echo 'success:' . $item['id'] . '执行时间:'.date('Y-m-d H:i:s') . PHP_EOL; | ||
| 82 | - }catch (\Exception $e){ | ||
| 83 | - echo 'error:' . $item['id'] . $e->getMessage() . '执行时间:'.date('Y-m-d H:i:s') . PHP_EOL; | ||
| 84 | - errorLog('delete_news_category删除失败', $item, $e); | ||
| 85 | - } | ||
| 86 | - } | ||
| 87 | - return true; | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - /** | ||
| 92 | - * @remark :更新分类 | ||
| 93 | - * @name :updateProductCategory | ||
| 94 | - * @author :lyh | ||
| 95 | - * @method :post | ||
| 96 | - * @time :2024/5/16 15:38 | ||
| 97 | - */ | ||
| 98 | - public function updateCategory(){ | ||
| 99 | - $page = 1; | ||
| 100 | - $newsModel = new News(); | ||
| 101 | - while (true){ | ||
| 102 | - $newsList = $newsModel->lists(['status'=>1],$page,1000,'id',['id','category_id']); | ||
| 103 | - if(empty($newsList) || empty($newsList['list'])){ | ||
| 104 | - return false; | ||
| 105 | - } | ||
| 106 | - foreach ($newsList['list'] as $v){ | ||
| 107 | - $category_id_arr = Arr::setToArr(trim($v['category_id'],',')); | ||
| 108 | - if(empty($category_id_arr)){ | ||
| 109 | - continue; | ||
| 110 | - } | ||
| 111 | - $categoryModel = new NewsCategory(); | ||
| 112 | - foreach ($category_id_arr as $k=>$cate_id){ | ||
| 113 | - $cateInfo = $categoryModel->read(['id'=>$cate_id],['id']); | ||
| 114 | - if($cateInfo === false){ | ||
| 115 | - //删除关联表 | ||
| 116 | - unset($category_id_arr[$k]); | ||
| 117 | - } | ||
| 118 | - } | ||
| 119 | - $str = !empty($category_id_arr) ? ','.Arr::arrToSet($category_id_arr).',' : ''; | ||
| 120 | - $newsModel->edit(['category_id'=>$str],['id'=>$v['id']]); | ||
| 121 | - } | ||
| 122 | - $page++; | ||
| 123 | - } | ||
| 124 | - return true; | ||
| 125 | - } | ||
| 126 | -} |
-
请 注册 或 登录 后发表评论