简介
是一款可以计算汽车油耗的小程序。根据加油量、所加油量跑的公里数、当时的油价。即可以计算出汽车的百公里油耗、每公里花费多少钱等数据。并且可以将每次数据永久记录下来,然后可以将多次的数据进行横向的对比,从而直观的看出油耗等数据随时间的变化。
该小程序目前已经上线。扫码即可体验,二维码在后面。
需求来源
前段时间买了人生第一辆车(嘎嘎),作为一个新车车主,想知道这个车的真实油耗是多少,和工信部的油耗差别有多大。每次去加油的时候掏出计时器来计算又很麻烦,自己又是做开发的,就想着是否可以用程序来计算。于是有了这一款小程序。
主要逻辑
从上图可以看出;如果只是计算油耗的话可以直接用上面第一个公式就可以计算出百公里油耗了。但是如果你想计算出每公里花费多少钱;就一定要知道油价了。所以采用的是第二种计算方法。
因此需要用户输入的是:加油总费用,油价,以及公里数三个值。得到的有:百公里油耗,每公里耗费的油钱。
记录的数据有:当前记录时间,当前油价,加油总费用,公里数,百公里油耗,每公里耗费的油钱。
代码实现
前端代码实现
计算页面
需要用户输入的几个值
<view class="input-view-item">
<input class="input" type="digit" v-model="unitPrice" placeholder="请输入油价(元/升)"/>
</view>
<view class="input-view-item">
<input class="input" type="digit" v-model="totalPrice" placeholder="加油的总价格(元)"/>
</view>
<view class="input-view-item">
<input class="input" type="digit" v-model="km" placeholder="行驶里程数(公里)"/>
</view>
<view class="button-view-box">
<button class="left" type="primary" @click="compute()">计算</button>
<!-- #ifdef MP-WEIXIN -->
<button class="right" @click="addToHistory">记录</button>
<!-- #endif -->
</view>
计算函数
compute (addToHistory) {
let msgArr = []
if(isNaN(Number(this.unitPrice)) || !this.unitPrice) {
this.unitPrice = ''
msgArr.push('油价')
}
if(isNaN(Number(this.totalPrice)) || !this.totalPrice) {
this.totalPrice = ''
msgArr.push('总价格')
}
if(isNaN(Number(this.km)) || !this.km) {
this.km = ''
msgArr.push('里程数')
}
if(msgArr.length) {
uni.showToast(
{
title: `请输入${msgArr.join(',')}`,
icon: 'none',
}
);
return
}
// 单价
let unitPrice = Number(this.unitPrice)
// 总价
let totalPrice = Number(this.totalPrice)
// 公里数
let km = Number(this.km)
// 没公里花费的钱
let money1km = (totalPrice / km).toFixed(2)
// 百公里油耗
let oil100 = (this.totalPrice / this.unitPrice / km * 100).toFixed(2)
// 是否重复点击
let isSame = this.money1km === money1km && this.oil100 === oil100
this.money1km = money1km
this.oil100 = oil100
// 是否点击的记录按钮
if(addToHistory) {
isSame = `${this.money1km}${this.oil100}` === this.oldData
if (isSame) {
uni.showToast(
{
title: '相同数据;无需重复记录。',
icon: 'none'
}
)
return
}
if (this.loading) {
return
}
this.loading = true
// 调用微信的云函数
wx.cloud.callFunction({
name: 'addDataToCould',
data: {
dbName: 'userOilCompute',
list: [
{
unitPrice,
totalPrice,
km,
oil100: this.oil100,
money1km: this.money1km
}
]
}
}).then(res => {
this.loading = false
this.oldData = `${this.money1km}${this.oil100}`
uni.showModal({
title: '提示',
content: `记录成功,可到历史油耗中查看`,
showCancel: false,
success: async (res3) => {
if (res3.confirm) {
} else if (res3.cancel) {
}
}
});
})
}
}
历史记录页面
view代码
<view class="history-box" v-if="historyList && historyList.length">
<view class="chart-box">
<view class="chart-title">百公里油耗变化折线图</view>
<canvas :style="canvasStyle" canvas-id="canvasLineA" id="canvasLineA" class="charts" @touchstart="touchLineA"></canvas>
</view>
<view class="history-list">
<view class="item" v-for="(item, index) in historyList" :key="index" @click="deleteItem(item)">
<view class="time">
<view class="cell">{{showTime(item.createTime)}}</view>
<view class="cell">
<view class="label">油价</view>
<view class="value">{{item.unitPrice}}</view>
</view>
<view class="cell">
<view class="label">加油费用</view>
<view class="value">{{item.totalPrice}}</view>
</view>
</view>
<view class="content">
<view class="cell">
<view class="label">公里数</view>
<view class="value">{{item.km}}</view>
</view>
<view class="cell">
<view class="label">百公里油耗</view>
<view class="value">{{item.oil100}}升</view>
</view>
<view class="cell">
<view class="label">每公里耗费</view>
<view class="value">{{item.money1km}}元</view>
</view>
</view>
</view>
</view>
</view>
<view v-else class="common-no-data-box">
<NoData :text="loading?'加载中...':'暂无数据'"></NoData>
</view>
js代码
获取历史油耗
// 获取历史油耗
async getOilHistory () {
this.loading = true
let res = await wx.cloud.callFunction({
name: 'getDbListData',
data: {
dbName: 'userOilCompute',
pageNo: 1,
pageSize: 50,
limitType: 1,
orderName: 'createTime',
orderType: 'desc',
params: {}
}
})
this.loading = false
if (res.errMsg === 'cloud.callFunction:ok') {
this.historyList = res.result.data
this.showLine()
}
},
转换数据结构
// 将历史数据historyList转换为uCharts所需要的数据结构
showLine () {
const canvasId = 'canvasLineA'
let chartData = {
categories: [],
series: [{
name: '油耗',
data: [],
color: '#4cd964',
style: 'curve'
}]
}
for (let i = this.historyList.length - 1; i >= 0; i--) {
let item = this.historyList[i]
chartData.categories.push(this.showTime(item.createTime))
chartData.series[0].data.push(item.oil100)
}
canvaLineA = new uCharts({
$this: _self,
canvasId: canvasId,
type: 'line',
fontSize: 10,
legend: {show: true},
dataLabel: false,
dataPointShape: false,
background: '#FFFFFF',
pixelRatio: _self.pixelRatio,
categories: chartData.categories,
series: chartData.series,
animation: true,
enableScroll: false,
xAxis: {
type: 'grid',
gridColor: 'transparent',
gridType: 'dash',
dashLength: 1,
fontColor: '#ffffff',
rotateLabel: true,
labelCount: 10
},
yAxis: {
gridType: 'line',
gridColor: '#242424',
splitNumber: 5,
// min:10,
// max:180,
data: [
{
fontColor: '#ffffff',
format: (val) => {
return val + '升'
}
}
]
},
width: _self.cWidth * _self.pixelRatio,
height: _self.cHeight * _self.pixelRatio,
legend: {
fontColor: '#ffffff',
show: false
},
extra: {
line: {
type: 'straight'
}
}
})
},
删除数据
// 删除
deleteItem (item) {
uni.showModal({
title: '提示',
content: `确认删除该条记录吗?`,
showCancel: true,
success: async (res3) => {
if (res3.confirm) {
let res = await wx.cloud.callFunction({
name: 'delDataFromCould',
data: {
dbName: 'userOilCompute',
primaryKey: '_id',
list: [item]
}
})
if (res.errMsg === 'cloud.callFunction:ok') {
uni.showToast({
title: `删除成功!`,
icon: 'none'
})
}
this.getOilHistory()
} else if (res3.cancel) {
}
}
})
},
后端代码实现
后端主要做的是将前端需要记录的几个数值,进行增删查的操作。
添加数据的云函数(addDataToCould
)
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
let addCount = 0
// 数据库名称 数据库唯一标识(用于添加时判断是否存在) 要插入的数据List
let {dbName, primaryKey, list} = event;
if (list &&list.length) {
for(let i = 0;i<list.length;i++) {
// 查询该条记录是否存在
let item = list[i];
item.openId = item.openId || wxContext.OPENID
item.createTime = new Date()
let countRes
if (primaryKey) { // 如果传来primaryKey;则先判断是否存在;不存在才添加
countRes = await db.collection(dbName).where({
[primaryKey]: item[primaryKey]
}).count();
} else { // 直接判定不存在
countRes = {
total: 0
}
}
if(countRes.total === 0) {// 不存在则添加
await db.collection(dbName).add({
// data 字段表示需新增的 JSON 数据
data: {
...item,
}
})
addCount ++
}
}
}
return {
status: 0,
data: {
addCount
},
message: '成功'
}
}
注意的是,上面的openId是wx给的,以此可用来标识某条数据是哪一个用户产生
查询数据的云函数(getDbListData
)
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
try{
let {params = {},orderName,orderType = 'desc',pageNo, pageSize,dbName} = event;
let totalData = await db.collection(dbName).where({
...params
}).count();
let listData = await (async ()=>{
let data;
let dbObj = await db.collection(dbName).where({
...params
})
if(orderName) { // 如果需要排序 asc 或 desc
dbObj = await dbObj.orderBy(orderName,orderType)
}
dbObj = await dbObj.skip((pageNo - 1) * pageSize) // 跳过结果集中的前 10 条,从第 11 条开始返回
.limit(pageSize) // 限制返回数量为 10 条
.get();
data = dbObj
return data;
})()
return {
totalCount:totalData.total,
status: 0,
message: '成功',
data: listData.data
}
}catch (e) {
return {
status: 1,
message: '失败',
data: e
}
}
}
删除数据的云函数(delDataFromCould
)
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
let delRes = []
// 数据库名称 数据库唯一标识(用于删除时判断是否存在)
let {dbName, primaryKey, list} = event;
if (list &&list.length) {
for(let i = 0;i<list.length;i++) {
// 查询该条记录是否存在
let item = list[i];
let res = await db.collection(dbName).where({
[primaryKey]: item[primaryKey]
}).remove();
delRes.push(res)
}
}
return {
status: 0,
data: delRes,
message: '成功'
}
}
数据库(userOilCompute
)
数据库的话其实只用了一个表userOilCompute
如下图
以上,即该小程序的主要核心代码,其实挺简单的一个小程序
下面是体验码