<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      一、小程序部分

      這是理財(cái)系統(tǒng)的前端,江蘇海洋大學(xué)微信小程序比賽,最后獲得了一等獎(jiǎng)
      GitHub:https://github.com/GeorgeLeoo/finance
      <https://github.com/GeorgeLeoo/finance>

      1. 項(xiàng)目描述
      (1). 此項(xiàng)目為記賬小程序 (2). 包括賬單、圖表、搜索、用戶等多個(gè)子模塊 (3). 使用微信小程序技術(shù) (4). 采用模塊化、組件化、工程化等模式開發(fā)
      2. 項(xiàng)目功能界面



      在 1.0.2版本中刪除了扇形圖

      3. 項(xiàng)目目錄


      * pages:頁(yè)面 * components:組件 * utils:工具類 |-- util.js:工具類 |-- wxcharts.js:圖表插件 *
      images:資源圖片 * config:配置文件 * filter:過濾器 * http:網(wǎng)絡(luò)請(qǐng)求 |-- http.js:對(duì) wx.request 的封裝
      |-- api.js:對(duì)網(wǎng)絡(luò)請(qǐng)求接口的封裝
      4. 請(qǐng)求封裝

      一開始使用 wx.request 對(duì)數(shù)據(jù)進(jìn)行網(wǎng)絡(luò)請(qǐng)求,可寫完后,發(fā)現(xiàn)太過冗余,也太麻煩,故對(duì)其做了封裝。
      通過創(chuàng)建一個(gè)函數(shù)返回 Promise 對(duì)象,就可以屏蔽公共的部分
      // http/http.js /** * 對(duì)微信普通網(wǎng)絡(luò)請(qǐng)求封裝 * @param url 請(qǐng)求地址 * @param data 請(qǐng)求的參數(shù) *
      @param method 請(qǐng)求的方法類型 * @param headers 頭部信息,在這里主要是 token 認(rèn)證功能 * @returns
      {Promise<unknown>} 返回請(qǐng)求的 Promise 對(duì)象 */ function http({url, data, method,
      headers = {}}) { return new Promise((resolve, reject) => { wx.request({ url,
      method, data, header: { Authorization: headers.token, expiresIn:
      headers.expiresIn }, success: (result) => { const res = result.data; if
      (res.code === 0) { resolve(res.data); } else if (res.code === 1) {
      reject(res.msg); } // 隱藏 loading wx.hideLoading(); }, fail: (err) => {
      console.error('server error', err); } }); }) } /** * 對(duì)文件上傳接口封裝 * @param url
      請(qǐng)求地址 * @param fileOptions 文件配置項(xiàng) * @param data 請(qǐng)求發(fā)送的數(shù)據(jù) * @param headers
      頭部信息,在這里主要是 token 認(rèn)證功能 * @returns {Promise<unknown>} 返回請(qǐng)求的 Promise 對(duì)象 */
      function uploadFile({url, fileOptions, data, headers = {}}) { return new
      Promise(((resolve, reject) => { wx.uploadFile({ url: url, filePath:
      fileOptions.filePath, name: fileOptions.name || 'file', header: {
      Authorization: headers.token, expiresIn: headers.expiresIn }, formData: data,
      success: (res) => { console.log(res.data); if (JSON.parse(res.data).code === 0)
      { resolve(res.data); } else if (res.code === 1) { reject(res.msg); } }, fail:
      (err) => { console.error('server error', err); } }) })) } module.exports = {
      http, uploadFile };
      5. 遇到的問題
      (1). 在更新賬單數(shù)據(jù)后,如何更新賬單界面的數(shù)據(jù)? 這個(gè)問題我的解決方案是,在 globalData 中添加一個(gè)全部變量
      isRefreshBills,默認(rèn)為 false, 當(dāng)更新賬單數(shù)據(jù)成功后,將 isRefreshBills 修改為 true,同時(shí)返回到賬單界面,在賬單界面的
      onShow()方法中,判斷 isRefreshBills 是否為 true,若為 true 則重新請(qǐng)求數(shù)據(jù),同時(shí)將 isRefreshBills 設(shè)為
      false,否則不請(qǐng)求。這樣就避免了沒有更新數(shù)據(jù)的情況下多次請(qǐng)求數(shù)據(jù)。
      對(duì)這個(gè)解法,還有一種更加節(jié)流的方法,就是更新后不去請(qǐng)求,而是對(duì)原來的獲取到的數(shù)據(jù)進(jìn)行個(gè)別刪除。比如當(dāng)
      更新數(shù)據(jù)成功后,獲取一個(gè)被更新的這條數(shù)據(jù)的id,然后在賬單頁(yè)面的 onShow() 方法中,遍歷找到這個(gè) id 對(duì)應(yīng)的
      數(shù)據(jù),并刪除這條數(shù)據(jù)也能達(dá)到數(shù)據(jù)更新的效果 (2). 在進(jìn)行類別添加的時(shí)候,自定義的類別會(huì)出現(xiàn)雙倍? 由于我有一分部初始數(shù)據(jù)是存在 globalData
      中的,每次從服務(wù)器獲取自定義類別時(shí),都會(huì)對(duì)其進(jìn)行拼接, 在拼接的時(shí)候修改了原來的 globalData
      中的值,所以每次添加后都會(huì)請(qǐng)求一次自定義數(shù)據(jù),進(jìn)行拼接。 解決方案:禁止更新 globalData 中的數(shù)據(jù) (3). 返回哪個(gè)頁(yè)面問題?
      在賬單頁(yè)面可以進(jìn)去修改賬單的頁(yè)面,在搜索頁(yè)面也可以進(jìn)入修改賬單賬單的頁(yè)面,他們用的是同一個(gè)組件,
      那么如何保證在賬單頁(yè)面進(jìn)入修改賬單頁(yè)面后返回到賬單頁(yè)面,在搜索頁(yè)面進(jìn)入修改賬單頁(yè)面后返回到搜索頁(yè)面。
      首先在路由跳轉(zhuǎn)的時(shí)候添加當(dāng)前路由信息,然后在修改賬單頁(yè)面中接受這個(gè)路由信息,最后通過這個(gè)路由信息返回到原來的路由
      6. 總結(jié)
      這個(gè)項(xiàng)目是我5月份參加學(xué)校微信小程序的項(xiàng)目,兩個(gè)禮拜倉(cāng)促的做了這么一個(gè)項(xiàng)目,前后端都有,最后榮獲一等獎(jiǎng)。 在之前比賽用的版本中其實(shí)有很多的 bug
      以及卡頓現(xiàn)象居多,故這兩天我有對(duì)這個(gè)項(xiàng)目進(jìn)行了一定的維護(hù),發(fā)現(xiàn)原來的代碼實(shí)在
      慘不忍睹,現(xiàn)在經(jīng)過升級(jí),頁(yè)面卡頓現(xiàn)象減少,若后期再想維護(hù),也相對(duì)于之前的版本好維護(hù)多了,但是還有很多可以維護(hù)的空間。
      其實(shí)我并不對(duì)這個(gè)項(xiàng)目很滿意,比如之前我沒做分頁(yè)加載, 現(xiàn)在想加個(gè)分頁(yè)加載的功能,我發(fā)現(xiàn)并不是一下子就能搞定的,
      因?yàn)槲业臄?shù)據(jù)結(jié)構(gòu)不是很合理,因?yàn)楹蠖朔祷氐臄?shù)據(jù)和前端要顯示的數(shù)據(jù)格式是不一致,故前端要重新定義數(shù)據(jù)結(jié)構(gòu),
      所以對(duì)分頁(yè)來說就有一定的困難。在我對(duì)項(xiàng)目進(jìn)行維護(hù)后,代碼比以前更簡(jiǎn)潔,可讀性相對(duì)于之前的版本來說要更加好。
      二、服務(wù)器部分

      1.簡(jiǎn)述

      這個(gè)項(xiàng)目是微信小程序記賬 app 的后端代碼,使用技術(shù):MongoDB+Express。
      GitHub:https://github.com/GeorgeLeoo/finance-server
      <https://github.com/GeorgeLeoo/finance-server>

      這個(gè)項(xiàng)目的目錄是這樣的


      * config: 配置文件
      * routes: 路由配置
      * utils: 工具類
      * db: 操作數(shù)據(jù)庫(kù)的代碼
      * controller: 控制是當(dāng)前地址否要 token 驗(yàn)證
      * service: 如何調(diào)用操作數(shù)據(jù)庫(kù)函數(shù)(我也不知道為什么要寫controller,service,感覺這兩個(gè)寫一個(gè)就可以了)
      2.遇到的問題

      (1). token 驗(yàn)證問題?

      關(guān)于 token 驗(yàn)證問題我使用了 jsonwebtoken 插件,故先用 npm 安裝這個(gè)插件。
      token 驗(yàn)證流程大概如下圖:


      使用這個(gè)插件: 定義兩個(gè)方法,一個(gè)用來生成 token,另一個(gè)用來驗(yàn)證 token。
      /** * 生成token * @param {object} content 對(duì)某個(gè)內(nèi)容生成 token */ const
      access_token=function (content) { let secret =
      'jizhangxitongfinancegeorgeleeo'; // 秘鑰 let expiresIn = Math.round((new
      Date().getTime()/1000)) + 3600; // 過期時(shí)間 let token = jwt.sign(content, secret, {
      expiresIn }); return { token, expiresIn }; } /** * 驗(yàn)證token * @param {string}
      token token值 */ const check_token= function (token) { let secret =
      'jizhangxitongfinancegeorgeleeo'; // 秘鑰,根生成的 token 要一致 return new
      Promise((resolve, reject) => { jwt.verify(token, secret, (err, decode) => { if
      (err) { //時(shí)間失效或偽造 token 或 token 不存在 reject({ status: 10010, error:
      'invalid_token' }); } else { resolve(); } }); }) }
      在controller.js 中,去判斷 token 驗(yàn)證成功與否
      function billController(method, options, req, res) { // 驗(yàn)證 token
      utils.check_token(req.headers.authorization, res).then(() => { //
      token驗(yàn)證成功,調(diào)用操作數(shù)據(jù)庫(kù)的方法 billService[method](options).then((data) => {
      res.json(data); }).catch((err) => { res.json(err) }); }).catch((err) => { //
      token 驗(yàn)證失敗 res.json(err) }) }
      (2). 文件上傳問題?

      在這個(gè)項(xiàng)目中,有使用文件上傳的功能,express 默認(rèn)是帶這個(gè)功能的,所以就必須使用 npm
      安裝 express-fileupload 這個(gè)插件,然后再 app.js 中引入并注冊(cè)這個(gè)插件
      var fileUpload = require('express-fileupload'); app.use(fileUpload());
      當(dāng)前端發(fā)送文件時(shí),后端從 req.files['name']獲取 file 對(duì)象,然后通過 file.mv()方法進(jìn)行文件存儲(chǔ)
      file.mv(fileSavePath, function (e) { if (e) { // 失敗時(shí) } else { // 成功時(shí) } });
      比如我的項(xiàng)目中,上傳圖片代碼抽取出來就是
      // 小程序代碼 wx.uploadFile({ url: 'http://localhost:3000/users/avatar', filePath:
      'XXXXXXX', name: 'avatar', header: { Authorization: headers.token, expiresIn:
      headers.expiresIn }, formData: data, success: (res) => {}, fail: (err) => {}
      }); // 服務(wù)器代碼 let file = req.files.avatar file.mv('upload/a.png', function (e) {
      if (e) { // 失敗時(shí) } else { // 成功時(shí) } });
      (3). 關(guān)于前端讀取upload中圖片的問題

      本來想用服務(wù)器的 ip 來讀取項(xiàng)目中 upload 中的圖片,但是發(fā)現(xiàn)并不能讀取,或顯示404,故最后將 upload 文件放在了項(xiàng)目的外邊,
      然后對(duì)這個(gè) upload 文件單獨(dú)開了一個(gè)服務(wù),把他當(dāng)做圖片服務(wù)器來使用。

      3. 總結(jié)
      當(dāng)初選用 Express + MongoDB 的唯一原因就是開發(fā)快,因?yàn)榛旧厦刻於紳M課,所以快速開發(fā)是我的需要。
      在這個(gè)項(xiàng)目中其實(shí)還有很多可以優(yōu)化的地方,還有一定的冗余,比如在操作數(shù)據(jù)的時(shí)候,所有的查詢成功或失敗的函數(shù)
      都可以存放到一個(gè)公共類里面,而不是每一對(duì)應(yīng)的文件里都有一個(gè)這個(gè)方法。
      Github:
      小程序:https://github.com/GeorgeLeoo/finance
      <https://github.com/GeorgeLeoo/finance>
      服務(wù)器:https://github.com/GeorgeLeoo/finance-server
      <https://github.com/GeorgeLeoo/finance-server>

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          日本少妇bbw撒尿视频 | 干妞网操逼 | 天天干 夜夜操 | 操嫩逼| 2025天天干 | 欧美性爱网站在线 | 日韩A级毛片免费视频 | 精品日韩三级 | 成人v精品秘 蜜桃久久一区 | 内射白浆视频 |