<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 登錄 先看效果: ![2015-07-03/5595db3b5f057](http://box.kancloud.cn/2015-07-03_5595db3b5f057.png) 后臺的權限比較大,什么資源都能管。 有的時候,為了安全考慮 很多產品把后臺設計的很復雜。比方說,密碼復雜度、驗證碼、錯誤幾次輸入密碼后,鎖死賬號、子管理員賬號不同權限等。 為了簡單的實現安全,我后臺干脆不用表存管理員賬號,配置中寫死。這樣就不存在說注入的問題。也不會實現多管理員登錄。然后密碼弄稍微復雜的自己能記憶的密碼。 賬號:freelog 密碼:jay2015 寫在admin模塊配置注釋里防止忘了。 由于登錄頁沒有導航這樣公共的模塊,所以所有模板代碼直接寫在一個html里。 我們看下代碼: ~~~ <!DOCTYPE HTML> <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta name="renderer" content="webkit"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>{:C('WEB_SITE_TITLE')}</title> <script type="text/javascript" src="__BOWER__/jquery/dist/jquery.js"></script> <!--[if lt IE 9]> <script src="__STATIC__/html5shiv.js"></script> <script src="__STATIC__/respond.js"></script> <![endif]--> <script type="text/javascript" src="__BOWER__/bootstrap/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> var url = ''; </script> <script type="text/javascript" src="__JS__/admin.js"></script> <link rel="stylesheet" type="text/css" href="__BOWER__/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="__CSS__/admin_custom.css"> </head> <body> <!--[if lt IE 8]> <div class="browsehappy">當前網頁 <strong>不支持</strong> 你正在使用的瀏覽器. 為了正常的訪問, 請 <a href="http://browsehappy.com/">升級你的瀏覽器</a>.</div> <![endif]--> <div class="container-fluid"> <div class="row-fluid"> <div class="col-md-5"></div> <div class="col-md-2"> <form class="login-form" method="post" action="{:U('System/check')}"> <fieldset> <h3 class="welcome"><i class="login-logo"></i>freelog</h3> <div class="form-group"> <div class="controls"> <input type="text" name="loginName" placeholder="用戶名" class="form-control" required title="請填寫用戶名"> </div> </div> <div class="form-group"> <div class="controls"> <input type="password" name="loginPwd" placeholder="密碼" class="form-control" required title="請填寫密碼"> </div> </div> <div class="form-group"> <div class="controls"> <button class="btn-block primary ajax-post" type="submit">登錄</button> <a class="btn-link" href="/">返回首頁</a> </div> </div> </fieldset> </form> </div> <div class="col-md-5"></div> </div> </div> </body> </html> ~~~ ~~~ <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> ~~~ 這樣的寫法叫瀏覽器條件注釋,專門針對ie低版本的寫法。 ~~~ <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> ~~~ 是為了保證兼容性,針對ie8的寫法,意思是裝了chrome的系統,ie打開時用chrome渲染,沒裝繼續用ie的edge引擎渲染。 ~~~ <script type="text/javascript" src="__BOWER__/jquery/dist/jquery.js"></script> <!--[if lt IE 9]> <script src="__STATIC__/html5shiv.js"></script> <script src="__STATIC__/respond.js"></script> <![endif]--> <script type="text/javascript" src="__BOWER__/bootstrap/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> var url = ''; </script> <script type="text/javascript" src="__JS__/admin.js"></script> <link rel="stylesheet" type="text/css" href="__BOWER__/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="__CSS__/admin_custom.css"> ~~~ 引入一些常規的jquery、bootstrap組件和自己后臺用的admin.js。 ~~~ <!--[if lt IE 8]> <div class="browsehappy">當前網頁 <strong>不支持</strong> 你正在使用的瀏覽器. 為了正常的訪問, 請 <a href="http://browsehappy.com/">升級你的瀏覽器</a>.</div> <![endif]--> ~~~ 做了一個ie8向下的提示更換瀏覽器的處理。讓ie6、7去見鬼吧。 ~~~ <div class="container-fluid"> <div class="row-fluid"> <div class="col-md-5"></div> <div class="col-md-2"> <form class="login-form" method="post" action="{:U('System/check')}"> <fieldset> <h3 class="welcome"><i class="login-logo"></i>freelog</h3> <div class="form-group"> <div class="controls"> <input type="text" name="loginName" placeholder="用戶名" class="form-control" required title="請填寫用戶名"> </div> </div> <div class="form-group"> <div class="controls"> <input type="password" name="loginPwd" placeholder="密碼" class="form-control" required title="請填寫密碼"> </div> </div> <div class="form-group"> <div class="controls"> <button class="btn-block primary ajax-post" type="submit">登錄</button> <a class="btn-link" href="/">返回首頁</a> </div> </div> </fieldset> </form> </div> <div class="col-md-5"></div> </div> </div> ~~~ 這里,用了bootstrap的網格流動布局。為了讓登錄框居中, 我按照bootstrap默認表單寬度,大概算出它占2列,然后左右留 各5個空白的列。 當屏幕小于5列寬時就會 表單撐開,全寬,達到響應式。 ![2015-07-05/559897c7df75d](http://box.kancloud.cn/2015-07-05_559897c7df75d.png) 更小寬度也是如此。 ![2015-07-05/559897e0dd49f](http://box.kancloud.cn/2015-07-05_559897e0dd49f.png) 由于只是后臺,沒分太細的寬度,如果要匹配不同寬度,需要div上加 col-sm col-sm 之類的類去控制。后臺登錄頁面沒必要做太細。 后臺登錄邏輯和前臺差不多,只不過不用查庫了,直接配置里的鍵去比較表單項。 ~~~ /* 登錄驗證 */ public function check() { //接收數據 $loginName = trim(I('post.loginName')); $loginPwd = trim(I('post.loginPwd')); if (C('ADMIN.LOGIN_NAME') == $loginName) { if (md5($loginPwd) == C('ADMIN.PWD')) { $user = array( 'admin_id' => 1, 'admin_name' => $loginName, 'login_time' => NOW_TIME, //上次登錄時間 ); //設置登錄SESSION session(C('USER_AUTH_KEY'), $user); session(C('USER_AUTH_SIGN_KEY'), user_auth_sign($user)); $this->success('登錄成功', U('System/index')); } else { $this->error('密碼錯誤'); } } else { $this->error('該管理員不存在'); } } ~~~ 里面的簽名方法復用了OneThink的。 然后注意的一點是 NOW_TIME 常量。每次獲取當前時間戳用time() 多次用就浪費效率了。 所以TP定義了一個常量供框架使用。 `System/check` 比`User/login` 難讓黑客們猜到。 # 導航 登錄過后,就可以看見除了登錄頁面外,每個頁面都有的導航 ![2015-07-05/55989d05a979a](http://box.kancloud.cn/2015-07-05_55989d05a979a.png) 我是在bootstrap3 默認的帶下拉菜單的導航基礎上加上反轉背景色、加上子菜單箭頭和高亮當前導航實現的效果。 ~~~ <div class="navbar navbar-inverse"> <div class="navbar-inner"> <div class="container-fluid"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="{:U('System/index')}">首頁 <span class="sr-only">(current)</span></a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">資源 <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="{:U('Resource/tags')}">標簽</a></li> <li><a href="{:U('Resource/pics')}">圖片庫</a></li> <li><a href="{:U('Resource/files')}">文件庫</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">文章 <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="{:U('Post/text')}">文章</a></li> <li><a href="{:U('Post/picture')}">圖片</a></li> <li><a href="{:U('Post/music')}">音樂</a></li> <li><a href="{:U('Post/video')}">視頻</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">微信 <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="{:U('Weixin/index')}">服務器</a></li> <li><a href="{:U('Weixin/menu')}">菜單</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">配置 <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="{:U('Config/group?id=1')}">網站設置</a></li> <li><a href="{:U('Config/index')}">配置列表</a></li> </ul> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li class="divider-vertical"></li> <li><a href="javascript:;">{:get_admin_name()}</a></li> <li class="divider-vertical"></li> <li><a href="{:U('System/cleancache')}" class="ajax-get">清除緩存</a></li> <li class="divider-vertical"></li> <li><a href="{:U('System/logout')}">登出</a></li> <li class="divider-vertical"></li> <li><a href="/">網站</a></li> </ul> </div> <!-- /.nav-collapse --> </div> </div> <!-- /navbar-inner --> </div> ~~~ ![高亮效果](http://box.kancloud.cn/2015-07-05_55989d87ca32e.png) 高亮代碼實現參考了OneThink的后臺高亮。 先js獲取當前url: ~~~ var url = window.location.pathname + window.location.search; url = url.replace(/(\/(p)\/\d+)|(&p=\d+)|(\/(id)\/\d+)|(&id=\d+)|(\/(group)\/\d+)|(&group=\d+)/, ""); url = url.replace('.html', ''); ~~~ 然后admin.js里定義一個高亮菜單的函數: ~~~ function highlight_menu(url) { $('.nav li').removeClass('active'); $('.nav .dropdown-menu>li>a[href*="'+url+'"]').parent().addClass('active').parents('.dropdown').addClass('active'); $('.nav-collapse .nav li a[href*="'+url+'"]').parent().addClass('active'); } ~~~ admin.js最后, 初始話時調用這個函數。 ~~~ $(function(){ //導航子頁面高亮選中 highlight_menu(url); }); ~~~ # 配置 在我遇到typecho 時,我就被它的簡潔所打敗了。它的后臺也是如此。因此,在我開發OneBlog時,我就用OneThink的功能,然后移植typecho的后臺風格,包括登錄頁之類的。 像這樣: ![2015-07-05/5598a16156584](http://box.kancloud.cn/2015-07-05_5598a16156584.png) 配置我是直接移植OneThink的模板加控制器。前面大家前臺也看到了,同樣的初始化里,讀取數據庫配置,合并到配置數組里去。 后臺的模板代碼我就不帖了,和OneBlog里的差不多。只不過繼承的父模板不一樣。 主要說一下保存。 OneBlog 里的配置,我是copy OneThink里的 控制器方法。 在freelog里,我們不是寫了api了嗎? 我就把那個配置里的保存方法,給他整合到api里面了。其他和OneBlog一樣,列表、編輯頁讀數據什么的。 用過OneThink的開發人員都清楚,OneThink里的配置保存有兩種,一種是所有配置保存,一種是單獨配置項的保存。 ![全部配置](http://box.kancloud.cn/2015-07-05_5598a3333300d.png) ![某一項配置](http://box.kancloud.cn/2015-07-05_5598a356b256f.png) ![全部配置保存](http://box.kancloud.cn/2015-07-05_5598a3a283079.png) 全部配置保存的html里保存的是個多維數組,然后提交到 api.php/config/save方法里。 而單獨配置的保存,我還是api的config,只不過提交時表單里帶id,鍵名不是數組了,是配置項的對應鍵,如sort。 ![2015-07-05/5598a42869472](http://box.kancloud.cn/2015-07-05_5598a42869472.png) ![2015-07-05/5598a4412b180](http://box.kancloud.cn/2015-07-05_5598a4412b180.png) 因此,api里,config不能像普通表的curd那么去做。 我們回去看api的EmptyController ![2015-07-05/5598a49a8d3bb](http://box.kancloud.cn/2015-07-05_5598a49a8d3bb.png) 先定義了其他處理的資源,config。 然后控制器里單獨實現config方法: ~~~ public function config($name = 0){ $model = D('Config'); $result = true; $data = array(); $code = 404; $url = ''; switch ($this->_method){ case 'head': break; case 'option': break; case 'get': // 列出資源 if('list' == $name){ $data = $model->select(); }else{ $id = intval($name); $data = $model->find($id); } if($model->getError() || $model->getDbError()){ $result = false; }else{ $code = 200; } break; case 'put': if('save' == $name){ // 批量更新資源 $config = I('put.config'); if(empty($config)){ $result = false; $data = '表單為空'; }else{ if($config && is_array($config)){ foreach ($config as $name => $value) { $map = array('name' => $name); $model->where($map)->setField('value', $value); } } S('DB_CONFIG_DATA',null); $code = 200; } }else{ $puts = $model->create(I('put.')); if(false === $puts){ $result = false; $data = $model->getError(); }else{ $id = $puts['id']; if($find = $model->find($id)){ $result = false !== $model->save($puts); $code = $result? 200: 404; }else{ $result = false; $data = "record not found"; $code = 412; } } } break; case 'post': // 新增資源 $posts = $model->create(); if(false == $posts){ $data = $model->getError(); $result = false; }else{ $id = $model->add(); if(!$id){ $result = false; }else{ $code = 201; $data = $id; $url = '/admin.php/Config/index'; } } break; case 'delete':// 刪除資源 // parse_str(file_get_contents('php://input'), $_DELETE); // slog($_DELETE); $id = array_unique((array)I('get.id',0)); slog($id); if ( empty($id) ) { $code = 404; $data = '請選擇要操作的數據'; }else{ $code = 200; $map = array('id' => array('in', $id) ); if(M('Config')->where($map)->delete()){ S('DB_CONFIG_DATA',null); //記錄行為 $url = '/admin.php/Config/index'; $data = '刪除成功'; } else { $code = 412; $result = false; $data = '刪除失敗!'; } } break; } if($result){ $this->success($data, $code, $url); }else{ $this->error($data, $code, $url); } } ~~~ 先看更新: ~~~ if('save' == $name){ // 批量更新資源 $config = I('put.config'); if(empty($config)){ $result = false; $data = '表單為空'; }else{ if($config && is_array($config)){ foreach ($config as $name => $value) { $map = array('name' => $name); $model->where($map)->setField('value', $value); } } $code = 200; } }else{ $puts = $model->create(I('put.')); if(false === $puts){ $result = false; $data = $model->getError(); }else{ $id = $puts['id']; if($find = $model->find($id)){ $result = false !== $model->save($puts); $code = $result? 200: 404; }else{ $result = false; $data = "record not found"; $code = 412; } } S('DB_CONFIG_DATA',null); } ~~~ 通過$name 是否為save,區分是批量更新還是單個更新。單個更新和之前所有數據表資源的更新一樣。而批量更新,獲取的是 I('put.config') 多維數組,并且通過遍歷去更新每一個: ~~~ foreach ($config as $name => $value) { $map = array('name' => $name); $model->where($map)->setField('value', $value); } ~~~ 最后清除一下緩存。 # 資源 資源導航包括了文件、圖片和標簽。 我以文件為例,其他的都差不多,只是模板里個別字段不一樣。 ![2015-07-05/55994a872cfab](http://box.kancloud.cn/2015-07-05_55994a872cfab.png) 模板resource/files.html代碼: ~~~ <extend name="Public/base" /> <block name="body"> <div class="main-title location"> <h2>文件</h2> </div> <div class="data-table table-striped"></div> <div class="typecho-table-wrap"> <table class="table table-hover" id="del_table"> <thead> <tr> <th>ID</th> <th>原始名</th> <th>后綴</th> <th>路徑</th> <th>大小</th> <th>上傳時間</th> </tr> </thead> <tbody> <notempty name="list"> <volist name="list" id="file"> <tr> <td>{$file.id}</td> <td>{$file.savename}</td> <td>{$file.ext}</td> <td><a href="{$file.path}" target="_blank">{$file.path}</a></td> <td>{$file.size|format_bytes}</td> <td>{$file.create_time|date="Y-m-d h:i:s",###}</td> </tr> </volist> <else/> <td colspan="6" class="text-center"> aOh! 暫時還沒有內容! </td> </notempty> </tbody> </table> </div> <!-- 分頁 --> <div class="pagination"> <div class="pull-right"> {$_page} </div> </div> </block> ~~~ 處理了大小的格式化顯示,和創建時間格式化。 控制器代碼也簡單: ~~~ <?php namespace Admin\Controller; use Think\Controller; class ResourceController extends CommonController { //標簽 public function tags(){ /* 查詢條件初始化 */ $map = array('status' => 1); if(isset($_GET['title'])){ $map['title'] = array('like', '%'.(string)I('title').'%'); } $this->meta_title = '標簽'; $this->_list(array('source' => 'Tags', 'map' => $map, 'order' => '`id`')); } //圖片 public function pics(){ /* 查詢條件初始化 */ $map = array('status' => 1); $this->meta_title = '圖片'; $this->_list(array('source' => 'Picture', 'map' => $map, 'order' => '`id`')); } public function files(){ /* 查詢條件初始化 */ $map = array('status' => 1); $this->meta_title = '文件'; $this->_list(array('source' => 'File', 'map' => $map, 'order' => '`id`')); } } ~~~ 圖片和標簽只不過換了資源名,并且標簽加了title搜索。 這一切復用了common控制器里的_list方法。 因為文件、圖片、標簽都是用戶產生,本來后臺就不應該有刪除的行為。因為刪除了文章里關聯的數據就會有問題。 顯示出來是為了方便審查,萬一用戶上傳了黃色圖片和音頻怎么辦。 讀取時按照status=1處理的。到時候加刪除也簡單,通過刪除鏈接和ajax類更新該記錄為status=0就好了。 # 文章 文章,為了方便管理,將四種類型通過菜單區分管理列表。 ![2015-07-05/55994d96cf877](http://box.kancloud.cn/2015-07-05_55994d96cf877.png) 為了實現動態菜單, 控制器里方法也是通過空操縱實現: ~~~ <?php namespace Admin\Controller; use Think\Controller; class PostController extends CommonController { public function _empty($action = 'text'){ if(!in_array($action, array('text', 'picture', 'video', 'music'))) $this->error('錯誤的文章類型'); /* 查詢條件初始化 */ $map = array(); $map['type'] = $action; if($search = I('get.title', '', 'trim')){ $map['_string'] = "`title` LIKE '%{$search}%' OR `description` LIKE '%{$search}' OR FIND_IN_SET('{$search}', tags)"; } $this->meta_title = '文章管理'; $this->_list(array('source' => 'Post', 'map' => $map, 'order' => '`id`', 'tpl'=>strtolower($action))); } } ~~~ 不過比之前標簽搜索,提供多了一些字段,如描述、和標簽。模板也是動態的。如文章模板。 ~~~ <extend name="Public/base" /> <block name="body"> <div class="main-title location"> <h2>文章</h2> </div> <div class="data-table table-striped"> <div class="clearfix"> <!-- 高級搜索 --> <div class="search-form pull-right clearfix form-inline"> <div class="input-group mb10"> <form action="{:U()}" method="GET"> <input type="text" name="title" class="form-control text-s" value="{:I('title')}" placeholder="請輸入標簽名稱"> <span class="input-group-btn"> <button class="btn btn-default"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button> </span> </form> </div><!-- /input-group --> </div> </div> <div class="typecho-table-wrap"> <table class="table table-hover" id="del_table"> <thead> <tr> <th>ID</th> <th>標題</th> <th>描述</th> <th>作者</th> <th>標簽</th> <th>瀏覽數</th> <th>最后更新時間</th> <th>操作</th> </tr> </thead> <tbody> <notempty name="list"> <volist name="list" id="post"> <tr> <td>{$post.id}</td> <td>{$post.title}</td> <td>{$post.description}</td> <td>{$post.author}</td> <td>{$post.tags}</td> <td>{$post.views}</td> <td>{$post.update_at}</td> <td><a href="/api.php/post?id={$post.id}" class="ajax-delete confirm">刪除</a></td> </tr> </volist> <else/> <td colspan="6" class="text-center"> aOh! 暫時還沒有內容! </td> </notempty> </tbody> </table> </div> <!-- 分頁 --> <div class="pagination"> <div class="pull-right"> {$_page} </div> </div> </block> ~~~ 這里為了以后擴展方便預留了。每個類別文章沒用一個模板,是為了以后實現不同的預覽和編輯著想,先只顯示基礎數據吧。 至于搜索,一個get表單搞定: ~~~ <form action="{:U()}" method="GET"> <input type="text" name="title" class="form-control text-s" value="{:I('title')}" placeholder="請輸入標簽名稱"> <span class="input-group-btn"> <button class="btn btn-default"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button> </span> </form> ~~~ 至于刪除,和前臺一樣,交給api、ajax-delete。 `<a href="/api.php/post?id={$post.id}" class="ajax-delete confirm">刪除</a>` # 微信 本來微信想做很多功能,實現像公眾平臺一樣的功能(多媒體管理,消息查看)。可是后來嘗試發現,個人開發者未認證用戶,沒那些高級接口的權限。 所以干脆,只做了2個功能頁:微信服務器ip列表,和微信平臺(iframe實現,要怎么管理自己登錄去吧)。 ## 服務器ip ![效果](http://box.kancloud.cn/2015-07-05_5599509c92098.png) 直接看控制器 : ~~~ <?php namespace Admin\Controller; use Think\Controller; use Com\Wechat; use Com\WechatAuth; class WeixinController extends CommonController { //初始化方法 protected function _initialize() { if(!C('WEIXIN.APPID')){ $this->error('請先配置好微信'); } } //首頁 public function index(){ $wechatauth = new WechatAuth(C('WEIXIN.APPID'), C('WEIXIN.SECRET'), C('')); $access_token = $wechatauth->getAccessToken(); $result = $wechatauth->getServerIp($access_token); if(isset($result['errcode'])) $this->error($result['errmsg']); slog($result); $this->assign('ip', $result['ip_list']); $this->display(); } //菜單 public function menu(){ $this->display(); } } ~~~ weixin/index.html 代碼: ~~~ <extend name="Public/base" /> <block name="body"> <div class="col-md-4"></div> <div class="col-md-4"> <table class="table table-hover"> <thead><th>微信服務器IP:</th></thead> <tbody> <volist name="ip" id="vo"> <tr><td>{$vo}</td></tr> </volist> </tbody> </table> </div> <div class="col-md-4"></div> </block> ~~~ 我也是盲人摸象,摸索出WechatAuth類的使用。并且,自己擴展了一個getServerIp的方法: ~~~ public function getServerIp($token){ return $this->api('getcallbackip', array('access_token'=>$token)); } ~~~ 后面微信開發里會細講。 ## 菜單 沒啥技術含量,但是思路不錯: ~~~ <extend name="Public/base" /> <block name="body"> <iframe width="100%" height="700" src="https://mp.weixin.qq.com/"></iframe> </block> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看