作者 李美松

Merge branch 'develop' into lms

正在显示 37 个修改的文件 包含 1197 行增加143 行删除
<?php
namespace App\Console\Commands;
use App\Helper\Arr;
use App\Models\Product\Category;
use App\Models\Product\Product;
use App\Models\RouteMap;
use GuzzleHttp\Client;
use GuzzleHttp\Promise\Utils;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
/**
* 网站引流
* Class Traffic
* @package App\Console\Commands
* @author zbj
* @date 2023/5/18
*/
class WebTraffic extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'web_traffic {type}';
/**
* The console command description.
*
* @var string
*/
protected $description = '网站引流';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* google域名后缀
* @var string[]
*/
protected $suffix = [
'co.jp' => '日本',
'com.tr' => '土耳其',
'nl' => '荷兰',
'ru' => '俄罗斯',
'fr' => '法国',
'co.kr' => '韩国',
'fi' => '芬兰',
'be' => '比利时',
'lt' => '立陶宛',
'es' => '西班牙',
'it' => '意大利',
'com.au' => '澳大利亚',
'no' => '挪威',
'al' => '阿尔巴尼亚',
'pt' => '葡萄牙',
'lv' => '拉脱维亚',
'hu' => '匈牙利',
'cz' => '捷克',
'de' => '德国',
'ca' => '加拿大',
'co.in' => '印度',
'co.uk' => '英国',
'com.vn' => '越南',
'com.br' => '巴西',
'co.il' => '以色列',
'pl' => '波兰',
'com.eg' => '埃及',
'co.th' => '泰国',
'sk' => '斯洛伐克',
'ro' => '罗马尼亚',
'com.mx' => '墨西哥',
'com.my' => '马来西亚',
'com.pk' => '巴基斯坦',
'co.nz' => '新西兰',
'co.za' => '南非',
'com.ar' => '阿根廷',
'com.kw' => '科威特',
'com.sg' => '新加坡',
'com.co' => '哥伦比亚',
'co.id' => '印度尼西亚',
'gr' => '希腊',
'bg' => '保加利亚',
'mn' => '蒙古',
'dk' => '丹麦',
'com.sa' => '沙特阿拉伯',
'com.pe' => '秘鲁',
'com.ph' => '菲律宾',
'com.ua' => '乌克兰',
'ge' => '格鲁吉亚',
'ae' => '阿拉伯联合酋长国',
'tn' => '突尼斯',
];
/**
* 概率值
* @var int[]
*/
protected $sjjg = [720, 280];//访问间隔占比 访问|不访问
//访问页面类型占比 产品详情页、单页|产品分类页
protected $ymzb = [
'urls_cats' => 700,
'urls_details' => 300
];
protected $sdzb = [600, 200, 150, 50]; //访问页面深度占比 1页|2页|3-6页|7-11页
protected $yddzb = [1 => 700, 2 => 300]; //移动端占比 pc|mobile
//模拟访问来源占比 (美国)
protected $lyzb = [
'https://www.google.com/' => 630,
'http://www.google.com/' => 30,
'http://www.bing.com/' => 20,
'https://www.bing.com/' => 5,
'https://www.youtube.com/' => 5,
'https://search.yahoo.com/' => 5,
'https://www.facebook.com/' => 5,
];
protected $otherzb = [700, 300]; //模拟访问来源占比 (非美国) google.com|google.其他后缀
protected $pc_ua = [
0 => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
1 => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
2 => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
];
protected $mobile_ua = [
0 => 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko; googleweblight) Chrome/38.0.1025.166 Mobile Safari/535.19',
];
/**
* @return bool
*/
public function handle()
{
$type = $this->argument('type');
$this->sleep($type);
$project_list = $this->getProjectList($type);
$project_chunk = array_chunk($project_list,500,true);
foreach ($project_chunk as $chunk) {
$need_project = [];
foreach ($chunk as $project) {
//随机引流间隔
$res_sjjg = $this->get_rand($this->sjjg);
if ($res_sjjg == 1) {
continue;
}
$project_urls = $this->getProductUrls($project['project_id']);
$project_urls['home'] = $project['domain'];
//随机访问页面
$project['visit_urls'] = $this->getVisitUrls($project_urls);
//随机客户端
$project['device_port'] = $this->get_rand($this->yddzb);
$project['user_agent'] = $project['device_port'] == 1 ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
$need_project[] = $project;
}
//随机访问ip
$ips = $this->getIpAreas(count($need_project));
//最多10层深度
$client = new Client(['verify' => false]);
for ($j = 0; $j < 10; $j++) {
for ($j = 0; $j < 10; $j++) {
//并发请求
$promises = [];
foreach ($need_project as $project_key => $project) {
if (empty($project['visit_urls'][$j])) {
continue;
}
$data = [
'ip' => $ips[$project_key]['ip'],
'referer' => $this->getReferer($ips[$project_key]['ip_area']),
'url' => $project['visit_urls'][$j],
'device_port' => $this->get_rand($this->yddzb)
];
$promises[] = $client->postAsync($project['domain'] . 'api/customerVisit', ['form_params' => $data]);
}
Utils::settle($promises)->wait();
//每个深度随机等待
sleep(rand(2, 10));
}
}
}
}
/**
* 不同项目 休眠
*/
protected function sleep($type){
if($type == 1){ //1-3个月的项目
sleep(rand(5,480));
}elseif($type == 2){ //4-8个月的项目
sleep(rand(5,240));
}elseif($type == 3){ // 大于9个月的项目
sleep(rand(5,120));
}
}
/**
* 引流的项目
*/
protected function getProjectList($type){
//todo 根据type获取需要引流的项目
return [
[
'project_id' => 1,
'domain' => 'https://demomark.globalso.com/',
]
];
}
/**
* 获取产品分类、单页和详情链接
*/
protected function getProductUrls($project_id){
//产品分类页面
$product_cate_ids = Category::where('project_id', $project_id)->where('status', Category::STATUS_ACTIVE)->pluck('id')->toArray();
$data['urls_cats'] = RouteMap::where('project_id', $project_id)->where('source', RouteMap::SOURCE_PRODUCT_CATE)->whereIn('source_id', $product_cate_ids)->get()->toArray();
//单页面
//todo 发布状态的单页面id
$data['urls_page'] = RouteMap::where('project_id', $project_id)->where('source', RouteMap::SOURCE_PAGE)->get()->toArray();
//产品详情页
$product_ids = Product::where('project_id', $project_id)->where('status', Product::STATUS_ON)->pluck('id')->toArray();
$data['urls_details'] = RouteMap::where('project_id', $project_id)->where('source', RouteMap::SOURCE_PRODUCT)->whereIn('source_id', $product_ids)->get()->toArray();
$data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
if(empty($data['urls_cats'])){
$data['urls_cats'] = $data['urls_details'];
}
return $data;
}
/**
* 获取地区IP
*/
protected function getIpAreas($num)
{
//本地时间为7-23点的地区
$h = date('H');
$areas = [];
$list = DB::table('gl_area_timezone')->get();
foreach ($list as $v) {
$v = (array)$v;
$country_hour = $h + $v['diff'];
if ($country_hour < 0) {
$country_hour = 24 + $country_hour;
}
if ($country_hour >= 7 && $country_hour < 23) {
$areas[] = $v['name'];
}
}
//根据地区随机取该地区的IP
$data = DB::table('gl_xunpan_ipdata')->whereIn('ip_area', $areas)->inRandomOrder()->limit($num)->get();
return Arr::s2a(Arr::a2s($data));
}
/**
* 概率算法
*/
protected function get_rand($proArr) {
$result = '';
$proSum = array_sum($proArr);
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset ($proArr);
return $result;
}
/**
* 根据随机访问深度 随机获取访问页面
*/
protected function getVisitUrls($project_urls){
//没有分类页 就只访问首页
if(!$project_urls['urls_cats']){
$url[] = $project_urls['home'];
return $url;
}
//随机访问深度
$res_sdzb = $this->get_rand($this->sdzb);
//随机访问页面类型
$res_ymzb = $this->get_rand($this->ymzb);
$all_url = array_merge($project_urls['urls_cats'],$project_urls['urls_details']);
if(!$all_url){
$url[] = $project_urls['home'];
return $url;
}
$url = [];
if($res_sdzb == 0){//深度一页
$url[] = $project_urls[$res_ymzb] ? Arr::random($project_urls[$res_ymzb])['route'] : '';
}elseif($res_sdzb == 1){//深度两页
$url[] = $project_urls['home'];
$url[] = $project_urls[$res_ymzb] ? Arr::random($project_urls[$res_ymzb])['route'] : '';
}elseif($res_sdzb == 2){//深度3-6页
$yms = rand(2,5); //随机页面数
$url = Arr::pluck(Arr::random($all_url, $yms), 'route');
$url = Arr::prepend($url, $project_urls['home']);//首页加到最前面去
}elseif($res_sdzb == 3){//深度7-11页
$yms = rand(6,10); //随机页面数
$url = Arr::pluck(Arr::random($all_url, $yms), 'route');
$url = Arr::prepend($url, $project_urls['home']);//首页加到最前面去
}
foreach ($url as &$v){
if(!Str::contains($v, $project_urls['home'])){
$v = $project_urls['home'] . $v;
}
}
return array_unique(array_filter($url));
}
/**
* 获取访问来路
*/
protected function getReferer($ip_area){
if($ip_area == '美国'){
$referer = $this->get_rand($this->lyzb);
}else{
$referer = 'https://www.google.com/';
$suffix = array_search($ip_area, $this->suffix);
if($suffix){
$res_qtzb = $this->get_rand($this->otherzb);
if($res_qtzb == 1){
$referer = 'https://www.google.'.$suffix.'/';
}
}
}
return $referer;
}
}
... ...
<?php
namespace App\Console\Commands\YesterdayCount;
use App\Helper\Common;
use App\Helper\FormGlobalsoApi;
use App\Models\CustomerVisit\CustomerVisitItem;
use App\Models\Project\DeployBuild;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class Yesterday extends Command
{
const STATUS_ERROR = 400;
public $error = 0;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'yesterday_count';
/**
* The console command description.
*
* @var string
*/
protected $description = '统计昨日数据';
/**
* @name :(定时执行生成昨日数据统计)handle
* @author :lyh
* @method :post
* @time :2023/5/12 14:48
*/
public function handle()
{
$deployModel = new DeployBuild();
$list = $deployModel->list();
$data = [];
$yesterday = Carbon::yesterday()->toDateString();
foreach ($list as $v){
$arr = [];
$arr['yesterday_pv_num'] = DB::table('gl_customer_visit_item')->whereDate('date', $yesterday)->where('domain',$v['test_domain'])->count();
$arr['yesterday_ip_num'] = DB::table('gl_customer_visit')->whereDate('date', $yesterday)->where('domain',$v['test_domain'])->count();
$inquiry_list = (new FormGlobalsoApi())->getInquiryList($v['test_domain']);
if($inquiry_list['status'] == self::STATUS_ERROR){
$arr['inquiry_num'] = 0;
}else{
$arr['inquiry_num'] = count($inquiry_list['data']['total']);
}
$arr['date'] = $yesterday;
$rank_info = DB::table('gl_rank_data')->where(['updated_date'=>$yesterday,'lang'=>''])->select(['compliance_day'])->first();
if(empty($rank_info)){
$arr['compliance_day'] = 0;
}else{
$arr['compliance_day'] = $rank_info->compliance_day;
}
$arr['service_day'] = $v['service_duration'] - Common::getDaysToTargetDate($v['created_at']);
$arr['project_id'] = $v['project_id'];
$arr['created_at'] = date('Y-m-d H:i:s');
$arr['updated_at'] = date('Y-m-d H:i:s');
$data[] = $arr;
}
DB::table('gl_count')->insert($data);
echo $this->error;
}
}
... ...
... ... @@ -23,9 +23,10 @@ class Kernel extends ConsoleKernel
$schedule->command('rank_data_recomm_domain')->weeklyOn(1, '01:00')->withoutOverlapping(1); // 排名数据-引荐域名,每周一凌晨执行一次
$schedule->command('rank_data_week')->weeklyOn(1, '01:00')->withoutOverlapping(1); // 排名数据,每周一凌晨执行一次
$schedule->command('share_user')->dailyAt('01:00')->withoutOverlapping(1); // 清除用户ayr_share数据,每天凌晨1点执行一次
$schedule->command('visit', ['type' => 1])->everyThirtyMinutes(); // 引流 1-3个月的项目,半小时一次
$schedule->command('visit', ['type' => 2])->cron('*/18 * * * *'); // 引流 4-8个月的项目,18分钟一次
$schedule->command('visit', ['type' => 3])->cron('*/12 * * * *'); // 引流 大于9个月的项目,12分钟一次
$schedule->command('yesterday_count')->dailyAt('01:00')->withoutOverlapping(1); // 清除用户ayr_share数据,每天凌晨1点执行一次
$schedule->command('web_traffic 1')->everyThirtyMinutes(); // 引流 1-3个月的项目,半小时一次
$schedule->command('web_traffic 2')->cron('*/18 * * * *'); // 引流 4-8个月的项目,18分钟一次
$schedule->command('web_traffic 3')->cron('*/12 * * * *'); // 引流 大于9个月的项目,12分钟一次
}
/**
... ...
... ... @@ -133,4 +133,19 @@ class Common
$arr = array_map('unserialize', $arr);
return $arr;
}
/**
* @param $targetDateTime
* @name :(获取时间差,精确时分秒,返回天数)getDaysToTargetDate
* @author :lyh
* @method :post
* @time :2023/5/24 9:38
*/
public static function getDaysToTargetDate($targetDateTime)
{
$currentTimestamp = time();
$targetTimestamp = strtotime($targetDateTime);
$days = floor(($currentTimestamp - $targetTimestamp) / (60 * 60 * 24));
return (int)$days;
}
}
... ...
... ... @@ -223,3 +223,24 @@ if (!function_exists('getThisWeekStarDate')) {
return Carbon::now()->startOfWeek()->toDateString();
}
}
if (!function_exists('object_to_array')) {
/**
* 获取本周一的日期
* @return mixed
* @author zbj
* @date 2023/5/11
*/
function object_to_array($data)
{
if(is_object($data)){
$data = (array)$data;
}else{
foreach ($data as $k => $v){
$data[$k] = object_to_array($v);
}
}
return $data;
}
}
... ...
... ... @@ -210,5 +210,4 @@ class BaseController extends Controller
}
}
... ...
... ... @@ -127,53 +127,53 @@ class ComController extends BaseController
* @method :post
* @time :2023/5/12 14:55
*/
// protected function ceShi(){
// $this->error = 0;
// //获取所有ayr_share用户
// $ayr_share_model = new AyrShareModel();
// $ayr_share_list = $ayr_share_model->list($this->map);
// if(!empty($ayr_share_list)){
// foreach ($ayr_share_list as $k => $v){
// //查询当前用户是否有未推送的博文
// $ayr_release = new AyrReleaseModel();
// $release_info = $ayr_release->read(['schedule_date'=>['>',date('Y-m-d H:i:s',time())],'share_id'=>$v['id']]);
// //有推文时,直接跳出循环
// if($release_info !== false){
// continue;
// }
// //查看用户是否在一周内有发送博客
// $start_at = Carbon::now()->modify('-7 days')->toDateString();
// $end_at = Carbon::now()->toDateString();
// $release_info = $ayr_release->read(['created_at'=>['between',[$start_at,$end_at]]]);
// //有发送博文,则跳出循环
// if($release_info == false){
// continue;
// }
// //删除用户第三方配置
// $ayr_share_helper = new AyrShareHelper();
// $data_profiles = [
// 'title'=>$v['title'],
// 'profileKey'=>$v['profile_key']
// ];
// $res = $ayr_share_helper->deleted_profiles($data_profiles);
// if($res['status'] == 'fail'){
// $this->error++;
// continue;
// }
// //更新数据库
// $data = [
// 'title'=>null,
// 'bind_plat_from'=>null,
// 'profile_key'=>null,
// 'ref_id'=>null,
// ];
// $res = $ayr_share_model->edit($data,['id'=>$v['id']]);
// if($res == false){
// $this->error++;
// }
// }
// }
// return $this->error;
// }
protected function ceShi(){
$this->error = 0;
//获取所有ayr_share用户
$ayr_share_model = new AyrShareModel();
$ayr_share_list = $ayr_share_model->list($this->map);
if(!empty($ayr_share_list)){
foreach ($ayr_share_list as $k => $v){
//查询当前用户是否有未推送的博文
$ayr_release = new AyrReleaseModel();
$release_info = $ayr_release->read(['schedule_date'=>['>',date('Y-m-d H:i:s',time())],'share_id'=>$v['id']]);
//有推文时,直接跳出循环
if($release_info !== false){
continue;
}
//查看用户是否在一周内有发送博客
$start_at = Carbon::now()->modify('-7 days')->toDateString();
$end_at = Carbon::now()->toDateString();
$release_info = $ayr_release->read(['created_at'=>['between',[$start_at,$end_at]]]);
//有发送博文,则跳出循环
if($release_info == false){
continue;
}
//删除用户第三方配置
$ayr_share_helper = new AyrShareHelper();
$data_profiles = [
'title'=>$v['title'],
'profileKey'=>$v['profile_key']
];
$res = $ayr_share_helper->deleted_profiles($data_profiles);
if($res['status'] == 'fail'){
$this->error++;
continue;
}
//更新数据库
$data = [
'title'=>null,
'bind_plat_from'=>null,
'profile_key'=>null,
'ref_id'=>null,
];
$res = $ayr_share_model->edit($data,['id'=>$v['id']]);
if($res == false){
$this->error++;
}
}
}
return $this->error;
}
}
... ...
<?php
namespace App\Http\Controllers\Bside\HomeCount;
use App\Enums\Common\Code;
use App\Helper\Common;
use App\Helper\FormGlobalsoApi;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\HomeCount\CountLogic;
use App\Models\Project\DeployBuild;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class CountController extends BaseController
{
const STATUS_ERROR = 400;
/**
* @name :(昨日统计数据)yesterday_count
* @author :lyh
* @method :post
* @time :2023/5/23 17:23
*/
public function count(CountLogic $countLogic){
$data = [];
//TODO::昨日数据统计
$data['yesterday'] = $countLogic->yesterday_count();
//TODO::全球搜方案信息
$data['scheme_info'] = $countLogic->scheme_info();
//TODO::网站访问量统计
$data['total_visit'] = $countLogic->total_count($data['yesterday']['inquiry_num']);
//TODO::关键字排名数据
$data['keyword_data'] = $countLogic->keyword_data_count();
//TODO::相关数据统计
$data['with_data'] = $countLogic->with_data_count();
//TODO::30天pv,ip统计
$data['visit_data'] = $countLogic->visit_data_count();
//TODO::询盘国家统计
$data['country_data'] = $countLogic->inquiry_country_count();
//TODO::来源排名
$data['country_data'] = $countLogic->referrer_count();
//TODO::访问国家前10
$data['access_country_count'] = $countLogic->access_country_count();
return $this->response('success',Code::SUCCESS,$data);
}
/***
* @name :(手动获取昨日数据统计)yesterday
* @author :lyh
* @method :post
* @time :2023/5/24 9:13
*/
public function yesterday(){
$deployModel = new DeployBuild();
$list = $deployModel->list();
$data = [];
$yesterday = Carbon::yesterday()->toDateString();
foreach ($list as $v){
$arr = [];
$arr['yesterday_pv_num'] = DB::table('gl_customer_visit_item')->whereDate('date', $yesterday)->where('domain',$v['test_domain'])->count();
$arr['yesterday_ip_num'] = DB::table('gl_customer_visit')->whereDate('date', $yesterday)->where('domain',$v['test_domain'])->count();
$inquiry_list = (new FormGlobalsoApi())->getInquiryList($v['test_domain']);
if($inquiry_list['status'] == self::STATUS_ERROR){
$arr['inquiry_num'] = 0;
}else{
$arr['inquiry_num'] = count($inquiry_list['data']['total']);
}
$arr['date'] = $yesterday;
$rank_info = DB::table('gl_rank_data')->where(['updated_date'=>$yesterday,'lang'=>''])->select(['compliance_day'])->first();
if(empty($rank_info)){
$arr['compliance_day'] = 0;
}else{
$arr['compliance_day'] = $rank_info->compliance_day;
}
$arr['service_day'] = $v['service_duration'] - Common::getDaysToTargetDate($v['created_at']);
$arr['project_id'] = $v['project_id'];
$arr['created_at'] = date('Y-m-d H:i:s');
$arr['updated_at'] = date('Y-m-d H:i:s');
$data[] = $arr;
}
DB::table('gl_count')->insert($data);
$this->response('success');
}
}
... ...
... ... @@ -25,13 +25,7 @@ class CategoryController extends BaseController
$map[] = ['title', 'like', "%{$this->param['search']}%"];
}
$sort = ['id' => 'desc'];
$data = $logic->getList($map, $sort, ['id', 'pid', 'title', 'image', 'keywords', 'describe', 'status','created_at'],0);
foreach ($data as &$v){
$v['product_num'] = $logic->getProductNum($v['id']);
}
if(!$map){
$data = Arr::listToTree($data);
}
$data = $logic->getList($map, $sort, ['id', 'project_id', 'pid', 'title', 'image', 'keywords', 'describe', 'status','created_at'],0);
return $this->success($data);
}
... ... @@ -42,7 +36,7 @@ class CategoryController extends BaseController
'id.required' => 'ID不能为空'
]);
$data = $logic->getInfo($this->param['id']);
return $this->success(Arr::twoKeepKeys($data, ['id', 'pid', 'title', 'image', 'keywords', 'describe', 'status']));
return $this->success(Arr::twoKeepKeys($data, ['id', 'project_id', 'pid', 'title', 'image', 'keywords', 'describe', 'status', 'route', 'url']));
}
public function save(CategoryRequest $request, CategoryLogic $logic)
... ...
... ... @@ -26,13 +26,7 @@ class KeywordController extends BaseController
$map[] = ['title', 'like', "%{$this->param['search']}%"];
}
$sort = ['id' => 'desc'];
$data = $logic->getList($map, $sort, ['id', 'title', 'seo_title', 'seo_keywords', 'seo_description', 'status', 'created_at']);
foreach ($data['list'] as &$v){
$v['product_num'] = $logic->getProductNum($v['id']);
$v['tdk'] = boolval($v['seo_title']) * boolval($v['seo_keywords']) * boolval($v['seo_description']);
//todo 获取域名 拼接链接
$v['url'] = $v['route'];
}
$data = $logic->getList($map, $sort, ['id', 'project_id', 'title', 'seo_title', 'seo_keywords', 'seo_description', 'status', 'created_at']);
return $this->success($data);
}
... ... @@ -43,7 +37,7 @@ class KeywordController extends BaseController
'id.required' => 'ID不能为空'
]);
$data = $logic->getInfo($this->param['id']);
return $this->success(Arr::twoKeepKeys($data, ['id', 'title', 'seo_title', 'seo_keywords', 'seo_description', 'created_at']));
return $this->success(Arr::twoKeepKeys($data, ['id', 'project_id', 'title', 'seo_title', 'seo_keywords', 'seo_description', 'created_at', 'route', 'url']));
}
public function save(KeywordRequest $request, KeywordLogic $logic)
... ...
... ... @@ -55,7 +55,7 @@ class ProductController extends BaseController
$map[] = ['status', $this->param['status']];
}
$sort = ['id' => 'desc'];
$data = $logic->getList($map, $sort, ['id', 'title', 'thumb', 'category_id', 'keyword_id', 'status', 'created_uid', 'created_at', 'updated_at']);
$data = $logic->getList($map, $sort, ['id', 'project_id', 'title', 'thumb', 'category_id', 'keyword_id', 'status', 'created_uid', 'created_at', 'updated_at']);
return $this->success($data);
}
... ... @@ -66,8 +66,8 @@ class ProductController extends BaseController
'id.required' => 'ID不能为空'
]);
$data = $logic->getInfo($this->param['id']);
return $this->success(Arr::twoKeepKeys($data, ['id', 'title', 'gallery', 'attrs', 'category_id', 'keyword_id', 'attr_id', 'describe_id', 'intro', 'content',
'describe', 'seo_mate', 'related_product_id', 'status', 'category_id_text', 'keyword_id_text', 'status_text', 'created_uid', 'created_uid_text', 'route']));
return $this->success(Arr::twoKeepKeys($data, ['id', 'project_id', 'title', 'gallery', 'attrs', 'category_id', 'keyword_id', 'attr_id', 'describe_id', 'intro', 'content',
'describe', 'seo_mate', 'related_product_id', 'status', 'category_id_text', 'keyword_id_text', 'status_text', 'created_uid', 'created_uid_text', 'route', 'url']));
}
public function save(ProductRequest $request, ProductLogic $logic)
... ...
... ... @@ -77,10 +77,8 @@ class RankDataController extends BaseController
public function export(RankDataLogic $logic){
$lang = $this->request['lang'] ??'';
$data = $logic->keywords_rank_list(true);
$img_position = $video_position= false;
foreach ($data as &$item){
$item['domain'] = explode(':', $item['domain'])[1];
$item['lang'] = $this->request['lang'] ?: 'en';
$item['g_text'] = RankData::gMap()[$item['g']]??'';
$item['img_position'] = $item['img_position'] ?? '';
... ... @@ -88,10 +86,10 @@ class RankDataController extends BaseController
foreach ($item['position'] as $date => $position){
$item[$date] = $position;
}
if(isset($item['img_position'])){
if(!empty($item['img_position'])){
$img_position = true;
}
if(isset($item['video_position'])){
if(!empty($item['video_position'])){
$video_position = true;
}
}
... ... @@ -199,7 +197,7 @@ class RankDataController extends BaseController
$promises['video_position'] = $client->getAsync('/google_video?'.Arr::query($param));
// 等待所有请求响应完成
$results = Utils:: settle($promises)->wait();
$results = Utils::settle($promises)->wait();
foreach ($results as $key => $result) {
if ($result['state'] == 'fulfilled') {
$res = Arr::s2a($result['value']->getBody()->getContents());
... ...
... ... @@ -122,8 +122,90 @@ class TemplateController extends BaseController
$data = TemplateLogic::instance()->first($source,$source_id);
return $this->response('',Code::SUCCESS,$data['html']);
$def = '<div class=" d-flex align-items-center justify-content-between py-md-4">
<div class="logo w-25 w-sm-auto"><a href="#"><img class="img-fluid" src="img/logo.png" alt=""></a></div>
<nav class="navbar navbar-expand-md navbar-dark flex-fill justify-content-end mx-2 pe-md-5">
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#navMenu"
aria-controls="navMenu">
<span class="navbar-toggler-icon"></span>
</button>
<ul class="nav column-gap-5 justify-content-end text-white d-none d-md-flex">
<li><a href="#">Home</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-bs-toggle="dropdown">Products</a>
<ul class="dropdown-menu fs-6 text-body shadow-sm border-0">
<li><a href="#" class="dropdown-item py-2">Product Information</a></li>
<li><a href="#" class="dropdown-item py-2">Change of Insurance</a></li>
<li><a href="#" class="dropdown-item py-2">Traveling Oxygen Program</a></li>
<li><a href="#" class="dropdown-item py-2">Contact</a></li>
</ul>
</li>
<li><a href="#">News</a></li>
<li><a href="#">Download</a></li>
<li><a href="#">FAQ</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<div class="d-flex align-items-center justify-content-end">
<div class="search">
<button type="button" class="btn border-0" data-bs-toggle="dropdown">
<svg viewBox="0 0 24 24" width="18" height="18" stroke="#ffffff" stroke-width="2"
fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</button>
<div class="dropdown-menu p-3 shadow-sm border-0">
<form action="">
<div class="d-flex mb-2">
<input type="text" class="form-control" name="search" placeholder="Start Typing...">
<button class="btn btn-search border-0" type="submit">
<svg viewBox="0 0 24 24" width="18" height="18" stroke="#333333"
stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"
class="css-i6dzq1">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</button>
</div>
<p class="search-attr">Hit enter to search or ESC to close</p>
</form>
</div>
</div>
<div class="change-language ms-md-4">
<div role="button" class="dropdown-toggle text-white d-flex align-items-center"
data-bs-toggle="dropdown">
<b class="country-flag language-flag-en"></b> <span>English</span>
</div>
<div class="dropdown-menu shadow-sm border-0">
<div class="d-flex flex-wrap p-3 text-body">
<a href="#" class="col-4 mb-3 pe-2 d-flex align-items-center" title="English">
<b class="country-flag language-flag-en"></b>
<span>English</span>
</a>
<a href="#" class="col-4 mb-3 pe-2 d-flex align-items-center" title="Françai">
<b class="country-flag language-flag-fr"></b>
<span>Françai</span>
</a>
<a href="#" class="col-4 mb-3 pe-2 d-flex align-items-center" title="Español">
<b class="country-flag language-flag-es"></b>
<span>Español</span>
</a>
<a href="#" class="col-4 mb-3 pe-2 d-flex align-items-center" title="Deutsch">
<b class="country-flag language-flag-de"></b>
<span>Deutsch</span>
</a>
<a href="#" class="col-4 mb-3 pe-2 d-flex align-items-center" title="Română">
<b class="country-flag language-flag-ro"></b>
<span>Română</span>
</a>
</div>
</div>
</div>
</div>
</div>';
return $this->response('',Code::SUCCESS,$data?$data['html']:$def);
}
... ... @@ -174,33 +256,33 @@ class TemplateController extends BaseController
* @time 2023/5/10 14:55
*/
public function customChunk(){
$html = $this->param['html']??[];
// 那个页面 的
$type = $this->param['type']??'';
if(!is_array($html)){
return $this->response('参数异常',Code::SYSTEM_ERROR);
}
// 项目id
$project_id = $this->user['project_id'];
// 当前模板
$template_id = BSetting::_get($project_id)['template_id'];
// 验证这个模板是否存在
if(!$type || !ATemplateHtml::_typeExist($template_id,$type)){
return $this->response('页面类型错误',Code::SYSTEM_ERROR);
}
$html = view("template.{$template_id}.{$type}")->render();
return $this->response('',Code::SUCCESS,$html);
// $data = BTemplateData::_insert();
//
// $html = $this->param['html']??[];
// // 那个页面 的
// $type = $this->param['type']??'';
//
// if(!is_array($html)){
// return $this->response('参数异常',Code::SYSTEM_ERROR);
// }
//
// // 项目id
// $project_id = $this->user['project_id'];
// // 当前模板
// $template_id = BSetting::_get($project_id)['template_id'];
//
// // 验证这个模板是否存在
// if(!$type || !ATemplateHtml::_typeExist($template_id,$type)){
// return $this->response('页面类型错误',Code::SYSTEM_ERROR);
// }
//
//
// $html = view("template.{$template_id}.{$type}")->render();
//
//
// return $this->response('',Code::SUCCESS,$html);
//// $data = BTemplateData::_insert();
//
//
}
... ...
... ... @@ -25,9 +25,6 @@ class UserController extends BaseController
//TODO::搜索参数统一处理
$this->map['project_id'] = $this->user['project_id'];
$lists = $userModel->lists($this->map,$this->page,$this->row,$this->order,['id','name','mobile','created_at','wechat','status']);
if(empty($lists)){
$this->response('error',Code::USER_ERROR,[]);
}
$this->response('success',Code::SUCCESS,$lists);
}
... ...
<?php
namespace App\Http\Controllers\Bside;
use App\Http\Logic\Bside\VisitLogic;
use Illuminate\Http\Request;
/**
* 访问明细
* Class VisitController
* @package App\Http\Controllers\Bside
* @author zbj
* @date 2023/5/22
*/
class VisitController extends BaseController
{
public function index(VisitLogic $logic)
{
$data = $logic->getList();
return $this->success($data);
}
public function item(Request $request, VisitLogic $logic){
$request->validate([
'id'=>'required'
],[
'id.required' => 'ID不能为空'
]);
$map = [
['customer_visit_id' => $this->param['id']]
];
$data = $logic->getItemList($map);
return $this->success($data);
}
}
... ...
... ... @@ -40,7 +40,9 @@ class AyrReleaseLogic extends BaseLogic
public function release_add(){
$this->param['project_id'] = $this->user['project_id'];
$this->param['operator_id'] = $this->user['id'];
$this->param['images'] = implode(',',$this->param['images']);
if(isset($this->param['images']) && !empty($this->param['images'])){
$this->param['images'] = implode(',',$this->param['images']);
}
$this->param['platforms'] = json_encode($this->param['platforms']);
$rs = $this->model->add($this->param);
if($rs === false){
... ...
... ... @@ -213,9 +213,11 @@ class AyrShareLogic extends BaseLogic
$this->fail('不支持视频');
}
//验证图片数
$img_num = count($this->param['images']);
if($img_num > $this->send_num[$v]){
$this->fail('发布图片数量超过最大限制,'.$v.'只允许'.$this->send_num[$v].'张图');
if(isset($this->param['images']) && !empty($this->param['images'])){
$img_num = count($this->param['images']);
if($img_num > $this->send_num[$v]){
$this->fail('发布图片数量超过最大限制,'.$v.'只允许'.$this->send_num[$v].'张图');
}
}
//验证图片数
// $img_num = count($this->param['video']);
... ...
... ... @@ -7,6 +7,7 @@ use App\Enums\Common\Code;
use App\Enums\Common\Common;
use App\Exceptions\BsideGlobalException;
use App\Http\Controllers\File\ImageController;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Http\Logic\Logic;
use App\Models\File\Image as ImageModel;
use Illuminate\Support\Facades\Cache;
... ... @@ -25,6 +26,8 @@ class BaseLogic extends Logic
protected $user;
protected $project;
protected $side = Common::B;
public function __construct()
... ... @@ -32,6 +35,7 @@ class BaseLogic extends Logic
$this->request = request();
$this->requestAll = request()->all();
$this->user = Cache::get(request()->header('token'));
$this->project = (new ProjectLogic())->getInfo($this->user['project_id']);
}
... ... @@ -152,4 +156,14 @@ class BaseLogic extends Logic
}
return $rs;
}
public function getProjectDomain(){
if(!empty($this->project['deploy_optimize']['domain'])){
return $this->project['deploy_optimize']['domain'];
}
if(!empty($this->project['deploy_build']['test_domain'])){
return $this->project['deploy_build']['test_domain'];
}
return '';
}
}
... ...
... ... @@ -34,15 +34,12 @@ class CustomLogic extends BaseLogic
*/
public function save($param)
{
$param['html'] = '';
$id = parent::save($param);
$data = $this->getInfo($id['id']);
try {
RouteMap::setRoute($data['url'],RouteMap::SOURCE_CUSTOM,$data['id'],$this->user['project_id']);
}catch (\Throwable $e){
}
return $data;
}
... ...
<?php
namespace App\Http\Logic\Bside\HomeCount;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\HomeCount\Count;
use App\Models\RankData\RankData as RankDataModel;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class CountLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->model = new Count();
}
/**
* @name :(昨日统计数据)yesterday_count
* @author :lyh
* @method :post
* @time :2023/5/23 17:30
*/
public function yesterday_count(){
$yesterday = Carbon::yesterday()->toDateString();
$param = [
'date' => $yesterday,
'project_id' => $this->user['project_id']
];
$info = $this->model->read($param,['pv_num','ip_num','inquiry_num','date','compliance_day','service_day']);
return $this->success($info);
}
/**
* @name :(方案信息)scheme_info
* @author :lyh
* @method :post
* @time :2023/5/24 11:48
*/
public function scheme_info(){
$data = [
'company'=>$this->project['company'],
'scheme'=>$this->project['deploy_build']['plan'],
'service_duration'=>$this->project['deploy_build']['service_duration'],
];
return $this->success($data);
}
/**
* @name :(总访问量)total_count
* @author :lyh
* @method :post
* @time :2023/5/24 13:33
*/
public function total_count($inquiry_num){
$pv = DB::table('gl_customer_visit_item')->where(['domain'=>$this->project['deploy_build']['test_domain']])->count();
$ip = DB::table('gl_customer_visit')->where(['domain'=>$this->project['deploy_build']['test_domain']])->count();
$data = [
'total_pv'=>$pv,
'total_ip'=>$ip,
'conversion_rate' => ($inquiry_num / $ip) * 100,
];
return $this->success($data);
}
/**
* @name :(前一天关键字排名统计)keyword_data
* @author :lyh
* @method :post
* @time :2023/5/24 14:03
*/
public function keyword_data_count(){
$yesterday = Carbon::yesterday()->toDateString();
$rankDataModel = new RankDataModel();
$param = [
'updated_date' => $yesterday,
'project_id' => $this->user['project_id']
];
$data = $rankDataModel->read($param,['first_num','first_page_num','first_three_pages_num','first_five_pages_num','first_ten_pages_num']);
return $this->success($data);
}
/**
* @name :(相关数据统计)with_data_count
* @author :lyh
* @method :post
* @time :2023/5/24 14:12
*/
public function with_data_count(){
$product_count = DB::table('gl_product')->where(['project_id' => $this->user['project_id']])->count();
$news_count = DB::table('gl_news')->where(['project_id' => $this->user['project_id']])->count();
$page_count = DB::table('gl_web_template')->where(['project_id' => $this->user['project_id']])->count();
$data = [
'product_count' => $product_count,
'news_count' => $news_count,
'page_count' => $page_count,
];
return $this->success($data);
}
/**
* @name :(30天数据统计)visit_data_count
* @author :lyh
* @method :post
* @time :2023/5/24 14:18
*/
public function visit_data_count(){
$param = [
'date' => ['between',[now()->subDays(30)->startOfDay()->toDateString(),now()->startOfDay()->toDateString()]],
'project_id' => $this->user['project_id']
];
$data = $this->model->list($param,'id',['id','pv_num','ip_num','date']);
return $this->success($data);
}
/**
* @name :(询盘国家统计)inquiry_country_count
* @author :lyh
* @method :post
* @time :2023/5/24 14:58
*/
public function inquiry_country_count(){
$data = DB::table('gl_xunpan_ipdata')
->select('ip_area', DB::raw('COUNT(ip_area) as count'))
->groupBy('ip_area')->orderBy('count','desc')->limit(20)->get()->toArray();
$data = object_to_array($data);
$total = DB::table('gl_xunpan_ipdata')->count();
foreach ($data as $k=>$v){
$data[$k]['proportion'] = ($v['count']/$total) * 100;
}
return $this->success($data);
}
/**
* @name :(访问来源统计)referrer_count
* @author :lyh
* @method :post
* @time :2023/5/24 15:32
*/
public function referrer_count(){
$data = DB::table('gl_customer_visit')
->select('referrer_url', DB::raw('COUNT(*) as count'))->groupBy('referrer_url')
->orderBy('count','desc')->limit(8)->get()->toArray();
$total = DB::table('gl_customer_visit')->count();
$data = object_to_array($data);
foreach ($data as $k=>$v){
$data[$k]['proportion'] = ($v['count']/$total) * 100;
}
return $this->success($data);
}
/**
* @name :(访问国家统计)access_country_count
* @author :lyh
* @method :post
* @time :2023/5/24 15:56
*/
public function access_country_count(){
$data = DB::table('gl_customer_visit')
->select('country',DB::raw('COUNT(*) as ip'),DB::raw('SUM(depth) as pv'))
->groupBy('country')->orderBy('ip','desc')->limit(20)->get()->toArray();
$data = object_to_array($data);
foreach ($data as $k => $v){
$v['pv'] = (int)$v['pv'];
$data[$k] = $v;
}
return $this->success($data);
}
}
... ...
... ... @@ -2,11 +2,15 @@
namespace App\Http\Logic\Bside\Product;
use App\Exceptions\BsideGlobalException;
use App\Helper\Arr;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Product\Category;
use App\Models\Product\CategoryRelated;
use App\Models\Product\KeywordRelated;
use App\Models\Product\Product;
use App\Models\RouteMap;
use Illuminate\Support\Facades\DB;
/**
* Class CategoryLogic
... ... @@ -23,6 +27,26 @@ class CategoryLogic extends BaseLogic
$this->model = new Category();
}
public function getList(array $map = [], array $sort = ['id' => 'desc'], array $columns = ['*'], int $limit = 20)
{
$data = parent::getList($map, $sort, $columns, $limit);
foreach ($data as &$v){
$v['url'] = $this->getProjectDomain() . $v['route'] ;
$v['product_num'] = $this->getProductNum($v['id']);
}
if(!$map){
$data = Arr::listToTree($data);
}
return $this->success($data);
}
public function getInfo($id)
{
$info = parent::getInfo($id);
$info['url'] = $this->getProjectDomain() . $info['route'] ;
return $this->success($info);
}
public function save($param){
$param['pid'] = $param['pid'] ?? 0;
if(!empty($param['pid'])){
... ... @@ -34,26 +58,53 @@ class CategoryLogic extends BaseLogic
$this->fail('上级分类不存在');
}
}
return parent::save($param);
DB::beginTransaction();
try {
$res = parent::save($param);
//路由映射
RouteMap::setRoute($param['title'], RouteMap::SOURCE_PRODUCT_CATE, $res['id'], $this->user['project_id']);
DB::commit();
} catch (\Exception $e){
DB::rollBack();
errorLog('产品分类保存失败', $param, $e);
$this->fail('保存失败');
}
return $this->success();
}
public function delete($ids, $map = []){
$ids= array_filter(Arr::splitFilterToArray($ids), 'intval');
foreach ($ids as $id){
$info = $this->getCacheInfo($id);
if(!$info){
continue;
}
//是否有子分类
if(Category::where('project_id', $this->user['project_id'])->where('pid', $id)->count()){
$this->fail("分类{$info['title']}存在子分类,不能删除");
}
//是否有对应商品
if(CategoryRelated::where('cate_id', $id)->count()){
$this->fail("分类{$info['title']}存在产品,不能删除");
DB::beginTransaction();
try {
foreach ($ids as $id){
$info = $this->getCacheInfo($id);
if(!$info){
continue;
}
//是否有子分类
if(Category::where('project_id', $this->user['project_id'])->where('pid', $id)->count()){
$this->fail("分类{$info['title']}存在子分类,不能删除");
}
//是否有对应商品
if(CategoryRelated::where('cate_id', $id)->count()){
$this->fail("分类{$info['title']}存在产品,不能删除");
}
//删除路由映射
RouteMap::delRoute(RouteMap::SOURCE_PRODUCT_CATE, $id, $this->user['project_id']);
}
parent::delete($ids);
DB::commit();
} catch (BsideGlobalException $e){
DB::rollBack();
$this->fail($e->getMessage());
} catch (\Exception $e){
DB::rollBack();
$this->fail('删除失败');
}
return parent::delete($ids);
return $this->success();
}
/**
... ...
... ... @@ -2,6 +2,7 @@
namespace App\Http\Logic\Bside\Product;
use App\Exceptions\BsideGlobalException;
use App\Helper\Arr;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Product\KeywordRelated;
... ... @@ -24,6 +25,24 @@ class KeywordLogic extends BaseLogic
$this->model = new Keyword();
}
public function getList(array $map = [], array $sort = ['id' => 'desc'], array $columns = ['*'], int $limit = 20)
{
$data = parent::getList($map, $sort, $columns, $limit);
foreach ($data['list'] as &$v){
$v['product_num'] = $this->getProductNum($v['id']);
$v['tdk'] = boolval($v['seo_title']) * boolval($v['seo_keywords']) * boolval($v['seo_description']);
$v['url'] = $this->getProjectDomain() . $v['route'];
}
return $this->success($data);
}
public function getInfo($id)
{
$info = parent::getInfo($id);
$info['url'] = $this->getProjectDomain() . $info['route'];
return $this->success($info);
}
public function save($param){
DB::beginTransaction();
try {
... ... @@ -44,8 +63,6 @@ class KeywordLogic extends BaseLogic
DB::beginTransaction();
try {
parent::delete($ids);
foreach ($ids as $id){
$info = $this->getCacheInfo($id);
if(!$info){
... ... @@ -60,8 +77,12 @@ class KeywordLogic extends BaseLogic
//删除路由映射
RouteMap::delRoute(RouteMap::SOURCE_PRODUCT_KEYWORD, $id, $this->user['project_id']);
}
parent::delete($ids);
DB::commit();
} catch (BsideGlobalException $e){
DB::rollBack();
$this->fail($e->getMessage());
}catch (\Exception $e){
DB::rollBack();
$this->fail('删除失败');
... ...
... ... @@ -53,6 +53,7 @@ class ProductLogic extends BaseLogic
$info['keyword_id_text'] = Arr::arrToSet($info['keyword_id_text'], 'trim');
$info['status_text'] = Product::statusMap()[$info['status']] ?? '';
$info['created_uid_text'] = (new UserLogic())->getCacheInfo($info['created_uid'])['name'] ?? '';
$info['url'] = $this->getProjectDomain() . $info['route'] ;
return $info;
}
... ... @@ -85,8 +86,6 @@ class ProductLogic extends BaseLogic
DB::beginTransaction();
try {
parent::delete($ids);
foreach ($ids as $id){
//删除路由映射
RouteMap::delRoute(RouteMap::SOURCE_PRODUCT, $id, $this->user['project_id']);
... ... @@ -97,6 +96,7 @@ class ProductLogic extends BaseLogic
//删除关键词关联
KeywordRelated::where('product_id', $id)->delete();
}
parent::delete($ids);
DB::commit();
}catch (\Exception $e){
... ...
... ... @@ -23,7 +23,7 @@ class DeptUserLogic extends BaseLogic
*/
public function dept_user_save(){
if(isset($this->param['id']) && !empty($this->param['id'])){
$rs = $this->dept_user_edit($this->param);
$rs = $this->dept_user_edit();
}else{
$rs = $this->dept_user_add();
}
... ... @@ -60,8 +60,8 @@ class DeptUserLogic extends BaseLogic
* @method :post
* @time :2023/5/17 17:54
*/
public function dept_user_edit($param){
$rs = $this->model->edit($param,['id'=>$this->param['id']]);
public function dept_user_edit(){
$rs = $this->model->edit($this->param,['id'=>$this->param['id']]);
if($rs === false){
$this->fail('error');
}
... ...
<?php
namespace App\Http\Logic\Bside;
use App\Http\Logic\Logic;
use App\Models\Visit\Visit;
use App\Models\Visit\VisitItem;
/**
* Class VisitLogic
* @package App\Http\Logic\Bside
* @author zbj
* @date 2023/5/22
*/
class VisitLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->model = new Visit();
}
public function getList(array $map = [], array $sort = ['id' => 'desc'], array $columns = ['*'], int $limit = 20)
{
return Logic::getList($map, $sort, ['id', 'url', 'referrer_url', 'device_port', 'country', 'ip', 'depth', 'created_at'], $limit);
}
public function getItemList(array $map = [], array $sort = ['id' => 'desc'], array $columns = ['*'], int $limit = 20){
$this->model = new VisitItem();
return Logic::getList($map, $sort, ['url', 'created_at'], 0);
}
}
... ...
... ... @@ -2,6 +2,9 @@
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Closure;
class AccessToken
{
/**
... ...
... ... @@ -24,12 +24,9 @@ class AyrReleaseRequest extends FormRequest
{
return [
'title'=>'required',
// 'images'=>'required|array',
// 'video'=>'required',
'content'=>'required',
'share_id'=>'required',
'platforms'=>'required|array',
// 'schedule_date'=>'required',
];
}
... ...
... ... @@ -36,7 +36,7 @@ class CustomRequest extends FormRequest
'keywords' => ['required','max:200'],
'description' => ['required','max:250'],
// 'html' => ['required'],
'url' => ['required','max:200'],
'url' => ['required','max:200','url'],
'status' => ['required','in:0,1'],
];
... ... @@ -70,6 +70,7 @@ class CustomRequest extends FormRequest
'url.required' => '链接必须',
'url.max' => '链接不能超过200个字符',
'url.url' => '链接不符合规则',
'status.required' => '状态选择错误',
'status.in' => '状态必须是显示/隐藏'
... ...
<?php
namespace App\Models\CustomerVisit;
use App\Models\Base;
class CustomerVisit extends Base
{
protected $table = 'gl_customer_visit';
}
... ...
<?php
namespace App\Models\CustomerVisit;
use App\Models\Base;
class CustomerVisitItem extends Base
{
protected $table = 'gl_customer_visit_item';
}
... ...
<?php
namespace App\Models\HomeCount;
use App\Models\Base;
class Count extends Base
{
protected $table = 'gl_count';
}
... ...
... ... @@ -4,6 +4,7 @@ namespace App\Models\Product;
use App\Models\Base;
use App\Models\RouteMap;
use App\Services\Facades\Upload;
use Illuminate\Database\Eloquent\SoftDeletes;
... ... @@ -14,12 +15,21 @@ class Category extends Base
//设置关联表名
protected $table = 'gl_product_category';
const STATUS_ACTIVE = 1;
/**
* 子分类
* @var array
*/
protected $child_ids_arr = [];
protected $appends = ['route'];
public function getRouteAttribute(){
return RouteMap::getRoute(RouteMap::SOURCE_PRODUCT_CATE, $this->id, $this->project_id);
}
public function getImageAttribute($value)
{
return Upload::path2url($value);
... ...
... ... @@ -22,6 +22,7 @@ class RouteMap extends Model
const SOURCE_PRODUCT = 'product';
const SOURCE_PRODUCT_CATE = 'product_category';
const SOURCE_PRODUCT_KEYWORD = 'product_keyword';
const SOURCE_PAGE = 'page'; //单页面
//路由类型
const SOURCE_BLOG = 'blog';
... ...
<?php
namespace App\Models\Visit;
use App\Models\Base;
/**
* Class Visit
* @package App\Models
* @author zbj
* @date 2023/5/22
*/
class Visit extends Base
{
//设置关联表名
protected $table = 'gl_customer_visit';
protected $appends = ['device_text'];
public static function deviceMap(){
return [
1 => 'PC',
2 => '移动端'
];
}
/**
* @return string
* @author zbj
* @date 2023/5/22
*/
public function getDeviceTextAttribute(){
return self::deviceMap()[$this->device_port] ?? '';
}
}
... ...
<?php
namespace App\Models\Visit;
use App\Models\Base;
/**
* Class VisitItem
* @package App\Models
* @author zbj
* @date 2023/5/22
*/
class VisitItem extends Base
{
//设置关联表名
protected $table = 'gl_customer_visit_item';
}
... ...
... ... @@ -6,9 +6,11 @@ use App\Models\Base;
class WebSetting extends Base
{
//锚文本常量配置在settingTextModel中
protected $table = 'gl_web_setting';
//连接数据库
// protected $connection = 'custom_mysql';
}
... ...
... ... @@ -6,7 +6,7 @@
use Illuminate\Support\Facades\Route;
//必须登录验证的路由组
Route::middleware(['bloginauth'])->group(function () {
Route::middleware(['bloginauth','accesstoken'])->group(function () {
//登录用户编辑个人资料
Route::any('/edit_info', [\App\Http\Controllers\Bside\ComController::class, 'edit_info'])->name('edit_info');
Route::any('/logout', [\App\Http\Controllers\Bside\ComController::class, 'logout'])->name('logout');
... ... @@ -262,6 +262,18 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/get_google_rank', [\App\Http\Controllers\Bside\RankDataController::class, 'get_google_rank'])->name('rank_data_get_google_rank');
});
//首页统计数据
Route::prefix('home')->group(function () {
Route::any('/count', [\App\Http\Controllers\Bside\HomeCount\CountController::class, 'count'])->name('home_count');
Route::any('/yesterday', [\App\Http\Controllers\Bside\HomeCount\CountController::class, 'yesterday'])->name('home_yesterday');
});
//访问数据
Route::prefix('visit')->group(function () {
Route::any('/', [\App\Http\Controllers\Bside\VisitController::class, 'index'])->name('visit_list');
Route::any('/item', [\App\Http\Controllers\Bside\VisitController::class, 'item'])->name('visit_item');
});
});
//无需登录验证的路由组
... ...