作者 赵彬吉

update

... ... @@ -9,11 +9,12 @@ use App\Helper\Translate;
use App\Models\Ai\AiCommand;
use App\Models\Mail\Mail;
use App\Models\Project\DeployOptimize;
use App\Models\Project\ProjectUpdateTdk;
use App\Models\User\User;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
/**
* 初始化项目
... ... @@ -132,31 +133,30 @@ class UpdateSeoTdk extends Command
public function handle()
{
while (true) {
$project_id = Redis::rpop('updateSeoTdk');
$task = ProjectUpdateTdk::getPendingTask();
$project_id = $task->project_id;
if (!$project_id) {
sleep(2);
sleep(10);
continue;
}
echo date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
try {
ProjectServer::useProject($project_id);
$this->seo_tdk($project_id);
$this->seo_tdk($project_id, $task->id);
DB::disconnect('custom_mysql');
}catch (\Exception $e){
echo date('Y-m-d H:i:s') . 'line: '. $e->getLine() .' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
ProjectUpdateTdk::retry($task->id, $e->getMessage());
}
echo date('Y-m-d H:i:s') . ' end: ' . $project_id . PHP_EOL;
}
}
public function seo_tdk($project_id)
public function seo_tdk($project_id, $task_id)
{
$data = [];
$update = [
'created_at'=>date('Y-m-d H:i:s'),
'updated_at'=>date('Y-m-d H:i:s'),
'project_id'=>$project_id,
];//更新统计
//更新统计
$update = [];
$ai_commands = AiCommand::where('is_batch', 1)->select('key', 'scene', 'ai')->get()->toArray();
$ai_commands = Arr::setValueToKey($ai_commands, 'key');
foreach ($this->maps as $table => $map) {
... ... @@ -186,6 +186,15 @@ class UpdateSeoTdk extends Command
echo $field.'已有值 跳过' . PHP_EOL;
continue;
}
//缓存 在处理的 项目 数据 id
$cache_key = "seo_tdk_{$project_id}_{$table}_{$v['id']}";
if(Cache::get($cache_key)){
echo '其他进程在处理' . PHP_EOL;
continue;
}
Cache::put($cache_key, 1, 120);
//AI生成
if (!empty($ai_commands[$ai_key]['ai'])) {
$prompt = $this->getPrompt($project_id, $ai_commands[$ai_key]['ai'], $table, $v);
... ... @@ -262,10 +271,9 @@ class UpdateSeoTdk extends Command
}
DB::connection('custom_mysql')->table($table)->where(['id' => $v['id']])->update($data);
}
$update[$table] = json_encode($update[$table]);
}
}
DB::table('gl_project_update_tdk')->insert($update);
ProjectUpdateTdk::finish($task_id, $update);
}
public function getPrompt($project_id, $prompt, $table, $data){
... ...
... ... @@ -151,6 +151,9 @@ class Arr extends \Illuminate\Support\Arr
*/
public static function s2a($str)
{
if(!$str){
return [];
}
if (is_array($str)) {
return $str;
}
... ...
... ... @@ -11,6 +11,7 @@ namespace App\Http\Controllers\Aside\Com;
use App\Helper\Common;
use App\Http\Controllers\Bside\BaseController;
use App\Models\Project\ProjectUpdateTdk;
use App\Services\ProjectServer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
... ... @@ -37,7 +38,7 @@ class UpdateController extends BaseController
],[
'project_id.required' => 'project_id不能为空',
]);
Redis::lpush('updateSeoTdk', $this->param['project_id']);
ProjectUpdateTdk::add_task($this->param['project_id']);
$this->response('任务添加成功');
}
}
... ...
... ... @@ -9,10 +9,104 @@
namespace App\Models\Project;
use App\Helper\Arr;
use App\Models\Base;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ProjectUpdateTdk extends Base
{
//设置关联表名
protected $table = 'gl_project_update_tdk';
const STATUS_PENDING = 0;
const STATUS_SUCCESS = 1;
const STATUS_FAIL = 2;
/**
* 新建任务
* @param $project_id
* @author zbj
* @date 2023/11/9
*/
public static function add_task($project_id){
$model = new self();
$model->project_id = $project_id;
$model->save();
}
/**
* 获取待处理任务
* @return mixed
* @author zbj
* @date 2023/11/9
*/
public static function getPendingTask(){
return self::where('status', self::STATUS_PENDING)->orderBy('id', 'asc')->first();
}
/**
* 重试任务
* @param $id
* @param $remark
* @author zbj
* @date 2023/11/9
*/
public static function retry($id, $remark)
{
DB::beginTransaction();
try {
//行锁 避免脏读写
$data = self::where('id', $id)->lockForUpdate()->first();
$data->retry = $data->retry + 1;
if ($data->retry > 3) {
$data->status = self::STATUS_FAIL;
}else{
$data->status = self::STATUS_PENDING;
}
$data->remark = mb_substr($remark, 0, 250);
$data->save();
DB::commit();
} catch (\Exception $e) {
DB::rollback();
Log::error('project_update_tdk retry error:' . $e->getMessage());
}
}
/**
* 完成
* @param $id
* @param $update_data
* @author zbj
* @date 2023/11/9
*/
public static function finish($id, $update_data){
DB::beginTransaction();
try {
//行锁 避免脏读写
$data = self::where('id', $id)->lockForUpdate()->first();
$data->status = self::STATUS_SUCCESS;
foreach($update_data as $field => $item){
$old_date = Arr::s2a($data->$field);
$new_data = [];
foreach($item as $k=>$v){
if($k == 'total_page'){
$new_data[$k] = $v;
}else{
$new_data[$k] = $v + ($old_date[$k] ?? 0);
}
}
$data->$field = $new_data;
}
$data->save();
DB::commit();
} catch (\Exception $e) {
DB::rollback();
Log::error('project_update_tdk finish error:' . $e->getMessage());
}
}
}
... ...