Przeglądaj źródła

Merge branch 'refs/heads/master' into stable

moshaorui 13 godzin temu
rodzic
commit
5e12d5a613

+ 63 - 48
app/Console/Commands/TimerSsmPost.php

@@ -63,58 +63,70 @@ class TimerSsmPost extends Command
             $sendLog = SmmPostLog::getSendLog(5);
             $logIds = [];
             foreach ($sendLog as $log) {
-                Log::info('开始发送社媒帖子,id:'. $log->id);
-                echo '开始发送社媒帖子,id:'. $log->id. "\n";
-                if ($log->media_name == 'Twitter' && SmmPostLog::twitterCanSend() == false) {
-                    //15分钟内不重复发送
-                    Log::info('twitter可发送时间未到,暂时无法发送,ID'.$log->id);
-                    continue;
-                }
-                Log::info('开始发送社媒帖子,把状态改为发送中');
-                //发送社媒帖子中
-                $log->status = 1;//发送中
-                $log->request_count = $log->request_count + 1;
-                $log->remark = '';
-                $log->updated_at = Carbon::now();
-                $log->save();
-                //发送社媒帖子中 end
-
-                $logIds[] = $log->id;
-                //获取帖子内容
-                $post = SmmPost::getPostById($log->post_id);
-                $message = $post->message;
-                $imageVideoUrl = $post->image_video_url;
-                $mediaName = $log->media_name;
-                $postType = $post->post_type;
-                $accountInfo = SmmUserAccount::getAccountById($log->account_id);
-                $accessToken = $accountInfo->access_token;
-                //发送帖子
-                $configData = ['accountInfo' => $accountInfo->toArray(),'postData'=>$post->toArray()];
-                $ssmService = new SmmService($mediaName,$configData);
-                if ($postType == 0) {
-                    //图片帖子
-                    $imageVideoUrl = explode(',', $imageVideoUrl);
-                    foreach ($imageVideoUrl as $key => $url) {
-                        $imageVideoUrl[$key] = CommonHelper::ossUrl($url);
+                try {
+                    Log::info('开始发送社媒帖子,id:'. $log->id);
+                    echo '开始发送社媒帖子,id:'. $log->id. "\n";
+                    if ($log->media_name == 'Twitter' && SmmPostLog::twitterCanSend() == false) {
+                        //15分钟内不重复发送
+                        Log::info('twitter可发送时间未到,暂时无法发送,ID'.$log->id);
+                        continue;
                     }
-                    $response = $ssmService->postImage($message, $imageVideoUrl,$accessToken);
-                    Log::info('图片帖子返回'.json_encode($response));
-                } else {
-                    $imageVideoUrl = CommonHelper::ossUrl($imageVideoUrl);
-                    $response = $ssmService->postVideo($message, $imageVideoUrl,$accessToken);
-                    Log::info('视频帖子返回'.json_encode($response));
-                }
-                $responseIds = isset($response['data']['responseIds'])? $response['data']['responseIds'] : [];
-                //更新post_logs表
-                if ($response['status'] == true) {
-                    $log->status = 2;//发送成功
-                    $log->response_ids = json_encode($responseIds);
+                    Log::info('开始发送社媒帖子,把状态改为发送中');
+                    //发送社媒帖子中
+                    $log->status = 1;//发送中
+                    $log->request_count = $log->request_count + 1;
+                    $log->remark = '';
                     $log->updated_at = Carbon::now();
-                    $log->send_time = Carbon::now();
                     $log->save();
-                } else {
+                    //发送社媒帖子中 end
+                    $logIds[] = $log->id;
+                    //获取帖子内容
+                    $post = SmmPost::getPostById($log->post_id);
+                    $message = $post->message;
+                    $imageVideoUrl = $post->image_video_url;
+                    $mediaName = $log->media_name;
+                    $postType = $post->post_type;
+                    $accountInfo = SmmUserAccount::getAccountById($log->account_id);
+                    if (!$accountInfo) {
+                        Log::info('帐号不存在,id:'. $log->account_id);
+                        throw new \Exception('帐号不存在,id:'. $log->account_id);
+                    }
+                    $accessToken = $accountInfo->access_token;
+                    //发送帖子
+                    $configData = ['accountInfo' => $accountInfo->toArray(),'postData'=>$post->toArray()];
+                    $ssmService = new SmmService($mediaName,$configData);
+                    if ($postType == 0) {
+                        //图片帖子
+                        $imageVideoUrl = explode(',', $imageVideoUrl);
+                        foreach ($imageVideoUrl as $key => $url) {
+                            $imageVideoUrl[$key] = CommonHelper::ossUrl($url);
+                        }
+                        $response = $ssmService->postImage($message, $imageVideoUrl,$accessToken);
+                        Log::info('图片帖子返回'.json_encode($response));
+                    } else {
+                        $imageVideoUrl = CommonHelper::ossUrl($imageVideoUrl);
+                        $response = $ssmService->postVideo($message, $imageVideoUrl,$accessToken);
+                        Log::info('视频帖子返回'.json_encode($response));
+                    }
+                    $responseIds = isset($response['data']['responseIds'])? $response['data']['responseIds'] : [];
+                    //更新post_logs表
+                    if ($response['status'] == true) {
+                        $log->status = 2;//发送成功
+                        $log->response_ids = json_encode($responseIds);
+                        $log->updated_at = Carbon::now();
+                        $log->send_time = Carbon::now();
+                        $log->save();
+                    } else {
+                        $log->status = 3;//发送失败
+                        $log->remark = $response['data'];
+                        $log->updated_at = Carbon::now();
+                        $log->send_time = Carbon::now();
+                        $log->save();
+                    }
+                } catch (\Exception $e) {
+                    Log::info('foreach 发送社媒帖子失败:'.$e->getMessage());
                     $log->status = 3;//发送失败
-                    $log->remark = $response['data'];
+                    $log->remark = $e->getMessage();
                     $log->updated_at = Carbon::now();
                     $log->send_time = Carbon::now();
                     $log->save();
@@ -211,10 +223,13 @@ class TimerSsmPost extends Command
 
     public function ossUpload()
     {
+        //把上传时间大于10分钟,则把状态oss_upload改为0,重新上传
         $has = SmmPost::hasOssUploadingPost();
         if ($has == true) {
+            Log::info('hasOssUploadingPost: false');
             return false;
         }
+        Log::info('hasOssUploadingPost: true');
         // 发送社媒帖子
         $ossUploadPost = SmmPost::getOssUploadPost();
         $disk = $this->disk('oss');

+ 2 - 1
app/Distributor/Controllers/SmmPostLogController.php

@@ -33,7 +33,7 @@ class SmmPostLogController extends AdminController
     {
         return Grid::make(SmmPostLog::with(['post', 'account']), function (Grid $grid) {
             $grid->column('id')->sortable();
-            $grid->column('account.name', admin_trans_label('account_name'));
+            $grid->column('account_name', admin_trans_label('account_name'));
             $grid->column('media_name',admin_trans_label('media_name'));
             //$grid->column('post.message',admin_trans_label('post_message'))->width('30%');
             $grid->column('created_at');
@@ -55,6 +55,7 @@ class SmmPostLogController extends AdminController
             $grid->disableCreateButton();
             $grid->disableDeleteButton();
             $grid->disableEditButton();
+            $grid->model()->where('dist_id', getDistributorId())->orderBy('id', 'desc');
         });
     }
 

+ 6 - 6
app/Distributor/Repositories/SmmPostLog.php

@@ -58,12 +58,12 @@ class SmmPostLog extends EloquentRepository
             return [];
         }
         //找出是否有帖子正在上传到Oss如果有,则不发送
-        $ossUploadPost = SmmPost::getOssUploadPost();
-
-        if ($ossUploadPost->isNotEmpty())  {
-            Log::info('有帖子正在上传到oss,不发送帖子');
-            return [];
-        }
+//        $ossUploadPost = SmmPost::getOssUploadPost();
+//
+//        if ($ossUploadPost->isNotEmpty())  {
+//            Log::info('有帖子正在上传到oss,不发送帖子');
+//            return [];
+//        }
 
         //找出待发送与发送失败的日志,重试2次
         $result = $log->wherein('status', [0,3])->where('request_count', '<=', 2)->where('send_time', '<', Carbon::now())->limit($limit)->get();

+ 9 - 9
app/Services/Smm/FacebookService.php

@@ -25,16 +25,16 @@ class FacebookService implements SmmPlatformInterface
     public function login()
     {
         $permissions = [
-            'publish_video',
-            'pages_manage_cta',
-            'pages_show_list',
-            'business_management',
-            'pages_read_engagement',
-            'pages_manage_metadata',
-            'pages_read_user_content',
-            'pages_manage_ads',
+        //    'publish_video',
+        //    'pages_manage_cta',
+        //    'pages_show_list',
+        //    'business_management',
+//            'pages_read_engagement',
+//            'pages_manage_metadata',
+//            'pages_read_user_content',
+//            'pages_manage_ads',
             'pages_manage_posts',
-            'pages_manage_engagement',
+//            'pages_manage_engagement',
         ];
 
         $query = http_build_query([

+ 2 - 1
app/Services/Smm/InstagramService.php

@@ -40,7 +40,8 @@ class InstagramService implements SmmPlatformInterface
                 'force_authentication'=>1,
                 'client_id' => $this->clientId,
                 'redirect_uri' => $this->redirectUri,
-                'scope' => 'instagram_business_basic,instagram_business_manage_messages,instagram_business_manage_comments,instagram_business_content_publish,instagram_business_manage_insights',
+                //'scope' => 'instagram_business_basic,instagram_business_manage_messages,instagram_business_manage_comments,instagram_business_content_publish,instagram_business_manage_insights',
+                'scope' => 'instagram_business_manage_messages',
                 'response_type' => 'code',
             ]);
         return ['status'=>true, 'data' => ['url'=>$loginUrl]];

+ 3 - 1
app/Services/Smm/YoutubeService.php

@@ -31,7 +31,7 @@ class YoutubeService implements SmmPlatformInterface
         $this->client->setClientSecret(env('SSM_YOUTUBE_CLIENT_SECRET'));
         $this->client->setRedirectUri(env('DIST_SITE_URL').'/dist/callback/youtube');
         $this->client->setScopes([
-            Google_Service_YouTube::YOUTUBE_UPLOAD,
+        //    Google_Service_YouTube::YOUTUBE_UPLOAD,
             Google_Service_YouTube::YOUTUBE,
         //    Google_Service_YouTube::YOUTUBE_FORCE_SSL,
         //    Google_Service_YouTube::YOUTUBE_READONLY,
@@ -126,6 +126,8 @@ class YoutubeService implements SmmPlatformInterface
             $snippet->setDescription($snippetData['description']);
             $snippet->setTags($snippetData['tags']);//'test', 'api'
             $snippet->setCategoryId($snippetData['categoryId']); // 人物与博客
+
+            //$snippet->setChannelId('目标频道ID'); // 不加代码默认发到默认频道(主频道)
             // 设置视频状态
             $status = new Google_Service_YouTube_VideoStatus();
             $status->setPrivacyStatus('public'); // public, private, unlisted

+ 116 - 51
resources/views/welcome.blade.php

@@ -3,82 +3,147 @@
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Mietubl Marketing System</title>
+    <title>Mietubl Marketing System - Multi-platform Content Sync Solution</title>
     <style>
         :root {
-            --primary: #2c3e50;
-            --accent: #3498db;
+            --primary-color: #2A5CAA;
+            --secondary-color: #F0F4F8;
         }
+
         body {
+            font-family: 'Segoe UI', system-ui, sans-serif;
+            line-height: 1.6;
             margin: 0;
-            font-family: system-ui, -apple-system, sans-serif;
-            background: #f8f9fa;
+            padding: 0;
+            background-color: var(--secondary-color);
+        }
+
+        header {
+            background-color: var(--primary-color);
+            color: white;
+            padding: 2rem;
+            text-align: center;
+            position: relative;
+        }
+
+        .header-nav {
+            position: absolute;
+            top: 1rem;
+            right: 1rem;
+        }
+
+        .header-nav a {
+            color: white;
+            text-decoration: none;
+            margin-left: 1.5rem;
+        }
+
+        .container {
+            max-width: 1200px;
+            margin: 0 auto;
+            padding: 2rem;
         }
-        nav {
-            padding: 1rem 5vw;
+
+        .brand-section {
             display: flex;
-            justify-content: space-between;
             align-items: center;
-            background: #fff;
-            box-shadow: 0 2px 8px rgba(0,0,0,0.05);
+            gap: 2rem;
+            margin-bottom: 3rem;
         }
-        main {
-            padding: 2rem 5vw;
+
+        .brand-logo {
+            width: 120px;
+            height: 120px;
+            background-color: var(--primary-color);
+            border-radius: 16px;
         }
-        .grid {
-            display: grid;
-            gap: 1.5rem;
-            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
-            margin-top: 3rem;
+
+        .feature-section {
+            background-color: white;
+            padding: 2rem;
+            border-radius: 12px;
+            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
+            margin: 2rem 0;
         }
-        .card {
-            background: #fff;
+
+        .data-privacy {
+            background-color: #fff3cd;
             padding: 1.5rem;
             border-radius: 8px;
-            box-shadow: 0 2px 6px rgba(0,0,0,0.06);
+            margin: 2rem 0;
         }
-        h2, h3 { color: var(--primary); }
-        .nav-links a {
-            color: var(--accent);
-            text-decoration: none;
-            margin-left: 1.5rem;
-            font-weight: 500;
+
+        .platform-list {
+            display: grid;
+            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+            gap: 1rem;
+            margin: 2rem 0;
         }
-        .icon {
-            font-size: 1.8rem;
-            margin-bottom: 0.5rem;
+
+        .cta-button {
+            background-color: var(--primary-color);
+            color: white;
+            padding: 1rem 2rem;
+            border: none;
+            border-radius: 6px;
+            font-size: 1.1rem;
+            cursor: pointer;
+            transition: opacity 0.3s;
+        }
+
+        .cta-button:hover {
+            opacity: 0.9;
         }
     </style>
 </head>
 <body>
-<nav>
-    <h2>Mietubl Marketing System</h2>
-    <div class="nav-links">
+<header>
+    <nav class="header-nav">
         <a href="/dist">Login</a>
         <a href="privacy_policy.html" target="_blank">Privacy</a>
-    </div>
-</nav>
-
-<main>
-    <div class="grid">
-        <div class="card">
-            <div class="icon">📈</div>
-            <h3>Analytics</h3>
-            <p>Real-time in-depth data analysis.</p>
-        </div>
+    </nav>
+    <h1>Mietubl Marketing System</h1>
+    <p>Intelligent Content Distribution System</p>
+</header>
 
-        <div class="card">
-            <div class="icon">🎯</div>
-            <h3>AI Content</h3>
-            <p>Generate marketing materials with AI.</p>
+<main class="container">
+    <section class="brand-section">
+        <div>
+            <h2>About Mietubl</h2>
+            <p>An intelligent solution for modern digital marketing, empowering customer service teams with efficient content management</p>
         </div>
+    </section>
 
-        <div class="card">
-            <div class="icon">🛠️</div>
-            <h3>Platform</h3>
-            <p>Unified advertising across all channels and social media platforms.</p>
+    <section class="feature-section">
+        <h3>Core Features</h3>
+        <ul>
+            <li>📌 One-click publishing to major social platforms (Facebook, Twitter, Instagram, Yutube.)</li>
+            <li>⏱️ Scheduled posting & automated queue management</li>
+            <li>📊 Cross-platform analytics & performance tracking</li>
+        </ul>
+
+        <div class="platform-list">
+            <div>📱 Facebook</div>
+            <div>🐦 Twitter</div>
+            <div>📸 Instagram</div>
+            <div>💼 Yutube</div>
         </div>
-    </div>
+    </section>
+
+    <section class="data-privacy">
+        <h3>Data Usage Declaration</h3>
+        <p>To deliver core services, we require:</p>
+        <ul>
+            <li>🔑 Social media access: For content publishing and analytics</li>
+            <li>📝 Basic user info: For personalized service configuration</li>
+            <li>📈 Engagement data: To optimize recommendation algorithms</li>
+        </ul>
+        <p>All data is encrypted with AES-256 and stored in compliance with GDPR regulations. We never use your data for undisclosed purposes.</p>
+    </section>
 </main>
+
+<footer style="background-color: var(--primary-color); color: white; text-align: center; padding: 1rem; margin-top: 3rem;">
+    <p>© 2025 Mietubl Marketing System</p>
+</footer>
 </body>
 </html>