fly hace 5 años
padre
commit
2ccb31c9eb

+ 26 - 0
app/Http/Controllers/QuickApp/WelcomeController.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Controllers\QuickApp;
+
+use Illuminate\Http\Request;
+use App\Http\Controllers\Controller;
+use App\Modules\SendOrder\Services\SendOrderService;
+use Hashids;
+
+class WelcomeController extends Controller
+{
+    public function index(Request $request, string $send_order_id_encode)
+    {
+        $send_order_id = Hashids::decode($send_order_id_encode)[0];
+        $send_order = SendOrderService::getSendOrderStatic($send_order_id);
+        $quick_send_order = SendOrderService::getQuickAppSendOrderStatic($send_order_id);
+        if ($send_order && $quick_send_order) {
+            return view('qapp.welcome')->with([
+                'gzh_code' => $quick_send_order->child_gzh_name,
+                'gzh_name' => $quick_send_order->child_gzh_nickname,
+                'hash_bid' => Hashids::encode($send_order->book_id),
+                'cid' => $send_order->chapter_id,
+            ]);
+        }
+    }
+}

+ 1 - 4
app/Http/Routes/QuickApp/QuickAppRoutes.php

@@ -92,9 +92,6 @@ Route::group(['domain' => env('QUICKAPP_DOMAIN'), 'namespace' => 'App\Http\Contr
 Route::group(['domain' => env('QUICKAPP_PROMOTION_DOMAIN'), 'namespace' => 'App\Http\Controllers\QuickApp'], function () {
 
     //快应用派单链接格式
-    Route::get('qyun/{id}', function () {
-        dump('快应用推广链接');
-        dump($_GET);
-    })->where('id', '\d+');
+    Route::get('qyun/{id}', 'WelcomeController@index')->where('id', '\w+');
 
 });

+ 16 - 0
app/Modules/SendOrder/Models/QuickAppSendOrder.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Modules\SendOrder\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class QuickAppSendOrder extends Model
+{
+    protected $table = 'quickapp_send_orders';
+    protected $fillable = [
+        'send_order_id',
+        'child_send_order_id',
+        'child_gzh_nickname',
+        'child_gzh_name',
+    ];
+}

+ 44 - 20
app/Modules/SendOrder/Services/SendOrderService.php

@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Created by PhpStorm.
  * User: hp
@@ -8,14 +9,33 @@
 
 namespace App\Modules\SendOrder\Services;
 
+use App\Modules\BaseService;
+use App\Modules\SendOrder\Models\QuickAppSendOrder;
 use App\Modules\SendOrder\Models\SendOrder;
 use App\Modules\SendOrder\Models\SendOrderExtraStat;
 use App\Modules\Statistic\Services\WapVisitStatService;
 use DB;
 use Redis;
 
+/**
+ * 
+ * @method static \App\Modules\SendOrder\Models\SendOrder getSendOrderStatic(int $id) 根据ID获取派单信息
+ * @method static \App\Modules\SendOrder\Models\QuickAppSendOrder getQuickAppSendOrderStatic(int $send_order_id) 获取快应用派单信息
+ */
 class SendOrderService
 {
+    use BaseService;
+
+    public function getSendOrder(int $id)
+    {
+        return SendOrder::find($id);
+    }
+
+    public function getQuickAppSendOrder(int $send_order_id)
+    {
+        return QuickAppSendOrder::where('send_order_id', $send_order_id)->first();
+    }
+
     /**
      *  更新派单的备注
      * @param $id  派单id
@@ -61,9 +81,9 @@ class SendOrderService
      * @param $channel_type  派单渠道类型.(允许值: AUTHENTICATED, UNAUTHENTICATED)
      * @return mixed
      */
-    static function updateSendOrderInfo($id, $distribution_channel_id, $name, $pre_send_date, $channel_type, $cost, $promotion_type,$subscribe_chapter=[])
+    static function updateSendOrderInfo($id, $distribution_channel_id, $name, $pre_send_date, $channel_type, $cost, $promotion_type, $subscribe_chapter = [])
     {
-        return SendOrder::updateSendOrderInfo($id, $distribution_channel_id, $name, $pre_send_date, $channel_type, $cost, $promotion_type,$subscribe_chapter);
+        return SendOrder::updateSendOrderInfo($id, $distribution_channel_id, $name, $pre_send_date, $channel_type, $cost, $promotion_type, $subscribe_chapter);
     }
 
     /**
@@ -160,7 +180,7 @@ class SendOrderService
      */
     static function getSendOrders($bookId, $distribution_channel_id, $name = null, $bookName = null, $sendOrderId, $start_time = '', $end_time = '', $isAll = false)
     {
-        return SendOrder:: getSendOrders($bookId, $distribution_channel_id, $name, $bookName, $sendOrderId, $start_time, $end_time, $isAll);
+        return SendOrder::getSendOrders($bookId, $distribution_channel_id, $name, $bookName, $sendOrderId, $start_time, $end_time, $isAll);
     }
 
 
@@ -178,7 +198,7 @@ class SendOrderService
      */
     static function getManageSendOrders($params = [], $is_all = false)
     {
-        return SendOrder:: getManageSendOrders($params, $is_all);
+        return SendOrder::getManageSendOrders($params, $is_all);
     }
 
     /**
@@ -219,7 +239,8 @@ class SendOrderService
         //return (float)Redis::hget('send_order_pv_' . $id, 'total');
     }
 
-    static function getBrowserUvAndPv($id){
+    static function getBrowserUvAndPv($id)
+    {
         return WapVisitStatService::getBrowserSendOrderTotalPvAndUv($id);
     }
 
@@ -274,7 +295,7 @@ class SendOrderService
      */
     static function getRedirectUrlById($id)
     {
-        return SendOrder::where('id', $id)->select('redirect_url', 'book_id', 'send_time', 'distribution_channel_id', 'name','promotion_point','force_show_qrcode','promotion_type')->first();
+        return SendOrder::where('id', $id)->select('redirect_url', 'book_id', 'send_time', 'distribution_channel_id', 'name', 'promotion_point', 'force_show_qrcode', 'promotion_type')->first();
     }
 
     /**
@@ -295,8 +316,8 @@ class SendOrderService
         $uv = 0;
         $pv = 0;
         foreach ($send_orders as $send_order) {
-            $uv += (float)Redis::hget('send_order_uv_' . $send_order->id, $date);
-            $pv += (float)Redis::hget('send_order_pv_' . $send_order->id, $date);
+            $uv += (float) Redis::hget('send_order_uv_' . $send_order->id, $date);
+            $pv += (float) Redis::hget('send_order_pv_' . $send_order->id, $date);
         }
         return compact('uv', 'pv');
     }
@@ -317,7 +338,7 @@ class SendOrderService
      */
     static function getContinueTotalReadUv($send_order_id)
     {
-        return (float)Redis::hget('send_order:continue:' . $send_order_id, 'total');
+        return (float) Redis::hget('send_order:continue:' . $send_order_id, 'total');
     }
 
     /**
@@ -391,7 +412,7 @@ class SendOrderService
      */
     static function search($params, $isAll = false)
     {
-        return SendOrder:: search($params, $isAll);
+        return SendOrder::search($params, $isAll);
     }
 
     /*
@@ -450,30 +471,33 @@ class SendOrderService
         return SendOrderExtraStat::getBySendOrderId($send_order_id);
     }
 
-    static function getPeriodActualSendOrdersNum($channel_id,$start_time,$end_time) {
+    static function getPeriodActualSendOrdersNum($channel_id, $start_time, $end_time)
+    {
         return SendOrder::where([
-            ['distribution_channel_id','=',$channel_id],
-            ['send_time','>=',$start_time],
-            ['send_time','<=',$end_time],
+            ['distribution_channel_id', '=', $channel_id],
+            ['send_time', '>=', $start_time],
+            ['send_time', '<=', $end_time],
         ])->count();
     }
 
-    static function getCompanyPromotionBooks($company_id,$start_time,$end_time) {
+    static function getCompanyPromotionBooks($company_id, $start_time, $end_time)
+    {
         $res = DB::select("select * from (select bcs.bid,bcs.book_name,count(so.id) as promotion_times 
  from channel_users cu
  left join distribution_channels dc on dc.channel_user_id=cu.id
  left join send_orders so on so.distribution_channel_id=dc.id
  left join book_configs bcs on bcs.bid=so.book_id
- where cu.company_id=".$company_id." and so.book_id is not null and so.send_time between '".$start_time."' and '".$end_time."' 
+ where cu.company_id=" . $company_id . " and so.book_id is not null and so.send_time between '" . $start_time . "' and '" . $end_time . "' 
  group by so.book_id) tmp order by tmp.promotion_times desc");
         return $res;
     }
 
     //成本统计
-    static function getCostStats($distribution_channels) {
-        return SendOrder::whereIn('distribution_channel_id',$distribution_channels)
-            ->where('is_enable',1)
+    static function getCostStats($distribution_channels)
+    {
+        return SendOrder::whereIn('distribution_channel_id', $distribution_channels)
+            ->where('is_enable', 1)
             ->whereNotNull('send_time')
             ->sum('cost');
     }
-}
+}

+ 377 - 0
resources/views/qapp/welcome.blade.php

@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8" />
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta name="viewport" content="user-scalable=no" />
+  <meta name="viewport"
+    content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,viewport-fit=cover" />
+  <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js" type="text/javascript"></script>
+</head>
+
+<body>
+  <style>
+    html,
+    body,
+    p,
+    div,
+    section {
+      margin: 0;
+      padding: 0;
+    }
+
+    img {
+      width: 100%;
+      -webkit-tap-highlight-color: transparent;
+    }
+
+    a {
+      color: currentColor;
+      -webkit-tap-highlight-color: transparent;
+    }
+
+    .application-content {
+      padding: 12px;
+      max-width: 100%;
+      transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+    }
+
+    .application-content .content-wrap {
+      width: 100%;
+      margin-right: auto;
+      margin-left: auto;
+    }
+
+    .content-card {
+      border-radius: 5px;
+      max-width: 100%;
+      outline: none;
+      text-decoration: none;
+      transition-property: box-shadow, opacity;
+      box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
+        0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
+      padding: 16px;
+      font-size: 14px;
+      line-height: 20px;
+    }
+
+    .card-text {
+      text-align: center;
+    }
+
+    .card-text .wechat-title {
+      color: red;
+      font-weight: 700;
+      margin-bottom: 16px;
+      font-size: 18px;
+    }
+
+    .card-text .wechat-name {
+      color: teal;
+      font-weight: 700;
+      font-size: 24px;
+      line-height: 40px;
+      margin-bottom: 16px;
+    }
+
+    .card-text .wechat-step {
+      color: #000;
+      font-weight: 900;
+      font-size: 18px;
+      line-height: 24px;
+      margin-bottom: 16px;
+    }
+
+    .card-text .copy-text {
+      height: 28px;
+      min-width: 50px;
+      padding: 0 12px;
+      color: #009688;
+      caret-color: #009688;
+      border: 1px solid #009688;
+      background-color: #fff;
+      border-radius: 5px;
+      font-size: 20px;
+      margin: 0 auto 16px;
+      display: block;
+    }
+
+    .card-text .copy-button {
+      height: 36px;
+      min-width: 64px;
+      padding: 0 16px;
+      background-color: #ff5252;
+      border-radius: 5px;
+      border: 1px solid #ff5252;
+      color: #fff;
+      font-size: 20px;
+      line-height: 36px;
+      display: block;
+      margin: 0 auto 16px;
+      box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
+        0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
+    }
+
+    .toast-wrap {
+      position: fixed;
+      top: 50%;
+      left: 50%;
+      -webkit-transform: translate(-50%, -50%);
+      transform: translate(-50%, -50%);
+      padding: 5px 10px;
+      color: #fff;
+      font-size: 14px;
+      text-align: center;
+      background: rgba(0, 0, 0, 0.8);
+      border-radius: 4px;
+    }
+
+    .hw-guide {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      top: 0;
+      left: 0;
+      display: none;
+    }
+
+    .hw-guide img {
+      width: 100%;
+    }
+
+    .hw-guide .btn-know {
+      width: 180px;
+      height: 40px;
+      line-height: 40px;
+      text-align: center;
+      border: none;
+      outline: none;
+      background: linear-gradient(0deg,
+          rgba(255, 210, 0, 1),
+          rgba(255, 239, 75, 1));
+      border-radius: 10px;
+      text-align: center;
+      font-size: 14px;
+      font-family: PingFang-SC-Bold;
+      font-weight: bold;
+      color: rgba(255, 93, 123, 1);
+      position: absolute;
+      top: 62%;
+      left: 50%;
+      margin-left: -90px;
+    }
+
+    .open-gif {
+      position: absolute;
+      background: rgba(0, 0, 0, 0.5);
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+    }
+
+    .open-gif .open-conetent {
+      width: 53vw;
+      position: absolute;
+      height: 0;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      margin: auto;
+      background-color: #f7f5eb;
+      border-radius: 10px;
+      overflow: hidden;
+      text-align: center;
+    }
+
+    .open-gif .open-conetent img {
+      width: 36%;
+      display: inline-block;
+      margin-top: 12%;
+    }
+
+    .open-gif .open-conetent p {
+      margin-top: 8%;
+      font-size: 14px;
+    }
+  </style>
+  <div class="application-wrap">
+    <main class="application-content">
+      <div class="content-wrap" style="display: none;">
+        <div class="content-card">
+          <div class="card-text">
+            <p class="wechat-title">请认准官方唯一认证公众号:</p>
+            <p class="wechat-name">{{$gzh_name}}</p>
+            <p class="wechat-step">
+              打开微信 → 右上角+号 → 添加朋友 → 公众号
+            </p>
+            <button class="copy-text" type="button">
+              {{$gzh_code}}
+            </button>
+            <button type="button" class="copy-button" id="copy" data-clipboard-text="{{$gzh_code}}">
+              一键复制公众号
+            </button>
+            <img src="https://cdn-novel.iycdm.com/quickapp/static/1.gif" />
+          </div>
+        </div>
+      </div>
+    </main>
+    <div class="hw-guide">
+      <img src="https://cdn-novel.iycdm.com/quickapp/static/guide.jpg " />
+      <div class="btn-know">知道了</div>
+    </div>
+    <div class="open-gif">
+      <div class="open-conetent">
+        <img src="https://cdn-novel.iycdm.com/quickapp/static/gidf.gif" />
+        <p>正在打开快应用...</p>
+      </div>
+    </div>
+    <p class="toast-wrap" style="display: none"></p>
+  </div>
+  <script type="text/javascript" src="https://cdn-novel.iycdm.com/quickapp/static/clipboard.js" async="async"></script>
+  <script type="text/javascript" src="https://statres.quickapp.cn/quickapp/js/routerinline.min.js"></script>
+  <script type="text/javascript">
+    //获取url参数
+    function getQueryString(name) {
+      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
+      var r = decodeURIComponent(window.location.search)
+        .substr(1)
+        .match(reg);
+      if (r != null) return unescape(r[2]);
+      return null;
+    }
+    //没有打开快应用注册h5事件及其方法
+    var wePage = {
+      showToast: function (text) {
+        $(".toast-wrap")
+          .text(text)
+          .show();
+        setTimeout(function () {
+          $(".toast-wrap").hide();
+        }, 2000);
+      },
+      lisen: function () {
+        var _self = this;
+        $(".copy-button").on("click", function () {
+          var clip = new ClipboardJS("#copy");
+          clip.on("success", function (e) {
+            _self.showToast("复制成功");
+          });
+
+          clip.on("error", function (e) {
+            _self.showToast("复制失败");
+          });
+        });
+      },
+      init: function () {
+        this.lisen();
+      }
+    };
+    //全局变量
+    var glob = {
+      ua: window.navigator.userAgent.toLocaleLowerCase(),
+      isHuaWei: /huawei|honor/.test(window.navigator.userAgent.toLowerCase()),
+      isOpenApp: false,
+      obAvailable: false //机型是否支持快应用
+    };
+
+    //快应用配置
+    var QYY = {
+      isWx: /micromessenger/.test(glob.ua), //是否微信环境
+      isIos: /iphone|ipod|ipad/.test(glob.ua), //是否是ios
+      entry: "Reader", //拉起快应用阅读器页面
+      packName: "com.beidao.kuaiying.zsy", //快应用包名
+      bid: "{{$hash_bid}}", //书籍id
+      cid: "{{$cid}}" //章节id
+    };
+    //判断机型是否支持快应用
+    try {
+      channelReady(function (bAvailable) {
+        glob.obAvailable = bAvailable;
+      });
+    } catch (e) {
+      glob.obAvailable = false;
+    }
+    //显示公众号落地页
+    function showH5Page() {
+      wePage.init();
+      var time = QYY.isIos ? 0 : 5000;
+      setTimeout(function () {
+        $(".content-wrap").show();
+        showPop(false);
+      }, time);
+    }
+    //是否显示拉起快应用弹窗
+    function showPop(show) {
+      if (show) {
+        $(".open-gif").show();
+      } else {
+        $(".open-gif").hide();
+      }
+    }
+    //打开快应用逻辑
+    function openQyy() {
+      var parmas = {
+        bid: QYY.bid,
+        chapter_id: QYY.cid
+      };
+      try {
+        //尝试直接拉起
+        appRouter(QYY.packName, "/" + QYY.entry, parmas);
+      } catch (e) {
+        //唤醒失败 尝试url sheme唤醒
+        routerAHap(parmas);
+      }
+    }
+    //URL唤醒快应用
+    function routerAHap(data) {
+      var parmas = $.param(data);
+      var ohapa = document.createElement("a");
+      ohapa.href = "hap://app/" + QYY.pname + "/" + QYY.entry + "?" + parmas;
+      ohapa.setAttribute(
+        "style",
+        "position: absolute;left: -1000rem;height: 1rem;width: 1rem;overflow: hidden"
+      );
+      document.body.appendChild(ohapa);
+      ohapa.click();
+    }
+    //初始化
+    function startDeep() {
+      showH5Page();
+      !QYY.isIos && openQyy();
+    }
+    //华为h5流程
+    var hwPage = {
+      init: function () {
+        this.lisen();
+        $(".hw-guide").css("height", $(".hw-guide").width() * 1.778);
+        $(".hw-guide").show();
+      },
+      lisen: function () {
+        $(".btn-know").on("click", function () {
+          $(".hw-guide").hide();
+          showPop(true);
+          startDeep();
+        });
+      }
+    };
+    $(function () {
+      //页面流程开始
+      //处理弹出框的高度
+      $(".open-conetent").height($(".open-conetent").width() * 0.75);
+      //华为手机显示提示页
+      if (glob.isHuaWei) {
+        setTimeout(function () {
+          hwPage.init();
+          showPop(false);
+        }, 3000);
+      } else {
+        startDeep();
+      }
+    });
+  </script>
+</body>
+
+</html>