因為涉及的東西比較多,所以需要準備的東西也比較雜。當然,你得首先知道自己要做什么,畢竟這一切準備和將來的勞動都將為這個產品服務。
開發者資質、服務器、數據庫、域名(需要預留至少20天備案時間)、SSL證書等可以通過申請、購買獲得,工具及操作環境如下:
工具:Axure RP、putty、WinSCP、Photoshop、微信web開發者工具、Sublime Text、Zend Studio
操作環境:微信公眾平臺、騰訊云、業務服務器CentOS 7.2(nginx/1.10.1、php-fpm(PHP 5.6.26, Zend Engine v2.6.0))、會話管理服務器CentOS
7.2(PHP+Mysql+Apache)、微信小程序數據庫MySQL
整個過程會產生一些費用,根據自己選擇,大概幾百元的樣子。不過別擔心,騰訊云可以滿足所有需求,其中的微信小程序解決方案,就是專門針對小程序量身定制的。
目前小程序的開放注冊范圍僅限于企業、政府、媒體和其他組織,是不開放對個人注冊的,所以首先你需要給自己一個合法的身份,我是找了個朋友的企業注冊的。申請小程序的開發權限,請移步微信公眾平臺。吐槽一句,現在開發者也流行繳納“入會費”,這里需要300元。
其次是騰訊云注冊,這里可以獲得小程序用到的一切資源,包括域名、SSL證書、服務器、數據庫等。小程序畢竟是騰訊的產品,服務器支持肯定自家的兼容更好些,騰訊云官網為廣大開發者提供了微信解決方案服務器。首次購買半年需要516元,后期續費每月91元。
見到下面這個界面,就申請成功了。
騰訊云可以申請域名,(.com域名一般需要45元左右),審核過程會持續4-5個工作日,之后需要解析域名,在騰訊云管理中心可以直接操作(登錄騰訊云管理中心-云產品-域名服務-云解析)。域名備案比較耗時,要在指定背景下拍照。如果你距離指定地點比較近,可以到指定地點拍照,基本各省都有拍照點,見拍照點地圖。
如果不方便,可以申請郵寄給你個背景幕布,按照要求拍照,見辦理拍照指南,備案材料提交管局審核,需要大概20個工作日(你得習慣這工作效率),所以最好提前申請域名,給備案預留出時間。
另外,域名實名認證也需要4-5天。
在騰訊云購買小程序解決方案時需要選后臺語言,決定了分配給你的是什么系統及環境的服務器(有PHP、Java、Node.js、.NET四種選擇),后期可更改、重裝系統。云端小程序構建完成后會得到三個服務器:業務服務器、會話管理服務器、MySQL數據庫服務器,之后以短信形式發送分配的服務器登錄密碼,用戶名統一是root。
在騰訊云登錄服務器后可以在彈出的黑色命令窗口輸入命令,見下圖:
之后輸入用戶名和密碼即登錄成功。這個登錄窗口是用canvas做的,不能拖動滾動條查看一屏以外的東西,相當憋屈。所以還得有個稱手的工具,現在putty可以登場了。
運行putty之后輸入公網IP地址,點擊Open,之后輸入用戶名密碼,就可以執行各種shell命令了。
至于上傳下載文件,為了安全起見,默認安裝的鏡像 FTP 不支持,官方推薦用WinSCP/SecureFX,這兩個都可以支持,操作跟 FTP 類似。
這里不得不說下關于三個服務器需要注意的點,或者說是坑。系統雖然可以重裝,不過需謹慎,因為有些配置重裝后并不能恢復成最初分配時的狀態。下圖是業務服務器重裝界面(再次提醒:重裝需謹慎):
關于業務服務器:我選的是PHP環境服務器,購買后默認并不支持mysql,需要自己安裝。下面是關于PHP環境業務服務器升級支持mysql擴展方法:
### Update php and install php-mysql extension
wget 'https://mirrors.tuna.tsinghua.edu.cn/remi/enterprise/remi.repo' -O /etc/yum.repos.d/remi.repo
yum --enablerepo=remi-php56 -y update php
yum --enablerepo=remi-php56 -y install php-mysql
service php-fpm restart
以上四行,從上到下按次序執行或保存為一文件,如update_php.sh(見附件), 然后執行
chmod +x update_php.sh
再執行
./update_php.sh
即可
業務服務器配置參考這里,修改Linux - /etc/qcloud/sdk.config文件。
業務服務器的文件存放路徑/data/release/php-weapp-demo
關于會話服務器:首先查看《騰訊云小程序會話管理服務器BUG修復與升級方案》(見附件),然后如果你也重裝了會話服務器,你可能還會發現一個問題,官方給出的三木聊天室demo鏈接失敗。問題解決參考這里 。
1.執行
cd /opt/lampp/htdocs/mina_auth/system/db/
vi db.ini
記下配置里的host和pass_wd值,之后ctrl+Z退出。
2.執行
cd /opt/lampp/bin/
之后按照參考,本應執行
./mysql -h #ip -P #port -u #username -p #passwd(其中#ip、#port、#username、#passwd是在1.2步驟中查看到的具體信息)
但因為重裝系統默認提供的IP和密碼不正確,需要在微信小程序數據庫MySQL賬號管理里為session_user重置密碼,見下圖:
然后用mysql內網IP和新密碼執行如下命令:
./mysql -h IP -P 3306 -u session_user -p新密碼
或直接用root賬號登錄,執行:
mysql -h IP -P 3306 -u root -proot密碼
(IP為微信小程序數據庫MySQL內網地址,用戶名和密碼為登錄數據庫服務器的賬號密碼,注意參數-p后沒有空格)
3.登錄微信公眾號打開開發設置,記下AppID(小程序ID)和AppSecret(小程序密鑰)
4.執行(命令行后帶;設置字段值不用引號,退出mysql命令行直接輸入;回車):
use cAuth;
update cAppinfo set appid = 這里是AppID,secret =這里是 AppSecret;
5.為會話服務器云主機安全組添加默認安全組放通全部端口,并更改優先級在前面
6.更新/opt/lampp/htdocs/mina_auth/system/db/vi db.ini內容為以下:
[db]
host = 數據庫MySQL內網地址
port = 3306
user_name = session_user
pass_wd = 新密碼
data_base= cAuth
或
[db]
host = 數據庫MySQL內網地址
port = 3306
user_name = root
pass_wd = root密碼
data_base= cAuth
會話服務器文件存放路徑/opt/lampp/htdocs
關于數據庫服務器:如果有數據表格需要導入,如果你要導入的.sql文件大于2048k,可以壓縮成zip,一般可以壓縮到原來的1/20,壓縮比率還是很可觀的。
騰訊云實名認證后可以獲得騰訊云的代金券,還可以更好的保障你的號安全,認證后你的騰訊云號也是獨一無二的。具體見實名認證指引,大約1-2個工作日。
為了保護小程序應用安全,微信官方的需求文檔要求每個微信小程序必須事先設置一個域名,并通過HTTPS請求進行網絡通信,不滿足條件的域名和協議無法請求。所以需要購買或申請SSL證書。目前正規渠道購買SSL證書還是很貴的,不過如果您選的是微信小程序方案,這個SSL證書是免費的(大約需要1個工作日審核下發),頒發后會獲得一個壓縮包,內含安全證書。安裝ssl證書參考這里,把ssl證書壓縮包內Nginx下的證書拷貝至/etc/nginx下
至此,環境算搭好了,剩下的就專注于你的小程序開發了。
我最初是想做一個車友會之類的小程序,但涉及車友互動發文之類,需要有互聯網電子公告服務許可證, 總之各種條條框框。反正我是練手,還是繞過這個限制,改做記賬本之類的小工具了,鑒于目前小程序只能匹配全名,只在個別關鍵詞開啟了模糊匹配,經過查驗,“養車”和“記賬”兩個詞都可以模糊搜索,所以名字就叫“養車記賬本”了,可以給車主提供個專門記錄養車所產生的費用的統計工具。從用戶開始訪問小程序開始,大概流程圖如下:
主要涉及以下幾個功能:增加記賬、賬單列表、賬單篩選、修改賬目、刪除賬目、賬單統計、車型選擇、分類設置等。
增加記賬和修改賬目可以共用同一個界面,根據實際需要,要用到賬單分類、賬單產生日期,再就是額度。記賬頁面操作簡單,見后面設計圖。
賬單列表頁和賬單統計作為一個展示模塊,需要能夠通過設置篩選條件比如時間段、類別勾選來展示指定賬目,展示方式為按時間列表,統計方式為餅圖。
用戶可以設置車型,可以不填。如果用戶有不止一輛車,這個必須為必填,不過第一版先不考慮多輛車這個維度,后期再加。
至于分類,我大概歸納了一下用車、養車過程可能產生費用的方面,大概包括(停車費、加油費、養護、保險、罰款、高速、維修、購車、年檢、改裝、賠償等),如果不夠用可以在分類設置里增加分類,如果用不到的可以關閉,避免干擾。
再就是象征性的來個建議反饋、關于之類的。
小程序有推薦的設計規范,見微信小程序設計指南,為方便設計師進行設計,微信提供一套可供Web設計和小程序使用的基礎控件庫;同時提供方便開發者調用的資源。設計小程序推薦以iphone6的尺寸為標準,即750px*1334px。
其中圖標我用的鋼筆工具,選擇的2像素路徑描邊,無填充色。一共分兩種狀態:選中狀態和未選中狀態。未選中狀態描邊色# 7a7e83,背景色# f5f5f5;選中狀態描邊色#ffffff,背景色# 1aad19 。
開始碼代碼了,開發分前端和后臺。
小程序在前端上的貢獻不得不點贊,wxss在css的基礎上擴展了rpx(responsive pixel)單位,rpx換算px為屏幕寬度/750,px換算rpx為750/屏幕寬度。這樣就可以根據屏幕寬度進行自適應,讓前端開發可以解放出來不用過多考慮兼容問題。使用rpx規定屏幕寬為750rpx,比如在 iPhone6 上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。wxml是 微信 的一套標簽語言,結合基礎組件、事件系統,可以構建出頁面的結構。開發工具不大好用(遇到N次閃退,有個好的保存習慣還是不錯的;還有就是調試時候如果需要點開非默認頁面,有時候不能刷出Wxml結構,重啟開發工具可以解決),但畢竟不是一天兩天打造完美的,相信微信團隊一定能做更好。如果不習慣也可以用你喜歡的工具。我的頁面結構如下:
"pages":[
"pages/add/index/index",
"pages/statistics/index/index",
"pages/my/index/index",
"pages/my/autoBrand/autoBrand",
"pages/my/autoSerial/autoSerial",
"pages/my/autoModel/autoModel",
"pages/my/sort/sort",
"pages/my/feedback/feedback",
"pages/my/about/about",
"pages/other/reLogin/reLogin"
],
如果問你,小程序放開的用戶數據夠嗎?你一定說不夠。那我們能做的就是物盡其用吧!如果你的接口涉及wx.getUserInfo當中的 openId,接口的明文內容將不包含這些敏感數據。如果需要獲取敏感數據,需要對接口返回的加密數據( encryptedData )進行對稱解密??蓞⒖嘉⑿判〕绦蚩蛻舳蓑v訊云增強 SDK。
在微信登錄,解密encryptData后,可以在userInfo里可以看到用戶信息
在登錄后做了這些工作:獲取用戶信息,對照數據庫,如果庫里有該用戶,將車型和類別設置存儲到本地,以供其他頁面調用;如果沒有則保存該用戶。如果庫里有該用戶且設備信息有變化則更新設備信息,如果沒有則追加設備信息。如果用戶拒絕獲取用戶信息,授權失敗,顯示重新授權教程。篇幅有限,只截取部分代碼展示。代碼如下:
// 用戶登錄
UserLoginFn:function(){
var that = this;
// qcloud.request() 方法和 wx.request() 方法使用是一致的,不過如果用戶已經登錄的情況下,會把用戶的會話信息帶給服務器,服務器可以跟蹤用戶
qcloud.request({
url: config.service.requestUrl, // 要請求的地址
login: true, // 請求之前是否登錄,如果該項指定為 true,會在請求之前進行登錄
success(result) {
wx.setStorageSync('ThisUserInfo', result);
var usr = result.data.data.userInfo;
that.setData({
ThisUserInfo: result
});
wx.setStorageSync('OpenID', usr.openId);
// 用戶登錄(如果庫里有該用戶,將車型和類別設置存儲到本地,如果沒有則保存該用戶)
wx.request({
url: 'https://xxx.php', //這里不是真實地址
data: {
OpenID: usr.openId,
NickName: usr.nickName,
AvatarUrl: usr.avatarUrl,
Gender: usr.gender,
Country: usr.country,
Province: usr.province,
City: usr.city
},
success: function(res) {
if(res.data){
wx.setStorageSync('ThisUserInfoModelID', res.data.ModelID);
wx.setStorageSync('ThisUserInfoSortIDList', res.data.sortIDList);
that.sortFormat(); // 登錄成功后為該用戶格式化表單
}
}
});
// 用戶設備信息采集
wx.getNetworkType({
success: function(res) {
// 返回網絡類型, 有效值:wifi/2g/3g/4g/unknown(Android下不常見的網絡類型)/none(無網絡)
var networkType = res.networkType;
wx.getSystemInfo({
success: function(res) {
// 如果庫里有該用戶且設備信息有變則更新設備信息,如果沒有則追加設備信息
wx.request({
url: 'https://xxx.php', //這里不是真實地址
data: {
OpenID: usr.openId,
Model: res.model,
System: res.system,
Language: res.language,
Version: res.version,
Platform: res.platform,
Network: networkType,
WindowWidth: res.windowWidth,
WindowHeight: res.windowHeight,
DevicePixelRatio: res.pixelRatio
}
});
}
})
}
});
},
fail(error) {
wx.showModal({
title: '提示',
content: '未授權不可使用,請刪除后重新獲取養車記賬本。',
showCancel: false,
confirmText: '查看教程',
confirmColor: '#3CC51F',
success: function(res) {
if (res.confirm) {
wx.redirectTo({
url: '/pages/other/reLogin/reLogin'
});
}
}
});
}
});
},
前端開發過程中遇到的問題順便提一句,canvas、textarea、video等組件使用原生渲染,如果需要彈層交互的話它們會擋住彈層,解決辦法就是在彈層后將這些組件hidden屬性設置為true,彈層消失時重置為false。另外還有個問題:我想把data里的數據保存成對象格式的,如果追加key值的話,不支持a.b:'c'這樣追加,只能a:{b:'c'},但前者可以更直觀的表示某一組賦值是給一個特定對象的,尤其有時候不能確定你要追加的key值就限于你指定的那幾個的時候,但setData并不支持這種做法,不知是出于何種考慮,如果沒有特殊原因還是希望能改進下。再有就是css不支持標簽名選擇器,也是目前支持標簽比較單一,所以要想美化某個組件,必須給它實實在在賦個樣式,略顯臃腫。
后臺開發語言我選的是PHP,主要是網上資料多,函數方法齊全。關于PHP對MySQL的增刪改查操作網上很容易找到。在同事的指點下,采取了一些措施,防止SQL注入與XSS攻擊,主要是過濾文本,做了字符串轉換、格式化等操作。在賬單查詢頁面,通過聯合查詢列出用戶表和賬單表信息,對查詢結果裝入數組,之后進行格式化輸出供小程序使用,代碼如下:
$accountArr = array();
$MonthList = array();
$dateTemp = '';
$switch = false;
function wk($date1) {
$datearr = explode('-',$date1); //將傳來的時間使用“-”分割成數組
$year = $datearr[0]; //獲取年份
$month = sprintf('%02d',$datearr[1]); //獲取月份
$day = sprintf('%02d',$datearr[2]); //獲取日期
$hour = $minute = $second = 0; //默認時分秒均為0
$dayofweek = mktime($hour,$minute,$second,$month,$day,$year); //將時間轉換成時間戳
$shuchu = date('w',$dayofweek); //獲取星期值
$weekarray = array('星期日','星期一','星期二','星期三','星期四','星期五','星期六');
return $weekarray[$shuchu];
}
while($row = mysql_fetch_array($result,MYSQL_ASSOC)){
if( $switch && (substr($dateTemp,0,7) != substr($row['Date'],0,7)) ){
$monthTemp = array(
'Month' => substr($dateTemp,0,7),
'MonthList' => $MonthList
);
$accountArr[] = $monthTemp;
$MonthList = array();
}
$temp = array(
'ID' => $row['ID'],
'Date' => $row['Date'],
'DateWk' => substr($row['Date'],8,2).'日 ('.wk($row['Date']).')',
'SortID' => $row['SortID'],
'Name' => $row['Name'],
'Mony' => preg_replace('/^0+/','',$row['Mony'])
);
$MonthList[] = $temp;
$dateTemp = $row['Date'];
$switch = true;
}
$monthTemp = array(
'Month' => substr($dateTemp,0,7),
'MonthList' => $MonthList
);
$accountArr[] = $monthTemp;
if($dateTemp == ''){ // 如果沒有結果
$accountArr = array(); //返回空數組
}
$str = json_encode($accountArr); //將數組轉化為json格式的字符串
echo $str;
針對自己的項目,需要設計合理的數據庫表以滿足記賬的需要。關于賬單表字段設置如下:
CREATE TABLE `user_account` (
`ID` int(10) UNSIGNED NOT NULL COMMENT '指針',
`OpenID` varchar(32) NOT NULL COMMENT '用戶ID',
`SortID` int(10) UNSIGNED NOT NULL COMMENT '類別ID',
`Mony` decimal(11,2) UNSIGNED ZEROFILL NOT NULL DEFAULT '000000000.00' COMMENT '金額',
`Date` date NOT NULL COMMENT '添加日期'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='賬目表';
此外還有用戶表、設備表、類別表、車型表。除了車型表獨立存在之外,其他幾個表都是以OpenID字段相互關聯的,以實現相互間的互查。
開發者工具 集成了開發調試、代碼編輯及程序發布等功能,其中模擬器模擬微信小程序在客戶端真實的邏輯表現,對于絕大部分的 API 均能在模擬器上呈現出正確的狀態。自帶的調試工具分為 6 大功能模塊:Wxml、Console、Sources、Network、Appdata、Storage,平時開發的時候及時糾錯,問題不大。馬上就要車展了,鑒于時間關系,第一版就這樣匆匆提交了。不過比較幸運,首次提交就通過審核了。
提交審核需要填一些簡單的信息,有利于用戶快速搜索出你的信息。之后可以在微信公眾平臺查看數據分析,其中的自定義分析功能強大(不過目前正在內測中,暫時只支持開發者測試數據上報;6.5.4及以上微信版本支持用戶數據上報,用戶微信版本更新以前無法收集數據。新版本覆蓋全量用戶前,數據可能有缺失),可以從不同角度分析訪問者信息,為你進一步挖掘用戶信息做足準備。
隨著小程序不斷增長,越來越多的小程序滲透到網友生活、工作的方方面面。弱水三千只取一瓢。本著滿足客戶某項需求的前提下盡量做一個小而美的工具。
問題是養車記賬本目前只具雛形,限于時間和個人能力,班門弄斧,只完成了基礎功能,還有很多細節需要調整,功能也不太完善,比如篩選交互邏輯還需要進一步優化,每個網友現在也只能為一輛車記錄賬單,賬單統計還可以列出篩選具體額度以及增加趣味評價,甚至可以考慮增加位置定位等功能……也懇請大家提出寶貴意見,未來一個月比較忙,等車展過后繼續!
最后,感謝hjiang、ningtian給出的好點子,感謝wqcheng給出的服務器升級、部署方面的指導,感謝lightllchen在php開發方面的幫助。