作者 刘锟

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

... ... @@ -13,6 +13,7 @@ use App\Helper\Arr;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiBlogList;
use App\Models\Com\NoticeLog;
use App\Models\Com\Notify;
use App\Models\Devops\ServerConfig;
use App\Models\Devops\ServersIp;
... ... @@ -337,6 +338,9 @@ class AiBlogTask extends Command
'is_sitemap' => 0
];
$res = http_post($c_url, json_encode($param,true));
if(empty($res)){
NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url'=>$c_url,'c_params'=>$param]),date('Y-m-d H:i:s',time()+300));
}
$this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
}
... ...
... ... @@ -10,12 +10,15 @@
namespace App\Console\Commands\LyhTest;
use App\Helper\Common;
use App\Models\Blog\Blog;
use App\Models\Com\V6WeeklyReport;
use App\Models\News\News;
use App\Models\Product\Category;
use App\Models\Product\CategoryRelated;
use App\Models\Product\Product;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\RouteMap\RouteMap;
use App\Models\Template\BTemplate;
use App\Models\Visit\Visit;
use App\Models\Visit\VisitItem;
use App\Models\Workchat\MessagePush;
... ... @@ -43,16 +46,51 @@ class DownloadProject extends Command
public function handle(){
echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
ProjectServer::useProject(535);
$this->model = new Visit();
$data = $this->importVisit();
dd($data);
ProjectServer::useProject(671);
$this->newsImportBlog();
DB::disconnect('custom_mysql');
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
return true;
}
/**
* @remark :新闻导入到博客
* @name :newsImportBlog
* @author :lyh
* @method :post
* @time :2025/6/7 11:12
*/
public function newsImportBlog(){
$newsModel = new News();
$newsLists = $newsModel->list(['status'=>1]);
$blogModel = new Blog();
foreach ($newsLists as $item){
$data = [
'name'=>$item['name'],
'status'=>1,
'remark'=>$item['remark'],
'text'=>$item['text'],
'image'=>$item['image'],
'url'=>$item['url'],
'seo_title'=>$item['seo_title'],
'seo_description'=>$item['seo_title'],
'seo_keywords'=>$item['seo_title'],
'project_id'=>671,
'release_at'=>$item['release_at'],
'og_image'=>$item['og_image']
];
$id = $blogModel->addReturnId($data);
RouteMap::delRoute(RouteMap::SOURCE_NEWS,$item['id'],671);
$route = RouteMap::setRoute($item['url'],RouteMap::SOURCE_BLOG,$id,671);
$blogModel->edit(['url'=>$route],['id'=>$id]);
//更新当前的可视化归宿
$templateModel = new BTemplate();
$templateModel->edit(['source'=>3,'source_id'=>$id],['source'=>4,'source_id'=>$item['id'],'is_custom'=>0,'is_list'=>0]);
}
return true;
}
/**
* @remark :导出明细
* @name :importVisit
* @author :lyh
... ...
... ... @@ -10,6 +10,7 @@
namespace App\Console\Commands\LyhTest;
use App\Console\Commands\Domain\DomainInfo;
use App\Helper\OaGlobalsoApi;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
... ... @@ -57,26 +58,28 @@ class lyhDemo extends Command
protected $description = '更新路由';
public function handle(){
$str = '3671,955,752,1270,439,2674,3588,2388,1271,1543,738,624,552,1417,1237,651,1143,817,1556,1234,1350,650,538,491,631,2059,1845,866,1194,1699,546,684,905,1805,1728,2811,952,2972,2827,983,812,3081,554,741,1349,980';
$arr = explode(',',$str);
$model = new TranslateBigProject();
foreach ($arr as $val){
$model->addReturnId(['project_id'=>$val]);
$projectModel = new Project();
$buildModel = new DeployBuild();
$lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'is_upgrade'=>0,'id'=>['<',1659],'extend_type'=>0,'type'=>['in',[1,2,3,4,6]]], 'id', ['id','notice_order_id']);
foreach ($lists as $item){
echo date('Y-m-d H:i:s') . '开始--项目的id:'. $item['id'] . PHP_EOL;
try {
if(!empty($item['notice_order_id'])){
$api = new OaGlobalsoApi();
$data = $api->order_info($item['notice_order_id']);
if(!empty($data)){
if(isset($data['data']['ads_price'])){
echo '奖励金额:'.$data['data']['ads_price'].PHP_EOL;
$buildModel->edit(['ads_price'=>$data['data']['ads_price'] ?? 0],['project_id'=>$item['id']]);
}
}
}
}catch (\Exception $e){
continue;
}
DB::disconnect('custom_mysql');
}
return true;
// $projectModel = new Project();
// $lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'extend_type'=>0,'type'=>['in',[1,2,3,4,6]]], 'id', ['id']);
// foreach ($lists as $item){
//// echo date('Y-m-d H:i:s') . '开始--项目的id:'. $item['id'] . PHP_EOL;
// ProjectServer::useProject($item['id']);
// $webSettingModel = new WebSetting();
// $info = $webSettingModel->read(['project_id'=>$item['id']]);
// if($info === false){
// $webSettingModel->addReturnId(['project_id'=>$item['id']]);
// echo '当前数据为空:'.$item['id'].PHP_EOL;
// }
// DB::disconnect('custom_mysql');
// }
echo date('Y-m-d H:i:s') . '结束。。。' . PHP_EOL;
}
public function _actionTemplateMain(){
... ...
... ... @@ -227,7 +227,8 @@ class SyncProject extends Command
'version'=>$version
],
'deploy_build' => [
'login_mobile'=>$param['principal_mobile']
'login_mobile'=>$param['principal_mobile'],
'ads_price'=>$param['ads_price'] ?? 0
],
'deploy_optimize' => [
// 'api_no' => 0
... ...
<?php
namespace App\Console\Commands\Tdk;
use App\Exceptions\ValidateException;
use App\Helper\Arr;
use App\Helper\Gpt;
use App\Models\Ai\AiCommand;
use App\Models\Com\NoticeLog;
use App\Models\Domain\DomainInfo;
use App\Models\Product\Keyword;
use App\Models\Project\AggregateKeywordAffix;
use App\Models\Project\DeployBuild;
use App\Models\Project\DeployOptimize;
use App\Models\Project\ProjectKeywordAiTask;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
/**
* 关键词聚合页AI生成内容
* Class InitProject
* @package App\Console\Commands
* @author zbj
* @date 2025/06/06
*/
class KeywordPageAiContent extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'keyword_page_ai_content';
/**
* The console command description.
*
* @var string
*/
protected $description = '关键词聚合页AI生成内容';
/**
* 统计图表类型 随机一个
* @var string[]
*/
protected $chart_types = [
'柱状图',
'折线图',
];
/**
* @return bool
*/
public function handle()
{
while (true) {
$task = ProjectKeywordAiTask::getPendingTask();
if (!$task) {
sleep(10);
continue;
}
$project_id = $task->project_id;
echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
try {
ProjectServer::useProject($project_id);
$update_rows = $this->ai_content($task);
DB::disconnect('custom_mysql');
ProjectKeywordAiTask::finish($task->id, $update_rows);
// $update_rows && $this->sendNotify($project_id);
} catch (ValidateException $e) {
echo getmypid() . ' ' . date('Y-m-d H:i:s') . 'line: ' . $e->getLine() . ' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
$task->status = ProjectKeywordAiTask::STATUS_FAIL;
$task->remark = mb_substr($e->getMessage(), 0, 250);
$task->save();
} catch (\Exception $e) {
echo getmypid() . ' ' . date('Y-m-d H:i:s') . 'line: ' . $e->getLine() . ' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
ProjectKeywordAiTask::retry($task->id, $e->getMessage());
}
echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' end project_id: ' . $project_id . PHP_EOL;
}
}
/**
* @param ProjectKeywordAiTask $task
* @author zbj
* @date 2025/6/6
*/
public function ai_content(ProjectKeywordAiTask $task)
{
//前后缀
$affix = AggregateKeywordAffix::where('project_id', $task->project_id)->first();
$prefix = empty($affix['prefix']) ? [] : explode("\r\n", $affix['prefix']);
$suffix = empty($affix['suffix']) ? [] : explode("\r\n", $affix['suffix']);
if (!$prefix || !$suffix) {
throw new ValidateException('扩展标题前后缀不存在');
}
//公司英文描述
$company_en_description = DeployOptimize::where('project_id', $task->project_id)->value('company_en_description');
if (!$company_en_description) {
throw new ValidateException('公司英文描述不存在');
}
//指令
$ai_commands = AiCommand::whereIn('key', ['tag_sale_content', 'tag_count_content', 'tag_data_table'])->where('project_id', 0)->select('key', 'scene', 'ai')->get()->toArray();
$project_ai_commands = AiCommand::whereIn('key', ['tag_sale_content', 'tag_count_content', 'tag_data_table'])->where('project_id', $task->project_id)->select('key', 'scene', 'ai')->get()->toArray();
$ai_commands = Arr::setValueToKey($ai_commands, 'key');
$project_ai_commands = Arr::setValueToKey($project_ai_commands, 'key');
foreach ($ai_commands as $k => $ai_command) {
if (!empty($project_ai_commands[$k])) {
$ai_commands[$k] = $project_ai_commands[$k];
}
}
//没有标题、文案、图表的关键词
$keyword_ids = Keyword::whereNull('sale_title')->orWhereNull('sale_content')->orWhereNull('table_html')
->orWhereNull('count_title')->orWhereNull('count_html')
->pluck('id')
->toArray();
$update_rows = 0;
foreach ($keyword_ids as $id) {
//缓存 在处理的项目数据 id
$cache_key = "keyword_page_ai_content_task_lock_{$task->project_id}_{$id}";
if (!Redis::setnx($cache_key, 1)) {
continue;
}
Redis::expire($cache_key, 120);
$keyword = Keyword::where('id', $id)->select(['id', 'title', 'sale_title', 'sale_content', 'table_html', 'count_title', 'count_html'])->first();
echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' id:' . $keyword['id'] . ' project_id:' . $task->project_id . PHP_EOL;
$update = false;
if (empty($keyword['sale_title'])) {
$sale_title = $this->new_title($keyword['title'], $prefix, $suffix);
$keyword->sale_title = $sale_title;
$update = true;
}
if (empty($keyword['sale_content']) && $keyword->sale_title) {
$content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_sale_content']['ai']);
if ($content) {
$keyword->sale_content = $content;
$update = true;
}
}
if (empty($keyword['table_html']) && $keyword->sale_title) {
$content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_data_table']['ai']);
if ($content) {
$keyword->table_html = str_replace(['```html', '``html', '```'], '', $content);
$update = true;
}
}
if (empty($keyword['count_title'])) {
$count_title = $this->new_title($keyword['title'], $prefix, $suffix);
$count_title && $keyword->count_title = $count_title;
$update = true;
}
if (empty($keyword['count_html']) && $keyword->sale_title) {
$content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_count_content']['ai']);
if ($content) {
$keyword->count_html = $this->fixChart(str_replace(['```html', '``html', '```'], '', $content));
$update = true;
}
}
if ($update) {
$keyword->save();
$update_rows++;
}
}
return $update_rows;
}
public function new_title($title, $prefix, $suffix)
{
//打乱顺序
shuffle($prefix);
shuffle($suffix);
//标题(title):{聚合页扩展标题前缀} keywords {聚合页扩展标题后缀} {聚合页扩展标题后缀}
return sprintf('%s %s %s %s', $prefix[0], $title, $suffix[0], $suffix[1]);
}
public function ai_send($title, $company_description, $prompt)
{
if (strpos($prompt, '{title}') !== false) {
$prompt = str_replace('{title}', $title, $prompt);
}
if (strpos($prompt, '{company introduction}') !== false) {
$prompt = str_replace('{company introduction}', $company_description, $prompt);
}
if (strpos($prompt, '{chart_type}') !== false) {
shuffle($this->chart_types);
$prompt = str_replace('{chart_type}', $this->chart_types[0], $prompt);
}
$text = Gpt::instance()->openai_chat_qqs($prompt);
if (!$text) {
echo getmypid() . ' ' . '生成失败' . PHP_EOL;
}
return $text;
}
function fixChart($html)
{
$html = '<body>' . $html . '</body>';
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$canvas_count = $dom->getElementsByTagName('canvas')->count();
//没有canvas
if (!$canvas_count) {
$div = $dom->getElementsByTagName('div');
foreach ($div as $element) {
if ($element->hasAttribute('id')) {
$canvas = $dom->createElement('canvas');
$canvas->setAttribute('id', $element->getAttribute('id'));
$element->removeAttribute('id');
$element->appendChild($canvas);
break;
}
}
}
$body = $dom->getElementsByTagName('body')->item(0);
$modifiedHtml = '';
foreach ($body->childNodes as $child) {
$modifiedHtml .= $dom->saveHTML($child);
}
return $modifiedHtml;
}
public function sendNotify($project_id)
{
//获取当前项目的域名
$domainModel = new DomainInfo();
$domainInfo = $domainModel->read(['project_id' => $project_id]);
if ($domainInfo === false) {
//获取测试域名
$deployBuildModel = new DeployBuild();
$buildInfo = $deployBuildModel->read(['project_id' => $project_id]);
$domain = $buildInfo['test_domain'];
} else {
$domain = 'https://' . $domainInfo['domain'] . '/';
}
$url = $domain . 'api/update_page/';
$param = [
'project_id' => $project_id,
'type' => 1,
'route' => 2,
'url' => [],
'language' => [],
];
NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url' => $url, 'c_params' => $param]), date('Y-m-d H:i:s', time() + 300));
echo getmypid() . ' ' . '更新中请稍后, 更新完成将会发送站内信通知更新结果!' . PHP_EOL;
}
}
... ...
<?php
namespace App\Exceptions;
use Exception;
/**
* @notes: 验证
* Class ValidateException
* @package App\Exceptions
*/
class ValidateException extends Exception
{
}
... ...
... ... @@ -31,6 +31,19 @@ class HrController extends BaseController
}
/**
* @remark :获取列表数据
* @name :getManagerList
* @author :lyh
* @method :post
* @time :2025/6/7 9:22
*/
public function getManagerList(){
$manageHrModel = new ManageHr();
$lists = $manageHrModel->lists($this->map,$this->page,$this->row);
$this->response('success', Code::SUCCESS, $lists);
}
/**
* @remark :获取详情
* @name :info
* @author :lyh
... ...
... ... @@ -3,13 +3,17 @@
namespace App\Http\Controllers\Bside\Product;
use App\Enums\Common\Code;
use App\Helper\Common;
use App\Helper\Gpt;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Product\KeywordLogic;
use App\Http\Requests\Bside\Product\KeywordRequest;
use App\Models\Ai\AiCommand;
use App\Models\Product\Keyword;
use App\Models\Product\KeywordPage;
use App\Models\Product\KeywordRelated;
use App\Models\Product\Product;
use App\Models\Project\AggregateKeywordComment;
use App\Rules\Ids;
use Illuminate\Http\Request;
... ... @@ -312,4 +316,70 @@ class KeywordController extends BaseController
$logic->delAllRelated($this->param['keyword_id']);
$this->response('success');
}
/**
* @remark :添加评论
* @name :saveComment
* @author :lyh
* @method :post
* @time :2025/6/9 14:27
*/
public function saveComment(KeywordLogic $logic){
$this->request->validate([
'text'=>'required',
'nickname'=>'required',
],[
'text.required' => '评论内容不能为空',
'nickname.required'=>'昵称不能为空',
]);
$data = $logic->saveComment();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :生成评论
* @name :sendComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:10
*/
public function sendComment(KeywordLogic $logic){
$this->request->validate([
'count'=>'required|max:10',
],[
'count.required' => '生成条数不能为空',
'count.max'=>'count最大10',
]);
$data = $logic->sendComment();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :获取评论
* @name :getComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:45
*/
public function getComment(KeywordLogic $logic){
$data = $logic->getComment($this->map,$this->page,$this->row);
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :删除评论
* @name :getComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:45
*/
public function delComment(KeywordLogic $logic){
$this->request->validate([
'id'=>'required',
],[
'id.required' => '主键不能为空',
]);
$data = $logic->delComment();
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
... ... @@ -81,12 +81,14 @@ class RenewLogic extends BaseLogic
}
DB::beginTransaction();
try {
$this->model->edit(['project_id'=>$this->param['id'],'operator_id'=>$this->manager['id']],['id'=>$this->param['renew_id']]);
if($this->param['renew_id'] != 0){
$this->model->edit(['project_id'=>$this->param['id'],'operator_id'=>$this->manager['id']],['id'=>$this->param['renew_id']]);
}
$param = $this->param;
$param['api_no'] = $info['api_no'] ?? 0;
$this->saveLog($param);
$this->updateProject($this->param['id'],$this->param['type']);
$this->updateProjectBuild($this->param['id'],$this->param['service_duration'],$this->param['plan']);
$this->updateProjectBuild($this->param['id'],$this->param['service_duration'] ?? 0,$this->param['plan']);
DB::commit();
}catch (\Exception $e){
DB::rollBack();
... ... @@ -120,12 +122,12 @@ class RenewLogic extends BaseLogic
public function saveLog($param){
$data = [
'renew_id'=>$param['renew_id'],
'service_duration'=>$param['service_duration'],
'service_duration'=>$param['service_duration'] ?? 0,
'plan'=>$param['plan'],
'old_plan'=>$param['old_plan'],
'type'=>$param['type'],
'old_type'=>$param['old_type'],
'amount'=>$param['amount'],
'amount'=>$param['amount'] ?? 0,
'api_no'=>$param['api_no'],
'project_id'=>$param['id'],
'operator_id'=>$this->manager['id'],
... ...
... ... @@ -68,6 +68,7 @@ class AiBlogLogic extends BaseLogic
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
}
$this->sendHttpC([$this->param['route'],'top-blog']);
shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &");
return $this->success();
}
... ...
... ... @@ -175,6 +175,9 @@ class NewsLogic extends BaseLogic
RouteMap::delRoute(RouteMap::SOURCE_NEWS, $id, $this->user['project_id']);
$this->delRoute($id);
$this->model->del(['id' => $id]);
//删除扩展字段
$extendInfoModel = new NewsExtendInfo();
$extendInfoModel->del(['news_id'=>$id]);
}
}
DB::commit();
... ...
... ... @@ -5,12 +5,15 @@ namespace App\Http\Logic\Bside\Product;
use App\Exceptions\BsideGlobalException;
use App\Helper\Arr;
use App\Helper\Common;
use App\Helper\Gpt;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Ai\AiCommand;
use App\Models\Com\NoticeLog;
use App\Models\News\News;
use App\Models\Product\Keyword;
use App\Models\Product\KeywordRelated;
use App\Models\Product\Product;
use App\Models\Project\AggregateKeywordComment;
use App\Models\RouteMap\RouteMap;
use App\Models\User\User;
use Illuminate\Support\Facades\DB;
... ... @@ -345,4 +348,104 @@ class KeywordLogic extends BaseLogic
return $this->success();
}
/**
* @remark :手动添加评论
* @name :saveComment
* @author :lyh
* @method :post
* @time :2025/6/9 14:29
*/
public function saveComment(){
$keywordCommonModel = new AggregateKeywordComment();
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$keywordCommonModel->edit($this->param,['id'=>$this->param['id']]);
}else{
$param = [
'nickname' => $this->param['nickname'],
'text' => $this->param['text'],
'project_id' => $this->user['project_id'],
'type' => 1,
'uid' => 0,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
$id = $keywordCommonModel->addReturnId($param);
}
return $this->success(['id'=>$id]);
}
/**
* @remark :保存数据
* @name :sendComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:19
*/
public function sendComment()
{
$aiCommonModel = new AiCommand();
$info = $aiCommonModel->read(['key' => 'tag_comment','project_id'=>$this->user['project_id']]);
if($info === false){
$info = $aiCommonModel->read(['key' => 'tag_comment']);
$info['ai'] = str_replace('50', $this->param['count'], $info['ai']);
}
$text = Gpt::instance()->openai_chat_qqs($info['ai']);
$text = Common::deal_keywords($text);
preg_match_all('/\{[^{}]*\}/', $text, $matches);
$data = [];
if (!empty($text)) {
foreach ($matches[0] as $item) {
$item = str_replace("'", '"', $item);
// 解码成 PHP 关联数组
$item = json_decode($item, true);
if (!isset($item['name']) || !isset($item['comment'])) {
continue;
}
$data[] = [
'nickname' => $item['name'],
'text' => $item['comment'],
'project_id' => $this->user['project_id'],
'type' => 1,
'uid' => 0,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
}
}
$keywordCommonModel = new AggregateKeywordComment();
$keywordCommonModel->insertAll($data);
return $this->success($data);
}
/**
* @remark :获取评论
* @name :getComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:46
*/
public function getComment($map,$page,$row){
$keywordCommonModel = new AggregateKeywordComment();
$map['project_id'] = $this->user['project_id'];
$lists = $keywordCommonModel->lists($map,$page,$row);
return $this->success($lists);
}
/**
* @remark :删除评论
* @name :delComment
* @author :lyh
* @method :post
* @time :2025/6/9 11:48
*/
public function delComment(){
$keywordCommonModel = new AggregateKeywordComment();
if($this->param['id'] = 0){
$keywordCommonModel->del(['project_id'=>$this->param['project_id']]);
}else{
$rs = $keywordCommonModel->del(['id'=>$this->param['id']]);
}
return $this->success($rs);
}
}
... ...
<?php
namespace App\Models\Project;
use App\Helper\Arr;
use App\Models\Base;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
class ProjectKeywordAiTask extends Base
{
//设置关联表名
protected $table = 'gl_project_keyword_ai_task';
const STATUS_PENDING = 0;
const STATUS_SUCCESS = 1;
const STATUS_FAIL = 2;
public static function add_task($project_id){
$task = self::where('project_id', $project_id)->where('status', self::STATUS_PENDING)->first();
if($task){
throw new \Exception('该项目有未执行的任务,请勿重复添加');
}
$model = new self();
$model->project_id = $project_id;
$model->save();
Redis::lpush('projectKeywordAiTask', $project_id);
}
public static function getPendingTask(){
//有其他任务 就取其他任务 没有其他任务运行未结束的任务
$project_id = Redis::rpop('projectKeywordAiTask');
$data = [];
if($project_id){
$data = self::where('status', self::STATUS_PENDING)->where('project_id', $project_id)->orderBy('id', 'asc')->first();
}
if($data){
return $data;
}
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_keyword_ai_task retry error:' . $e->getMessage());
}
}
/**
* 完成
* @param $id
* @param $update_rows
* @author zbj
* @date 2023/11/9
*/
public static function finish($id, $update_rows){
DB::beginTransaction();
try {
//行锁 避免脏读写
$data = self::where('id', $id)->lockForUpdate()->first();
$data->status = self::STATUS_SUCCESS;
$data->update_rows = $update_rows;
$data->save();
DB::commit();
} catch (\Exception $e) {
DB::rollback();
Log::error('project_keyword_ai_task finish error:' . $e->getMessage());
}
}
}
... ...
... ... @@ -149,6 +149,7 @@ Route::middleware(['aloginauth'])->group(function () {
//人事管理
Route::prefix('hr')->group(function () {
Route::any('/', [Aside\Manage\HrController::class, 'list'])->name('admin.hr');
Route::any('/getManagerList', [Aside\Manage\HrController::class, 'getManagerList'])->name('admin.hr_getManagerList');
Route::any('/info', [Aside\Manage\HrController::class, 'info'])->name('admin.hr_info');
Route::post('/save', [Aside\Manage\HrController::class, 'save'])->name('admin.hr_save');
Route::post('/sort', [Aside\Manage\HrController::class, 'sort'])->name('admin.hr_sort');
... ...
... ... @@ -327,6 +327,10 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('keyword/batchKeywordIsVideo', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordIsVideo'])->name('product_keyword_batchKeywordIsVideo');
Route::any('keyword/batchKeywordFiled', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordFiled'])->name('product_keyword_batchKeywordFiled');
Route::any('keyword/delRelatedProductId', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delRelatedProductId'])->name('product_keyword_delRelatedProductId');
Route::any('keyword/sendComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'sendComment'])->name('product_keyword_sendComment');
Route::any('keyword/getComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'getComment'])->name('product_keyword_getComment');
Route::any('keyword/delComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delComment'])->name('product_keyword_delComment');
Route::any('keyword/saveComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'saveComment'])->name('product_keyword_saveComment');
//产品参数
Route::get('attr', [\App\Http\Controllers\Bside\Product\AttrController::class, 'index'])->name('product_attr');
Route::get('attr/info', [\App\Http\Controllers\Bside\Product\AttrController::class, 'info'])->name('product_attr_info');
... ...