作者 刘锟

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

... ... @@ -51,12 +51,13 @@ class GeoQuestionRes extends Command
sleep(300);
continue;
}
$lock_key = "geo_task_lock:$task_id";
$lock_key = "geo_task_lock_" . $task_id;
if (!Redis::setnx($lock_key, 1)) {
$this->output("任务 $task_id 已被其他进程锁定,跳过");
sleep(30); // 程序挂起, 避免最后一个任务 扫数据表和Redis
continue;
}
Redis::expire($lock_key, 1200); // 1小时自动解锁
Redis::expire($lock_key, 600); // 10自动解锁
$this->output('执行的任务ID:' . $task_id);
$geoQuestionModel = new GeoQuestion();
$taskInfo = $geoQuestionModel->read(['id'=>$task_id]);
... ... @@ -86,6 +87,7 @@ class GeoQuestionRes extends Command
$geoResultModel = new GeoQuestionResult();
$geoLogModel = new GeoQuestionLog();
foreach ($taskInfo['question'] as $question) {
Redis::expire($lock_key, 1200); // 一个问题执行时间可能会达到15-18分钟
$en_question = Translate::tran($question, 'zh') ?? '';
$this->output('项目ID:' . $taskInfo['project_id'] . ', 问题 开始:' . $question);
foreach ($platformsArr as $platform) {
... ... @@ -345,19 +347,28 @@ class GeoQuestionRes extends Command
$key = 'geo_task_list';
$task_id = Redis::rpop($key);
if(empty($task_id)){
$project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))
->orderBy('next_time', 'asc')->pluck('project_id')->unique()->values()->toArray();
if(!empty($project_ids)){
foreach ($project_ids as $project_id){
$ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('next_time', '<=', date('Y-m-d'))->pluck('id');
foreach ($ids as $id) {
//检查任务是否执行过
if (!Redis::exists("geo_task_lock:$id")) {
Redis::lpush($key, $id);
}
}
$task_id = Redis::rpop($key);
$lock_key = 'geo_task_generation_lock';
$lock_ttl = 60; // 锁时间大于当前 锁功能执行时间
// 尝试获取锁,非阻塞方式
$lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
if (empty($lock)){
return $task_id;
}
$project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->pluck('project_id')->unique()->values()->toArray();
if(FALSE == empty($project_ids)){
$ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
->whereIn('project_id', $project_ids)
->where(function ($query){
$query->where('current_time', '!=', date('Y-m-d'))
->orWhereNull('current_time');
})
->orderBy('project_id', 'asc')
->pluck('id');
foreach ($ids as $id) {
Redis::lpush($key, $id);
}
$task_id = Redis::rpop($key);
}
}
return $task_id;
... ...
... ... @@ -39,6 +39,11 @@ class GeoWritingTaskController extends BaseController
* @time :2025/10/25 15:12
*/
public function lists(){
$this->request->validate([
'project_id'=>'required',
],[
'project_id.required' => 'project_id不能为空',
]);
$data = $this->logic->listWritingTask($this->map,$this->page,$this->row,$this->order);
$this->response('success',Code::SUCCESS,$data);
}
... ...
... ... @@ -39,6 +39,11 @@ class GeoWritingsController extends BaseController
* @time :2025/10/25 15:53
*/
public function lists(){
$this->request->validate([
'project_id'=>'required',
],[
'project_id.required' => 'project_id不能为空',
]);
$data = $this->logic->listWriting($this->map,$this->page,$this->row,$this->order);
$this->response('success',Code::SUCCESS,$data);
}
... ...
... ... @@ -251,7 +251,6 @@ class InquiryController extends BaseController
$data = $data['list'] ?? [];
foreach ($data as &$item){
//非正常登录的
if(($this->user['login_source']??0) != 2 && ($this->user['login_source']??0) != 3){
if(!empty($item['email']) && (strpos($item['email'], '@') !== false)){
$item['email'] = email_desensitize($item['email']);
... ... @@ -259,9 +258,7 @@ class InquiryController extends BaseController
//脱敏
!empty($item['phone']) && $item['phone'] = substr($item['phone'], 0, -4) . '****';
}
$item['ip_address'] = "{$item['country']}({$item['ip']})";
if(!empty($this->param['form_id'])){
$item = array_merge($item, $item['data']);
}
... ...
... ... @@ -69,9 +69,11 @@ class GeoConfirmLogic extends BaseLogic
{
$data = $this->model->read($this->param);
if($data === false){
$this->fail('当前数据不存在或者已被删除');
return $this->success();
}
if(empty($data['confirm'])){
$data['confirm'] = $data['content'];
}
$data['confirm'] = $data['content'];
return $this->success($data);
}
... ...
... ... @@ -112,6 +112,9 @@ class GeoLogic extends BaseLogic
{
//获取问题数量
$geo_question_count = GeoQuestion::selectRaw('SUM(JSON_LENGTH(question)) as total_count')->where('project_id',$this->param['project_id'])->value('total_count');
if(empty($geo_question_count)){
$geo_question_count = 0;
}
$geo_pr_count = GeoLink::where('project_id',$this->param['project_id'])->count();
$geo_writings_count = GeoWritings::where('project_id',$this->param['project_id'])->count();
return $this->success(['geo_writings_count'=>$geo_writings_count,'geo_pr_count'=>$geo_pr_count,'geo_question_count'=>$geo_question_count]);
... ...
... ... @@ -8,6 +8,7 @@
namespace App\Models\Geo;
use App\Models\Base;
use App\Models\Project\Project;
use App\Models\Workchat\MessagePush;
/**
... ... @@ -42,8 +43,23 @@ class GeoConfirm extends Base
public static function typeMapping()
{
return [
self::TYPE_TITLE => '确认标题',
self::TYPE_KEYWORD => '确认关键词'
self::TYPE_TITLE => '核心关键词问题已整理,请查看并确认',
self::TYPE_KEYWORD => '文章标题已整理,请查看并确认'
];
}
/**
* @remark :确认返回数据
* @name :typeDesc
* @author :lyh
* @method :post
* @time :2025/10/31 10:10
*/
public static function typeDesc()
{
return [
self::TYPE_TITLE => '需选择确认10个文章标题,后续根据您确认的文章标题整理文章内容;如有补充展会、资质证书等资料,可一并提供。',
self::TYPE_KEYWORD => '需选择确认10个核心关键词问题,后续根据您确认的核心关键词问题整理文章标题;建议提供展会、资质证书等资料。'
];
}
... ... @@ -98,9 +114,12 @@ class GeoConfirm extends Base
$type = MessagePush::TYPE_GEO_CONFIRM;
$token = uniqid().$friend_id;
$created_at = $updated_at = now();
$projectModel = new Project();
$projectInfo = $projectModel->read(['id'=>$project_id],['company','seo_plan']);
$seo_plan = ($projectModel::seoMap()[$projectInfo['seo_plan']]) ?? '无选择';
$content_array = [
'title' => self::typeMapping()[$data->type],
'desc' => self::typeMapping()[$data->type],
'title' => "【{$projectInfo['company']} {$seo_plan}】".self::typeMapping()[$data->type],
'desc' => self::typeDesc()[$data->type],
'size' => 0,
'thumbSize' => 0,
'thumbUrl' => 'https://hub.globalso.com/logocm.png',
... ...
... ... @@ -8,6 +8,7 @@
namespace App\Models\Geo;
use App\Models\Base;
use App\Models\Project\Project;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\Workchat\MessagePush;
use Illuminate\Support\Facades\Crypt;
... ... @@ -90,10 +91,13 @@ class GeoWritings extends Base
'project_id' => $project_id,
'send_at' => time()
];
$projectModel = new Project();
$projectInfo = $projectModel->read(['id'=>$project_id],['company','seo_plan']);
$seo_plan = ($projectModel::seoMap()[$projectInfo['seo_plan']]) ?? '无选择';
$token = Crypt::encrypt($param);
$content_array = [
'title' => "确认核心文章",
'desc' => '确认核心文章',
'title' => "【{$projectInfo['company']} {$seo_plan}】核心文章已整理,请查看并确认",
'desc' => '需选择确认10篇文章,后续根据您确认的文章进行外链发布。',
'size' => 0,
'thumbSize' => 0,
'thumbUrl' => 'https://hub.globalso.com/logocm.png',
... ...