序言
對於一名開發者來說,獨自開發一款小程式與App,也許總會有一些疑問:
1. 需要掌握哪些技術?
答:java、vue、及常規Linux命令
2. 需要多少成本?
答:伺服器購買,雲伺服器新人50多三年;
域名購買,10塊的域名夠用,後續每年30左右的續期費用;
簡訊套餐購買,50塊錢,夠用很久了;
微信小程式釋出,需要300塊錢的稽核費用;
ios版本的App釋出,貌似也要錢。
3.需要多久完成?
答:如果第一次,需完成域名備案、伺服器環境搭建、程式基礎功能開發等,可能用時較久;
如果第二次,僅僅在第一次的基礎加改程式碼,短時間可以完成就夠了。
1. 心得說明
本文基於個人開發和釋出《九雲題庫》H5/微信小程式/APP的經驗,分享從零到完成一套完整系統開發、釋出的全過程,其中涉及到部署資源的獲取,開發過程、部分程式設計思路、注意事項以及最終部署方法等。
1.1 功能說明
- 實現PC端/H5/App/小程式4端的常規登陸/註冊/更新等
- 實現題目分類和題目的增刪改查功能,支援手機端和PC端操作
- 實現題目收藏/取消收藏,移動端
- 實現錯題記錄/移除記錄,移動端
- 實現刷題/看題/搜題功能,移動端
- 實現題目提問/留言討論功能,移動端
- 其它移動端的基礎必備功能
1.2 附件截圖
以下是App、H5、微信小程式三個移動端的部分截圖
2. 實現方案
1.1 資源方案
2.1.1 伺服器選擇與規劃
伺服器選擇,系統需要有一個承載平臺,因此需要一個伺服器,購買雲伺服器centos7系統是一個不錯的選擇,或者使用其它伺服器。
伺服器規劃,軟體和應用盡可能都放在/home路徑,方便統一管理,如:/home/app放系統軟體
/home/nginx放nginx配置
/home/docker放docker映象
/home/minio放minio檔案
/home/mysql_tump放mysql備份檔案
注:軟體安裝最好修改預設埠,否則伺服器容易被攻擊。
2.1.2 伺服器-jdk環境
將下載好的 jdk-8u211-linux-x64.tar.gz 放在 /home/app 路徑
# 進入目錄解壓 tar -zxvf jdk-8u211-linux-x64.tar.gz # 修改環境變數 vi /etc/profile # 新增以下配置 export JAVA_HOME=/home/app/jdk1.8.0_211 export CLASSPATH=${JAVA_HOME}/lib export PATH=$PATH:${JAVA_HOME}/bin # 應用配置 source /etc/profile # 校驗是否成功 javac java -version echo $PATH
2.1.3 伺服器-埠開通
雲伺服器平臺需要開通埠,伺服器啟用防火牆,開通各個服務的埠,以下是centos7下的防火牆相關操作,同時雲伺服器平臺也需要開通對應的埠
# 檢視防火牆狀態 systemctl status firewalld.service # 永久啟用防火牆 systemctl enable firewalld.service # 檢視防火牆配置情況 firewall-cmd --list-all # 檢視埠 netstat -apn | grep 8080 # 新增/移除埠 firewall-cmd --permanent --zone=public --add-port=8080/tcp firewall-cmd --permanent --zone=public --remove-port=80/tcp # 新增區間型別的埠 firewall-cmd --zone=public--add-port=4400-4600/udp --permanent firewall-cmd --zone=public--add-port=4400-4600/tcp --permanent # 重新載入防火牆 firewall-cmd --reload
2.1.4 伺服器-Nginx
執行命令-增加支援ssl
# 下載nginx包,解析到/home/app/nginx,安裝命令 ./configure --prefix=/home/app/nginx --with-http_ssl_module make make install nginx -V # 啟動nginx服務,切換目錄到/home/app/nginx/sbin下面 ./nginx # 重新載入配置|重啟|停止|退出 ./nginx -s reload|reopen|stop|quit # 檢視nginx服務是否啟動成功 ps -ef | grep nginx # 配置nginx全域性 vim /etc/profile # nginx NGINX_HOME=/home/app/nginx export PATH=$PATH:$NGINX_HOME/sbin # 應用配置 source /etc/profile
Nginx配置說明,在/home/app/nginx/conf/nginx.conf的http下增加引用配置,其具體nginx配置只需在引用目錄新增即可,方便管理和維護
include /home/nginx/conf/conf.d/*.conf;
在引用目錄下編寫對應各個需求的nginx配置,一個nginx配置寫一個檔案,cert專門放ssl證書
2.1.5 伺服器-gitea
安裝原始碼管理工具,gitea很佔用伺服器效能資源,也可以使用開源平臺
# nginx配置 server { listen 443 ssl; server_name git.ninecloud.top; ssl_certificate /home/nginx/conf/conf.d/cert/git.pem; ssl_certificate_key /home/nginx/conf/conf.d/cert/git.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:3000/; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; } }
2.1.6 伺服器-docker
安裝docker並設定遠端訪問,設定遠端訪問後,方便idea直接釋出後端
# 安裝docker yum install docker-ce # 啟動docker systemctl start docker # 設定開機自啟 systemctl enable docker # 配置docker遠端訪問 vi /usr/lib/systemd/system/docker.service # 在ExecStart=/usr/bin/dockerd後面新增 -H tcp://0.0.0.0:2375 # 重新載入和重啟 systemctl daemon-reload systemctl restart docker.service
2.1.7 伺服器-minio
安裝成功後,瀏覽器開啟9090埠,建立Minio倉庫並設定許可權,既可在後端配置使用,此處透過docker安裝minio
# 下載映象 docker pull minio/minio # 檢視映象 ddocker images # 建立兩個目錄,一個用來存放配置,一個用來儲存上傳檔案的目錄,啟動前需要先建立Minio外部掛載的配置檔案( /home/minio/config),和儲存上傳檔案的目錄( /home/minio/data) mkdir -p /home/minio/config mkdir -p /home/minio/data # 啟動 docker run -p 9000:9000 -p 9090:9090 \ --net=host \ --name minio \ -d --restart=always \ -e "MINIO_ACCESS_KEY=yourAccount" \ -e "MINIO_SECRET_KEY=yourPassword" \ -v /home/minio/data:/data \ -v /home/minio/config:/root/.minio \ minio/minio server \ /data --console-address ":9090" -address ":9000"
2.1.8 伺服器-redis
# 安裝 wget http://download.redis.io/releases/redis-6.2.1.tar.gz tar xzvf redis-6.2.1.tar.gz cd redis-6.2.1 make cd src make install PREFIX=/home/app/redis # redis全域性環境/etc/profile REDIS_HOME=/home/app/redis export PATH=$PATH:$REDIS_HOME/bin # 設定密碼,配置/home/app/redis/redis.conf # bind 127.0.0.1 -::1 daemonize yes protected-mode no requirepass yourPassword
最後這步很重要,修改redis埠,個人伺服器曾因未修改埠被攻擊,修改埠號方式
/home/app/redis/redis.conf # 改變預設埠號port 5268
2.1.9 伺服器-mysql8
安裝mysql8後,對於每個系統,要使用單獨的資料庫以及單獨的賬號,避免某個資料庫賬號洩露導致所有資料庫資料洩露的風險。
備份資料很重要,透過Linux的定時任務crontab,實現資料庫每日備份,並刪除過期的備份
在scripts中寫入備份和刪除備份指令碼
// 備份指令碼 vim /home/mysql_tump/scripts/backup.sh #!/bin/bash # 備份目錄 BACKUP_ROOT=/home/mysql_tump BACKUP_FILEDIR=$BACKUP_ROOT/files BACKUP_LOGDIR=$BACKUP_ROOT/logs # 當前日期 DATE=$(date +%Y%m%d) DATABASES=(testdb test2db) # 迴圈備份 echo 'Begin for mysql tump!' for db in ${DATABASES[@]} do echo 'Is tumpping' ${db} mysqldump --defaults-extra-file=/etc/my.cnf --default-character-set=utf8 --lock-all-tables --flush-logs --log-error=$BACKUP_LOGDIR/${db}_$DATE.error.log -E -R -B ${db} | gzip> $BACKUP_FILEDIR/${db}_$DATE.sql.gz done echo 'Success for mysql tump!'
// 刪除過期備份 vim /home/mysql_tump/scripts/backup_rm.sh #!/bin/bash # 刪除備份 echo 'Begin for remove tump!' find /home/mysql_tump/files -type f -mtime +5 | xargs rm -f find /home/mysql_tump/logs -type f -mtime +5 | xargs rm -f echo 'Success for remove tump!'
編輯Linux自帶的crontab任務,加入備份和刪除備份兩個任務
// 定時任務 crontab -e 00 05 * * * bash /home/mysql_tump/scripts/backup.sh 30 05 * * * bash /home/mysql_tump/scripts/backup_rm.sh
2.1.10 域名選擇與規劃
小程式只支援https域名式地址,因此必須有一個域名。可在雲服務商註冊購買域名或其它域名方式,域名需要進行備案。
域名規劃,可以解析多個子域名。子域名全部指向伺服器IP,具體子域名透過nginx指向不同的埠,負載均衡也由nginx完成,透過不同域名指向不同的領域系統或功能,如:
www.ninecloud.top — 網站首頁與靜態檔案路徑
api.ninecloud.top — 介面
fs.ninecloud.top — Nginx檔案服務
minio.ninecloud.top — Minio檔案服務
git.ninecloud.top — Gitea服務
doc.ninecloud.top —文件服務
每個子域名需要各自申請ssl證書,將證書檔案放在伺服器並在nginx裡配置,即可實現https訪問,在雲服務商購買的域名都有免費的ssl證書可用。
2.1.11 簡訊方案
系統存在驗證碼登入,找回密碼等場景,因此有簡訊傳送需求,可購買各服務商平臺的簡訊套餐,接入系統
傳送簡訊需要在服務商的雲平臺申請簽名和模版,各個雲平臺管理都比較嚴格,尤其是個人使用者,申請簽名和模版很難成功,需要耐心。
2.1.12 微信公眾平臺
微信釋出小程式,需要在微信公眾平臺註冊小程式賬號,進行一些認證,https地址白名單設定,許可權設定等,拿到後續開發需要的AppID,AppSecret等關鍵資料。
2.1.13 其它小程式平臺
嘗試成功釋出過支付寶小程式,和微信小程式大同小異。
2.1.14 App釋出
透過jre生成Android簽名證書,然後使用開發工具HbuilderX工具打包成apk檔案,放在伺服器,使用者直接透過瀏覽器下載即可安裝使用。
Window本地生成App證書方式,dos命令進入jre目錄
// 生成證書 # testalias為證書別名,test.keystore為證書名稱 keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore # 中間的內容不用填,在最後的提示中,確認證書密碼 Enter key password for <testalias> (RETURN if same as keystore password):
在HbuilderX中,打包app時,需要用到上面的檔案,別名,和密碼
1.2 程式碼方案
2.2.1 開發釋出說明
工具說明:
後端工具idea 框架若依Plus
前端工具VsCode 框架若依vue3
移動端工具HbuilderX 框架uniapp vue3
微信小程式的devtools
資料庫工具dbever
伺服器工具Xshell、Xftp
其它工具,介面除錯postman,P圖工具photoshop,redis客戶端等
釋出說明:
後端釋出,在idea設定docker遠端連線,打包jar,以docker命令部署
前端部署,生成靜態檔案,上傳伺服器/home/www/msw/目錄
移動端H5,生成靜態檔案,上傳伺服器/home/www/uquestion目錄
移動端App,打包生成Apk後,上傳/home/nginx/apk目錄,透過系統配置指定路徑和版本確定apk地址,App端可自動觸發升級,H5端可點選下載
移動端微信小程式,HbuilderX生成小程式專案檔案,透過微信小程式工具開啟檔案上傳即可,然後進入微信公眾平臺,進行稽核升級
2.2.2 後端開發-資料庫設計
分類表
問題表
評論表
日誌表
2.2.3 後端開發-框架基於若依Plus
在若依plus基礎上增加ruoyi-question模組,單獨存放題庫相關功能。
其中四個controller分別是:class-題目分類,option-題目,log-收藏和錯題,comment-提問與回覆
透過SaToken的SaMode.OR模式,給PC端和手機端都需要的介面增加兩個任意滿足許可權,手機端通用基礎許可權可固定為app:base:api,使用者註冊會預設給到相關許可權,許可權程式碼例如:
@SaCheckPermission(value = {"question:class:list", "app:base:api"}, mode = SaMode.OR) @GetMapping("/getAllList") public R<List<QuestionClass>> getAllList(QuestionClass entry) { return R.ok(baseService.getAllList(entry)); }
2.2.4 後端開發-登陸/序號產生器制
登入有兩種方式,賬號密碼登入和手機號驗證碼登入,個人版的微信小程式只能獲取OpenId無法獲取手機號,OpenId唯一可用於登入, 但由於多端可註冊可登入,避免同一使用者出現兩個賬號,因此小程式放棄OpenId登入,與其它端保持一致。
以下是登陸Body檔案, 其中透過登陸型別type來區分兩種登陸方式,透過registerFlag來判斷手機號驗證碼登入時,系統沒有賬號是否自動註冊。
@Data public class AppLoginBody { /** * 登入型別,0-密碼登入,1-驗證碼登入 */ @NotBlank(message = "登入型別不允許為空") private String type; /** * 使用者賬號 */ @NotBlank(message = "{user.username.not.blank}") @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}") private String username; /** * 使用者密碼 */ private String password; /** * 驗證碼 */ private String smsCode; /** * 註冊標記 為1表示無使用者則註冊 */ private String registerFlag; }
2.2.5 後端開發-其它說明
其它還需使用後端的功能有:公告,系統配置,退出登入,更新使用者資訊或頭像,找回密碼,傳送簡訊,生成二維碼等
2.2.6 前端開發-框架基於若依Vue3
將若依前端程式碼進行深度改造,樣式程式碼儘可能單獨提出來在index.scss引入,統一管理,如表格樣式,彈窗樣式,樹樣式等。
好處是儘可能在具體頁面不再寫css內容,確保整個系統樣式統一,便於維護和修改。
表格樣式
將函式方法元件分四個引用檔案一次性引入,避免在main.js檔案內寫太多的內容,不利於維護和管理
如框架工具具體情況如下,後續新增公共js方法檔案,直接在此檔案新增即可;新增單個的方法,直接在對應檔案新增方法即可,無需再引用。
2.2.7 前端開發-題目分類管理
題庫分類,使用樹形結構設計,支援增刪改查和複製,以及點選題目數量跳轉到對應分類的題目管理頁面
分類的編輯
2.2.8 前端開發-題目管理
題目管理,除常規的增刪改查外,還有批次刪除和複製功能,列表支援單擊勾選,表格關鍵字過濾題目,列顯示隱藏等。
編輯功能,選項支援新增與刪除,新增時,自動按ABCDE…的順序排列,刪除時重新排列順序。
2.2.9 移動端開發-框架參考若依App
僅僅是參考若依App移動端,第一是因為若依App是vue2版本,第二是因為若依App很多功能都沒有開發,不足以支撐完整功能。
與PC端一樣,儘可能把樣式檔案單獨提取出來,避免重複寫css,如圖片樣式,廣告樣式,列表樣式等
由於移動端的樣式複雜多變,很難固定統一,所以用基礎樣式,將常用的樣式全部寫好,html的class直接用即可。
公共方法的引用,同前端一樣,由一個檔案引用全部方法,然後在main.js裡面引用此檔案,方便維護和管理。
元件引用,uniapp元件只需要按規範寫在components檔案下即可
2.2.10 移動端開發-功能規劃
App採用常規設計,有三個導航按鈕,分別是首頁,題庫,我的
首頁,最上用滾動banner和動態公告,讓系統有一些動感,下方放直通分類的題目。
題庫頁,使用樹形結構展示所有分類和題目,最上方搜尋欄可以過濾題目和選擇是否有答案的題目。
我的頁,常規功能是使用者資訊,上傳影像,邀請好友,設定等,其中系統設定、題庫分類、題目管理不在App基礎許可權內,一般使用者未授權前不可見,我的收藏和我的錯題記錄刷題過程中的操作。
2.2.11 移動端開發-登陸機制
對於移動端,使用者登陸後,如果以賬號密碼方式登陸,則儲存使用者名稱密碼,同時儲存獲取到的token等資訊,後續登陸同PC前端一樣,header中攜帶token進行訪問;
不同之處在於,移動端token過期後,自動觸發重登陸機制,用儲存中的賬號密碼自動重新登入,使用者是沒有任何感覺的,避免每次開啟都要重新登陸。同時設定退出和清除快取功能,讓使用者可以清除快取資訊。
2.2.12 移動端開發-上傳影像
若依App原版上傳影像擷取,圖片是鋪滿方式,支援有限,個人用不慣。重寫影像裁剪元件,經過一番除錯後,相容H5、App和微信小程式。
元件支援左右上下翻轉、不同角度的旋轉、不同程度的放大縮小,支援預覽等。
2.2.13 移動端開發-App更新機制
H5端直接顯示最新版本,支援下載App。
App端每次更新一個版本進行打包,將打包的apk檔案以版本號命名,上傳到檔案伺服器,準備釋出新版本直接就改配置引數為對應版本即可;
使用者登陸後獲取到最新引數配置,其中有App的版本號,和當前系統版本號比對,如果不一致則提醒使用者更新。
以下分別是App-我的頁面,App關於頁面,H5關於頁面情況
2.2.14 移動端開發-分類/題目管理
分類和題目管理,都採用樹形結構,移動端錄入題目一樣支援複製,但如果在手機端操作還是沒那麼方便,如果是修改或者是新增少量,倒是比較快,如果很多,用電腦以H5地址開啟,或者直接在後端管理錄入,效果更好
2.2.15 移動端開發-題庫刷題
刷題頁面支援搜尋,搜尋後非末級也顯示題目數量,並可點選進入搜尋內容的全部題目
2.2.16 移動端開發-其它功能
邀請好友,伺服器根據使用者影像生成二維碼,更改二維碼樣式顏色等。
設定-含公告檢視,修改密碼,聯絡我們,清空快取,關於,退出登入
3. 總結一下
做一套完整的系統,可以完善自己所學的知識,找到自己的弱項,也有一種成就剛。
題庫功能還有最佳化空間,如題庫型別需要問答型題目,題目還可以展示做題人數,正確率等資訊,評論支援上傳圖片等。