准备和女朋友去旅游?赶紧撸个旅行账本小程序!

2019 年 3 月 15 日 程序人生

作者 | 豪豪

责编 | 伍杏玲

本文经授权转载自云开发x(ID:tcb2tcb)

【程序人生 编者按】春天来了,大家开始酝酿大大小小的旅行计划。除了线路计划外,很多人有记录各项花费的习惯。作为程序员,这点小事当然顺手就给女朋友给开发了呀,于是有了这个旅行小账本,一起看看如何实现的?


IDE

  • 微信开发者工具

  • VSCode

熟悉微信开发者工具的朋友们应该知道,它不支持Emmet缩写语法,并且WXML的属性值默认用单引号表示(强迫症表示很难受)。而VSCode很好的补足了微信开发者工具的不足之处,并且支持多元化插件开发,轻量好用。

所以这里推荐采用微信开发者工具+VSCode配合开发。微信开发者工具负责调试、模拟小程序运行情况,VSCode负责代码编辑工作。二者各司其职,会使开发更加的高效、便捷。后端采用云开发。


总体架构


该项目基于小程序云开发,使用的模板是云开发快速启动模板由于是个全栈项目,前端使用小程序所支持的 WXML + WXSS + JS 开发模式,命名采用BEM命名规范。后台则是借助云数据库+云储存进行数据管理。

  
  
    

逆向工程


在做该小程序之前,有必要进行项目的逆向工程,进一步解构每一个页面,从而深入了解这款小程序的交互细节。那么现在我假设自己是产品设计师,在绘制完界面原型后,撰写了相应的交互文档。以下是我绘制的界面原型:

接下来对每个页面的细节进行解构,并完成简单的WXML结构:

  
  
    

云开发


在做完逆向工程的解构,页面基础结构基本搭建完成。但页面依旧是静态的,需要数据来填充。所以第二步就是数据库的设计。而小程序的云控制台恰好提供了数据的操作功能,为数据驱动提供基石。

1.云数据库设计

云数据库是一种NoSQL数据库。每一张表是一个集合。值得注意的是在设计数据库时, _id 和 _openid这两个字段需要带上。 _id是表的主键,而 _openid是用户标识,每个用户都有不同的 _openid,可区分不同用户。

以下是项目中的数据表设计:

cover_photos 账本封面表  用于存储创建账本时需要的封面信息cover_photos 
- _id
- _openid
- cover_index 封面索引
- cover_url   封面url
- isSelected  封面是否选中
accounts 账本表   用于存储用户创建的账本
- _id
- _openid
- accountKey  账本唯一标识
- coverUrl    账本封面
- i           账本索引
- inputValue  账本名字
- now         账本创建时间
- spend       账本总花费
account_detail 支出类型表   用于存储消费类型
- _id
- _openid
- detail       类型细节
- pic_index    消费类型索引
- pic_url      未点击时的图片
- pic_url_act  点击后的图片
- type         消费类型
account_income 收入类型表   用于存储收入类型
- _id
- _openid
- pic_index    收入类型索引
- pic_url      未点击时的图片
- pic_url_act  点击后的图片
- type         收入类型
spend_items   消费明细表
- _id
- _openid
- accountKey   账本唯一标识
- address      消费地点
- desc         消费描述
- fullDate     消费时间
- money        消费金额
- pic_type     消费类型
- pic_url      消费类型图片

2.云储存管理

这是个非常实用的板块。类似于百度云盘,它提供了文件存储、上传与下载功能:

除此之外,它还会将你所上传的资源自动进行压缩操作,并生成一个地址供你引用。该项目中的一些图片资源就是存在于此,然后在云数据库的字段中引用这些资源地址即可,十分方便,不必在本地存储,占用小程序内存:

3.云函数设计

云函数简单来说就是在云后端(Node.js)运行的代码,本地看不到这些代码的执行过程,全封闭式只暴露接口供本地调用执行,本地只需等待云端代码执行完毕后返回结果。这也是面向接口编程的思想体现。

项目中的云函数设计:

// getTime  获取当前时间并格式化为 yyyy-mm-dd
// 云函数入口文件

const cloud = require('wx-server-sdk')
// 初始化云函数
cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
    var date = new Date()
    var seperator1 = "-"
    var year = date.getFullYear()
    var month = date.getMonth() + 1
    var strDate = date.getDate()
    if (month >= 1 && month <= 9) {
       month = "0" + month
    }
    if (strDate >= 0 && strDate <= 9) {
       strDate = "0" + strDate
    }

    // 格式化当前时间
    var currentdate = year + seperator1 + month + seperator1 + 
                      strDate
    return currentdate
}

// deleteItems  批量删除,云数据库的批量删除只允许在云函数中执行
// 云函数入口文件
const cloud = require('wx-server-sdk')
// 初始化云函数
cloud.init()

// 连接云数据库
const db = cloud.database()
const _ = db.command

// 云函数入口函数

exports.main = async (event, context) => {
     try {
          return await db.collection('spend_items')
             .where({
               accountKey: event.accountKey
             })
             .remove()
      } catch (e) {
        console.error(e)
    }
}

  
  
    



MVVM


界面有了,数据有了。万事俱备,只欠东风!所以下一步就是MVVM的设计。小程序本质就是基于MVVM所设计的,在MVVM的世界里,数据是灵魂,一切都由数据来驱动。

1.【账本页】显示

账本页有两种显示的风格,左上角的按钮可以来回切换风格,下拉可刷新页面,显示accounts数据表中存储的账本信息。显示时有个小细节,需要根据创建的时间先后来显示,越晚创建的越先显示:

  
  
    
    
    
      

// 页面数据设计, 在wxml中使用{{}}符号引用数据,数据就动态显示到了页面上
data: {
    isListfalse// 转换页面风格的标识 true为竖向风格 false为横向风格
    accounts: [],  // 存储查询的账本数据
    now: null,     // 存储当日时间
    year: null     // 存储年份
}

// 转换显示风格
switchList() {
// 设置页面风格样式
    let isList = !this.data.isList
    this.setData({
      isList
    })
    wx.setStorage({
      key"isList",
      data: isList
   })
}

// 获取页面风格转换标识
var isList = wx.getStorageSync('isList')

// 查询账本
db.collection('accounts')
.get({
    successres => {
      this.setData({
        accounts: res.data.reverse(),  // 反转数组,优先显示创建早的账本
        isList
    })
      wx.hideLoading()
   }
})

// 调用云函数接口 获取当前日期
wx.cloud.callFunction({
// 云函数接口名就是创建的云函数名字,这里是'getTime'
    name: 'getTime',
    success(res) => {
    let year = res.result.split('-')[0]
    this.setData({
      now: res.result,
      year
   })
   },
    failconsole.error
})

2.【账本页】增删改

账本页通过调用相应的云数据库API,可进行一系列的增删改操作。值得一提的是,修改时需要表单回显,删除时需要级联删除。因为一个账本中有许多收支情况,spenditems表就是进行收支记录,所以删除账本时需要级联删除对应的spenditems表中的收支信息。

3.【支出】与【收入】页面设计

因为收入与支出页面基本类似,所以使用自定义组件封装,可以复用,具体看源码。

4.【账本明细】页面

因为账本明细中需要显示每一天的消费信息,所以需要将数据表中的数据通过时间来分类,分成若干个数组,页面从而使用wx:for来遍历这些数组。在显示之前,首先需要判断有无收支信息:

  
  
    
    
    
      

// 通过时间分类算法  {} => [ [{时间1}], [{时间2}], [{时间3}] ]
arr.forEach(item => {
if (!_this.isExist(item.fullDate, dateArr)) {
    dateArr.push([item])
else {
    dateArr.forEach(res => {
        if (res[0].fullDate == item.fullDate) {
            res.push(item)
        }
   })
  }
})

// 使用map 方法构造 [{}, {}, {}, ...] 类型数组
dateArr = dateArr.map((item) => {
  let spend = 0
  let income = 0
  item.forEach(res => {
      if (res.money > 0) {
          spend += res.money
      } else {
          income += (-res.money)
     }
  })
return {
    item,
    spend,
    income
}
})

// 判断自身是否存在数组中
isExist(item, arr) {
    for (let i = 0; i < arr.length; i++) {
    if (item == arr[i][0].fullDate)
    return true
}
  return false
}

以上是小程序中比较复杂的逻辑实现。

源码传送门:

https://github.com/FightingHao/travelbook

正在学习小程序?

开发小程序遇到问题不知道问谁?

找不到小程序的组织?

欢迎加入我们的小程序开发者群!


 热 文 推 荐 

找 Bug 赚了 6,700,000元!这位 00 后是怎么做到的?

第一批 90 后程序媛已爆发焦虑症 | 程序员有话说

漫画:如何给女朋友解释为什么有些网站域名不以 WWW 开头

再见,中国移动 3G!

少儿编程只学会 Coding 就够了?比这更重要的是……

杨超越第一,Python第二

以安全之名:2019年DevSecOps社区调研白皮书解读

虎口夺食! 打破Facebook谷歌垄断, MIT大神和他的区块链数据库传奇! |人物志

那些简历造假拿 Offer 的程序员,后来都怎样了?

System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"

喜欢就点击“在看”吧!
登录查看更多
0

相关内容

【2020新书】实战R语言4,323页pdf
专知会员服务
100+阅读 · 2020年7月1日
AI创新者:破解项目绩效的密码
专知会员服务
33+阅读 · 2020年6月21日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【北京大学】面向5G的命名数据网络物联网研究综述
专知会员服务
36+阅读 · 2020年4月26日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
224+阅读 · 2020年3月22日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
67+阅读 · 2020年3月9日
微信小程序支持webP的WebAssembly方案
前端之巅
19+阅读 · 2019年8月14日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
阿里技术大牛:一份架构师成神路线图!
51CTO博客
30+阅读 · 2019年7月6日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
秒懂的RPA解读
炼数成金订阅号
9+阅读 · 2019年2月28日
携程的旅游知识图谱构建和应用
数据猿
37+阅读 · 2018年12月31日
可能是 Android 上最好用的写作 App
少数派
10+阅读 · 2018年12月21日
【动画连载】3分钟了解什么是区块链(中文动画)
33款可用来抓数据的开源爬虫软件工具 (推荐收藏)
数据科学浅谈
7+阅读 · 2017年7月29日
Arxiv
4+阅读 · 2019年12月2日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
100+阅读 · 2020年7月1日
AI创新者:破解项目绩效的密码
专知会员服务
33+阅读 · 2020年6月21日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【北京大学】面向5G的命名数据网络物联网研究综述
专知会员服务
36+阅读 · 2020年4月26日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
224+阅读 · 2020年3月22日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
67+阅读 · 2020年3月9日
相关资讯
微信小程序支持webP的WebAssembly方案
前端之巅
19+阅读 · 2019年8月14日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
阿里技术大牛:一份架构师成神路线图!
51CTO博客
30+阅读 · 2019年7月6日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
秒懂的RPA解读
炼数成金订阅号
9+阅读 · 2019年2月28日
携程的旅游知识图谱构建和应用
数据猿
37+阅读 · 2018年12月31日
可能是 Android 上最好用的写作 App
少数派
10+阅读 · 2018年12月21日
【动画连载】3分钟了解什么是区块链(中文动画)
33款可用来抓数据的开源爬虫软件工具 (推荐收藏)
数据科学浅谈
7+阅读 · 2017年7月29日
Top
微信扫码咨询专知VIP会员