uniapp + 微信小程序 + 云开发。实现一个可以计算汽车油耗的工具类微信小程序

简介

是一款可以计算汽车油耗的小程序。根据加油量、所加油量跑的公里数、当时的油价。即可以计算出汽车的百公里油耗、每公里花费多少钱等数据。并且可以将每次数据永久记录下来,然后可以将多次的数据进行横向的对比,从而直观的看出油耗等数据随时间的变化。
该小程序目前已经上线。扫码即可体验,二维码在后面。

需求来源

前段时间买了人生第一辆车(嘎嘎),作为一个新车车主,想知道这个车的真实油耗是多少,和工信部的油耗差别有多大。每次去加油的时候掏出计时器来计算又很麻烦,自己又是做开发的,就想着是否可以用程序来计算。于是有了这一款小程序。

主要逻辑

从上图可以看出;如果只是计算油耗的话可以直接用上面第一个公式就可以计算出百公里油耗了。但是如果你想计算出每公里花费多少钱;就一定要知道油价了。所以采用的是第二种计算方法。
因此需要用户输入的是:加油总费用,油价,以及公里数三个值。得到的有:百公里油耗,每公里耗费的油钱。
记录的数据有:当前记录时间,当前油价,加油总费用,公里数,百公里油耗,每公里耗费的油钱。

代码实现

前端代码实现

计算页面

需要用户输入的几个值

<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 如下图

以上,即该小程序的主要核心代码,其实挺简单的一个小程序

下面是体验码

 

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值