作者 刘锟

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

<?php
namespace App\Console\Commands\Inquiry;
use App\Helper\Arr;
use App\Models\Inquiry\ReInquiryCost;
use App\Utils\HttpUtils;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Console\Command;
/**
* Class SyncAdCost
* @package App\Console\Commands\Inquiry
*/
class SyncAdCost extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sync_ad_cost';
/**
* The console command description.
*
* @var string
*/
protected $description = '同步广告费用';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @author zbj
* @date 2024/12/4
*/
public function handle()
{
$list = $this->getAdCost();
foreach ($list as $item) {
ReInquiryCost::saveData($item['ad_id'], $item['spend'], $item['lead'], $item['single_cost'], $item['start_date'], $item['end_date']);
}
}
/**
* 获取远程询盘信息
* @return array
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAdCost()
{
try {
$res = HttpUtils::get('https://fob.ai.cc/api/fb_ad_cost', []);
$res = Arr::s2a($res);
} catch (\Exception | GuzzleException $e) {
$this->output($e->getMessage());
return [];
}
return $res['data']?? [];
}
public function output($message)
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
}
}
... ...
... ... @@ -56,7 +56,7 @@ class WeekProject extends Command
$this->weekData($v);
DB::disconnect('custom_mysql');
}
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
}
/**
... ... @@ -77,14 +77,14 @@ class WeekProject extends Command
// 上一周的结束时间(周日 23:59:59)
$endOfLastWeek = strtotime("last week sunday 23:59:59");
// 格式化为日期时间字符串
$startOfLastWeekFormatted = date('Y-m-d', $startOfLastWeek);
$endOfLastWeekFormatted = date('Y-m-d', $endOfLastWeek);
$data['start_date'] = $startOfLastWeekFormatted = date('Y-m-d', $startOfLastWeek);
$data['end_date'] = $endOfLastWeekFormatted = date('Y-m-d', $endOfLastWeek);
$countModel = new Count();
$startOfLastWeekFormattedInfo = $countModel->read(['date'=>$startOfLastWeekFormatted,'project_id'=>$value['id']],['inquiry_num','country']);
$endOfLastWeekFormattedInfo = $countModel->read(['date'=>$endOfLastWeekFormatted,'project_id'=>$value['id']],['inquiry_num']);
$data['inquiry_total'] = $startOfLastWeekFormattedInfo['inquiry_num'] ?? 0;//询盘数量
$data['inquiry_country'] = $startOfLastWeekFormattedInfo['country'] ?? json_encode([]);
$data['week_inquiry_total'] = ($startOfLastWeekFormattedInfo['inquiry_num'] ?? 0) - ($endOfLastWeekFormattedInfo['inquiry_num'] ?? 0);
$endOfLastWeekFormattedInfo = $countModel->read(['date'=>$endOfLastWeekFormatted,'project_id'=>$value['id']],['inquiry_num','country']);
$data['inquiry_total'] = $endOfLastWeekFormattedInfo['inquiry_num'] ?? 0;//询盘数量
$data['inquiry_country'] = $endOfLastWeekFormattedInfo['country'] ?? json_encode([]);
$data['week_inquiry_total'] = ($endOfLastWeekFormattedInfo['inquiry_num'] ?? 0) - ($startOfLastWeekFormattedInfo['inquiry_num'] ?? 0);
$rankDataModel = new RankData();
$rankInfo = $rankDataModel->read(['project_id'=>$value['id'],'lang'=>''],['first_num','first_page_num','first_three_pages_num','first_five_pages_num','first_ten_pages_num','indexed_pages_num']);
$data['google_indexed_num'] = $rankInfo['indexed_pages_num'] ?? 0;
... ... @@ -108,7 +108,8 @@ class WeekProject extends Command
$data['aggregation_minor_update_num'] = $notifyModel->counts(['type'=>2,'route'=>4,'project_id'=>$value['id']]) ?? 0;
//日均访问量
$data['daily_average_num'] = 0;
$pv_num_count = $countModel->whereBetween('date', [$startOfLastWeekFormatted,$endOfLastWeekFormattedInfo])->sum('pv_num');
$pv_num_count = $countModel->where('project_id',$value['id'])->whereBetween('date', [$startOfLastWeekFormatted,$endOfLastWeekFormatted])->sum('pv_num');
echo date('Y-m-d H:i:s') . 'pv总量:'.$pv_num_count . PHP_EOL;
if($pv_num_count != 0){
$data['daily_average_num'] = round($pv_num_count / 7,2);
}
... ...
... ... @@ -42,6 +42,8 @@ class Kernel extends ConsoleKernel
$schedule->command('updateAiProjects')->everyFourHours()->withoutOverlapping(1);
//每日同步询盘文案
$schedule->command('sync_inquiry_text')->dailyAt('09:00')->withoutOverlapping(1);
//FB询盘费用同步
$schedule->command('sync_ad_cost')->everyThirtyMinutes()->withoutOverlapping(1);
}
/**
... ...
... ... @@ -88,7 +88,7 @@ class BaseController extends Controller
break;
case "end_at":
$this->_btw[1] = $v;
$this->map['updated_at'] = ['between', $this->_btw];
$this->map['created_at'] = ['between', $this->_btw];
break;
default:
if ($v != null) {
... ...
... ... @@ -13,9 +13,74 @@ use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Models\Manage\LoginLog;
use App\Models\Manage\Manage;
use App\Models\Manage\ManageLog;
use App\Models\User\User;
use App\Models\User\UserLog;
class ManagerLogController extends BaseController
{
/**
* @remark :管理员操作日志
* @name :log
* @author :lyh
* @method :post
* @time :2024/12/4 16:51
*/
public function logList(ManageLog $manageLog){
$managerModel = new Manage();
if(isset($this->map['name']) && !empty($this->map['name'])){
$ids = $managerModel->where('name', 'like', '%' . $this->param['name'] . '%')->pluck('id')->toArray();
$this->map['manage_id'] = ['in',$ids];
unset($this->map['name']);
}
if(isset($this->map['url']) && !empty($this->map['url'])){
$this->map['url'] = ['like','%'.$this->map['url'].'%'];
}
if(isset($this->map['ip']) && !empty($this->map['ip'])){
$this->map['ip'] = ['like','%'.$this->map['ip'].'%'];
}
$lists = $manageLog->lists($this->map,$this->page,$this->row,$this->order);
if(!empty($lists) && !empty($lists['list'])){
foreach ($lists['list'] as $k => $v){
$v['name'] = $managerModel->getName($v['manage_id']);
$lists['list'][$k] = $v;
}
}
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :v6操作日志
* @name :UserLogList
* @author :lyh
* @method :post
* @time :2024/12/4 17:37
*/
public function userLogList(UserLog $userLogModel){
$userModel = new User();
if(isset($this->map['name']) && !empty($this->map['name'])){
$ids = $userModel->where('name', 'like', '%' . $this->param['name'] . '%')->pluck('id')->toArray();
$this->map['operator_id'] = ['in',$ids];
unset($this->map['name']);
}
if(isset($this->map['model']) && !empty($this->map['model'])){
$this->map['model'] = ['like','%'.$this->map['model'].'%'];
}
if(isset($this->map['remark']) && !empty($this->map['remark'])){
$this->map['remark'] = ['like','%'.$this->map['remark'].'%'];
}
$lists = $userLogModel->lists($this->map,$this->page,$this->row,$this->order);
if(!empty($lists) && !empty($lists['list'])){
$userModel = new User();
foreach ($lists['list'] as $k => $v){
$v['name'] = $userModel->getName($v['operator_id']);
$lists['list'][$k] = $v;
}
}
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :管理员日志列表
* @name :lists
... ...
... ... @@ -510,6 +510,10 @@ class OptimizeController extends BaseController
'is_minor_languages.required' => '项目is_minor_languages不能为空',
]);
$projectModel = new Project();
$info = $projectModel->read(['id'=>$this->param['id']],['main_lang_id']);
if($info['main_lang_id'] != 1){
$this->fail('当前主语种不允许操作小语种监控配置');
}
$projectModel->edit(['is_minor_languages'=>$this->param['is_minor_languages']],['id'=>$this->param['id']]);
$this->response('success');
}
... ...
... ... @@ -13,6 +13,7 @@ use App\Helper\QuanqiusouApi;
use App\Http\Controllers\Aside\BaseController;
use App\Models\Channel\Channel;
use App\Models\Domain\DomainInfo;
use App\Models\Inquiry\ReInquiryCost;
use App\Models\Inquiry\ReInquiryCount;
use App\Models\Inquiry\ReInquiryDetail;
use App\Models\Inquiry\ReInquiryForm;
... ... @@ -57,15 +58,21 @@ class AdsController extends BaseController
}
})
->orderBy('id', 'desc')
->paginate($page_size);
->paginate($page_size)
->toArray();
$relay_site_total = 0;
foreach ($result as &$item){
$relay_site_total += count($item->target);
$item->requiry_num = ReInquiryDetail::where('task_id', $item->id)->where('status', ReInquiryDetail::STATUS_SUCCESS)->count();
$item->form_num = ReInquiryForm::whereIn('ad_id', explode(',', $item->ad_id))->count();
foreach ($result['list'] as &$item){
$relay_site_total += count($item['target']);
$item['requiry_num'] = ReInquiryDetail::where('task_id', $item['id'])->where('status', ReInquiryDetail::STATUS_SUCCESS)->count();
$item['form_num'] = ReInquiryForm::whereIn('ad_id', explode(',', $item['ad_id']))->count();
//关联网站是否有重复的
foreach ($item['target'] as $k=>$target){
$repeat = ReInquiryTask::where('target', 'like', '%'.$target['url'].'%')->where('id', '<>', $item['id'])->first();
$item['target'][$k]['is_repeat'] = $repeat ? 1 : 0;
}
$item['cost'] = ReInquiryCost::getCostByAdIds($item['ad_id']);
}
$result = $result->toArray();
$result['relay_site_total'] = $relay_site_total;
$result['default_ai_param'] = ReInquiryTask::DEFAULT_AI_PARAM;
... ...
... ... @@ -41,7 +41,9 @@ class OperationHeartbeatController extends BaseController
'is_custom.required' => '是否为扩展模版',
'is_template.required' => '详情页/可视化',
]);
if(empty($this->param['source_id'])){
$this->response('success');
}
$condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'],
'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
$operationHeartbeatModel = new OperationHeartbeat();
... ...
... ... @@ -279,4 +279,16 @@ class KeywordController extends BaseController
$logic->delRelated($this->param['keyword_id'],$this->param['product_id']);
$this->response('success');
}
/**
* @remark :清除当前项目所有关键字
* @name :delAllKeyword
* @author :lyh
* @method :post
* @time :2024/12/5 16:34
*/
public function delAllKeyword(KeywordLogic $logic){
$logic->delAllKeyword();
$this->response('success');
}
}
... ...
... ... @@ -313,7 +313,11 @@ class KeywordLogic extends BaseLogic
$productIdArr = $keywordRelatedModel->selectField(['keyword_id'=>$keyword_id],'product_id');
if(!empty($productIdArr)){
$productModel = new Product();
$productList = $productModel->list(['id'=>['in',$productIdArr]],['id','title']);
$productList = $productModel->list(['id'=>['in',$productIdArr]],['id','title','route']);
foreach ($productList as $k => $v){
$v['route'] = $this->user['domain'].$v['route'];
$productList[$k] = $v;
}
}
return $this->success($productList);
}
... ... @@ -336,4 +340,31 @@ class KeywordLogic extends BaseLogic
return $this->success();
}
/**
* @remark :删除所有的关键字
* @name :delAllKeyword
* @author :lyh
* @method :post
* @time :2024/12/5 15:37
*/
public function delAllKeyword(){
DB::beginTransaction();
try {
//截断关联表
KeywordRelated::truncate();
//截断关键词表
Keyword::truncate();
//清空产品表的keyword_id字段
$routeMapModel = new RouteMap();
$routeMapModel->del(['source'=>'product_keyword']);
$productModel = new Product();
$productModel->edit(['keyword_id'=>''],['id'=>['>',0]]);
DB::commit();
}catch (\Exception $e){
DB::rollBack();
$this->fail('操作失败,请联系管理员');
}
return $this->success();
}
}
... ...
<?php
namespace App\Models\Inquiry;
use App\Models\Base;
use Illuminate\Support\Facades\Cache;
/**
* Class ReInquiryCost
* @package App\Models\Inquiry
* @author zbj
* @date 2024/12/4
*/
class ReInquiryCost extends Base
{
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_re_inquiry_cost';
public static function saveData($ad_id, $spend, $lead, $single_cost, $start_date, $end_date){
$cost = self::where('ad_id', $ad_id)->first();
if(!$cost){
$cost = new self();
}
$cost->ad_id = $ad_id;
$cost->spend = $spend;
$cost->lead = $lead;
$cost->single_cost = $single_cost;
$cost->start_date = $start_date;
$cost->end_date = $end_date;
$cost->save();
}
public static function getCostByAdIds($ad_ids){
if(is_string($ad_ids)){
$ad_ids = explode(',',$ad_ids);
}
$cache_key = 'GET_COST_BY_AD_IDS_' . implode(',', $ad_ids);
$data = Cache::get($cache_key);
if(!$data){
$data = [];
$list = self::whereIn('ad_id', $ad_ids)->get();
foreach ($list as $item){
$data['cost'][] = '$' . $item['spend'];
$data['single_cost'][] = '$' . $item['single_cost'];
}
Cache::set($cache_key, $data);
}
return $data;
}
}
... ...
... ... @@ -53,6 +53,7 @@ class Project extends Base
3 => '告知书一',
4 => '告知书二',
5 => 'Q告知书二',
6 => 'CKA',
];
}
... ...
... ... @@ -148,6 +148,8 @@ Route::middleware(['aloginauth'])->group(function () {
//管理员日志
Route::prefix('log')->group(function () {
Route::any('/', [Aside\Manage\ManagerLogController::class, 'lists'])->name('admin.manager_log_lists');
Route::any('/logList', [Aside\Manage\ManagerLogController::class, 'logList'])->name('admin.manager_log_logList');
Route::any('/userLogList', [Aside\Manage\ManagerLogController::class, 'userLogList'])->name('admin.manager_log_userLogList');
});
});
... ...
... ... @@ -282,6 +282,7 @@ Route::middleware(['bloginauth'])->group(function () {
Route::post('keyword/batchDel', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchDel'])->name('product_keyword_batchDel');
Route::any('keyword/delete', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delete'])->name('product_keyword_delete');
Route::any('keyword/delRelated', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delRelated'])->name('product_keyword_delRelated');
Route::any('keyword/delAllKeyword', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delAllKeyword'])->name('product_keyword_delAllKeyword');
Route::any('keyword/batchUpdateKeyword', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchUpdateKeyword'])->name('product_keyword_batchUpdateKeyword');
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');
... ...