摘要:小程序心理學辭典應(yīng)用開發(fā)的心得前言最近學習小程序,用了五天工作之余從開始,到一個簡單的完成,有點心得,記錄下來。數(shù)據(jù)庫方面,小程序最近推出云開發(fā)的服務(wù),這東西類似,這些后端云服務(wù),而且這些第三方的服務(wù)對微信支持的也不錯。
小程序-心理學辭典應(yīng)用開發(fā)的心得 前言
最近學習小程序,用了五天工作之余從0開始,到一個簡單的App完成,有點心得,記錄下來。
想法最近在學習算法動態(tài)規(guī)劃那部分,有點感悟,不要想著怎么樣讓整體結(jié)果最優(yōu),因為在系統(tǒng)足夠復雜的情況下太消耗時間。如果按貪婪算法的思路,讓每一步都是當下最優(yōu),也許結(jié)果并不是最優(yōu),但也足夠優(yōu)秀了,關(guān)鍵時間很快。
所以這次寫項目改了思路,不像之前設(shè)計的很完整后再做,這次只先做最核心的功能,其他功能暫時用簡單技術(shù)替代,先做出東西來,再慢慢優(yōu)化。
坑還是只有走過了才印象深刻。
前陣子剛學習了心理學皮毛,里面有個心理學詞典的內(nèi)容,我覺得很受用,就像做個詞典類的App,讓我能時常回顧溫習,運氣好的話還可以幫助到別人。
所以我的核心需求就是:做個“心理學辭典”,能夠瀏覽各個詞條,并推薦一些文章供擴展閱讀。
花了點時間大致構(gòu)思了下,我要做的事情有:
設(shè)計原型
設(shè)計界面
設(shè)計數(shù)據(jù)庫
技術(shù)選型
瀏覽一遍小程序文檔(不用深入,只需要知道它有哪些能力,在大腦建個索引,需要時能快速查找)
數(shù)據(jù)庫方案
制作測試數(shù)據(jù)
開發(fā)階段
界面制作
數(shù)據(jù)
優(yōu)化
總結(jié)歸納
進入開發(fā) 設(shè)計原型因為需求簡單,原型也不需要高保真,手繪就搞定了。一個搜索框,一個標簽列表,一個結(jié)果列表。一個詞典的內(nèi)容并不會很多,可以在列表項中直接做展開。
因為詞典數(shù)據(jù)量有限,選擇一次加載完所有的項目(包含_id,name,tags),點擊后查詢詳情緩存結(jié)果,再展開。
搜索有兩種模式,普通搜索和標簽搜索。為了更好展示,這里設(shè)計成,tag搜索也當做條件,只是在前面加個“#”號。
具體交互效果可查看小程序。
交互稿確定后,去網(wǎng)絡(luò)上找了幾個對眼的設(shè)計稿,參考了下,在psd上大致設(shè)計了下(設(shè)計和PS技術(shù)太渣 ( ̄. ̄)|||)
數(shù)據(jù)庫設(shè)計App的第一階段做純展示,就涉及一張表
vocabulary(_id, name, tags, content, remark, links, create_at, update_at)
技術(shù)選型小程序的語法很簡單,和Vue有點相似,發(fā)展到如今有基于React的Taro,基于Vue的mpvue/wepy,還有uni-app。可選擇的挺多的,但是我任然選擇用小程序自帶的語法來寫,畢竟在用其他語法時,明白其原先的樣子總是有好處的。確實在實際過程中發(fā)現(xiàn)小程序自身語法設(shè)計不足與不同之處。
數(shù)據(jù)庫方面,小程序最近推出云開發(fā)的服務(wù),這東西類似Leancloud,Bmob這些后端云服務(wù),而且這些第三方的服務(wù)對微信支持的也不錯。這次項目選用云開發(fā),畢竟是一家的,集成的應(yīng)該會更好一些。不過實際使用過程中發(fā)現(xiàn)這玩意不足的地方很多,大項目慎用。
因為選用的技術(shù)都是沒有使用的技術(shù),這里就要用些策略了,我是這樣做的。
先把文檔大致看下,主要了解下大體情況,了解小程序和云開發(fā)的能力,在腦海里建立個索引,知道哪些內(nèi)容文檔里有,在要用到的時候就能快速查找。
遇到云開發(fā)增刪改查的問題,我是把常用的方法和場景都羅列到自己的筆記本里,為了更方便的查找
制作測試數(shù)據(jù)數(shù)據(jù)源主要來自《武志紅的心理學課》,在課程末尾老師有把講到的關(guān)鍵詞都羅列出來了。但是有個問題,老師給的那些資料里,都是以圖片展示的,如果一個個手動錄入也太不像程序員了。于是找了個Mac下好用的OCR工具iText,App Store里可以下載到。如此一來靜態(tài)文本數(shù)據(jù)就不是問題了,但是要怎么入庫呢?
云開發(fā)里有個通過CSV或JSON上傳數(shù)據(jù)的功能。那么我們就做個JSON文件吧。
又有個問題,在content字段里存的是比較復雜的文本數(shù)據(jù),JSON文件處理字符串麻煩。所以我借用yaml,把數(shù)據(jù)卸載yml文件里,然后寫個函數(shù)把結(jié)果翻譯成JSON
這里記錄幾個開發(fā)過程中遇到的幾個問題
獲取多條數(shù)據(jù)因為云開發(fā)有對取數(shù)據(jù)做限制,客戶端請求數(shù)據(jù)最多每次20條,云函數(shù)每次100條。因為我的需求是取出所有詞條的基本數(shù)據(jù),所以需要做點工作,我拿官方的代碼稍作修改:
// 云函數(shù)目錄/db_get_many_record/index.js const cloud = require("wx-server-sdk") cloud.init() const db = cloud.database() const MAX_LIMIT = 100 // 云函數(shù)一次最多獲取100條數(shù)據(jù) /** * 取出多條數(shù)據(jù) * wx.cloud.callFunction({ name: "db_get_many_record", data: { collection: "vocabulary", field: { name: true, tags: true }, } }).then().catch() */ exports.main = async (event, context) => { const { collection = "", where, field } = event let commond = db.collection(collection) if (collection === ""){ return; } if(where){ commond = commond.where(where) } // 先取出集合記錄總數(shù) const { total } = await commond.count() // 計算需分幾次取 const batchTimes = Math.ceil(total / 100) // 承載所有讀操作的 promise 的數(shù)組 const tasks = [] if (field) { commond = commond.field(field) } for (let i = 0; i < batchTimes; i++) { const promise = commond.skip(i * MAX_LIMIT).limit(MAX_LIMIT).get() tasks.push(promise) } // 等待所有 return (await Promise.all(tasks)).reduce((acc, cur) => { return { data: acc.data.concat(cur.data), errMsg: acc.errMsg, } }) }換存數(shù)據(jù)
為了減少請求的次數(shù),提示性能,緩存數(shù)據(jù)是必要的。我利用app.globalData,和微信提供的Storage能力。
本來是想用Map類型來做數(shù)據(jù)存儲的,但是Storage不支持這種數(shù)據(jù)類型。
內(nèi)容是分段落的,但是小程序本身是不支持html標簽的,但還好有個rich-text的組件可以用。
如何把自己收集的內(nèi)容翻譯成html的內(nèi)容?寫個腳本遍歷下。當然后期會寫個可視化的界面來管理內(nèi)容。
const fs = require("fs"); const readYaml = require("read-yaml"); readYaml("./data.yml", function(err, data) { if (err) throw err; // 處理content內(nèi)容 let result = data.map(item => { let _content = item.content.split(/[ ]/).map(item => { return "補充 總結(jié)目前小程序云開發(fā)會用到的代碼" + item + "
" }) item.content = _content.join("") return item }); fs.writeFileSync("./result.json", JSON.stringify(result)); });
const db = wx.cloud.database() const _ = db.command const xxCollection = db.collection("collection") /////////////////////////////////////// 查詢記錄 /////////////////////////////////////// xxCollection.doc("id").get() // ID查詢 db.collection("collection").doc("id").get().then(res => {}).catch(error => {}) // 條件查詢 db.collection("collection").where({}).get() db.collection("collection").where({name:_.eq("xxx")}).get() // _.eq neq lt lte gt gte in nin and or // 限制返回字段 db.collection("collection").where({}).field({name: true}).get() // 排序 db.collection("collection").where({}).orderBy("field", "asc|desc").get() // 分頁 db.collection("collection").where({}).skip(0).limit(10).get() // 統(tǒng)計 db.collection("collection").where({}).count() /////////////////////////////////////// 新增記錄 /////////////////////////////////////// db.collection("collection").add({ data:{ update_at: db.serverDate(), location: db.Geo.Point(113, 23) } }) /////////////////////////////////////// 更新數(shù)據(jù) /////////////////////////////////////// db.collection("collection").where({}).update({}) db.collection("collection").doc("id").set({}) // 替換記錄 db.collection("collection").doc("id").update({ data:{ // _.inc(自增) _.set(更新對象使用) _.push _.pop _.shift _.unshift(數(shù)組) } }) /////////////////////////////////////// 刪除數(shù)據(jù) /////////////////////////////////////// db.collection("collection").doc("id").remove() db.collection("collection").where({}).remove() // 目前只能在云函數(shù)里操作 //////////////////////////////////////// 文件 ///////////////////////////////////////// wx.chooseImage({ success: chooseResult => { // 將圖片上傳至云存儲空間 wx.cloud.uploadFile({ // 指定上傳到的云路徑 cloudPath: "my-photo.png", // 指定要上傳的文件的小程序臨時文件路徑 filePath: chooseResult.tempFilePaths[0] }) }, }) wx.cloud.downloadFile({ fileID: "", }) wx.cloud.deleteFile({ fileID: "", }) // 換取臨時鏈接 wx.cloud.getTempFileURL({ fileList: [], }) /////////////////////////////////////// 云函數(shù) //////////////////////////////////////// wx.cloud.callFunction({ name: "methodName", data: { a: 12, }, success: res => {}, fail: error => {}, complete: () => {} }) wx.cloud.callFunction({ name: "methodName", data: { a: 12, } }).then(res => {}).catch(error => {}) // error: errCode errMsg /////////////////////////////////////// 錯誤參考 /////////////////////////////////////// error => { let message; switch (error.errCode) { case -1: message = "通用錯誤" break case -401001: message = "無權(quán)限使用 API" break case -401002: message = "API 傳入?yún)?shù)錯誤" break case -401003: message = "API 傳入?yún)?shù)類型錯誤" break case -402001: message = "檢測到循環(huán)引用" break case -403001: message = "上傳的文件超出大小上限" break case -404001: case -404002: case -404003: case -404004: case -404005: case -404006: case -404007: case -404008: case -404009: message = "云函數(shù)調(diào)用失敗" break case -404010: message = "云函數(shù)執(zhí)行失敗" break case -601004: message = "無權(quán)限使用 API" break case -501001: message = "云端系統(tǒng)錯誤" break case -501002: message = "云端響應(yīng)超時" break case -501003: message = "請求次數(shù)超出環(huán)境配額" break case -501004: message = "請求并發(fā)數(shù)超出環(huán)境配額" break case -501005: message = "環(huán)境信息異常" break case -501009: message = "操作的資源對象非法或不存在" break case -502001: message = "數(shù)據(jù)庫請求失敗" break case -502002: message = "非法的數(shù)據(jù)庫指令" break case -502003: message = "無權(quán)限操作數(shù)據(jù)庫" break case -502005: message = "集合不存在" break case -503001: message = "云文件請求失敗" break case -503002: message = "無權(quán)限訪問云文件" break case -503003: message = "文件不存在" break case -504001: message = "云函數(shù)調(diào)用失敗" break case -504002: message = "云函數(shù)執(zhí)行失敗" break default: message = error.errMsg break } }總結(jié)
雖然初看小程序的語法和vue有點像,實際做起來,和想象的差太多,很多功能不支持,做起來不是那么順手
云開發(fā)的能力也很有限,解決一點簡單數(shù)據(jù)可以,稍微復雜點功能要自己用代碼實現(xiàn)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98389.html
摘要:程序員的思維是嚴謹?shù)箾]錯,但有時候卻不一定開闊。南京傳作為一個新南京人,聽聽老南京人講南京故事就挺好,這本書滿足了我的這個愿望。顧名思義,就是使用非暴力的方式進行溝通。這種感覺對于當下競爭激烈的程序員們來說真的是非常珍貴了。 ...
閱讀 4365·2021-11-24 10:24
閱讀 1409·2021-11-22 15:22
閱讀 2038·2021-11-17 09:33
閱讀 2428·2021-09-22 15:29
閱讀 515·2019-08-30 15:55
閱讀 1652·2019-08-29 18:42
閱讀 2731·2019-08-29 12:55
閱讀 1772·2019-08-26 13:55