作者 赵彬吉
... ... @@ -27,7 +27,7 @@ class RemainDay extends Command
* @var 按优化时间统计
*/
protected $projectId = [
1434,1812,276,2414,2974
1434,1812,276,2414,2974,
];//需要单独处理的项目
/**
... ... @@ -37,7 +37,13 @@ class RemainDay extends Command
protected $bm_projectId = [
4247,4299,4310,4215,4038,4084,4148,4178,4405
];
/**
* @var
* 优化项目,中途切换按服务时间长计时,单独计算
*/
protected $projectSwitchId = [
793,
];
/**
* @var 暂停的项目
... ... @@ -85,8 +91,8 @@ class RemainDay extends Command
public function saveRemainDay(){
$list = $this->project->list(['extend_type'=>Project::TYPE_ZERO,'type'=>['in',[Project::TYPE_TWO,Project::TYPE_THREE,Project::TYPE_FOUR,Project::TYPE_SIX]]],'id',['id','type','level','uptime','remain_day','is_remain_today','pause_days','finish_remain_day','bm_finish_remain_day']);
foreach ($list as $item){
$deploy_build = $this->deployBuild->read(['project_id'=>$item['id']],['service_duration','seo_service_duration','plan','seo_plan']);
echo 'start->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL;
$deploy_build = $this->deployBuild->read(['project_id'=>$item['id']],['service_duration','seo_service_duration','plan','seo_plan']);
if(in_array($item['id'],$this->ceaseProjectId)){//暂停的项目
if(($item['type'] == Project::TYPE_TWO) && ($item['is_remain_today'] == 1)){
$pause_days = $item['pause_days'] + 1;
... ... @@ -97,6 +103,11 @@ class RemainDay extends Command
$this->project->edit(['pause_days'=>$pause_days],['id'=>$item['id']]);
continue;
}
//todo::优化项目中途达标计时切换为按天计时
if(in_array($item['id'],$this->projectSwitchId)){
$this->project->edit(['remain_day'=>($item['remain_day'] - 1),'finish_remain_day'=>($item['finish_remain_day'] + 1)],['id'=>$item['id']]);
continue;
}
//白帽版本单独计算
$this->seoRemainDay($deploy_build,$item);
//默认版本统计
... ...
... ... @@ -51,6 +51,12 @@ class GeoQuestionRes extends Command
sleep(300);
continue;
}
$lock_key = "geo_task_lock:$task_id";
if (!Redis::setnx($lock_key, 1)) {
$this->output("任务 $task_id 已被其他进程锁定,跳过");
continue;
}
Redis::expire($lock_key, 1200); // 1小时自动解锁
$this->output('执行的任务ID:' . $task_id);
$geoQuestionModel = new GeoQuestion();
$taskInfo = $geoQuestionModel->read(['id'=>$task_id]);
... ... @@ -339,16 +345,19 @@ class GeoQuestionRes extends Command
$key = 'geo_task_list';
$task_id = Redis::rpop($key);
if(empty($task_id)){
//todo::这里需要执行统计一次,统计当前项目当前日期的统计
# TODO 按照项目进行获取, 一个项目当天需要将所有跑完
$project_id = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->value('project_id');
if (!empty($project_id)){
$this->project_id = $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) {
Redis::lpush($key, $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);
}
$task_id = Redis::rpop($key);
}
}
return $task_id;
... ...
... ... @@ -73,7 +73,7 @@ class GeoWritingsTask extends Command
'status'=>2,
'writings_id'=>$id,
];
$geoWritingsTaskModel->edit($data,['task_id'=>$task_id]);
$geoWritingsTaskModel->edit($data,['id'=>$task_id]);
}catch (\Exception $e){
echo date('Y-m-d H:i:s').'保存失败:'.$task_id.$e->getMessage().PHP_EOL;
continue;
... ...
... ... @@ -5,6 +5,7 @@ namespace App\Console\Commands\Inquiry;
use App\Models\Inquiry\ForwardCount;
use App\Models\Inquiry\InquiryInfo;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
class InquiryForwardDayCount extends Command
{
... ... @@ -55,6 +56,8 @@ class InquiryForwardDayCount extends Command
$day_count->save();
}
Cache::forget('inquiry_manage_count');
$this->output('success');
}
... ...
... ... @@ -59,15 +59,30 @@ class MonthProjectCount extends Command
* @time :2024/1/8 9:05
*/
public function count($project_id,$url,$is_upgrade = 0){
$data = [];
$list = DB::connection('custom_mysql')->table('gl_customer_visit')
->select(DB::raw('DATE_FORMAT(updated_date, "%Y-%m") as month'))
->orderBy('month', 'asc')
->groupBy('month')->get()->toArray();
foreach ($list as $v){
$data[] = $v->month;
$data = [];
if (!empty($list)) {
// 提取已有月份
foreach ($list as $v) {
$data[] = $v->month;
}
// 生成连续月份
$startMonth = $data[0];
$endMonth = end($data);
$fullMonths = [];
$current = $startMonth;
while ($current <= $endMonth) {
$fullMonths[] = $current;
$current = date('Y-m', strtotime($current . ' +1 month'));
}
$data = $fullMonths;
} else {
$data = [];
}
$list = $this->fillMissingMonths($data);
$list = $data;
foreach ($list as $v){
$arr = [];
$monthCountModel = new MonthCount();
... ... @@ -179,38 +194,4 @@ class MonthProjectCount extends Command
$arr['referrer_port'] = json_encode($referrer_port);
return $arr;
}
/**
* @remark :补齐月份
* @name :fillMissingMonths
* @author :lyh
* @method :post
* @time :2024/8/14 11:11
*/
public function fillMissingMonths($dates) {
// 将字符串日期转换为 Carbon 对象
$carbonDates = array_map(function($date) {
return Carbon::createFromFormat('Y-m', $date);
}, $dates);
// 排序日期,确保列表按时间顺序排列
usort($carbonDates, function($a, $b) {
return $a->gt($b);
});
// 用于存储完整日期的数组
$completeDates = [];
// 遍历日期列表,补齐中间缺失的月份
for ($i = 0; $i < count($carbonDates) - 1; $i++) {
$current = $carbonDates[$i];
$next = $carbonDates[$i + 1];
// 将当前月份加入完整日期数组
array_push($completeDates, $current->format('Y-m'));
// 循环补齐中间缺失的月份
while ($current->addMonth()->lt($next)) {
array_push($completeDates, $current->format('Y-m'));
}
}
// 加入最后一个月份
array_push($completeDates, $carbonDates[count($carbonDates) - 1]->format('Y-m'));
return $completeDates;
}
}
... ...
... ... @@ -53,24 +53,28 @@ class SendProduct extends Command
if(empty($domain)){
continue;
}
$arr1 = $this->sendProduct();
$arr2 = $this->sendBlog();
$arr3 = $this->sendNews();
$url = array_merge((array)$arr1,(array)$arr2,(array)$arr3);
if(!empty($url)){
$c_url = $domain.'api/update_page/';
$param = [
'project_id' => $v['id'],
'type' => 1,
'route' => 3,
'url' => $url,
'language'=> [],
'is_sitemap' => 0
];
http_post($c_url, json_encode($param));
try {
$arr1 = $this->sendProduct();
$arr2 = $this->sendBlog();
$arr3 = $this->sendNews();
$url = array_merge((array)$arr1,(array)$arr2,(array)$arr3);
if(!empty($url)){
$c_url = $domain.'api/update_page/';
$param = [
'project_id' => $v['id'],
'type' => 1,
'route' => 3,
'url' => $url,
'language'=> [],
'is_sitemap' => 0
];
//TODO::通知C端生成界面
http_post($c_url, json_encode($param));
}
}catch (\Exception $e){
DB::disconnect('custom_mysql');
continue;
}
//TODO::通知C端生成界面
DB::disconnect('custom_mysql');
}
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
}
... ... @@ -83,7 +87,6 @@ class SendProduct extends Command
* @time :2024/8/30 14:44
*/
public function sendProduct(){
$start_date = date('Y-m-d 00:00:00');
$end_date = date('Y-m-d 23:59:59');
$productModel = new Product();
$arr = $productModel->formatQuery(['send_time'=>['<=',$end_date],'status'=>3])->pluck('route')->toArray();
... ... @@ -99,7 +102,6 @@ class SendProduct extends Command
* @time :2024/8/30 15:19
*/
public function sendBlog(){
$start_date = date('Y-m-d 00:00:00');
$end_date = date('Y-m-d 23:59:59');
$blogModel = new Blog();
$arr = $blogModel->formatQuery(['release_at'=>['<=',$end_date],'status'=>3])->pluck('url')->toArray();
... ... @@ -115,7 +117,6 @@ class SendProduct extends Command
* @time :2024/8/30 15:19
*/
public function sendNews(){
$start_date = date('Y-m-d 00:00:00');
$end_date = date('Y-m-d 23:59:59');
$newsModel = new News();
$arr = $newsModel->formatQuery(['release_at'=>['<=',$end_date],'status'=>3])->pluck('url')->toArray();
... ...
<?php
/**
* Created by PhpStorm.
* User: zhl
* Date: 2025/10/27
* Time: 13:42
*/
namespace App\Console\Commands\Product;
use App\Console\Commands\Tdk\UpdateSeoTdk;
use App\Models\Product\Keyword;
use App\Models\Project\Project;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class SplicePrefix extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'splice_prefix';
/**
* The console command description.
*
* @var string
*/
protected $description = '未达标项目,拼接关键词聚合页前缀';
/**
* @return bool
*/
public function handle()
{
#TODO 获取当日不达标项目, 检查关键词前缀拼接
$project_ids = $this->getProject();
if (empty($project_ids))
return true;
foreach ($project_ids as $project_id) {
if ($project_id == 1)
continue;
$this->output('project start: ' . $project_id);
$this->bind($project_id);
}
return true;
}
/**
* @param $project_id
* @return bool
*/
public function bind($project_id)
{
$project = ProjectServer::useProject($project_id);
// 客户前缀
$tdk_class = new UpdateSeoTdk();
$info = $tdk_class->getDeployOptimize($project_id);
$fix_keyword = explode(",", $info['keyword_prefix']);
$fix_keyword = array_filter($fix_keyword);
// 所有前缀
$all_prefixes = $tdk_class->getAllPrefix(1, $project_id);
$all_prefixes = array_map('strtolower', $all_prefixes);
$keywords = Keyword::select(['id', 'title', 'seo_title'])->get();
foreach ($keywords as $item) {
$this_fix_keyword = $fix_keyword;
if (empty($item->title))
continue;
$this->output('keyword id:' . $item->id . ' | title: ' . $item->title . ' | old seo title: ' . $item->seo_title);
// 没有 SEO Title 直接生成
if (empty($item->seo_title)) {
$prefix = $tdk_class->getPrefixKeyword($project_id, 'prefix', 2, $item->title);
$suffix = $tdk_class->getPrefixKeyword($project_id, 'suffix', 2, trim($prefix . ' ' . $item->title));
if(Str::startsWith($suffix, ', ')){
$seo_title = $prefix . ' ' . $item->title . $suffix;
}else{
$seo_title = $prefix . ' ' . $item->title . ' ' . $suffix;
}
// $item->seo_title = trim($seo_title);
// $item->save();
$this->output('new seo title: ' . $seo_title);
continue;
}
// 有 SEO Title 需要分析前后缀
$start = strpos($item->seo_title, $item->title);
// Title 和 SEO Title 不存在包含关系
if ($start === FALSE) {
$this->output('Title 和 SEO Title 不存在包含关系');
continue;
}
$prefix = $start == 0 ? '' : trim(substr($item->seo_title, 0, $start));
$prefix_array = explode(' ', $prefix);
$prefix_array = array_filter($prefix_array);
$need_num = 2 - count($prefix_array);
// 已经有两个前缀, 不在处理
if ($need_num <= 0) {
$this->output('已经有两个前缀, 不在处理');
continue;
}
// 关键词最后一个词是前缀的词,前后缀都不拼
$title_words = explode(' ', strtolower($item->title));
// 关键词最后一个词是前缀的词,前后缀都不拼
if(in_array(Arr::last($title_words), $all_prefixes)) {
$this->output('关键词最后一个词是前缀的词, 前后缀都不拼');
continue;
}
// in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀
$ban = [];
// 关键词本身包含了前缀,也可以再拼一个不重复的前缀, 包含两个前缀就不拼前缀了
foreach ($title_words as $title_word) {
if(in_array($title_word, $all_prefixes)){
$ban[] = $title_word;
}
}
$need_num = $need_num - count($ban);
// 关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理
if ($need_num <= 0) {
$this->output('关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理');
continue;
}
// services/service 结尾的词,后缀不拼manufacturer,factory
// manufacturer,factory 结尾的词,后缀不拼 services/service
// 有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company
// 关键词以manufacturer,factory,exporter,company结尾, 前缀不拼wholesale或cheap的词
if (Str::endsWith(strtolower($item->title), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']))
$ban = array_merge($ban, ['wholesale', 'cheap', 'buy']);
foreach ($this_fix_keyword as $k => $keyword) {
// 被禁用的关键词
if (in_array(strtolower(Str::plural($keyword)), $ban)) {
unset($this_fix_keyword[$k]);
}
if (in_array(strtolower(Str::singular($keyword)), $ban)) {
unset($this_fix_keyword[$k]);
}
}
$this_fix_keyword = array_diff($this_fix_keyword, $prefix_array);
shuffle($this_fix_keyword);
$need_keyword = [];
foreach ($this_fix_keyword as $v) {
if ($need_num == 0)
break;
$is_repeat = false;
foreach ($need_keyword as $keyword) {
if (Str::singular($keyword) == Str::singular($v)) {
$is_repeat = true;
break;
}
}
if ($is_repeat)
continue;
$need_keyword[] = $v;
$need_num--;
}
// $item->seo_title = trim(implode(' ', $need_keyword) . ' ' . trim($item->seo_title));
// $item->save();
$this->output('new seo title: ' . implode(' ', $need_keyword) . ' ' . trim($item->seo_title));
}
return true;
}
/**
* 获取当日未达标项目
* @return mixed
*/
public function getProject()
{
$project_ids = Project::where(['type' => Project::TYPE_TWO, 'project_type' => Project::TYPE_ZERO, 'delete_status' => Project::IS_DEL_FALSE, 'is_remain_today' => 0])->pluck('id')->toArray();
return $project_ids;
}
/**
* 输出日志
* @param $message
* @return bool
*/
public function output($message)
{
$message = now() . ' ' . $message . PHP_EOL;
file_put_contents(storage_path('logs/splice_prefix.log'), $message, FILE_APPEND);
echo $message;
return true;
}
}
... ...
... ... @@ -171,6 +171,10 @@ class HtmlCollect extends Command
$html = str_replace('Broflanilide', '', $html);
$html = str_replace('broflanilide', '', $html);
}
if ($project_id == 587) {
//437项目单词替换
$html = str_replace('Horny Goat Weed', 'Icariin', $html);
}
$collect_info->html = $html;
$collect_info->status = CollectTask::STATUS_COM;
$collect_info->save();
... ...
... ... @@ -138,6 +138,10 @@ class ProjectUpdate extends Command
//2078项目单词替换
$replace = ['Broflanilide' => '', 'broflanilide' => ''];
}
if ($project_id == 587) {
//587项目单词替换
$replace = ['Horny Goat Weed' => 'Icariin'];
}
//设置数据库
$project = ProjectServer::useProject($project_id);
... ... @@ -322,6 +326,16 @@ class ProjectUpdate extends Command
//分类
$category_id = '';
$category_arr = [];
if ($project_id == 596 && empty($item['category'])) {
//596项目,产品没有分类,默认属于Featured分类
$item['category'] = [
[
'id' => 623,
'name' => 'Featured',
'pid' => 0
]
];
}
if ($item['category'] ?? []) {
if ($project_id == 4075 && count($item['category']) == 1 && $item['category'][0]['name'] == 'Featured') {
//4075项目特殊处理:不采集Featured分类下的产品
... ...
... ... @@ -31,15 +31,17 @@ class GeoController extends BaseController
try {
$token = trim($this->param['token']);
$param = Crypt::decrypt($token);
if ($param['send_at'] + 86400 < time()) {}
$project_id = $param['project_id'];
} catch (\Exception $e) {
return $this->error('非法请求');
}catch (\Exception $e){
$this->response('非法请求',Code::SYSTEM_ERROR);
}
if ($param['send_at'] + 86400 < time()) {
$this->response('非法请求,已过期',Code::SYSTEM_ERROR);
}
$project_id = $param['project_id'];
$projectModel = new Project();
$projectInfo = $projectModel->read(['project_id' => $project_id],['title','version']);
$projectInfo = $projectModel->read(['id' => $project_id],['title','version']);
$geoWritingsModel = new GeoWritings();
$lists = $geoWritingsModel->list(['project_id' => $project_id, 'status' => 2 ,'is_del' => GeoWritings::IS_DEL_FALSE],'id',['title', 'status', 'uniqid', 'confirm_at']);
$lists = $geoWritingsModel->list(['project_id' => $project_id, 'status' => ['in',[GeoWritings::STATUS_RUNNING,GeoWritings::STATUS_FINISH]] ,'is_del' => GeoWritings::IS_DEL_FALSE],'id',['title', 'status', 'uniqid', 'confirm_at']);
$result = [
'project' => $projectInfo,
'list' => $lists
... ... @@ -93,7 +95,7 @@ class GeoController extends BaseController
$this->param['content_length'] = strlen($this->param['content']);
$this->param['status'] = GeoWritings::STATUS_FINISH;
$geoWritingsModel->edit($this->param,['uniqid' => $token]);
return true;
$this->response('success',Code::SUCCESS);
}
/**
... ... @@ -106,13 +108,16 @@ class GeoController extends BaseController
$token = trim($this->param['token']);
$data = GeoConfirm::where(['uniqid' => $token])->first();
if (empty($data)){
return $this->error('当前授权已失效');
return $this->error('确认链接已重置,请查看最新推送链接!');
}
$content = explode("\n", $data->content);
$confirm = explode("\n", $data->confirm);
$type = $data->type;
$status = $data->status;
$result = compact('content', 'confirm', 'type', 'status');
$projectModel = new Project();
$projectInfo = $projectModel->read(['id' => $data->project_id],['title','version']);
$project_title = $projectInfo['title'] ?? '';
$result = compact('content', 'confirm', 'type', 'status', 'project_title');
$this->response('success',Code::SUCCESS,$result);
}
... ... @@ -134,6 +139,8 @@ class GeoController extends BaseController
]);
$geoConfirmModel = new GeoConfirm();
$this->param['status'] = $geoConfirmModel::STATUS_FINISH;
$this->param['confirm_ip'] = $this->request->ip();
$this->param['confirm_at'] = date('Y-m-d H:i:s');
$result = $geoConfirmModel->edit($this->param,['uniqid'=>$this->param['uniqid']]);
$this->response('success',Code::SUCCESS,$result);
}
... ...
... ... @@ -205,4 +205,22 @@ class NoticeController extends BaseController
MessagePush::addInquiryMessage(0, $project->id, $country, $name, $submit);
return $this->success();
}
/**
* 获取6.0所有使用域名
* @return false|string
* @author Akun
* @date 2025/10/30 10:42
*/
public function getAllDomain(){
$domainModel = new DomainInfo();
$lists = $domainModel->list(['status'=>DomainInfo::STATUS_ONE],'id',['domain','project_id'],'asc');
$project_model = new Project();
foreach ($lists as &$v){
$pro_info = $project_model->read(['id'=>$v['project_id']],['company']);
$v['company'] = $pro_info ? $pro_info['company'] : '';
}
return $this->success($lists);
}
}
... ...
... ... @@ -29,6 +29,27 @@ class GeoConfirmController extends BaseController
}
/**
* @remark :确认信息详情
* @name :getInfo
* @author :lyh
* @method :post
* @time :2025/10/30 09:08
*/
public function getInfo()
{
$this->request->validate([
'project_id' => 'required',
'type' => 'required|integer',
], [
'project_id.required' => '项目ID不能为空',
'type.required' => '确定数据类型不能为空',
'type.integer' => '确定数据类型不正确',
]);
$data = $this->logic->getConfirmInfo();
$this->response('success', Code::SUCCESS, $data);
}
/**
* 保存确认数据, 并推送微信群
* @param Request $request
* @throws \App\Exceptions\AsideGlobalException
... ... @@ -50,4 +71,26 @@ class GeoConfirmController extends BaseController
$data = $this->logic->saveConfirmContent($this->param);
$this->response('success', Code::SUCCESS, $data);
}
/**
* @remark :保存确认信息
* @name :saveInfo
* @author :lyh
* @method :post
* @time :2025/10/30 11:30
*/
public function saveInfo()
{
$this->request->validate([
'id' => 'required',
'confirm' => 'required',
'confirm_num' => 'required',
], [
'id.required' => '主键id不能为空',
'confirm.required' => '客户确认内容不能为空',
'confirm_num.max' => '客户确认数量不能为空',
]);
$data = $this->logic->saveConfirmInfo();
$this->response('success', Code::SUCCESS, $data);
}
}
... ...
... ... @@ -68,4 +68,22 @@ class GeoController extends BaseController
$data = $this->logic->saveConfig($this->param);
$this->response('success', Code::SUCCESS, $data);
}
/**
* @remark :统计数据
* @name :getCount
* @author :lyh
* @method :post
* @time :2025/10/30 10:37
*/
public function getCount()
{
$this->request->validate([
'project_id' => 'required',
], [
'project_id.required' => '项目ID不能为空',
]);
$data = $this->logic->getCount();
$this->response('success', Code::SUCCESS, $data);
}
}
... ...
... ... @@ -32,7 +32,7 @@ class InquiryForwardController extends BaseController
$this->map['message'] = ['like', '%' . $this->map['message'] . '%'];
}
if (isset($this->param['start_date']) && isset($this->param['end_date'])) {
$this->map['inquiry_date'] = ['between', [$this->map['start_date'] . ' 00:00:00', $this->map['end_date'] . ' 00:00:00']];
$this->map['inquiry_date'] = ['between', [$this->map['start_date'] . ' 00:00:00', $this->map['end_date'] . ' 23:59:59']];
unset($this->map['start_date']);
unset($this->map['end_date']);
} elseif (isset($this->param['start_date'])) {
... ...
... ... @@ -462,7 +462,7 @@ class ProjectController extends BaseController
}
$manageModel = new ManageHr();
//geo项目
if (($item['plan'] == 0) && ($item['seo_plan'] != 0)) {
if (($item['seo_plan'] != 0) && ($item['seo_plan'] != 9 || $item['plan'] == 0)) {
//geo项目负责人
$geoConfModel = new GeoConf();
$manage_id = $geoConfModel->getValue(['project_id' => $item['id']], 'manager_id');
... ...
... ... @@ -24,7 +24,7 @@ class AiBlogController extends BaseController
if(isset($this->map['new_title']) && !empty($this->map['new_title'])){
$this->map['new_title'] = ['like', '%'.$this->map['new_title'].'%'];
}
$lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','keyword','new_title','route','image','task_id','status','created_at','updated_at']);
$lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','keyword','new_title','route','image','task_id','status','uuid','created_at','updated_at']);
if(!empty($lists) && !empty($lists['list'])){
foreach ($lists['list'] as $k => $v){
$v['image'] = getImageUrl($v['image']);
... ...
... ... @@ -236,8 +236,11 @@ class CNoticeController extends BaseController
if(!$project_info){
$this->fail('未查询到项目数据');
}
$project_ids = [
4041,4094,3514
];
// --------------------------------------------------- 特殊处理通知生成页面 --------------------------------------------------------------
if ($type == 2 && ($project_id != 4041) && ($project_id != 4094) && ($project_info['main_lang_id'] == 8)) {
if ($type == 2 && !in_array($project_id,$project_ids) && ($project_info['main_lang_id'] == 8)) {
$this->fail('申请项目主语种为俄语,禁止翻译小语种,如若需要翻译小语种, 请联系售后人员确认!');
}
... ...
<?php
/**
* @remark :
* @name :SettingFaqController.php
* @author :lyh
* @method :post
* @time :2025/10/29 16:32
*/
namespace App\Http\Controllers\Bside\Setting;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Setting\SettingFaqLogic;
use App\Models\RouteMap\RouteMap;
use Illuminate\Http\Request;
class SettingFaqController extends BaseController
{
public function __construct(Request $request)
{
parent::__construct($request);
$this->logic = new SettingFaqLogic();
}
/**
* @remark :获取所有路由
* @name :getRouteList
* @author :lyh
* @method :post
* @time :2025/10/30 09:35
*/
public function getRouteList(){
$data = $this->logic->getRouteList();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :faq列表页数据
* @name :lists
* @author :lyh
* @method :post
* @time :2025/10/29 16:38
*/
public function lists()
{
$lists = $this->logic->getFaqLists($this->map,$this->page,$this->row,$this->order);
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :获取详情
* @name :getInfo
* @author :lyh
* @method :post
* @time :2025/10/30 09:28
*/
public function getInfo()
{
$this->request->validate([
'id'=>'required',
],[
'id.required' => 'ID不能为空',
]);
$data = $this->logic->getFaqInfo();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :保存faq数据
* @name :saveFaq
* @author :lyh
* @method :post
* @time :2025/10/29 17:21
*/
public function saveFaq()
{
$this->request->validate([
'route'=>'required',
'qa'=>'required',
],[
'route.required' => '路由不能为空',
'qa.required' => 'qa不能为空',
]);
$data = $this->logic->saveFaq();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :删除对应数据
* @name :deleteFaq
* @author :lyh
* @method :post
* @time :2025/10/29 17:23
*/
public function deleteFaq(){
$this->request->validate([
'id'=>'required|array',
],[
'id.required' => 'ID不能为空',
'id.array' => 'ID为数组',
]);
$data = $this->logic->deleteFaq();
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
... ... @@ -40,11 +40,11 @@ class GeoConfirmLogic extends BaseLogic
public function saveConfirmContent($param)
{
try {
$info = $this->model->read(['project_id' => $param['project_id']]);
$info = $this->model->read(['project_id' => $param['project_id'],'type' => $param['type']]);
if($info === false){
$id = $this->model->addReturnId($param);
}else{
$id = $param['id'];
$id = $info['id'];
$this->model->edit($param,['id'=>$info['id']]);
}
$friend = ProjectAssociation::where(['project_id' => $param['project_id']])->first();
... ... @@ -57,4 +57,35 @@ class GeoConfirmLogic extends BaseLogic
}
return $this->success(['id'=>$id]);
}
/**
* @remark :获取数据详情
* @name :getInfo
* @author :lyh
* @method :post
* @time :2025/10/30 09:13
*/
public function getConfirmInfo()
{
$data = $this->model->read($this->param);
if($data === false){
$this->fail('当前数据不存在或者已被删除');
}
$data['confirm'] = $data['content'];
return $this->success($data);
}
/**
* @remark :保存确认信息
* @name :saveConfirmInfo
* @author :lyh
* @method :post
* @time :2025/10/30 11:41
*/
public function saveConfirmInfo()
{
$this->param['status'] = GeoConfirm::STATUS_FINISH;
$this->model->edit($this->param,['id'=>$this->param['id']]);
return $this->success(['id'=>$this->param['id']]);
}
}
... ...
... ... @@ -9,8 +9,12 @@
namespace App\Http\Logic\Aside\Geo;
use App\Console\Commands\Geo\GeoQuestionRes;
use App\Http\Logic\Aside\BaseLogic;
use App\Models\Geo\GeoConf;
use App\Models\Geo\GeoLink;
use App\Models\Geo\GeoQuestion;
use App\Models\Geo\GeoWritings;
use App\Models\Manage\ManageHr;
use App\Models\Project\KeywordPrefix;
use App\Models\Project\Project;
... ... @@ -97,4 +101,20 @@ class GeoLogic extends BaseLogic
return $this->success(['id'=>$id]);
}
/**
* @remark :获取统计数据
* @name :getCount
* @author :lyh
* @method :post
* @time :2025/10/30 10:39
*/
public function getCount()
{
//获取问题数量
$geo_question_count = GeoQuestion::selectRaw('SUM(JSON_LENGTH(question)) as total_count')->where('project_id',$this->param['project_id'])->value('total_count');
$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]);
}
}
... ...
... ... @@ -54,6 +54,7 @@ class GeoWritingsLogic extends BaseLogic
$id = $this->param['id'];
$this->model->edit($this->param,['id'=>$id]);
}else{
$this->param['type'] = GeoWritings::TYPE_SUBMIT;
$this->param['uniqid'] = uniqid().$this->param['project_id'];
$id = $this->model->addReturnId($this->param);
}
... ... @@ -89,7 +90,10 @@ class GeoWritingsLogic extends BaseLogic
public function sendWechatMessage()
{
$this->model->edit(['status'=>2],['status'=>1,'project_id'=>$this->param['project_id']]);
GeoWritings::sendConfirmMessage($this->param['project_id']);
return $this->success();
$data = GeoWritings::sendConfirmMessage($this->param['project_id']);
if($data === false){
$this->fail('项目未绑定微信群');
}
return $this->success($data);
}
}
... ...
... ... @@ -17,6 +17,7 @@ use App\Models\Inquiry\InquiryRelayDetail;
use App\Models\Inquiry\InquiryRelayDetailLog;
use App\Models\Manage\Manage;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
... ... @@ -525,13 +526,36 @@ class InquiryForwardLogic extends BaseLogic
*/
public function inquiryManageCount()
{
$type = $this->param['type'] ?? 1;//统计类型:1周统计,2月统计
$data = Cache::get('inquiry_manage_count');
if (!$data) {
$manage_ids = ForwardCount::select('manage_id')->orderBy('manage_id', 'asc')->distinct()->pluck('manage_id')->toArray();
$manageModel = new Manage();
//月统计
$data_month = [];
$data_month_total = [];
$now_month = date('Y-m');
$last_year_month = date('Y-m', strtotime('-11 months'));
while ($last_year_month <= $now_month) {
$month_arr = explode('-', $last_year_month);
$year = $month_arr[0];
$month = $month_arr[1];
foreach ($manage_ids as $mid) {
$name = $manageModel->getName($mid);
$month_count = intval(ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->sum('count') ?? 0);
$data_month_total[$name] = ($data_month_total[$name] ?? 0) + $month_count;
$data_month[$last_year_month][$name] = $month_count;
}
$last_year_month = date('Y-m', strtotime($last_year_month . ' +1 month'));
}
$data_month['total'] = $data_month_total;
$manage_ids = ForwardCount::select('manage_id')->orderBy('manage_id', 'asc')->distinct()->pluck('manage_id')->toArray();
$manageModel = new Manage();
$data = [];
if ($type == 1) {
//周统计
$data_week = [];
$data_week_total = [];
$now_day = date('Y-m-d');
$last_week_day = date('Y-m-d', strtotime('-1 week'));
while ($last_week_day < $now_day) {
... ... @@ -542,27 +566,18 @@ class InquiryForwardLogic extends BaseLogic
foreach ($manage_ids as $mid) {
$name = $manageModel->getName($mid);
$data[$last_week_day][$name] = ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->where('day', $day)->value('count') ?? 0;
$day_count = ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->where('day', $day)->value('count') ?? 0;
$data_week_total[$name] = ($data_week_total[$name] ?? 0) + $day_count;
$data_week[substr($last_week_day, 5)][$name] = $day_count;
}
$last_week_day = date('Y-m-d', strtotime($last_week_day . ' +1 day'));
}
} else {
//月统计
$now_month = date('Y-m');
$last_year_month = date('Y-m', strtotime('-11 months'));
while ($last_year_month <= $now_month) {
$month_arr = explode('-', $last_year_month);
$year = $month_arr[0];
$month = $month_arr[1];
$data_week['total'] = $data_week_total;
foreach ($manage_ids as $mid) {
$name = $manageModel->getName($mid);
$data[$last_year_month][$name] = intval(ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->sum('count') ?? 0);
}
$data = ['data_month' => $data_month, 'data_week' => $data_week];
$last_year_month = date('Y-m', strtotime($last_year_month . ' +1 month'));
}
Cache::add('inquiry_manage_count', $data);
}
return $this->success($data);
... ...
... ... @@ -201,7 +201,7 @@ class TicketUploadDataLogic extends BaseLogic
'title' => $info['text']['title'],
'thumb'=>$thumb,
'gallery'=>$info['text']['image'] ?? [],
'intro'=>$info['text']['remark'],
'intro'=>$info['text']['intro'] ?? '',
'category_id'=>$category_id ?? '',
'keyword_id'=>$keyword_id ?? '',
'status'=>1,
... ... @@ -242,6 +242,7 @@ class TicketUploadDataLogic extends BaseLogic
'name' => $info['text']['title'],
'image'=>$info['text']['image'],
'text'=>$info['text']['remark'],
'remark'=>$info['text']['intro'] ?? '',
'category_id'=>$category_id ?? '',
'status'=>1,
];
... ... @@ -276,6 +277,7 @@ class TicketUploadDataLogic extends BaseLogic
'name' => $info['text']['title'],
'image'=>$info['text']['image'],
'text'=>$info['text']['remark'],
'remark'=>$info['text']['intro'] ?? '',
'category_id'=>$category_id ?? '',
'status'=>1,
];
... ...
... ... @@ -187,7 +187,9 @@ class AiBlogLogic extends BaseLogic
}
if(isset($param['id']) && !empty($param['id'])){
$id = $param['id'];
$data['task_id'] = $param['task_id'];
if(!empty($param['task_id'])){
$data['task_id'] = $param['task_id'];
}
if(!isset($param['seo_keyword']) || empty($param['seo_keyword'])){
$ai = "contains keyword {$param['title']} recommend 8 purchaser search keywords, separated by commas";
$text = Gpt::instance()->openai_chat_qqs($ai);
... ... @@ -222,7 +224,7 @@ class AiBlogLogic extends BaseLogic
//todo::更新列表页
shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &");
}else{
$this->fail('发布失败,请编辑后重新发布');
$this->fail('文章已发布,文章无法同步到列表,请编辑后保存');
}
return $this->success();
}
... ...
... ... @@ -135,16 +135,23 @@ class GeoQuestionResLogic extends BaseLogic
];
}else{
$keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]);
$keywordArrs = [];
$urlArrs = [];
foreach ($list as $item){
$keywordArrs = array_merge($keywordArrs,$item['keywords'] ?? []);
$urlArrs = array_merge($urlArrs,$item['url'] ??[]);
$questionTotalCount += count($item['question'] ?? []);
$keywordsTotalCount += count($item['keywords'] ?? []);
$urlTotalCount += count($item['url'] ?? []);
foreach ($item['keywords'] as $keyWordItem){
if (!array_key_exists($keyWordItem, $keywordArr)) {
$keywordArr[$keyWordItem] = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'keywords'=>['like','%"'.$keyWordItem.'"%']]);
}
}
}
// 去重
$keywordArrs = array_unique($keywordArrs);
$keywordsTotalCount = count($keywordArrs);
$urlArrs = array_unique($urlArrs);
$urlTotalCount = count($urlArrs);
$data = [
'question_count'=>$questionTotalCount,
'keywords_count'=>$keywordsTotalCount,
... ...
<?php
/**
* @remark :
* @name :SettingFaqLogic.php
* @author :lyh
* @method :post
* @time :2025/10/29 16:34
*/
namespace App\Http\Logic\Bside\Setting;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\RouteMap\RouteMap;
use App\Models\WebSetting\SettingFaq;
class SettingFaqLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->model = new SettingFaq();
$this->param = $this->requestAll;
}
/**
* @remark :获取数据
* @name :getRouteList
* @author :lyh
* @method :post
* @time :2025/10/30 09:36
*/
public function getRouteList($map = [])
{
$routeModel = new RouteMap();
$list = $routeModel->list($map,'id',['*'],'desc',20);
return $this->success($list);
}
/**
* @remark :获取列表页数据
* @name :getFaqLists
* @author :lyh
* @method :post
* @time :2025/10/29 16:50
*/
public function getFaqLists($map = [],$page = 1, $row = 10,$order = 'id')
{
$lists = $this->model->lists($map,$page,$row,$order);
return $this->success($lists);
}
/**
* @remark :获取详情数据
* @name :getFaqById
* @author :lyh
* @method :post
* @time :2025/10/30 09:29
*/
public function getFaqInfo(){
$data = $this->model->read($this->param);
return $this->success($data);
}
/**
* @remark :保存数据
* @name :saveFaq
* @author :lyh
* @method :post
* @time :2025/10/29 16:50
*/
public function saveFaq()
{
//todo::根据路由获取对应数据详情
$routeModel = new RouteMap();
$routeInfo = $routeModel->read(['route'=>$this->param['route']],['source','source_id']);
if($routeInfo === false){
$this->fail('路由不存在');
}
$this->param['qa'] = json_encode($this->param['qa'],true);
$this->param['source'] = $routeInfo['source'];
$this->param['source_id'] = $routeInfo['source_id'];
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->model->edit($this->param,['id'=>$id]);
}else{
$id = $this->model->addReturnId($this->param);
}
return $this->success(['id' => $id]);
}
/**
* @remark :删除数据
* @name :deleteFaq
* @author :lyh
* @method :post
* @time :2025/10/29 17:27
*/
public function deleteFaq(){
$this->model->del(['id'=>['in',$this->param['id']]]);
return $this->success();
}
}
... ...
... ... @@ -35,7 +35,7 @@ class GeoConf extends Base
$optimize = Cache::get($key);
if (empty($optimize)) {
$optimize = ManageHr::where(['status' => ManageHr::STATUS_ONE, 'entry_position' => 46])->pluck('name', 'id')->toArray();
$optimize[1] = '陶婵';
$optimize[11] = '陶婵';
$optimize[875] = '艾媛媛';
ksort($optimize);
Cache::put($key, $optimize, 3600);
... ...
... ... @@ -79,7 +79,7 @@ class GeoWritings extends Base
{
$friend = ProjectAssociation::where(['project_id' => $project_id])->first();
if (empty($friend)) {
throw new \Exception('项目未绑定微信群');
return false;
}
$content_type = 'Link';
$send_time = now();
... ...
<?php
/**
* @remark :
* @name :SettingFaq.php
* @author :lyh
* @method :post
* @time :2025/10/29 16:35
*/
namespace App\Models\WebSetting;
use App\Helper\Arr;
use App\Models\Base;
class SettingFaq extends Base
{
protected $table = 'gl_setting_faq';
//连接数据库
protected $connection = 'custom_mysql';
public function getQaAttribute($value)
{
$value = Arr::s2a($value);
return $value;
}
}
... ...
... ... @@ -74,6 +74,9 @@ Route::post('selfSiteSsl', [\App\Http\Controllers\Api\SelfSiteController::class,
//创建301跳转任务
Route::any('/addRedirect',[\App\Http\Controllers\Api\NoticeController::class,'addRedirect']);
//获取所有有效域名
Route::any('/getAllDomain',[\App\Http\Controllers\Api\NoticeController::class,'getAllDomain']);
//关联域名
Route::post('/inquiry_relate_domain', [\App\Http\Controllers\Api\PrivateController::class, 'inquiry_relate_domain']);
// 通过域名获取项目人员配置
... ...
... ... @@ -591,10 +591,13 @@ Route::middleware(['aloginauth'])->group(function () {
Route::prefix('conf')->group(function () {
Route::any('/getConfig', [Aside\Geo\GeoController::class, 'getConfig'])->name('admin.geo_conf_getConfig');
Route::any('/saveConfig', [Aside\Geo\GeoController::class, 'saveConfig'])->name('admin.geo_conf_saveConfig');
Route::any('/getCount', [Aside\Geo\GeoController::class, 'getCount'])->name('admin.geo_conf_getCount');
});
//geo客户确认信息
Route::prefix('confirm')->group(function () {
Route::any('/saveConfirmContent', [Aside\Geo\GeoConfirmController::class, 'saveConfirmContent'])->name('admin.geo_confirm_saveConfirmContent');
Route::any('/getInfo', [Aside\Geo\GeoConfirmController::class, 'getInfo'])->name('admin.geo_confirm_getInfo');
Route::any('/saveInfo', [Aside\Geo\GeoConfirmController::class, 'saveInfo'])->name('admin.geo_confirm_saveInfo');
});
//geoai文章任务管理
Route::prefix('writing_task')->group(function () {
... ...
... ... @@ -768,6 +768,15 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/getSearchDate', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getSearchDate'])->name('geo_result_getSearchDate');//搜索记录时间
Route::any('/getPlatformCount', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getPlatformCount'])->name('geo_result_getPlatformCount');//搜索记录时间
});
//faq渲染数据
Route::prefix('faq')->group(function () {
Route::any('/', [\App\Http\Controllers\Bside\Setting\SettingFaqController::class,'lists'])->name('faq_lists');
Route::any('/getRouteList', [\App\Http\Controllers\Bside\Setting\SettingFaqController::class,'getRouteList'])->name('faq_getRouteList');
Route::any('/saveFaq', [\App\Http\Controllers\Bside\Setting\SettingFaqController::class,'saveFaq'])->name('faq_saveFaq');
Route::any('/deleteFaq', [\App\Http\Controllers\Bside\Setting\SettingFaqController::class,'deleteFaq'])->name('faq_deleteFaq');
Route::any('/getInfo', [\App\Http\Controllers\Bside\Setting\SettingFaqController::class,'getInfo'])->name('faq_getInfo');
});
});
//无需登录验证的路由组
Route::group([], function () {
... ...