微信小程序项目总结之记账小程序功能的实现(包括后端)


Posted in Javascript onAugust 20, 2019

一、小程序部分

这是理财系统的前端,江苏海洋大学微信小程序比赛,最后获得了一等奖
GitHub:https://github.com/GeorgeLeoo/finance

1. 项目描述

(1). 此项目为记账小程序
(2). 包括账单、图表、搜索、用户等多个子模块
(3). 使用微信小程序技术
(4). 采用模块化、组件化、工程化等模式开发

2. 项目功能界面

微信小程序项目总结之记账小程序功能的实现(包括后端)

在 1.0.2版本中删除了扇形图

3. 项目目录

微信小程序项目总结之记账小程序功能的实现(包括后端)

* pages:页面
  * components:组件
  * utils:工具类 
    |-- util.js:工具类 
    |-- wxcharts.js:图表插件
  * images:资源图片
  * config:配置文件
  * filter:过滤器
  * http:网络请求
    |-- http.js:对 wx.request 的封装
    |-- api.js:对网络请求接口的封装

4. 请求封装

一开始使用 wx.request 对数据进行网络请求,可写完后,发现太过冗余,也太麻烦,故对其做了封装。
通过创建一个函数返回 Promise 对象,就可以屏蔽公共的部分

// http/http.js
/**
 * 对微信普通网络请求封装
 * @param url  请求地址
 * @param data 请求的参数
 * @param method  请求的方法类型 
 * @param headers  头部信息,在这里主要是 token 认证功能
 * @returns {Promise<unknown>} 返回请求的 Promise 对象
 */
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);
      }
    });
  })
}

/**
 * 对文件上传接口封装
 * @param url  请求地址
 * @param fileOptions  文件配置项
 * @param data 请求发送的数据
 * @param headers  头部信息,在这里主要是 token 认证功能
 * @returns {Promise<unknown>} 返回请求的 Promise 对象
 */
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). 在更新账单数据后,如何更新账单界面的数据?
        这个问题我的解决方案是,在 globalData 中添加一个全部变量 isRefreshBills,默认为 false,
     当更新账单数据成功后,将 isRefreshBills 修改为 true,同时返回到账单界面,在账单界面的
     onShow()方法中,判断 isRefreshBills 是否为 true,若为 true 则重新请求数据,同时将 isRefreshBills
     设为 false,否则不请求。这样就避免了没有更新数据的情况下多次请求数据。
        对这个解法,还有一种更加节流的方法,就是更新后不去请求,而是对原来的获取到的数据进行个别删除。比如当
     更新数据成功后,获取一个被更新的这条数据的id,然后在账单页面的 onShow() 方法中,遍历找到这个 id 对应的
     数据,并删除这条数据也能达到数据更新的效果
    
(2). 在进行类别添加的时候,自定义的类别会出现双倍?
        由于我有一分部初始数据是存在 globalData 中的,每次从服务器获取自定义类别时,都会对其进行拼接,
     在拼接的时候修改了原来的 globalData 中的值,所以每次添加后都会请求一次自定义数据,进行拼接。
     解决方案:禁止更新 globalData 中的数据
    
(3). 返回哪个页面问题?
        在账单页面可以进去修改账单的页面,在搜索页面也可以进入修改账单账单的页面,他们用的是同一个组件,
     那么如何保证在账单页面进入修改账单页面后返回到账单页面,在搜索页面进入修改账单页面后返回到搜索页面。
     首先在路由跳转的时候添加当前路由信息,然后在修改账单页面中接受这个路由信息,最后通过这个路由信息返回到原来的路由

6. 总结

 这个项目是我5月份参加学校微信小程序的项目,两个礼拜仓促的做了这么一个项目,前后端都有,最后荣获一等奖。
    在之前比赛用的版本中其实有很多的 bug 以及卡顿现象居多,故这两天我有对这个项目进行了一定的维护,发现原来的代码实在
    惨不忍睹,现在经过升级,页面卡顿现象减少,若后期再想维护,也相对于之前的版本好维护多了,但是还有很多可以维护的空间。
    其实我并不对这个项目很满意,比如之前我没做分页加载, 现在想加个分页加载的功能,我发现并不是一下子就能搞定的,
    因为我的数据结构不是很合理,因为后端返回的数据和前端要显示的数据格式是不一致,故前端要重新定义数据结构,
    所以对分页来说就有一定的困难。在我对项目进行维护后,代码比以前更简洁,可读性相对于之前的版本来说要更加好。

二、服务器部分

1.简述

这个项目是微信小程序记账 app 的后端代码,使用技术:MongoDB+Express。
GitHub:https://github.com/GeorgeLeoo/finance-server

这个项目的目录是这样的

微信小程序项目总结之记账小程序功能的实现(包括后端)

  • config: 配置文件
  • routes: 路由配置
  • utils: 工具类
  • db: 操作数据库的代码
  • controller: 控制是当前地址否要 token 验证
  • service: 如何调用操作数据库函数(我也不知道为什么要写controller,service,感觉这两个写一个就可以了)

2.遇到的问题

(1). token 验证问题?

关于 token 验证问题我使用了 jsonwebtoken 插件,故先用 npm 安装这个插件。
token 验证流程大概如下图:

微信小程序项目总结之记账小程序功能的实现(包括后端)

使用这个插件: 定义两个方法,一个用来生成 token,另一个用来验证 token。

/**
 * 生成token
 * @param {object} content 对某个内容生成 token
 */
 const access_token=function (content) {
   let secret = 'jizhangxitongfinancegeorgeleeo'; // 秘钥
   let expiresIn = Math.round((new Date().getTime()/1000)) + 3600; // 过期时间
   let token = jwt.sign(content, secret, { expiresIn });
   return {
     token,
     expiresIn
   };
 }
 /**
 * 验证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) {
         //时间失效或伪造 token 或 token 不存在
         reject({
           status: 10010,
           error: 'invalid_token'
         });
       } else {
         resolve();
       }
     });
   })
 }

在controller.js 中,去判断 token 验证成功与否

function billController(method, options, req, res) {
  // 验证 token
  utils.check_token(req.headers.authorization, res).then(() => {
    // token验证成功,调用操作数据库的方法
    billService[method](options).then((data) => {
      res.json(data);
    }).catch((err) => {
      res.json(err)
    });
  }).catch((err) => {
    // token 验证失败
    res.json(err)
  })
}

(2). 文件上传问题?

在这个项目中,有使用文件上传的功能,express 默认是带这个功能的,所以就必须使用 npm
安装 express-fileupload 这个插件,然后再 app.js 中引入并注册这个插件

var fileUpload = require('express-fileupload');
app.use(fileUpload());

当前端发送文件时,后端从 req.files['name']获取 file 对象,然后通过 file.mv()方法进行文件存储

file.mv(fileSavePath, function (e) {
    if (e) {
      // 失败时
    } else {
      // 成功时
    }
  });

比如我的项目中,上传图片代码抽取出来就是

// 小程序代码
    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) => {}
    });

  // 服务器代码
    let file = req.files.avatar
    file.mv('upload/a.png', function (e) {
      if (e) {
        // 失败时
      } else {
        // 成功时
      }
    });

(3). 关于前端读取upload中图片的问题

本来想用服务器的 ip 来读取项目中 upload 中的图片,但是发现并不能读取,或显示404,故最后将 upload 文件放在了项目的外边,

然后对这个 upload 文件单独开了一个服务,把他当做图片服务器来使用。

3. 总结

当初选用 Express + MongoDB 的唯一原因就是开发快,因为基本上每天都满课,所以快速开发是我的需要。在这个项目中其实还有很多可以优化的地方,还有一定的冗余,比如在操作数据的时候,所有的查询成功或失败的函数都可以存放到一个公共类里面,而不是每一对应的文件里都有一个这个方法

Github:

小程序:https://github.com/GeorgeLeoo/finance

服务器:https://github.com/GeorgeLeoo/finance-server

总结

以上所述是小编给大家介绍的微信小程序项目总结之记账小程序功能的实现(包括后端),希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
ext读取两种结构的xml的代码
Nov 05 Javascript
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
Apr 24 Javascript
jQuery用unbind方法去掉hover事件及其他方法介绍
Mar 18 Javascript
编写自己的jQuery提示框(Tip)插件
Feb 05 Javascript
JS实现文档加载完成后执行代码
Jul 09 Javascript
jquery validate demo 基础
Oct 29 Javascript
原生js实现autocomplete插件
Apr 14 Javascript
javascript笔记之匿名函数和闭包
Feb 06 Javascript
jQuery实现导航回弹效果
Feb 27 Javascript
详解React开发中使用require.ensure()按需加载ES6组件
May 12 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
Aug 01 Javascript
微信小程序拖拽排序列表的示例代码
Jul 08 Javascript
ES6中Symbol、Set和Map用法详解
Aug 20 #Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
Aug 20 #Javascript
node中使用log4js4.x版本记录日志的方法
Aug 20 #Javascript
vue 获取视频时长的实例代码
Aug 20 #Javascript
vue+elementUI实现图片上传功能
Aug 20 #Javascript
vue+elementUi图片上传组件使用详解
Aug 20 #Javascript
vue集成chart.js的实现方法
Aug 20 #Javascript
You might like
php面向对象全攻略 (三)特殊的引用“$this”的使用
2009/09/30 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
2017/06/16 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
PHP简单实现图片格式转换(jpg转png,gif转png等)
2019/10/30 PHP
PHP安全之register_globals的on和off的区别
2020/07/23 PHP
ExtJS Grid使用SimpleStore、多选框的方法
2009/11/20 Javascript
Jquey拖拽控件Draggable使用方法(asp.net环境)
2010/09/28 Javascript
JavaScript 上万关键字瞬间匹配实现代码
2013/07/07 Javascript
jquery简单的拖动效果实现原理及示例
2013/07/26 Javascript
js获取html文件的思路及示例
2013/09/17 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
2017/01/24 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
微信小程序中页面FOR循环和嵌套循环
2017/06/21 Javascript
AngularJs点击状态值改变背景色的实例
2017/12/18 Javascript
使用async-validator编写Form组件的方法
2018/01/10 Javascript
JavaScript变量作用域及内存问题实例分析
2019/06/10 Javascript
[01:13]DOTA2群星解读国服召集令 一起说出回归的理由
2013/07/17 DOTA
详解如何使用Python编写vim插件
2017/11/28 Python
python 使用值来排序一个字典的方法
2018/11/16 Python
使用Python实现跳一跳自动跳跃功能
2019/07/10 Python
Python实现动态循环输出文字功能
2020/05/07 Python
Python非单向递归函数如何返回全部结果
2020/12/18 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
python SOCKET编程基础入门
2021/02/27 Python
CSS3制作ajax loader icon实现思路及代码
2013/08/25 HTML / CSS
HTML5中的Scoped属性使用实例
2014/04/23 HTML / CSS
英国著名的化妆品折扣网站:Allbeauty.com
2016/07/21 全球购物
Farfetch阿联酋:奢侈品牌时尚购物平台
2019/07/26 全球购物
Yankee Candle官网:美国最畅销蜡烛品牌之一
2020/01/05 全球购物
本科毕业生专业自荐书范文
2014/02/05 职场文书
2014乡镇机关党员个人对照检查材料思想汇报
2014/10/09 职场文书
违反学校规则制度检讨书
2015/01/01 职场文书
2016年10月份红领巾广播稿
2015/12/21 职场文书
阿里云Nginx配置https实现域名访问项目(图文教程)
2021/03/31 Servers