初音未来12周年生日快乐!
初音未來 Magical Mirai 2019演唱會 - 未來馬戲團 參見公主殿下! 等身大小miku醬 啊,地板滑,摔了一跤 初音未來明信片珍藏版 預告:本月將迎來部落格三週年活動,即期將寄出這些明信片…….待
初音未來 Magical Mirai 2019演唱會 - 未來馬戲團 參見公主殿下! 等身大小miku醬 啊,地板滑,摔了一跤 初音未來明信片珍藏版 預告:本月將迎來部落格三週年活動,即期將寄出這些明信片…….待
自從5.20表白後,鴿主就一直處於失蹤狀態……. 時隔不知道多少個月,三合一它竟然又更新了,兩個月前在群裡立下的flag,今天我把它給圓了,不要問我中間兩個月幹嘛去了-.- (忙著參加大型鴿子聚會) 正文 由於網路識別經常掛掉,非常不穩定,一直有小夥伴在跟我反饋,所以這次特意更新了本地識別。 推薦1G記憶體以上的機子安裝,推薦配置2核2G,最佳配置16核32G [#手動滑稽] v2.0 新增本地二維碼識別與生成 移除網路識別介面 修復已知BUG 其他一些細節優化 詳細說明和安裝教程可點擊這裡查看上個版本 新版網站均保留了舊版本資料,不影響之前使用者使用,並且與贊助版資料同步 贊助版 由於舊版本盜版氾濫,新版三合一增設了贊助版。 演示網站:https://qr.moeins.cn 贊助版主要特色: 優化二維碼的識別與生成,大大提高識別準確率,更快的識別速度,不佔CUP與記憶體,更穩定 新增21套三合一生成模板,並且可支援無限擴展,添加教程在文末 新增對外的API介面,不再針對該程式使用,任何程式都可呼叫 如何獲得: 點擊這裡贊助項目18.88元以上即可獲得收款碼三合一的贊助專享版,你值得擁有! 關於贊助版的一些小小說明(之前都是沒有特意拿出來說明 ) 到目前為止,我所有的贊助版項目均不綁定網域,不曾加密,可自由擴展,支援二次開發,且贊助金額都偏低,即可獲得。所以還請有贊助的小夥伴們不要隨意分享贊助得到的原始碼,這是對作者的尊重也是對自己權益的保障。由於不存在買賣關係,如無重大BUG作者將不定期更新或無限期拖更。如遇小問題,在作者空閒之餘願意指導或幫助修改,但是要新增大功能這種情況下我有權拒絕幫忙或需另外付費。 贊助版模板擴展教程 模板推薦尺寸為:900*1200 將模板圖片放至/public/static/images/template/模板目錄,注意請不要使用中文名,且只支援jpg副檔名 在根目錄的config.php中 qr_template 項下配置相關資料,格式如下: ‘001’ => [ ’name’ => ‘預設模板’, ‘data’ => [ 150,200 ], ’title’ => true, ‘size’ => 20 ] 參數說明 名稱 變數名 必填 類型 範例值 描述 模板ID 無 是 int 001 模板的檔案名,推薦數字,不可重複 別名 name 是 string 預設模板 在前台顯示的模板別名 X,Y data 是 array [150,200] 二維碼生成的左上角的起始X(橫坐標),Y(縱坐標)坐標,不可為負數且小於模板尺寸 模板標題 ...
我喜歡二次元, 是因為我喜歡那個世界, 我為他們的純真而感動, 為他們的夢想所激勵, 為他們的堅持所鼓舞, 那些夢幻的,可能存在的或不可能存在的美好, 很多我在三次元世界裡已經找不到了, 我多麼想穿越次元的隧道, 與我所愛的人一起, 因為無法穿越, 讓我總在二次元與三次元中徘徊, 無論我多麼愛你, 我還是要說一聲對不起, 因為我活在三次元……
不知道大家們寫小程序是怎麼個寫法的,前幾個月在寫微信小程序,自己整理的一種架構,或者叫框架 微信原生的架構是這樣子 ├── app.js ├── app.json ├── app.wxss ├── pages │ │── index │ │ ├── index.wxml │ │ ├── index.js │ │ ├── index.json │ │ └── index.wxss │ └── logs │ ├── logs.wxml │ └── logs.js └── utils 為什麼不用微信原生的寫法呢? 小程序就類似手機APP,都會有一個tabBar欄對吧,微信官方的tabBar欄是在app.json中進行的全局配置。做一般的開發是沒有任何問題的,但涉及到一個複雜的tabBar欄時,使用官方原生的就無法實現,也無法動態載入,比如某影片app中間的拍照錄影功能 這意味著,我們不能使用官方給我們提供的tabBar欄,需要我們自己寫 最開始我的做法還是保持原生的結構,只是自己寫tabBar欄,所以頁面程式碼都寫在一個文件中,預設顯示第一屏,其他的都隱藏起來,切換頁面的時候再把相應的頁面顯示,其他的隱藏起來,並且動態渲染資料上去。但是有個問題是,如果是小專案倒沒什麼大問題,但是如果是大專案程式碼量非常龐大,都寫在一個文件中,後期難以維護,所以這個方法最後被pass掉 再後來將切換頁面的方式改為跳轉(wx.switchTab等),把不同頁面的程式碼放到了不同的文件,但是還有一個問題,切換也會閃爍,每次切換頁面就等於重新打開一個網頁一樣,tabBar都被重新渲染,所以會閃爍。pass 由此就有了現在的全新架構方式: 將/pages/index/下的文件全部定義為入口文件,js入口,css入口,視圖入口,不同頁面的文件還是放到不同的位置去,為了好管理,新建了一個template的資料夾,用於放不同頁面間的程式碼,結構和官方的單頁面結構是一樣的 根目錄下的app.js用於存放全域函數,其他頁面呼叫只需getApp()即可 js的入口文件 const app = getApp(); var index\_js = require("../../template/index/index.js"); var types\_js = require("../../template/types/types.js"); var Global\_Data = \[\]; Page({ data: { active: 0, show: { index: true, types: false, course: false, user: false } }, onLoad(options) { this.setData({ Global\_Data: index\_js.getData() }) }, // 底部nav切换 tabbar\_onChange(event) { var key = ''; this.data.show = { index: false, types: false, course: false, user: false }; console.log(event) switch (event.detail) { case 0: key = 'index'; Global\_Data = index\_js.getData(); break; case 1: key = 'types'; Global\_Data = types\_js.getData() break; case 2: key = 'course'; Global\_Data = index\_js.getData(); break; case 3: key = 'user'; Global\_Data = index\_js.getData(); break; } this.data.show\[key\] = true; console.log(Global\_Data) this.setData({ show: this.data.show, Global\_Data: Global\_Data }) }, }); wxml入口文件 ...
這是一個非常基礎的HTML表單提交問題,但卻是一個非常實用的技巧 我的業務場景是這樣的: 一個可動態建立input的表單,如下圖 這意味著input的name不能是一個固定的,否則肯定會被覆蓋掉的 第一種,傳統的普通提交方式,給每一個要提交的input一個唯一的name ...... 瀏覽器提交抓到的格式是這樣子的 伺服器獲取列印出來的是這樣的,對後端的資料處理就非常不友善 第二種,陣列的方式進行表單提交 ...... 瀏覽器和後端列印的結果分別為 細心觀察就會發現,提交的name值發生了變化,變成了一樣的?陣列? 提交到後端就會發現資料比之前整齊多了 但這裡要注意的是,提交的陣列鍵中不需要使用引號,否則引號也會成為鍵的一部分 當然了,實際中還可能遇到這樣的問題,要提交的組數(像上面的1、2、3)是不確定的,可以在前端隨意地添加,這個時候怎麼去用陣列提交這些內容呢? 下面就是我業務中的實際解決方案 這樣的話,二維陣列的鍵則不需要我們自己去維護了,由瀏覽器幫我們自動生成 後端接收到的資料則變成了這樣子,變得非常好處理了 此方法適用於,要提交一堆不確定個數的一組相關的資料對 完結撒花!~
穿著睡衣出門取外賣, 不想遇到熟人,偏偏被好多熟人看見; 看電影時昏昏欲睡, 中途上個廁所,就錯過高光片段; 在景區排隊買票, 不管排到哪一邊,另一邊總是走得更快…更不用說每次下雨不帶傘,帶傘時卻不下雨, 剛買東西就降價,一翹課就被點名, 想抽的卡抽不到,喜歡的人不喜歡你了…生活為什麼總對我動手? 不是命中註定,全因「墨菲定律」。 墨菲定律 一件事情無論機率有多小, 總會有發生的可能, 而你越擔心某種情況發生, 它就越有可能發生。 正如俗話說的, 你越怕什麼,就越來什麼。 就像網站越做越好了,擔心樹大招風, 果然就遭到DDoS、CC攻擊; 伺服器還在「裸奔」,怕被駭客盯上, 一不留神,就被木馬、病毒深度「捆綁」; 憂心業務安全,每天謹小慎微, 沒曾想,還是因為操作失誤丟了數據…為什麼總是會出現這些問題? 因為機率本身就是一種「玄學」, 像前沿數據事件、程式設計師刪庫跑路事件, 在發生之前誰也無法預測, 可一旦碰上,就是100%,打擊也尤為致命… 而令人遺憾的是,這些後果本來是可以避免的…試想一下,如果你提前做好了安全防禦, DDoS、CC就無法擊潰你; 而部署了防火牆、打了系統補丁, 駭客也不會有可乘之機; 再極端一點,即使程式設計師刪庫跑路了, 只要快照備份還在,也能有迴轉餘地… 所以,即使是對於小機率的「危險」事件, 我們同樣不能忽視, 做好一切的準備, 才能確保99%的安全,避免1%的損害。大規模流量攻擊來了, 有DDoS高防/ BGP高防IP隔離入侵, 遇到網頁篡改、訪問緩慢問題, 找web應用防火牆、CDN加速搞定; 而數據安全和通訊加密,交給雲硬碟、SSL憑證就行如果以上幾點你都能做到, 那麼恭喜,網站安全的flag已經摘取, 即使不幸「中招」, 也可以放寬心態,無所畏懼了
不起眼女主角培育法 – 英梨梨 – 簡稱黃毛 郵政小包 開箱 外殼轉一圈,外殼也值得收藏 看到了點不得了的東西 開箱取出,泳裝好像沒穿好,這。。。(捂眼)少兒不宜,打碼打碼 好不容易幫妹子穿好了泳裝 這腿好白,舔 轉一圈 小虎牙真棒 角度刁鑽 第一人稱(笑-。- 開箱結束,完美Ψ( ̄∀ ̄)Ψ
1、情境:查詢一位選手的排名及距離上一名差多少票 方法二(去重排序查詢比自己少的數量) $temp = DB::fetch_first("SELECT distinct total+jewel_vote+forge_vote ,COUNT(*)+1 AS RANK FROM " . DB::table('vote_competition') ." WHERE total+jewel_vote+forge_vote>" . $competition['all'] . " and aid={$aid} ORDER by forge_vote desc"); $rank = $temp['RANK']; // 無法直接查詢到上一名選手票數 if ($temp['total+jewel_vote+forge_vote']) { // 這裡查詢出來的是和第一名選手相差的票數 $up = $temp['total+jewel_vote+forge_vote']-$competition['all']; } 方法一(定義變數累加排序) $temp = DB::fetch_all("SELECT a.cid,a.total,a.forge_vote,a.jewel_vote,(@rowNum:=@rowNum+1) AS rank FROM pre_vote_competition AS a, (SELECT (@rowNum :=0) ) b WHERE aid={$aid} ORDER BY (a.total+a.forge_vote+a.jewel_vote) DESC "); foreach ($temp as $key => $value) { if ($value['cid'] == $cid) { // 當前自己的排名 $rank = $value['rank']; if ($up) { $up = $up - ($value['total'] + $value['forge_vote'] + $value['jewel_vote']); } break; } // 和上一名選手相差的票數 $up = $value['total'] + $value['forge_vote'] + $value['jewel_vote']; } 2、情境:查詢一篇文章的上一篇和下一篇,支援斷號 ...
文件:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319 微信的授權登入與QQ、新浪等平台的授權登入大同小異,均採用OauthOAuth2.0鑑權方式。 微信授權分為兩種: 靜默授權 彈窗授權,需要用戶手動同意 兩種scope的區別說明 以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的用戶openid的,並且是靜默授權並自動跳轉到回調頁的。用戶感知的就是直接進入了回調頁(往往是業務頁面) 以snsapi_userinfo為scope發起的網頁授權,是用來獲取用戶的基本資訊的。但這種授權需要用戶手動同意,並且由於用戶同意過,所以無須關注,就可在授權後獲取該用戶的基本資訊。 用戶管理類介面中的「獲取用戶基本資訊介面」,是在用戶和公眾號產生訊息交互或關注後事件推送後,才能根據用戶OpenID來獲取用戶基本資訊。這個介面,包括其他微信介面,都是需要該用戶(即openid)關注了公眾號後,才能呼叫成功的。 具體而言,網頁授權流程分為四步: 引導用戶進入授權頁面同意授權,獲取code 透過code換取網頁授權access_token(與基礎支援中的access_token不同) 如果需要,開發者可以重新整理網頁授權access_token,避免過期 透過網頁授權access_token和openid獲取用戶基本資訊(支援UnionID機制) 以下是封裝的微信操作類,需要用到兩個資料表,用於保存access_token、ticket,由於它們具有一定有效期,且每天請求數有上限,所以開發者需自行保存 <?php /\*\* \* 微信操作表 \* wxtoken 表結構 \* id \* access\_token \* addtime \* wxticket 表結構 \* id \* ticket \* addtime \*/ class WX { private $appid; private $appserect; private $curl; private $msg; protected $errs = array( '-1' => '系統繁忙,此時請開發者稍候再試', '0' => '請求成功', '40001' => 'AppSecret錯誤或者AppSecret不屬於這個公眾號,請開發者確認AppSecret的正確性', '40002' => '請確保grant\_type字段值為client\_credential', '40164' => '呼叫介面的IP地址不在白名單中,請在介面IP白名單中進行設定。', ); function \_\_construct($appid, $appserect) { $this->appid = $appid; $this->appserect = $appserect; $this->curl = new Curl(); } /\* 微信網頁授權登入 需要在公眾號設定 - 功能設定 - 網頁授權域名 第一步:用戶同意授權,獲取code scope : snsapi\_base 只能獲取openid 直接跳轉 snsapi\_userinfo \*/ public function getCode($redirect\_uri, $scope = 'snsapi\_userinfo',$state = '1') { $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect\_uri={$redirect\_uri}&response\_type=code&scope={$scope}&state={$state}#wechat\_redirect"; header("Location:{$url}"); exit; } /\* 第二步:透過code換取網頁授權access\_token \*/ public function getAccessTokenByCode($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access\_token?appid={$this->appid}&secret={$this->appserect}&code={$code}&grant\_type=authorization\_code"; // exit($url); // $curl = new Curl(); $result = $this->curl->doGet($url); if (!$result) { // $this->curl->getError() $this->msg = "獲取token失敗"; return false; } $result = json\_decode($result, true); if ($result\['errcode'\]) { $this->msg = $result\['errmsg'\]; return false; } return $result; } // 第三步:重新整理access\_token(如果需要) 透過code 獲取openid $type 0靜默授權 1彈窗授權 public function getUserInfo($code, $type = 0, $lang = 'zh\_CN ') { $result = $this->getAccessTokenByCode($code); if (!$result) { return false; } $member = C::t(PT\_USER)->getByOpenid($result\['openid'\]); if ($member) { return $member; } else { if ($type) { $url = "https://api.weixin.qq.com/sns/userinfo?access\_token={$result\['access\_token'\]}&openid={$result\['openid'\]}&lang={$lang}"; // $return = $this->curl->doGet($url); // 這介面有病 強制顯示文件頭 $return = file\_get\_contents($url); if (!$return) { $this->msg = '獲取用戶資訊失敗'; return false; } $return = json\_decode($return, true); if (!$return) { $this->msg = '獲取用戶資訊返回失敗'; return false; } // file\_put\_contents('ccc.txt',print\_r($return,true),FILE\_APPEND); $data = array( 'openid' => $return\['openid'\], 'name' => $return\['nickname'\], 'sex' => $return\['sex'\], 'province' => $return\['province'\], 'city' => $return\['city'\], 'country' => $return\['country'\], 'img' => $return\['headimgurl'\], 'bindtel' => 0, ); } else { $data = array( 'openid' => $result\['openid'\], 'username' => "微信用戶\_" . random(6,1) ); } $name = rand(100000, 1000000000); $e = $name . "@qq.com"; $password = $e; $id = UserAddEdit(0, $data\['username'\], $password, $e,10,0,"", $msg); if ($id <= 0) { $this->msg = $msg; return false; } C::t(PT\_USER)->update($data, $id); $member = C::t(PT\_USER)->get($id); return $member; } } /\* 公眾號 安全中心 設定IP白名單 公眾號的全局唯一介面呼叫憑據,公眾號呼叫各介面時都需使用access\_token。開發者需要進行妥善保存。access\_token的儲存至少要保留512個字符空間。access\_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access\_token失效。 \*/ public function getAccessToken($type) { $addtime = TIMESTAMP - 7200; $url = "https://api.weixin.qq.com/cgi-bin/token?grant\_type=client\_credential&appid={$this->appid}&secret={$this->appserect}"; $row = C::t(PT\_WXTOKEN)->getNew($addtime, $type); if ($row) { return $row\['access\_token'\]; } else { $result = $this->curl->doGet($url); if (!$result) { $this->msg = "無法獲取令牌內容"; return false; } $result = json\_decode($result, true); if (!$result) { $this->msg = "解析令牌內容失敗"; return false; } if ($result\['access\_token'\]) { C::t(PT\_WXTOKEN)->addToken($result\['access\_token'\], $type); return $result\['access\_token'\]; } else { $this->msg = "獲取令牌失敗"; return false; } } } // 獲取js票據 需要在公眾號設定 - 功能設定 - JS介面安全域名設定 public function getJsTicket() { $addtime = TIMESTAMP - 7200; $row = C::t(PT\_WXTICKET)->getNew($addtime); if ($row) { return $row\['ticket'\]; } else { $token = $this->getAccessToken(); if (!$token) { return false; } $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access\_token={$token}&type=jsapi"; $result = $this->curl->doGet($url); if (!$result) { $this->msg = "無法獲取js票據"; return false; } $result = json\_decode($result, true); if (!$result) { $this->msg = "解析js票據內容失敗"; return false; } if ($result\['ticket'\]) { C::t(PT\_WXTICKET)->addTicket($result\['ticket'\]); return $result\['ticket'\]; } else { $this->msg = "獲取js票據失敗"; return false; } } } // js sdk 票據簽名 當前網頁的URL,不包含#及其後面部分 public function jsSign($data) { // 1.所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序) ksort($data); // 2.URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1 採用原始值,不進行URL 轉義 $string1 = $this->ToUrlParams($data); // echo "string1:{$string1}"; // 3.對string1做sha1加密 $sign = sha1($string1); // echo "signature:{$sign}"; return $sign; } // 獲取訊息內容 public function getMsg() { return $this->msg; } /\*\* \* 格式化參數格式化成url參數 \*/ public function ToUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is\_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } } ?> // 微信登入 function wxlogin() { global $_G,$identifier,$config,$wx; if (!$_G[‘uid’]) { if ($_GET[‘state’]) { // 回調 $member = $wx->getUserInfo($_GET[‘code’]); if (!$member) { exit($wx->getMsg()); } if (!function_exists(“setloginstatus”)) { include_once libfile(‘function/member’); } // 設定登入狀態$wx setloginstatus($member, 2592000); checkfollowfeed(); $_G[‘uid’] = $member[‘uid’]; $_G[‘member’] = $member; } else { // 請求授權 對參數編碼 $redirect = urlencode(getProtocol() . $_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’]); $wx->getCode($redirect, ‘snsapi_base’); } } } function getProtocol() { return is_HTTPS() ? ‘https://’ : ‘http://’; } function is_HTTPS() { if ($_SERVER[‘HTTPS’] === 1 || $_SERVER[‘HTTPS’] === ‘on’ || $_SERVER[‘SERVER_PORT’] == 443) { return true; } return false; }
前陣子一直在做微信相關的業務,雖說不是什麼新技術,但之前一直沒有機會接觸到,然後踩了些坑,抽空整理記錄下。 微信支付一共分為7種,分別是:付款碼支付、JSAPI支付、Native支付、APP支付、H5支付、小程序支付、人臉支付。 此次業務中使用到的是微信JSAPI支付:用戶透過微信掃碼、關注公眾號等方式進入商家H5頁面,並在微信內呼叫 JSSDK完成支付 文件:https://pay.weixin.qq.com/wiki/doc/api/index.html SDK:[https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=11_1 ](https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=11_1)JSAPI支付需要在微信中的瀏覽器打開才能喚起微信支付,效果如下圖 附上介面程式碼 程式碼中使用了模板引擎 html: {$competition\['username'\]} {$prices\[0\]}鑽 {$prices\[1\]}鑽 {$prices\[2\]}鑽 {$prices\[3\]}鑽 {$prices\[4\]}鑽 註:1鑽=1元,1鑽={$activity\['offset'\]}票 立即微信支付 JavaScript: // 投票 var offset = {$activity[‘offset’]}; $(’#tips’).html(‘正在給{$competition[‘code’]}號贈送{$prices[0]}鑽=’+({$prices[0]}*offset)+‘票’); $(’#vote’).click(function(){ $.post(’/index/index/detailed.html?cid={$cid}&aid={$aid}’,{ formhash :’{FORMHASH}’, submit:‘1’, type:1, openid:’{$_G[‘member’][‘openid’]}’ },function(res){ alert(res.msg); if (res.code == 0) { $(’.box-1 span’).text(res.data.all); $(’.box-2 span’).text(res.data.rank); $(’.box-3 span’).text(res.data.up + ‘票’); } }); }) /* jQuery物件級別外掛程式擴展 */ $.fn.extend({ /* 單選框 */ hlRadio:function () { var radioEl=$(this); radioEl.click(function () { var price = 0; price = $(‘input:radio:checked’).val(); $(’#price’).val(’’); $(’#tips’).html(‘正在給{$competition[‘code’]}號贈送’+price+‘鑽=’+(price*offset)+‘票’); radioEl.siblings(“div”).removeClass(“active”); $(this).siblings(“div”).addClass(“active”); }); }, }); $(“input[name=‘price’]”).hlRadio(); $(’#price’).bind(‘input propertychange’, function(){ var price = 0; price = $(’#price’).val(); $(’#tips’).html(‘正在給{$competition[‘code’]}號贈送’+price+‘鑽=’+(price*offset)+‘票’); }) ...