2019年的时候和朋友出去旅行,因为需要A账单,所以前一天开发了一个记账小程序,时间匆忙,就随便完成基础记账和AA计算功能后就上线,旅行结束后也就没用过了,前几天无意登录,发现被打了1.0分。
叔能忍,婶婶不可忍,摸鱼两周升级完成新的记账小程序。

技术栈:uni-app + uniCloud + TM-vuetify


具体实现功能思路:

  1. 用户进入小程序自动登录,未注册自动注册,免去登录步骤
  2. 记账功能
    • 多种记账类型(ICON图标)
    • 可选记账日期
    • 计算器(因为小程序为了安全起见不支持eval,所以这块需要自己实现)
  3. 月度账单图表查看(收支排行榜、当月结余)
  4. 年度账单查看
  5. 共享协同账单(目前只实现了AA协同方式,因为太懒了,其他先不搞了)
  6. 个人中心
    • 用户设置(头像啊、昵称什么的,共享账单不得知道谁是谁)
    • 意见反馈(用于收集用户反馈bug等,ps:不得给用户留个发泄口,免得再给我打1.0分)
    • 分享功能
    • 在线客服

需求理清楚了,开干!(好吧,其实并没有,因为没有设计天赋,所以摆烂了两天,o(╥﹏╥)o)

用户登录/注册

因为微信小程序一直在变更用户信息获取方式

从# UserInfo => # wx.getUserInfo => # wx.getUserProfile 最后到现在的需要通过用户授权才能获取到头像和昵称,所以初始化注册无法自动补全用户信息

# 小程序用户头像昵称获取规则

前端通过 uni.login 获取用户code

uni.login({success: async (res) => {// 获取用户codeconst {code} = res// 调用云函数登录/注册uniCloud.callFunction({name: 'user',data: {code}}).then(res => {// 存储返回的当前用户的信息uni.setStorageSync('userInfo', JSON.stringify(res.result))this.$store.dispatch('setUserInfo', res.result)})}
})

user云函数负责处理登录返回用户信息,未注册则自动注册后返回用户信息

/*
* 通过请求session接口获取用户openId(微信用户唯一标识)
* appid、secret在公众平台查看
*/
const res = await uniCloud.httpclient.request('https://api.weixin.qq.com/sns/jscode2session', {method: 'GET',data: {appid,secret,js_code,grant_type: 'authorization_code'},contentType: 'json',dataType: 'json'
})
/*
* 通过user集合的length可判断是否注册
*/
const {data:user} = await db.collection('user').where({openId}).get()
if(user.length > 0){// 已注册过直接返回用户信息return user[0]
}else{// 未注册则创建用户后返回用户信息const userObj = {nickname: `微信用户${str}`, // 因为初始化无法获取,所以给默认昵称,str:随机字符串avatar: null,openId,phone: ''}await db.collection('user').add(userObj)return userObj
}

记账

ICON图标

引用阿里字体图标,将资源包导入项目static目录,App.vue引入iconfont.css

创建icon组件,通过name参数生成图标

<text :class="'iconfont icon-' + name"></text>

计算器

因为微信小程序因为安全策略不支持eval函数,所以这块通过另类实现计算器功能

// 操作符
const code_symbol = ['.', '+', '-']
let str = (this.bill.money === '0' ? '0' : this.bill.money)const end = str[str.length - 1]
// 禁止触发多个操作符
if ((code_symbol.includes(key) && !code_symbol.includes(end)) || (!code_symbol.includes(key))
) str += key// 判断操作符变更
if (code_symbol.includes(end) && end !== key) {let key_arr = str.split('')key_arr[key_arr.length - 1] = keystr = key_arr.join('')
}/*
* 计算同理
*/
const code_symbol = ['+', '-']
// 格式化处理展示金额值
const arr = this.formatStr(this.bill.money)
let prev, result
for (let i = 0; i < arr.length - 1; i++) {const item = arr[i]const next = arr[i + 1]// 处理点位符,处理最后位数为操作符if (code_symbol.includes(item)) {item === '+' ? (result = parseFloat(prev || 0) + parseFloat(next || 0)) : (result =parseFloat( prev || 0) - parseFloat(next || 0))prev = result} else {prev = result || arr[i]}
}/** 格式化处理计算 string * return {Array}*/
formatStr(str) {let arr = []const code_symbol = ['+', '-']for (let i = 0; i < str.length; i++) {let len = arr.length === 0 ? 0 : arr.length - 1const v = str[i]if (code_symbol.includes(v)) {arr.push(v)} else {if (code_symbol.includes(arr[len])) {arr[len + 1] = (arr[len + 1] || '') + v} else {arr[len] = (arr[len] || '') + v}}}return arr
}

月度账单

引入echarts图表,实现收支饼状图

this.$refs.incomeChart.setOption({
tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)'
},
grid: {left: 20,
},
legend: {type: 'scroll',orient: 'vertical',right: 10,top: 10,bottom: 30,data: this.incomeData.map((v) => {return v.name}),formatter: function(name) {return name.length > 4 ? `${name.substring(0,4)}...` : name;}
},
toolbox: {show: true,feature: {mark: {show: true},dataView: {show: true,readOnly: false},restore: {show: true},saveAsImage: {show: true}}
},
series: [{type: 'pie',radius: ['40%', '70%'],center: ["30%", "50%"],label: {show: false},emphasis: {label: {show: true}},data: this.incomeData
}]

年度账单

这块需要判断查询年份是否为当年,如果为本年度则只展示到当前月份,如果为过去年份,则展示全年统计

const now = new Date().getFullYear()
const months = ((this.year === now) ? (new Date().getMonth() + 1) : 12)

协同账单

// 账单Schema
{name, // 账单名称img, // 缩略图users: [userId], // 成员、默认加入创建人createTime: Date.now(), bills: [], // 账单createUser: userId, audit, // 是否需要审核member, // 是否允许成员记账allocation // 计算方式
}// 邀请用户自动加入
if (!res.users.includes(this.userInfo.openId)) {// 判断是否开始审核if (!res.audit) {await uniCloud.callFunction({name: 'add-share-user',data: {_id: this.shareId,openId: this.userInfo.openId}})this.getDetail(this.shareId)} else {// 触发审核const params = {ownId: res.createUser,shareBillId: this.shareId,auditId: this.userInfo.openId}await uniCloud.callFunction({name: 'send-audit',data: params})setTimeout(() => {this.$refs.toast.show({model: 'warn',label: '创建者已开启审核,待审核通过后自动加入'})}, 1000)}
}

我的

这块主要说下个人设置,因为现在获取用户头像和昵称需要用户授权

官方文档说的是通过个人设置页面让用户授权获取,参考文档:头像昵称填写能力

注:如果需要存储用户手机号等敏感信息,务必在填写页面声明用户协议及隐私政策,否则不予通过

总结

记录下时隔好几年重新写小程序,官方生态很多都变了,现在官方越来越注重用户隐私这块了,基本上所以牵扯到用户的地方都需要用户授权后才可调用。代码大部分还是无脑梭出来的,毕竟时间有限,后续还需要优化代码,但是喜欢摆烂就这样吧。对了,我还接入了ChatGPT,但是被官方禁止了,不允许接入,那页面都做了能怎么办,接了个睿智机器人。

转载或者引用本文内容请注明来源及原作者:_元十七 (https://juejin.cn/post/7220262023472103485)

只因为给我打了0.1分,重新撸了个记账小程序相关推荐

  1. vue+uni-app商城实战 | 第一篇:从0到1快捷开发一个商城微信小程序,无缝接入OAuth2实现一键授权登录

    一. 前言 本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务. 有来商城 youlai-mall 项目是一套全栈商城系统,技术栈 ...

  2. 微信小程序 #项目笔记# | 从0到1实现外卖点餐系统小程序

    目录 开发前准备 项目展示 项目分析 项目初始化 封装网络请求 任务1 商家首页 任务分析 焦点图切换 中间区域单击跳转到菜单列表 底部商品展示 任务2 菜单列表 任务分析 折扣信息区 设计菜单列表布 ...

  3. 啦啦外卖开源至尊独立稳定版小程序 V43.0+客户端+配送端+商户端多个小程序安装及配置教程

    啦啦外卖开源至尊独立稳定版公众号+小程序 V43.0版系统为独立开源版是一套非常不错的外卖系统,使用过的都知道该系统功能非常强大,是目前外卖平台功能最全的一套系统.最大优势全开源拿来即用,也非常合适做 ...

  4. 「3.0」一个人开发一个App,小程序从0到1,删减添加

    在这个黄道吉日,咱们将要干一件,惊天地泣鬼神,妇孺皆知的大事,那就是删掉微信开发工具自动生成的源代码. 删掉pages下的index.logs目录,啥都不留: 删掉utils下的util.js,只流空 ...

  5. wamp3.0.6配置https + Nginx转发 + 满足微信小程序的接口调用域名

    环境:winserver2012 R2 wamp环境 安卓无法发起请求https://www.jianshu.com/p/61695bfae5f7?utm_campaign 一.  wamp3.0.6 ...

  6. 从0开始编写一个应用(android端+小程序端+服务器端)第二步 项目经理完成逻辑图。(下:产品细节思考后的实现逻辑图)

    上一篇说到产品经理思考完成大概逻辑图: 用户发布拼团信息可以选择金额发布,非金钱发布.并且可以分享.然后,其他用户点击获得奖励,或者分享获得奖励. 奖励的有钱,有发布机会.这个就是项目的主要流程,但是 ...

  7. c语言学籍管理系统小程序,学籍业务办理系统(开源 v2.0发布 优化代码,增加小程序端)...

    更新说明: 1.此2.0版,大幅度优化代码,增加小程序端方便使用 2.v1.0测试地址已关,请勿测试 学生在校期间避免不了要和各种证明打交道,比如学籍证明.转专业申请.休学申请.退学申请等等.此类业务 ...

  8. wordpress发布模块_微慕WordPress小程序专业版v3.0发布

    经过两个多月的紧张开发,微慕WordPress小程序专业版v3.0正式发布,新版本在v2.0的基础上,增加不少功能,同时优化和完善许多的功能细节.所有新功能开发和功能优化,都是围绕微慕小程序产品的核心 ...

  9. 微信小程序直播正式公测;刘强东 2020 年已卸任 8 家公司高管;React 16.13.0 发布| 极客头条...

    整理 | 屠敏 头图 | CSDN 下载自视觉中国 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦, ...

最新文章

  1. 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2
  2. MyBatis的动态SQL详解
  3. python 动画场景_Python GUI教程(十五):在PyQt5中使用动画
  4. python电脑发音-Python如何实现文本转语音
  5. Linux闲时自动抢占GPU脚本
  6. linux 启动一个网站_在线试用 200 多种 Linux 和 Unix 操作系统
  7. linux webshell 页面管理,instantbox:30s内快速搭建可通过webshell管理的Linux系统
  8. squid的简单介绍
  9. 设计导航网站|解决寻找合适的字体麻烦
  10. JAVA就诊叫号_基于B/S的JAVA门诊就诊系统
  11. C# 无法识别的转义序列
  12. 动态SQL实现批量删除指定数据库的全部进程
  13. jsp----中文乱码
  14. 稳定域的画法 matlab,基于MATLAB的铣削加工颤振稳定域仿真算法及实现
  15. Python爬虫教程-22-lxml-etree和xpath配合使用
  16. 我的世界JAVA会支持光追吗_《我的世界》RTX beta版视频体验:仿佛打破了次元壁...
  17. 计算机字体颜色太浅,我的打印机打字太淡,如何调,打印的字就能够颜色
  18. 基于Python实现的Alpha-Beta剪枝算法
  19. CodeSniffer使用教程
  20. 国际高智商组织门萨的智商测试题-谋杀你的脑细胞

热门文章

  1. yum -- Failed connect to mirrors.aliyuncs.com:80; No route to host
  2. FRED应用:激光二极管光源耦合到光纤的仿真
  3. yytextview多种格式_YYTextView使用笔记
  4. 如何调试微信内置浏览器应用(企业号、公众号、订阅号)
  5. 基于Visual C++2010 与office2010开发办公自动化(2)-自动生成excel与word并打开
  6. 【计算方法】线性方程组的数值解法
  7. MyBatis 入门级配置文件
  8. vue 2个方法先后执行_《拖延心理学》:2个对策,3个法宝,6个方法,教你战胜拖延...
  9. ubuntu16 环境配置
  10. Prometheus使用cAdvisor监控Docker容器指标