作者 刘锟

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

... ... @@ -25,7 +25,7 @@ class CountDate extends Command
*
* @var string
*/
protected $signature = 'count_data';
protected $signature = 'count_data {date}';
/**
* The console command description.
... ... @@ -42,6 +42,7 @@ class CountDate extends Command
*/
public function handle()
{
$date = $this->argument('date');
$list = DB::table('gl_project')->where('gl_project.extend_type','=',0)
->whereIn('gl_project.type',[1,2,3,4,6])
->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id')
... ... @@ -51,7 +52,7 @@ class CountDate extends Command
if(!empty($list)){
$list = $list->toArray();
// $yesterday = Carbon::yesterday()->toDateString();
$yesterday = '2024-08-31 00:00:00';
$yesterday = $date;
$domainInfo = new DomainInfo();
foreach ($list as $v){
$v = (array)$v;
... ...
<?php
/**
* @remark :
* @name :CountProject.php
* @author :lyh
* @method :post
* @time :2024/1/8 9:03
*/
namespace App\Console\Commands\MonthlyCount;
use App\Helper\FormGlobalsoApi;
use App\Models\Com\UpdateOldInfo;
use App\Models\Domain\DomainInfo;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Project\Project;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Models\HomeCount\MonthCount AS MonthCountModel;
class MonthCountDate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'month_counts_date {date}';
/**
* The console command description.
*
* @var string
*/
protected $description = '每天生成月统计记录';
public function handle(){
$list = DB::table('gl_project')->where('gl_project.extend_type','=',0)
->whereIn('gl_project.type',[1,2,3,4,6])
->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id')
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->select($this->selectParam())->get()->toArray();
foreach ($list as $v) {
$v = (array)$v;
if($v['type'] == Project::TYPE_ZERO){
continue;
}
if($v['is_upgrade'] == 1){
$oldModel = new UpdateOldInfo();
$info = $oldModel->read(['project_id' => $v['id']]);
if ($info !== false) {
$url = $info['old_domain_online'];
}else{
continue;
}
}else{
$domainInfo = new DomainInfo();
if(!empty($v['domain'])){
$info = $domainInfo->read(['id'=>$v['domain']]);
if($info !== false){
$url = $info['domain'];
}
}else{
$url = $v['test_domain'];
}
}
ProjectServer::useProject($v['id']);
echo date('Y-m-d H:i:s') . '项目id:'.$v['id'] . PHP_EOL;
$this->count($v['id'], $url);
DB::disconnect('custom_mysql');
}
}
/**
* @name :(查询参数设置)selectParam
* @author :lyh
* @method :post
* @time :2023/6/14 15:00
*/
public function selectParam(){
$select = [
'gl_project.id AS id',
'gl_project.type AS type',
'gl_project.extend_type AS extend_type',
'gl_project_deploy_build.test_domain AS test_domain',
'gl_project.is_upgrade AS is_upgrade',
'gl_project_deploy_optimize.domain AS domain',
'gl_project_deploy_build.project_id AS project_id',
'gl_project.cooperate_date AS cooperate_date',
'gl_project_deploy_build.service_duration AS service_duration',
];
return $select;
}
/**
* @remark :日统计记录
* @name :count
* @author :lyh
* @method :post
* @time :2024/1/8 9:05
*/
public function count($project_id,$url){
$arr = [];
$date = $this->argument('date');
$v = ['month'=>$date];
$monthCountModel = new MonthCountModel();
$info = $monthCountModel->read(['month'=>$v['month'],'project_id'=>$project_id]);
// 获取当月开始时间
$start = date('Y-m-01', strtotime($v['month']));
// 获取当月结束时间
$end = date('Y-m-t', strtotime($v['month']));
$arr['project_id'] = $project_id;
$res = (new FormGlobalsoApi())->getMonthInquiry($url,$v['month']);
$arr['total'] = $arr['month_total'] = 0;
if(isset($res['data']['count'])){
echo date('Y-m-d H:i:s') . '数据:'.$res['data']['count'] . PHP_EOL;
$arr['month_total'] = $res['data']['count'] + InquiryFormData::getCount([$start.' 00:00:00',$end.' 00:00:00']);
}
//获取上一个的count
$previousMonth = date('Y-m', strtotime($v['month'] . ' -1 month'));
$previousInfo = $monthCountModel->read(['month'=>$previousMonth,'project_id'=>$project_id]);
if($previousInfo === false){
$arr['total'] = $arr['month_total'];
}else{
$arr['total'] = $arr['month_total'] + ($previousInfo['total'] ?? 0);
}
$country = [];
if(isset($res['data']['data'])){
$country = $res['data']['data'];
}
$countryData = InquiryFormData::getCountryCount([$start.' 00:00:00',$end.' 00:00:00']);
foreach ($countryData as $v1){
if(isset($country[$v1['country']])){
$country[$v1['country']] += $v1['count'];
}else{
$country[$v1['country']] = $v1['count'];
}
}
$arr['country'] = json_encode($country);
$arr['month'] = $v['month'];
$arr = $this->pv_ip($arr,$start,$end,$project_id);
$arr = $this->sourceCount($arr,$start,$end);
if($info === false){
$selectedDate = $start;
$firstDayOfNextMonth = date('Y-m-01 01:00:00', strtotime("$selectedDate +1 month"));
$arr['created_at'] = $firstDayOfNextMonth;
$arr['updated_at'] = $firstDayOfNextMonth;
$monthCountModel->insert($arr);
}else{
$monthCountModel->edit($arr,['id'=>$info['id']]);
}
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
}
/**
* @remark :本月询盘总量
* @name :month_total
* @author :lyh
* @method :post
* @time :2024/1/8 11:02
*/
public function pv_ip(&$arr,$start,$end,$project_id){
$pv_ip = DB::table('gl_count')
->where(['project_id'=>$project_id])
->where('date','>=',$start.' 00:00:00')
->where('date','<=',$end.' 23:59:59')
->select(DB::raw('SUM(pv_num) as pv_num'), DB::raw('SUM(ip_num) as ip_num'),DB::raw('SUM(inquiry_num) as inquiry_num'))
->first();
$arr['pv'] = $pv_ip->pv_num;
$arr['ip'] = $pv_ip->ip_num;
if($arr['ip'] != 0){
$arr['rate'] = round((($arr['month_total'] ?? 0) / $arr['ip']) * 10,2);
}
return $arr;
}
/**
* @remark :来源访问前8
* @name :sourceCount
* @author :lyh
* @method :post
* @time :2023/6/30 16:14
*/
public function sourceCount(&$arr,$startTime,$endTime){
//访问来源前10
$source = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('referrer_url', DB::raw('COUNT(*) as count'))
->groupBy('referrer_url')
->whereBetween('updated_date', [$startTime,$endTime])
->orderByDesc('count')->limit(10)->get()->toArray();
$arr['source'] = json_encode($source);
//访问国家前15
$source_country = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('country',DB::raw('COUNT(*) as ip'),DB::raw('SUM(depth) as pv'))
->groupBy('country')
->whereBetween('updated_date', [$startTime,$endTime])
->orderBy('ip','desc')->limit(15)->get()->toArray();
$arr['source_country'] = json_encode($source_country);
//受访界面前15
$referrer_url = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('url',DB::raw('COUNT(*) as num'))
->orderBy('num','desc')
->whereBetween('updated_date', [$startTime,$endTime])
->groupBy('url')
->limit(15)->get()->toArray();
$arr['referrer_url'] = json_encode($referrer_url);
//访问端口
$referrer_port = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('device_port',DB::raw('COUNT(*) as num'))
->orderBy('num','desc')
->whereBetween('updated_date', [$startTime,$endTime])
->groupBy('device_port')
->limit(15)->get()->toArray();
$arr['referrer_port'] = json_encode($referrer_port);
return $arr;
}
}
... ...
<?php
namespace App\Console\Commands\Task;
use App\Mail\TextMail;
use App\Models\Subscribe\GroupSendTask;
use App\Models\Subscribe\GroupSendTaskLog;
use App\Models\Subscribe\Smtp;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
/**
*
* Class TaskDistribution
* @package App\Console\Commands
* @author zbj
* @date 2023/11/28
*/
class EmailGroupSend extends Command
{
protected $signature = 'email_group_send_task';
protected $description = '邮件群发任务';
public function handle()
{
while (true) {
$tasks = GroupSendTask::where('status', GroupSendTask::STATUS_PENDING)->where('send_time', '<=', time())->get();
if (!$tasks->count()) {
sleep(10);
}
foreach ($tasks as $task) {
$this->toQueue($task);
}
}
}
public function toQueue(GroupSendTask $task)
{
$this->output('开始执行任务:' . $task->id);
$smtp_config = Smtp::where('project_id', $task->project_id)->first();
if (!$smtp_config) {
$task->status = GroupSendTask::STATUS_ERROR;
$task->remark = '未配置SMTP';
$task->save();
$this->output('任务:' . $task->id . '失败,未配置SMTP');
return false;
}
Config::set('mail.mailers.smtp.host', $smtp_config['host']);
Config::set('mail.mailers.smtp.username', $smtp_config['email']);
Config::set('mail.mailers.smtp.password', $smtp_config['password']);
Config::set('mail.from.address', $smtp_config['email']);
Config::set('mail.from.name', $smtp_config['from_name']);
foreach ($task->emails as $email) {
try {
Mail::to([$email])->send(new TextMail(['subject' => $task->subject, 'text' => $task->text]));
GroupSendTaskLog::addLog($task->id, $task->project_id, $smtp_config['email'], $email);
} catch (\Exception $e) {
GroupSendTaskLog::addLog($task->id, $task->project_id, $smtp_config['email'], $email, 2, $e->getMessage());
$this->output('任务:' . $task->id . ' 邮箱' . $email . '发送失败,' . $e->getMessage());
}
}
$task->status = GroupSendTask::STATUS_SUCCESS;
$task->save();
}
/**
* 输出处理日志
*/
public function output($message): bool
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
return true;
}
}
... ...
... ... @@ -15,6 +15,7 @@ use App\Models\RouteMap\RouteMap;
use App\Models\User\ProjectMenu as ProjectMenuModel;
use App\Models\User\ProjectRole as ProjectRoleModel;
use App\Models\User\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
/***
... ... @@ -109,6 +110,10 @@ class ComController extends BaseController
if($projectCode != 1){
$info['role_menu'] = trim(str_replace(',50,',',',','.$info['role_menu'].','),',');
}
$is_subscribe = $this->getIsSubscribe();
if(!$is_subscribe){
$info['role_menu'] = trim(str_replace(',52,',',',','.$info['role_menu'].','),',');
}
$this->map = [
'status'=>0,
'is_role'=>0,
... ... @@ -217,6 +222,11 @@ class ComController extends BaseController
return 0;
}
public function getIsSubscribe(){
return $this->project['is_subscribe'];
}
/**
* @name :登录用户编辑资料/修改密码
* @author :liyuhang
... ...
... ... @@ -26,6 +26,7 @@ class BaseController extends Controller
protected $map = [];//处理后的参数
protected $uid = 0;
protected $user = [];//当前登录用户详情
protected $project = [];//当前登录项目详情
/**
* ceshi获取所有参数
*/
... ...
<?php
namespace App\Http\Controllers\Bside\Subscribe;
use App\Enums\Common\Code;
use App\Helper\Arr;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Inquiry\InquiryLogic;
use App\Models\Inquiry\InquiryForm;
use App\Models\Subscribe\Email;
use App\Models\Subscribe\GroupSendTask;
use App\Models\Subscribe\Smtp;
use App\Rules\Ids;
use App\Services\BatchExportService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
/**
* 订阅邮件管理
* Class EmailController
* @package App\Http\Controllers\Bside\Subscribe
* @author zbj
* @date 2024/8/29
*/
class EmailController extends BaseController
{
public function list(Email $emailModel)
{
$lists = $emailModel->lists($this->map, $this->page, $this->row);
$this->response('success', Code::SUCCESS, $lists);
}
public function delete(Email $emailModel)
{
$this->request->validate([
'id' => 'required',
], [
'id.required' => 'id不为空',
]);
$emailModel->del(['id' => $this->param['id']]);
$this->response('success');
}
public function export(Email $emailModel)
{
$data = $emailModel->list([], 'id', ['*'], 'desc', 1000);
//生成文件,发送到客户端
$map = [
'email' => '邮箱',
'created_at' => '订阅时间',
];
$table = new BatchExportService("订阅邮箱导出");
$file = $table->head($map)->data($data)->save();
if (!$file) {
throw new \Exception('文件生成失败,请重试');
}
$fileurl = Storage::disk('runtime')->url($file);
$this->response('success', Code::SUCCESS, ['url' => $fileurl]);
}
public function set_smtp(Smtp $smtp)
{
$this->request->validate([
'project_id' => ['required'],
'email' => ['required', 'email', 'max:200'],
'password' => ['required', 'max:200'],
'host' => ['required', 'max:200', 'regex:/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/'],
'from_name' => ['required', 'max:200'],
], [
'project_id.required' => '参数异常',
'email.required' => '邮箱必须',
'email.email' => '邮箱格式错误',
'password.required' => '授权码/密码必须',
'host.required' => 'smtp地址必须',
'host.regex' => 'smtp格式错误',
'from_name.required' => '发信人昵称必须',
]);
$info = $smtp->read(['project_id' => $this->param['project_id']]);
if (!$info) {
$smtp->add($this->param);
} else {
$smtp->edit($this->param, ['project_id' => $this->param['project_id']]);
}
$this->response('success');
}
public function group_send(GroupSendTask $groupSendTask)
{
$this->request->validate([
'project_id' => ['required'],
'emails' => ['required'],
'subject' => ['required'],
'text' => ['required'],
], [
'project_id.required' => '参数异常',
'emails.required' => '发送对象必须',
'subject.required' => '邮件主题必须',
'host.required' => 'smtp地址必须',
]);
if($this->param['send_time'] && !strtotime($this->param['send_time'])){
$this->fail('发送时间格式错误',Code::USER_ERROR);
}
$smtp = new Smtp();
$info = $smtp->read(['project_id' => $this->param['project_id']]);
if(!$info){
$this->fail('请先设置SMTP',Code::USER_ERROR);
}
$this->param['emails'] = Arr::a2s($this->param['emails']);
$this->param['send_time'] = empty($this->param['send_time']) ? 0 : strtotime($this->param['send_time']);
$this->param['user_id'] = $this->user['id'];
$groupSendTask->add($this->param);
$this->response('success');
}
}
... ...
... ... @@ -191,6 +191,7 @@ class UserLoginLogic
}
$info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority'];
$info['is_inquiry_country'] = $project['is_inquiry_country'];
$info['is_subscribe'] = $project['is_subscribe'];
//是否开通AMP
$is_amp = 0;
if(!empty($project['deploy_optimize']['domain'])){
... ... @@ -299,6 +300,7 @@ class UserLoginLogic
}
$info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority'];
$info['is_inquiry_country'] = $project['is_inquiry_country'];
$info['is_subscribe'] = $project['is_subscribe'];
//是否开通AMP
$is_amp = 0;
if(!empty($project['deploy_optimize']['domain'])){
... ...
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class TextMail extends Mailable
{
use Queueable, SerializesModels;
protected string $text;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($data)
{
$this->subject = $data['subject'];
$this->text = $data['text'];
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject($this->subject)->view('mail.text', ['text' => $this->text]);
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Email
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class Email extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $connection = "custom_mysql";
protected $table = 'gl_subscribe_email';
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Helper\Arr;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class GroupSendTask
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class GroupSendTask extends Base
{
use SoftDeletes;
const STATUS_PENDING = 0;
const STATUS_QUEUE = 1;
const STATUS_SUCCESS = 2;
const STATUS_ERROR = 9;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_group_send_task';
// public function setEmailsAttribute($value){
// $this->attributes['emails'] = Arr::a2s($value);
// }
public function getEmailsAttribute($value){
return Arr::s2a($value);
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class GroupSendTaskLog
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class GroupSendTaskLog extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_group_send_task_log';
//`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
// `task_id` int(11) unsigned NOT NULL DEFAULT '0',
// `project_id` int(11) unsigned NOT NULL DEFAULT '0',
// `from` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
// `to` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
// `status` tinyint(1) unsigned NOT NULL DEFAULT '0',
// `manage_id` int(11) unsigned NOT NULL DEFAULT '0',
// `created_at` datetime NOT NULL,
// `updated_at` datetime NOT NULL,
// `deleted_at` datetime DEFAULT NULL,
// `remark` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
public static function addLog($task_id, $project_id, $from, $to, $status = 1, $remark = '')
{
$model = new self();
$model->task_id = $task_id;
$model->project_id = $project_id;
$model->from = $from;
$model->to = $to;
$model->status = $status;
$model->remark = $remark;
$model->save();
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Smtp
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class Smtp extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_smtp';
}
... ...
... ... @@ -8,8 +8,10 @@ use App\Models\Inquiry\InquiryForm;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Project\InquiryFilterConfig;
use App\Models\Project\Project;
use App\Models\Subscribe\Email;
use App\Models\SyncSubmitTask\SyncSubmitTask;
use App\Models\Visit\Visit;
use App\Utils\LogUtils;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
... ... @@ -52,6 +54,20 @@ class SyncSubmitTaskService
}
$action = $task['type'];
//是否是订阅邮箱
if($action == 'inquiry' && !empty($project['is_subscribe'])){
//是否只有email字段
$filed = '';
foreach ($data['data']['data'] as $k => $v){
if(Str::startsWith(strtolower($k),'globalso-')){
continue;
}
$filed .= $k;
}
$filed == 'email' && $action = 'subscribe';
}
$handler = new self();
return $handler->$action($data, $date);
}
... ... @@ -75,7 +91,25 @@ class SyncSubmitTaskService
return $referer;
}
/**
*
* 订阅邮箱
* @param $data
* @param $date
* @throws InquiryFilterException
* @author zbj
* @date 2024/8/27
*/
public function subscribe($data, $date){
$email = $data['data']['data']['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$model = new Email();
$model->email = $email;
$model->save();
}else{
throw new InquiryFilterException( '邮箱格式异常:' . $email);
}
}
/**
* 询盘
... ... @@ -87,7 +121,6 @@ class SyncSubmitTaskService
*/
public function inquiry($data, $date)
{
$this->inquiryFilter($data['project_id'], $data);
//数组key转为小写
... ...
... ... @@ -608,6 +608,15 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/getInfo', [\App\Http\Controllers\Bside\BCom\OperationHeartbeatController::class, 'getInfo'])->name('operation_heartbeat_getInfo');
});
//订阅邮件管理
Route::prefix('subscribe')->group(function () {
Route::any('/', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'list'])->name('subscribe_email_list');
Route::any('/del', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'delete'])->name('subscribe_email_del');
Route::any('/export', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'export'])->name('subscribe_email_export');
Route::any('/set_smtp', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'set_smtp'])->name('subscribe_email_set_smtp');
Route::any('/group_send', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'group_send'])->name('subscribe_email_group_send');
});
});
//无需登录验证的路由组
Route::group([], function () {
... ...