作者 张关杰

Merge branch 'develop' of http://47.244.231.31:8099/zhl/globalso-v6 into bate

@@ -39,7 +39,7 @@ class RankWeek extends BaseCommands @@ -39,7 +39,7 @@ class RankWeek extends BaseCommands
39 LogUtils::info('start rank_data_week:' . count($list)); 39 LogUtils::info('start rank_data_week:' . count($list));
40 foreach ($list as $project_id => $api_no) { 40 foreach ($list as $project_id => $api_no) {
41 $rankDataLogic = new RankDataLogic(); 41 $rankDataLogic = new RankDataLogic();
42 - $rankDataLogic->syncRankWeek($api_no); 42 + $rankDataLogic->syncRankWeek($api_no, true);
43 } 43 }
44 44
45 return true; 45 return true;
@@ -167,13 +167,25 @@ class UpdateSeoTdk extends Command @@ -167,13 +167,25 @@ class UpdateSeoTdk extends Command
167 $ai_commands = AiCommand::where('is_batch', 1)->select('key', 'scene', 'ai')->get()->toArray(); 167 $ai_commands = AiCommand::where('is_batch', 1)->select('key', 'scene', 'ai')->get()->toArray();
168 $ai_commands = Arr::setValueToKey($ai_commands, 'key'); 168 $ai_commands = Arr::setValueToKey($ai_commands, 'key');
169 foreach ($this->maps as $table => $map) { 169 foreach ($this->maps as $table => $map) {
170 - $update[$table] = ['total_page'=>0, 'title'=>0, 'keyword'=>0, 'des'=>0,'keyword_title'=>0,'keyword_content'=>0]; 170 + $total_page = DB::connection('custom_mysql')->table($table)->count();
  171 + $update[$table] = ['total_page'=>$total_page, 'title'=>0, 'keyword'=>0, 'des'=>0,'keyword_title'=>0,'keyword_content'=>0];
171 echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL; 172 echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL;
172 - $list = DB::connection('custom_mysql')->table($table)->select('id')->get(); 173 + $list = DB::connection('custom_mysql')->table($table)
  174 + ->where(function ($query) use ($table, $map){
  175 + if($table == 'gl_product'){
  176 + foreach ($map as $field){
  177 + $field_arr = explode('.', $field);
  178 + $query->orWhereRaw('JSON_EXTRACT('.$field_arr[0].', "$.'.$field_arr[1].'") IS NULL OR JSON_EXTRACT('.$field_arr[0].', "$.'.$field_arr[1].'") = ""');
  179 + }
  180 + }else{
  181 + foreach ($map as $field){
  182 + $query->orWhereRaw($field . " IS NULL OR ".$field." = ''");
  183 + }
  184 + }
  185 + })->select('id')->get();
173 if (!empty($list)) { 186 if (!empty($list)) {
174 $list = $list->toArray(); 187 $list = $list->toArray();
175 foreach ($list as $v) { 188 foreach ($list as $v) {
176 - $update[$table]['total_page']++;  
177 $v = (array)$v; 189 $v = (array)$v;
178 190
179 //缓存 在处理的项目数据 id 191 //缓存 在处理的项目数据 id
@@ -36,7 +36,11 @@ class UpdateSeoTdkCrontab extends Command @@ -36,7 +36,11 @@ class UpdateSeoTdkCrontab extends Command
36 { 36 {
37 $project_ids = Project::where('type', Project::TYPE_TWO)->pluck('id')->toArray(); 37 $project_ids = Project::where('type', Project::TYPE_TWO)->pluck('id')->toArray();
38 foreach ($project_ids as $project_id){ 38 foreach ($project_ids as $project_id){
39 - ProjectUpdateTdk::add_task($project_id); 39 + try {
  40 + ProjectUpdateTdk::add_task($project_id);
  41 + }catch (\Exception $e){
  42 +
  43 + }
40 } 44 }
41 } 45 }
42 46
@@ -61,7 +61,8 @@ class WebTrafficSpecial extends Command @@ -61,7 +61,8 @@ class WebTrafficSpecial extends Command
61 * @var array 61 * @var array
62 */ 62 */
63 protected $projects = [ 63 protected $projects = [
64 - 509 => 30 64 + 509 => 30,
  65 + 79 => 20,
65 ]; 66 ];
66 67
67 68
@@ -24,7 +24,7 @@ class Kernel extends ConsoleKernel @@ -24,7 +24,7 @@ class Kernel extends ConsoleKernel
24 $schedule->command('rank_data_external_links')->dailyAt('18:00')->withoutOverlapping(1); // 排名数据-外链,每周一凌晨执行一次 24 $schedule->command('rank_data_external_links')->dailyAt('18:00')->withoutOverlapping(1); // 排名数据-外链,每周一凌晨执行一次
25 $schedule->command('rank_data_indexed_pages')->dailyAt('07:30')->withoutOverlapping(1); // 排名数据-页面收录,每周一凌晨执行一次 25 $schedule->command('rank_data_indexed_pages')->dailyAt('07:30')->withoutOverlapping(1); // 排名数据-页面收录,每周一凌晨执行一次
26 $schedule->command('rank_data_recomm_domain')->dailyAt('07:40')->withoutOverlapping(1); // 排名数据-引荐域名,每周一凌晨执行一次 26 $schedule->command('rank_data_recomm_domain')->dailyAt('07:40')->withoutOverlapping(1); // 排名数据-引荐域名,每周一凌晨执行一次
27 - $schedule->command('rank_data_week')->dailyAt('08:30')->withoutOverlapping(1); // 排名数据,每周一凌晨执行一次 27 + $schedule->command('rank_data_week')->weeklyOn([1,2], '08:300')->withoutOverlapping(1); // 排名数据,每周一、二早上执行一次
28 // $schedule->command('share_user')->dailyAt('01:00')->withoutOverlapping(1); // 清除用户ayr_share数据,每天凌晨1点执行一次 28 // $schedule->command('share_user')->dailyAt('01:00')->withoutOverlapping(1); // 清除用户ayr_share数据,每天凌晨1点执行一次
29 // $schedule->command('count')->dailyAt('00:30')->withoutOverlapping(1); //每天凌晨1点执行一次 29 // $schedule->command('count')->dailyAt('00:30')->withoutOverlapping(1); //每天凌晨1点执行一次
30 $schedule->command('service_count')->dailyAt('01:00')->withoutOverlapping(1); //服务器使用情况,每天凌晨1点执行一次 30 $schedule->command('service_count')->dailyAt('01:00')->withoutOverlapping(1); //服务器使用情况,每天凌晨1点执行一次
@@ -43,7 +43,7 @@ class Kernel extends ConsoleKernel @@ -43,7 +43,7 @@ class Kernel extends ConsoleKernel
43 $schedule->command('domain_info')->dailyAt('01:20')->withoutOverlapping(1);// 更新域名|证书结束时间,每天凌晨1点执行一次 43 $schedule->command('domain_info')->dailyAt('01:20')->withoutOverlapping(1);// 更新域名|证书结束时间,每天凌晨1点执行一次
44 $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息 44 $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息
45 // $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新 45 // $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新
46 - $schedule->command('update_seo_tdk_crontab')->dailyAt('00:00')->withoutOverlapping(1); //更新上线项目TDK 46 + $schedule->command('update_seo_tdk_crontab')->dailyAt('20:00')->withoutOverlapping(1); //更新上线项目TDK
47 // $schedule->command('website_data')->dailyAt('01:00')->withoutOverlapping(1); // 向AICC推送数据 47 // $schedule->command('website_data')->dailyAt('01:00')->withoutOverlapping(1); // 向AICC推送数据
48 // $schedule->command('project_file_pdf')->dailyAt('00:00')->withoutOverlapping(1); // 网站项目数据,生成PDF文件 48 // $schedule->command('project_file_pdf')->dailyAt('00:00')->withoutOverlapping(1); // 网站项目数据,生成PDF文件
49 $schedule->command('sync_manager')->dailyAt('01:00')->withoutOverlapping(1); //TODO::手机号码同步 每天执行一次 49 $schedule->command('sync_manager')->dailyAt('01:00')->withoutOverlapping(1); //TODO::手机号码同步 每天执行一次
@@ -27,21 +27,21 @@ class QuanqiusouApi @@ -27,21 +27,21 @@ class QuanqiusouApi
27 */ 27 */
28 public function getSiteRes() 28 public function getSiteRes()
29 { 29 {
30 - $key = 'quanqiusou_api_site_res_' . date('Y-m-d');  
31 - $res = Cache::get($key);  
32 - if (!$res) { 30 +// $key = 'quanqiusou_api_site_res_' . date('Y-m-d');
  31 +// $res = Cache::get($key);
  32 +// if (!$res) {
33 $api_url = $this->url . '/google-rank/echo_site_res.php'; 33 $api_url = $this->url . '/google-rank/echo_site_res.php';
34 try { 34 try {
35 $res = HttpUtils::get($api_url, []); 35 $res = HttpUtils::get($api_url, []);
36 if($res){ 36 if($res){
37 $res = Arr::s2a($res); 37 $res = Arr::s2a($res);
38 - Cache::put($key, $res, 2 * 3600); 38 +// Cache::put($key, $res, 2 * 3600);
39 } 39 }
40 } catch (\Exception | GuzzleException $e) { 40 } catch (\Exception | GuzzleException $e) {
41 errorLog('获取站点收录页面数', [], $e); 41 errorLog('获取站点收录页面数', [], $e);
42 return false; 42 return false;
43 } 43 }
44 - } 44 +// }
45 return $res; 45 return $res;
46 } 46 }
47 47
@@ -10,10 +10,14 @@ @@ -10,10 +10,14 @@
10 namespace App\Http\Controllers\Aside\Com; 10 namespace App\Http\Controllers\Aside\Com;
11 11
12 12
  13 +use App\Enums\Common\Code;
13 use App\Http\Controllers\Aside\BaseController; 14 use App\Http\Controllers\Aside\BaseController;
14 use App\Models\Domain\DomainInfo; 15 use App\Models\Domain\DomainInfo;
  16 +use App\Models\Project\Country as CountryModel;
15 use App\Models\Project\DeployBuild; 17 use App\Models\Project\DeployBuild;
  18 +use App\Models\WebSetting\WebLanguage;
16 use Illuminate\Http\Request; 19 use Illuminate\Http\Request;
  20 +use Illuminate\Support\Facades\DB;
17 21
18 22
19 /** 23 /**
@@ -55,4 +59,23 @@ class CNoticeController extends BaseController @@ -55,4 +59,23 @@ class CNoticeController extends BaseController
55 $this->response('更新中请稍后, 更新完成将会发送站内信通知更新结果!'); 59 $this->response('更新中请稍后, 更新完成将会发送站内信通知更新结果!');
56 } 60 }
57 61
  62 + /**
  63 + * @remark :获取当前项目选中的语种
  64 + * @name :getCountry
  65 + * @author :lyh
  66 + * @method :post
  67 + * @time :2023/9/12 15:20
  68 + */
  69 + public function getCountry(){
  70 + $countryModel = new CountryModel();
  71 + $info = $countryModel->read(['project_id'=>$this->param['project_id']],['id','country_lists']);
  72 + $ids = [];
  73 + if($info !== false){
  74 + $ids = explode(',',$info['country_lists']);
  75 + }
  76 + $languageModel = new WebLanguage();
  77 + //根据排序查询选中的小语种
  78 + $lists = $languageModel->whereIn('id', $ids)->orderByRaw(DB::raw("FIND_IN_SET(id,'" . implode(',', $ids) . "'" . ')'))->get()->toArray();
  79 + $this->response('success',Code::SUCCESS,$lists);
  80 + }
58 } 81 }
@@ -40,7 +40,11 @@ class UpdateController extends BaseController @@ -40,7 +40,11 @@ class UpdateController extends BaseController
40 ], [ 40 ], [
41 'project_id.required' => 'project_id不能为空', 41 'project_id.required' => 'project_id不能为空',
42 ]); 42 ]);
43 - ProjectUpdateTdk::add_task($this->param['project_id']); 43 + try {
  44 + ProjectUpdateTdk::add_task($this->param['project_id']);
  45 + }catch (\Exception $e){
  46 + $this->fail($e->getMessage());
  47 + }
44 $this->response('任务添加成功'); 48 $this->response('任务添加成功');
45 } 49 }
46 50
@@ -4,6 +4,7 @@ namespace App\Http\Logic\Aside\Domain; @@ -4,6 +4,7 @@ namespace App\Http\Logic\Aside\Domain;
4 4
5 5
6 use App\Http\Logic\Aside\BaseLogic; 6 use App\Http\Logic\Aside\BaseLogic;
  7 +use App\Jobs\EditDomainBt;
7 use App\Models\Devops\ServerConfig; 8 use App\Models\Devops\ServerConfig;
8 use App\Models\Domain\DomainInfo; 9 use App\Models\Domain\DomainInfo;
9 use App\Models\Project\CountryCustom; 10 use App\Models\Project\CountryCustom;
@@ -302,12 +303,13 @@ class DomainInfoLogic extends BaseLogic @@ -302,12 +303,13 @@ class DomainInfoLogic extends BaseLogic
302 ]; 303 ];
303 $this->model->edit($data,['id'=>$this->param['id']]); 304 $this->model->edit($data,['id'=>$this->param['id']]);
304 //生成证书 305 //生成证书
305 - $this->setDomainSsl($server_info['init_domain'],$info['domain'],$this->param['extend_config'] ?? [],$this->param['other_domain'] ?? [],$this->param['is_https'] ?? 0); 306 + EditDomainBt::dispatch($this->param['id']);
  307 +// $this->setDomainSsl($server_info['init_domain'],$info['domain'],$this->param['extend_config'] ?? [],$this->param['other_domain'] ?? [],$this->param['is_https'] ?? 0);
306 308
307 //amp站点生成证书 309 //amp站点生成证书
308 - if($data['amp_status']){  
309 - $this->setAmpDomainSsl($server_info['init_domain'],$info['domain']);  
310 - } 310 +// if($data['amp_status']){
  311 +// $this->setAmpDomainSsl($server_info['init_domain'],$info['domain']);
  312 +// }
311 313
312 return $this->success(); 314 return $this->success();
313 } 315 }
@@ -47,18 +47,13 @@ class ProductLogic extends BaseLogic @@ -47,18 +47,13 @@ class ProductLogic extends BaseLogic
47 $this->param = $this->handleSaveParam($this->param); 47 $this->param = $this->handleSaveParam($this->param);
48 try { 48 try {
49 if(isset($this->param['id']) && !empty($this->param['id'])){ 49 if(isset($this->param['id']) && !empty($this->param['id'])){
50 - $seo_mate = (array)$this->model->read(['id'=>$this->param['id']],['seo_mate'])['seo_mate']; 50 +
51 $is_upgrade = $this->param['is_upgrade'] ?? 0;//1:5.0数据 0:6.0 51 $is_upgrade = $this->param['is_upgrade'] ?? 0;//1:5.0数据 0:6.0
52 $six_read = $this->param['six_read'] ?? 0;//是否按6.0显示 52 $six_read = $this->param['six_read'] ?? 0;//是否按6.0显示
53 if($is_upgrade == 0 || $six_read == 1){ 53 if($is_upgrade == 0 || $six_read == 1){
54 $this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_PRODUCT, $this->param['id'], $this->user['project_id']); 54 $this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_PRODUCT, $this->param['id'], $this->user['project_id']);
55 } 55 }
56 - if(!empty($seo_mate)){  
57 - $seo_mate['title'] = $this->param['title'] ?? '';  
58 - }  
59 - $this->param['seo_mate'] = json_encode($seo_mate,true);  
60 $route = $this->param['route']; 56 $route = $this->param['route'];
61 - @file_put_contents(storage_path('logs/lyh_error.log'), var_export($this->param, true) . PHP_EOL, FILE_APPEND);  
62 $this->model->edit($this->param,['id'=>$this->param['id']]); 57 $this->model->edit($this->param,['id'=>$this->param['id']]);
63 $id = $this->param['id']; 58 $id = $this->param['id'];
64 }else{ 59 }else{
  1 +<?php
  2 +
  3 +namespace App\Jobs;
  4 +
  5 +use App\Models\Devops\ServerConfig;
  6 +use App\Models\Domain\DomainInfo;
  7 +use App\Models\Project\Project;
  8 +use App\Utils\HttpUtils;
  9 +use GuzzleHttp\Exception\GuzzleException;
  10 +use Illuminate\Bus\Queueable;
  11 +use Illuminate\Contracts\Queue\ShouldQueue;
  12 +use Illuminate\Foundation\Bus\Dispatchable;
  13 +use Illuminate\Queue\InteractsWithQueue;
  14 +use Illuminate\Queue\SerializesModels;
  15 +
  16 +class EditDomainBt implements ShouldQueue
  17 +{
  18 + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  19 +
  20 + public $tries = 1; // 可配置任务重试次数
  21 +
  22 + protected $domain_id;
  23 +
  24 + /**
  25 + * Create a new job instance.
  26 + *
  27 + * @param $domain_id
  28 + */
  29 + public function __construct($domain_id)
  30 + {
  31 + $this->domain_id = $domain_id;
  32 + }
  33 +
  34 + /**
  35 + * Execute the job.
  36 + *
  37 + * @return bool
  38 + */
  39 + public function handle()
  40 + {
  41 + //获取域名数据
  42 + $domain_model = new DomainInfo();
  43 + $domain_info = $domain_model->read(['id' => $this->domain_id]);
  44 + if ($domain_info === false) {
  45 + return $this->output($domain_info['domain'] . ':获取域名数据失败');
  46 + }
  47 +
  48 + //获取项目数据
  49 + $project_model = new Project();
  50 + $project_info = $project_model->read(['id' => $domain_info['project_id']], 'serve_id');
  51 + if ($project_info === false) {
  52 + return $this->output($domain_info['domain'] . ':获取项目数据失败');
  53 + }
  54 +
  55 + //获取服务器数据
  56 + $server_model = new ServerConfig();
  57 + $server_info = $server_model->read(['id' => $project_info['serve_id']], ['init_domain', 'host']);
  58 + if ($server_info === false) {
  59 + return $this->output($domain_info['domain'] . ':获取服务器数据失败');
  60 + }
  61 +
  62 + //编辑主站
  63 + if ($domain_info['type'] == 2) {
  64 + $api_url = 'http://' . $server_info['init_domain'] . '/api/setSsl';
  65 + $api_param = [
  66 + 'domain' => $domain_info['domain'],
  67 + 'private_key' => $domain_info['private_key'],
  68 + 'cert' => $domain_info['private_cert'],
  69 + 'rewrite' => $domain_info['extend_config'],
  70 + 'other_domain' => $domain_info['other_domain'],
  71 + 'is_https' => $domain_info['is_https']
  72 + ];
  73 + } else {
  74 + $api_url = 'http://' . $server_info['init_domain'] . '/api/applySsl';
  75 + $api_param = [
  76 + 'domain' => $domain_info['domain'],
  77 + 'rewrite' => $domain_info['extend_config'],
  78 + 'other_domain' => $domain_info['other_domain'],
  79 + 'is_https' => $domain_info['is_https']
  80 + ];
  81 + }
  82 + try {
  83 + $rs = HttpUtils::get($api_url, $api_param);
  84 + $rs = json_decode($rs, true);
  85 + if (isset($rs['status']) && $rs['status'] == 200) {
  86 + $this->output($domain_info['domain'] . ':主站编辑成功');
  87 + } else {
  88 + $this->output($domain_info['domain'] . ':主站编辑失败,原因:' . ($rs['message'] ?? ''));
  89 + }
  90 + } catch (\Exception | GuzzleException $e) {
  91 + $this->output($domain_info['domain'] . ':主站编辑失败,原因:' . $e->getMessage());
  92 + }
  93 +
  94 + //编辑amp站
  95 + if ($domain_info['amp_status']) {
  96 + $api_url_amp = 'http://' . $server_info['init_domain'] . '/api/createSiteAmp';
  97 + $api_param_amp = [
  98 + 'domain' => $domain_info['domain'],
  99 + ];
  100 + if ($domain_info['amp_type'] == 2) {
  101 + $api_param_amp['private_key'] = $domain_info['amp_private_key'];
  102 + $api_param_amp['cert'] = $domain_info['amp_private_cert'];
  103 + }
  104 +
  105 + try {
  106 + $rs_amp = HttpUtils::get($api_url_amp, $api_param_amp);
  107 + $rs_amp = json_decode($rs_amp, true);
  108 + if (isset($rs_amp['status']) && $rs_amp['status'] == 200) {
  109 + $this->output($domain_info['domain'] . ':amp站编辑成功');
  110 + } else {
  111 + $this->output($domain_info['domain'] . ':amp站编辑失败,原因:' . ($rs_amp['message'] ?? ''));
  112 + }
  113 + } catch (\Exception | GuzzleException $e_amp) {
  114 + $this->output($domain_info['domain'] . ':amp站编辑失败,原因:' . $e_amp->getMessage());
  115 + }
  116 + }
  117 +
  118 + return true;
  119 + }
  120 +
  121 + /**
  122 + * 输出处理日志
  123 + * @param $message
  124 + * @return bool
  125 + */
  126 + public function output($message)
  127 + {
  128 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  129 + return true;
  130 + }
  131 +
  132 + public function failed(\Exception $exception)
  133 + {
  134 + return $this->output($exception->getMessage());
  135 + }
  136 +}
@@ -48,8 +48,8 @@ class QueryListener @@ -48,8 +48,8 @@ class QueryListener
48 $log = $log.' [ RunTime:'.$event->time.'ms ] '; 48 $log = $log.' [ RunTime:'.$event->time.'ms ] ';
49 Log::debug($log); 49 Log::debug($log);
50 } 50 }
51 - //监听9644这个api_no是TM咋个被改的  
52 - if (in_array(9644, $event->bindings) && Str::contains($event->sql, 'update') && Str::contains($event->sql, '`api_no` =')) { 51 + //监听api_no是TM咋个被改的
  52 + if (Str::contains($event->sql, 'update') && Str::contains($event->sql, '`api_no` =')) {
53 //记录debug 根据这个溯源 53 //记录debug 根据这个溯源
54 $trace = debug_backtrace(); 54 $trace = debug_backtrace();
55 $traces = []; 55 $traces = [];
@@ -27,14 +27,20 @@ class ProjectUpdateTdk extends Base @@ -27,14 +27,20 @@ class ProjectUpdateTdk extends Base
27 /** 27 /**
28 * 新建任务 28 * 新建任务
29 * @param $project_id 29 * @param $project_id
  30 + * @throws \Exception
30 * @author zbj 31 * @author zbj
31 * @date 2023/11/9 32 * @date 2023/11/9
32 */ 33 */
33 public static function add_task($project_id){ 34 public static function add_task($project_id){
34 - Redis::lpush('updateSeoTdk', $project_id); 35 + $task = self::where('project_id', $project_id)->where('status', self::STATUS_PENDING)->first();
  36 + if($task){
  37 + throw new \Exception('该项目有未执行的任务,请勿重复添加');
  38 + }
35 $model = new self(); 39 $model = new self();
36 $model->project_id = $project_id; 40 $model->project_id = $project_id;
37 $model->save(); 41 $model->save();
  42 +
  43 + Redis::lpush('updateSeoTdk', $project_id);
38 } 44 }
39 45
40 /** 46 /**
@@ -15,6 +15,7 @@ Route::middleware(['aloginauth'])->group(function () { @@ -15,6 +15,7 @@ Route::middleware(['aloginauth'])->group(function () {
15 Route::get('/logout', [Aside\LoginController::class, 'logout'])->name('admin.logout.white'); 15 Route::get('/logout', [Aside\LoginController::class, 'logout'])->name('admin.logout.white');
16 Route::any('/getAccessAddress', [Aside\LoginController::class, 'getAccessAddress'])->name('admin.getAccessAddress');//获取B端地址 16 Route::any('/getAccessAddress', [Aside\LoginController::class, 'getAccessAddress'])->name('admin.getAccessAddress');//获取B端地址
17 Route::get('/sendNotify', [Aside\Com\CNoticeController::class, 'sendNotify'])->name('admin.sendNotify'); 17 Route::get('/sendNotify', [Aside\Com\CNoticeController::class, 'sendNotify'])->name('admin.sendNotify');
  18 + Route::get('/getCountry', [Aside\Com\CNoticeController::class, 'getCountry'])->name('admin.getCountry');
18 19
19 //会员相关 20 //会员相关
20 Route::prefix('user')->group(function () { 21 Route::prefix('user')->group(function () {