数据库架构
-
数据库集合分为12个月份
-
每条记录对应一个用户(openid)
-
每个用户下对应本月的每一天及本月总价及openid
-
每一天中,每条记账记录为一个对象,以随机生成的字符串作为id,以及本日总价
-
每一条记账记录包含了此条账单的各个属性:名称、价格、类别、支付方式等
源码
源码我就不一一介绍了,直接全部放在下面了。源码中页面设计用到了vant-weapp插件。
在这里简单介绍一下整个小程序的架构:
记账页面
分析页面
- 从云数据库中获取本日本月信息,存放到本地用于显示。
源码如下
1、APP
app.js
/*
*/
var timestamp = Date.parse(new Date()),
date = new Date(timestamp),
year = date.getFullYear(),
month = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1),
day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
App({
globalData:{
mon :['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
dayNum : [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
year : year,
month : month,
day : day,
},
onLaunch: function () {
var that = this;
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
traceUser: true,
})
wx.cloud.callFunction({
name: 'login',
data: {},
success: res => {
console.log("云函数 [login] user openid: ", res.result.openid)
that.globalData.openid = res.result.openid;
},
fail: res => {
console.log("云函数 [login] 调用失败")
}
})
}
}
})
app.json
{
"usingComponents": {
"van-dropdown-menu": "../components/dist/dropdown-menu/index",
"van-dropdown-item": "../components/dist/dropdown-item/index",
"van-field": "../components/dist/field/index",
"van-button": "../components/dist/button/index",
"van-cell": "../components/dist/cell/index",
"van-cell-group": "../components/dist/cell-group/index",
"van-card": "../components/dist/card/index",
"van-radio": "../components/dist/radio/index",
"van-radio-group": "../components/dist/radio-group/index",
"van-sidebar": "../components/dist/sidebar/index",
"van-sidebar-item": "../components/dist/sidebar-item/index",
"van-tab": "../components/dist/tab/index",
"van-tabs": "../components/dist/tabs/index",
"van-dialog": "../components/dist/dialog/index",
"van-grid": "../components/dist/grid/index",
"van-grid-item": "../components/dist/grid-item/index",
"van-divider": "../components/dist/divider/index",
"van-image": "../components/dist/image/index",
"van-notify": "../components/dist/notify/index"
},
"pages": [
"pages/onLoad/onLoad",
"pages/analysis/analysis",
"pages/index/index"
],
"tabBar": {
"color":"#000000",
"selectedColor": "#1CBBB4",
"backgroundColor": "white",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "/images/icon/bookkeeping_off.png",
"selectedIconPath": "/images/icon/bookkeeping_on.png"
},
{
"pagePath": "pages/analysis/analysis",
"iconPath": "/images/icon/analysis_off.png",
"selectedIconPath": "/images/icon/analysis_on.png"
}
]
},
"sitemapLocation": "sitemap46.json"
}
app.wxss 未用到
2、加载页面
onLoad.wxml
<view class='begin'>
<van-button
type="default"
bind:click="start"
>开始使用
</van-button>
</view>
<view class='text_container'>
<text>如出现问题或者有更好的建议欢迎联系</text>
<text>[email protected]</text>
</view>
onLoad.js
const app = getApp()
const db = wx.cloud.database()
var mon = app.globalData.mon
var year = app.globalData.year
var month = app.globalData.month
var day = app.globalData.day
var dayNum = app.globalData.dayNum
Page({
data: {
openid:''
},
start(){
db.collection(mon[month - 1]).where({
_openid: app.globalData.openid
}).get({
success: res => {
console.log(res.data.length)
if (res.data.length == 0) {
var j = 0
for (var i = 0; i < dayNum[month - 1]; i++) {
if (i < 9) {
j = '0' + (i + 1)
}
else {
j = i + 1
}
wx.cloud.callFunction({
name: 'update',
data: {
collect: mon[month - 1],
openid: app.globalData.openid,
data: {
[mon[month - 1] + j]: { dayPrice: 0.0 }
}
},
success: res => {
},
fail: res => {
console.log("调用失败", res)
}
})
}
db.collection(mon[month - 1]).add({
data: {
monPrice: 0.0,
},
success: res => {
},
fail: err => {
wx.showToast({
icon: 'none',
title: '新增记录失败'
})
console.error('[数据库] [新增记录] 失败:', err)
}
})
wx.switchTab({
url: '../index/index',
})
}
else {
wx.switchTab({
url: '../index/index',
})
}
}
})
},
subscribe() {
var that = this
wx.requestSubscribeMessage({
tmplIds: [
'5izIuACRUSIMs8eES-Drl92yVQI52fVypgRslHyk1W8'],
success(res) { that.start()}
})
},
onLoad: function () {
}
})
onLoad.wxss
Page{
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('base64格式图片,由于过长,故不在这里展示了,可以自行转码粘贴')
}
.begin{
position:fixed;
bottom:23%;
display:flex;
width:100%;
justify-content:center;
}
.text_container{
display: flex;
align-items: center;
vertical-align: center;
justify-content: center;
flex-direction:column;
font-size: 25rpx;
color: #666666;
position:fixed;
bottom:4%;
left: 25%
}
3、记账页面
index.wxml
<van-dialog />
<van-notify />
<view class='qs'>
<view class = 'container'style="height: 150rpx">
<view class='container_head'>
<view class='container_head_main'>
<view>
<view class='main_Ttitle'>今日总价</view>
<view class='main_main'>{{dayPrice}}</view>
<!--<view class='main_mintitle'>元</view> -->
</view>
<view>
<view class='main_Ttitle'>本月总价</view>
<view class='main_main'>{{monPrice}}</view>
<!--<view class='main_mintitle'>次/分钟</view> -->
</view>
</view>
</view>
</view>
<view class='container'style="height: 350rpx">
<van-dropdown-menu>
<van-dropdown-item value="{{ categroyIndex }}" options="{{ categroy }}" bind:change="switchValue1" />
<van-dropdown-item value="{{ paymentIndex }}" options="{{ payment }}" bind:change="switchValue2" />
</van-dropdown-menu>
<van-cell-group>
<van-field
value="{{ goodsName }}"
label="名称"
placeholder="请输入名称"
border="{{ false }}"
bind:blur="nameBlur"
/>
<van-field
value="{{ goodsPrice }}"
label="价格"
border="{{ false }}"
placeholder="请输入价格"
bind:change="onChange"
type="digit"
maxlength="6"
/>
</van-cell-group>
</view>
<view class='btn_container' >
<van-button class='btn' type="default" round bind:click='post'> 保 存 </van-button>
<van-button class='btn' type="default" round bind:click='clear'> 清 空 </van-button>
</view>
<view class='container' style="height: auto">
<van-divider contentPosition="center">今日已买</van-divider>
<view wx:for="{{today}}" wx:for-index="id" wx:for-item="value">
<van-card
tag="{{value.categroy}}"
price="{{value.price}}"
desc="支付方式:{{value.payment}}"
title="{{value.name}}"
thumb="{{img[value.categroy]}}"
>
<view slot="footer">
<van-button size="mini" data->删除</van-button>
</view>
</van-card>
<text>\n</text>
</view>
</view>
</view>
index.js
const app = getApp()
const db = wx.cloud.database()
const _ = db.command
var mon = app.globalData.mon
var year = app.globalData.year
var month = app.globalData.month
var day = app.globalData.day
var dayNum = app.globalData.dayNum
var myDate = new Date()
var time = myDate.toLocaleTimeString()
import Dialog from '../../components/dist/dialog/dialog'
import Notify from '../../components/dist/notify/notify'
Page({
data: {
img: {
'饮食': 'cloud://bookkeeping-ywonchall.626f-bookkeeping-ywonchall-1303847606/icon/饮食.png',
'淘宝': 'cloud://bookkeeping-ywonchall.626f-bookkeeping-ywonchall-1303847606/icon/淘宝.png',
'娱乐': 'cloud://bookkeeping-ywonchall.626f-bookkeeping-ywonchall-1303847606/icon/娱乐.png',
'其他': 'cloud://bookkeeping-ywonchall.626f-bookkeeping-ywonchall-1303847606/icon/其他.png'
},
categroy: [
{ text: '饮食', value: 0 },
{ text: '淘宝', value: 1 },
{ text: '娱乐', value: 2 },
{ text: '其他', value: 3 },
],
categroyIndex: 0,
name:'',
price:'',
openid:'',
today:{},
goodsName:'',
goodsPrice:'',
monPrice:'',
dayPrice:0,
payment:[
{ text: '微信', value: 0 },
{ text: '支付宝', value: 1 },
{ text: '银行卡', value: 2 },
{ text: '校园卡', value: 3 },
],
paymentIndex:0
},
onClick(event) {
const { name } = event.currentTarget.dataset;
this.setData({
radio: name,
});
},
onClose() {
this.setData({ show: false });
},
deleteData(event){
var dayPrice = this.data.today[event.target.dataset.id]['price']
this.setData({
dayPrice: parseFloat((this.data.dayPrice - this.data.today[event.target.dataset.id]['price']).toFixed(2)),
monPrice: parseFloat((this.data.monPrice - this.data.today[event.target.dataset.id]['price']).toFixed(2)),
})
var dayBook = this.data.today
delete dayBook[event.target.dataset.id]
console.log(dayBook)
dayBook['dayPrice'] = this.data.dayPrice
wx.cloud.callFunction({
name: 'remove',
data: {
collect: mon[month - 1],
openid: this.data.openid,
data: [mon[month - 1] + day]
},
success: res => {
console.log("delete success1")
this.updata(dayBook).then(result => {
delete dayBook['dayPrice']
console.log("delete success2")
this.setData({
today: dayBook
})
})
},
fail: res => {
console.log("调用失败", res)
}
})
},
clear(){
this.setData({
goodsName: '',
goodsPrice: '',
name: '',
price: ''
})
},
updata(event){
return new Promise(resolve => {
console.log(mon[month - 1]
请发表评论