目录

1 项目准备

1.1 腾讯云服务空间

1.2 准备阿里云域名

1.3 准备支付宝支付能力

1.3.1下载app支付宝助手

1.4新建项目

2 注册

2.1验证码使用

2.2注册逻辑

2.3报错记录

3 登录

3.1传统密码登录

3.2短信密码登录

3.3手机一键登录

4 登录与退出登录

5 轮播图

6 公告栏

7 ThreeJs商品展示

8 商品购买


这是我3月-5月单人负责的一个数藏项目,巅峰时刻同时在线3w人,也算我第一个uniapp综合项目,不够目前我做的已经停运了,当初学了很多,但是缺乏整理,项目缺点也很多。我想通过这段时间把代码重新写一遍,整理一下。我不会把所有功能都重新梳理,但是重要的几样我肯定都一一梳理,而且会有增加,例如:注册、登录、一键登录、短信、抢购、转赠、支付宝支付、版本热更新、公告等

当然里面涉及的上链操作我不是很会,你们可以把这个当作一个售卖东西的App,里面不会涉及上一个公司的信息,只是单纯的整理一下目前项目主要的技术和自学时候的壁垒

我这里使用的是Mac电脑,不影响window电脑的学习,排版可能不好看

github上面每天都在更新,如果认可,不要吝啬正反馈:GitHub - chenqi13814529300/light-ship: 复习和加强uniapp/unicloud学习

点赞收藏超过100,我将录播视频

1 项目准备

1.1 腾讯云服务空间

开通空间

配置短信签名和模版

模版需要短信签名审核成功后才可以编辑模版

开通一键登录

1.2 准备阿里云域名

需要购买至少3个月的服务器,然后实名认证啥的才可以,这些自己弄吧,然后我再域名解析为如下本项目使用的域名

1.3 准备支付宝支付能力

绝大部分人都没有创建公司或者实体,所以这里的支付能力我将采用支付宝沙箱带你们一起如何使用支付宝。

1.3.1下载app支付宝助手

1.3.2支付宝开放平台

登录 - 支付宝

你需要自己设置账户密码啥的,这个自己弄。

最终你可以得到几个有用的信息

appid:20210001111111111

mchid:2088621911111111

商家账户:wtesjg2746@sandbox.com

商家登录密码:111111

买家账户:qhsfny9975@sandbox.com

买家登录密码:111111

买家支付密码:111111

准备关于支付能力的密钥和证书,打开之前下的软件,点击生成应用密钥和应用公钥

方法一用阿里云公钥(二选一):

点击查看

然后把应用公钥放到里面,生成支付宝公钥

方法一有应用私钥和支付宝公钥即可进行支付测试

方法二用证书:

获取csr文件,组织/公司和域名填写商家账户

上传csr文件,然后下载3个证书

ok,支付支付能力准备好了!

1.4新建项目

这里使用的是vue2,unicloud,以及默认空模版

并关联腾讯云服务器空间

2 注册

2.1验证码使用

首先需要开通验证码,签名和模版都审核通过,并充值些许钱。

需要先引入uni-id组件

uni-id - DCloud 插件市场

本次项目采用的是老版uni-id这个用起来比较顺手

引入uni-id后需要配置uni-id/config.json

config.json的配置参考官网文档uni-app官网

发送验证码——前端代码

我这边是做了发送验证码前进行判断(是否已经注册),避免浪费验证码次数

     async getCode() {if (this.regsiterInfo.mobile && this.isAgree) {this.settime()const sms = uniCloud.importObject("sms")// 正常查找到就说,该用户名已经被注册const isRegister = await sms.getUserByMobile(this.regsiterInfo.mobile)console.log(isRegister)if (isRegister.code == 0) {uni.showToast({title: "该用户名已经被注册",icon: "none"})this.countdown = 0}if (isRegister.code == -100) {const res = await sms.sendSms(this.regsiterInfo.mobile, "register")console.log(res)if (res.code != 0) {uni.showToast({title: "验证码发送失败",icon: "none"})return }uni.showToast({title: "验证码发送成功",icon: "none"})}} else {uni.showToast({title: "请输入手机号并且勾选协议",icon: "none"})}}

验证码冷却时间——前端代码

也是节约成本,同时减少后端请求

         settime() {let smsTime = nullif (this.countdown == 0) {this.isdisabledFn = falsethis.isSms = "获取验证码"this.countdown = 60;clearInterval(smsTime)} else {this.isdisabledFn = truethis.isSms = "重新发送(" + this.countdown + ")"this.countdown--;smsTime = setTimeout(() => {this.settime()}, 1000)}},

校验验证码——前端代码

参数就是手机号和验证码

                     const sms = uniCloud.importObject("sms")const smsInfo = await sms.verifySmsCode(this.regsiterInfo.mobile, this.regsiterInfo.code,"register")console.log(smsInfo)

验证码方法——后端代码

// 开发文档: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
const uniID = require('uni-id')
const db = uniCloud.database();
module.exports = {// 发送验证码async sendSms(mobile, type) {// 生成验证码可以按自己的需求来,这里以生成6位数字为例const randomStr = '00000' + Math.floor(Math.random() * 1000000)const code = randomStr.substring(randomStr.length - 4)const res = await uniID.sendSmsCode({mobile,templateId: "14408",code,type})return res},// 校验验证码async verifySmsCode(mobile, code, type) {const res = await uniID.verifyCode({mobile,code,type})return res},// 根据电话号码查找个人信息async getUserByMobile(mobile) {let {data} = await db.collection("uni-id-users").where({"mobile": mobile}).get()if (data[0]) {return {code: 0,msg: '查询成功',}} else {return {code: -100,}}}// 手机+短信 登录// 注册后的可以直接登录,如果没有注册过则去注册页面async smsLogin(mobile, code) {// 判断mobild是否注册了const sms = uniCloud.importObject("sms")try {const res = await sms.getUserByMobile(mobile)} catch (e) {// 异常则显示未注册-100return {res: e}}try {const res = await uniID.loginBySms({mobile,code})return {res: res}} catch (e) {return {res: e}}}}

2.2注册逻辑

手机号、密码、验证码、用户协议都填写才可以注册,上述完成后,便在云数据库中产生一条数据。

同时需要把注册的token保存下来,vuex保存下来。并跳转到登录页面

注册逻辑——前端代码

     uniCloud.callFunction({name: 'register',data,async success(res) {console.log(res)if (res.result.code === 0) {uni.showToast({title: '注册成功',icon: 'none'})// 2.8.0版本起调整为蛇形uni_id_token(调整后在一段时间内兼容驼峰uniIdToken)uni.setStorageSync('uni_id_token', res.result.token)uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)// 把邀请码清单归到邀请码数据库之中(存在就入库不存在不执行)if (that.regsiterInfo.inviteCode) {console.log("我有邀请码奥")const userInfo = {"registerUserId": res.result.uid,"mobile": res.result.mobile,"username": res.result.username}const invite = uniCloud.importObject("invite")await invite.updateInvite(that.regsiterInfo.inviteCode,userInfo)}// 跳转到登录页setTimeout(function() {uni.navigateTo({url: "/pages/login/Login"})}, 1000)} else if (res.result.code == -100) {uni.showToast({title: res.result.msg,icon: "none"})} else {uni.redirectTo({content: res.result.message,showCancel: false})}},fail(res) {console.log(res)uni.showModal({content: '注册失败,请稍后再试',showCancel: false})}})

注册逻辑——后端代码

// 云函数register的代码
const uniID = require('uni-id')
exports.main = async function(event, context) {const {mobile,password,inviteCode} = event// 自动验证用户名是否与已经注册的用户名重复,如果重复会直接返回错误。否则会自动生成token并加密password存储username、password、token到数据表uni-id-users,并返回如上响应参数const res = await uniID.register({ //支持传入任何值,比如可以直接传入mobile即可设置手机号码,切勿直接传入event否则这是一个极大的安全问题"username":mobile,"password": password,"mobile": mobile,"avatar": 'https://7463-tcb-d4ae9humf98e68-0dudeafb75fdc-1310755086.tcb.qcloud.la/head/good3.jpg',"goods_count": 0,"mobile_confirmed": 1,"realname_auth": 0,"invite_code": inviteCode,"create_invite_code": '',})return res}

注册成功!

2.3报错记录

Error: Method name required代表你创建的是云对象,不是云函数。云对象调用需要方法(例如一开始我创建的是register是云对象,一切操作符合文档结果报这个错误)

3 登录

3.1传统密码登录

密码登录——前端代码

一个是判断是否是传统登录方式,登录成功后执行登录后的逻辑,保存token,以及记录登录时长(用于3天后清空token,登录失效,需要重新登录)

if (this.isTradition) {const login = uniCloud.importObject("login")const loginInfo = await login.commonLogin(data)console.log(loginInfo)if (loginInfo.code == 0) {// 执行登录成功后的逻辑that.loginAfter(loginInfo)}} // 登录成功后的逻辑loginAfter(res) {// uni.closeAuthView()uni.showToast({title: '登录成功',icon: 'none',})// 保存tokenuni.setStorageSync('uni_id_token', res.token)uni.setStorageSync('uni_id_token_expired', res.tokenExpired)var dayAdd1 = new Date();dayAdd1 = dayAdd1.setDate(dayAdd1.getDate() + 1);dayAdd1 = new Date(dayAdd1);// 记入token终止日期,1天uni.setStorageSync('uni_id_token_end_time', dayAdd1.getTime())// 其他业务代码,如跳转到首页等this.setUserInfo(res.userInfo)setTimeout(function() {uni.switchTab({url: "/pages/index/Index"})}, 1000)},

密码登录——后端代码

const uniID = require('uni-id')module.exports = {// 普通账号 密码登录async commonLogin(userInfo) {const {mobile,password} = userInfo// 自动完成mobile、password验证是否合法的逻辑const res = await uniID.login({username: mobile,password,})return res},// 重置密码async resetPwdBySms(resetInfo) {const {mobile,code,password} = resetInfoawait uniID.resetPwdBySms({mobile,code,password})return {code:0}},}

3.2短信密码登录

短信登录——前端代码

短信登录其实跟注册获取验证码逻辑类似

     // 电话号码+验证码登录// 1.是否填写验证码if (that.loginInfo.code) {const sms = uniCloud.importObject("sms")const {res} = await sms.smsLogin(that.loginInfo.mobile, that.loginInfo.code)// res.code为-100则res.errMsg 未注册// 50202  errMsg "验证码错误或已失效"// 0 是成功的console.log(res)switch (res.code) {case 0:// 执行登录成功后的逻辑that.loginAfter(res)break;case -100:uni.showToast({title: res.errMsg,icon: 'none'});break;case 50202:uni.showToast({title: res.errMsg,icon: 'none'});break;case -300:uni.showToast({title: res.errMsg,icon: 'none'});break;}} else {uni.showToast({title: "请填写验证码",icon: 'none'})}

短信登录——后端代码

这部分代码,在注册的后端sms代码里面

3.3手机一键登录

一键登录——前端代码

目前有缺陷,ios一键登录uni.closeAuthView()不生效,是官方还没修复

 // 判断是否支持一键登录isAutoLogin() {let _that = thisuni.getProvider({ //获取可用的服务提供商service: 'oauth',success: function(res) {console.log(res.provider) // ['weixin', qq', 'univerify']}});uni.preLogin({ //预登录provider: 'univerify', //用手机号登录success() {_that.autoStatus = trueconsole.log('预登录成功')_that.fasterLogin()},fail(err) { //预登录失败_that.autoStatus = false_that.error = errconsole.log('错误码:' + err.errCode)console.log(err.errMsg)}})},async fasterLogin() {let that = thisuni.login({provider: 'univerify',async success(res) { // 登录成功console.log(res.authResult); // {openid:'登录授权唯一标识',access_token:'接口返回的 token'}const login = uniCloud.importObject("login")const fastLoginRes = await login.fastLogin(res.authResult)console.log(fastLoginRes)if (fastLoginRes.code == -100) {uni.showToast({title: "请先注册",icon: "none"})setTimeout(function() {uni.closeAuthView()uni.navigateTo({url: "/pages/register/Register"})}, 1000)}if (fastLoginRes.code == 0) {uni.closeAuthView()that.loginAfter(fastLoginRes)}},fail(res) { // 登录失败console.log(res.errCode)uni.closeAuthView()}})},

一键登录——后端代码

type:指定操作类型,可选值为loginregister,不传此参数时表现为手机号已注册则登录,手机号未注册则进行注册

 // 手机一键登录async fastLogin(userInfo) {const {access_token,openid} = userInfoconst res = await uniID.loginByUniverify({access_token,openid,type:'login'})return res},

4 登录与退出登录

登录成功跳转到首页,并且显示登录状态和用户名

点击退出后如下

完整代码如下——前端代码

<template><view><nav-bar><view slot="left" class="left">启航</view><view slot="right" v-if="isLogin" @click="goLogin">{{getUserInfo._id.slice(0,12)}} <text @click="outLogin"class="outLogin">退出</text></view><view slot="right" v-else @click="goLogin">登录</view></nav-bar></view>
</template><script>import NavBar from '../../components/NavBar.vue'import {mapGetters,mapMutations} from "vuex";export default {components: {NavBar},data() {return {}},computed: {...mapGetters(["getUserInfo"]),isLogin() {console.log(this.getUserInfo)if (Object.keys(this.getUserInfo).length > 0) {return true;} else {return false;}},},methods: {...mapMutations(['setUserInfo']),// 去登录goLogin() {uni.navigateTo({url: "/pages/login/Login"})},// 退出登录outLogin() {this.setUserInfo({})uni.removeStorageSync('uni_id_token')uni.removeStorageSync('uni_id_token_expired')uni.navigateTo({url: "/pages/Login/Login"})},}}
</script><style></style>

NavBar组件——前端代码

<template><view class="nav-bar"><view class="left"><slot name="left"></slot></view><view class="center"><slot name="center"></slot></view><view class="right"><slot name="right"></slot></view></view></template><script>export default {name: "NavBar"}
</script><style scoped>.nav-bar {position: -webkit-sticky;position: sticky;top: var(--window-top);z-index: 99;height: 80rpx;overflow: hidden;line-height: 80rpx;background-color: #242729;color: white;}.left{float: left;}.right{float: right;}</style>

5 轮播图

效果如下

点击轮播图进入图片详情

轮播图——前端代码

     <!-- 轮播图 --><uni-swiper-dot :info="info" :current="current" field="content" mode="round"><swiper class="swiper-box" @change="change" autoplay="true"><swiper-item v-for="(item ,index) in info" :key="index"><image @click="bigImgDeatils(item)" :src="require(`@/static/lun/${item.content}`)" mode="widthFix"></image></swiper-item></swiper></uni-swiper-dot>
             // 轮播图片 这里就不从后端获取了,大家应该都会info: [{content: 'lun2.jpeg',big: 'lun2-big.jpeg'},{content: 'lun1.jpeg',big: 'lun1-big.jpeg'},],current: 0,
         // 轮播图详情页面bigImgDeatils(item) {// 预览图片let imgArr = [];/* 这里可以使用网络路径,也可以使用图片的base64编码 */imgArr.push(require(`@/static/lun/${item.big}`))//预览图片uni.previewImage({urls: imgArr,current: imgArr[0]});},// 轮播图改变都时候的方法change(e) {this.current = e.detail.current;},

6 公告栏

效果如下

这里使用的是插件,效果不错

公告栏——前端代码

 <!-- 公告 --><view class="lwNoticeBox"><lwNotice :showScale="true" @itemClick="newsItemDetails" :list="newsList"></lwNotice><uni-icons class="more" @click="oatoUrl" type="bars" size="30" color="white"></uni-icons></view>
             // 新闻公告栏 也是写死,反正这个简单newsList: ["启航官网jrx.jrxtiejin.com","江河地笑CSDN",]
         // 公告详情newsItemDetails(data) {// 数据库中的新闻是包含title和id字段// 通过title找到对应的新闻对象,然后通过新闻对象的id得到新闻详情,这里就不演示后端代码了// const currentNews = this.newsList.find(item => item.title == data)// uni.navigateTo({//   url: '/pages/activities/OfficialNewsDeatils?id=' + currentNews.id// })},

7 ThreeJs商品展示

商品展示环节很简单,做了几个组件,难点在于ThreeJS3d环节。然后点击进入到商品展示页面

然后点击购买进入付款环节,我们这次测试付款主要使用的是支付宝

皮肤设置数据库字段如下:

goods_type值得是皮肤类型,0是法师皮肤,1是战士皮肤,2是辅助皮肤

rank_index代表是皮肤展示前后顺序,0代表在最前面展示

sale_status代表是销售状态1:预销售,2:热销中,3:已售罄

首页展示单个皮肤组件——前端代码

 <!-- 单个皮肤展示组件 --><digit-goods v-for="item in goodsList.data" :goodsItem="item" v-show="currentIndex==0"@click.native="toGoodsDetails(item)"></digit-goods>
<template><view class="goodsItem"><view class="goodsStatus">{{goodsStatus}}</view><image class="goodImg" :src="goodsItem.goods_img" mode="widthFix"></image><view class="content"><view class="title">{{goodsItem.goods_name}}<text class="remain_count">库存:{{goodsItem.goods_count}}</text></view><view class="tag"><text class="quality">限量:</text><text class="count">{{goodsItem.goods_count}}份</text><text class="classes">{{goodsItem.goods_desc}}</text></view><view class="price"><text class="left"><image :src="goodsItem.framer_img" mode="aspectFill"></image>{{goodsItem.framer}}</text><text class="right">¥ {{goodsItem.goods_price.toFixed(2)}}</text></view></view></view>
</template><script>export default {name: "DigitGoods",props: {goodsItem: {type: Object,default () {return {name: ''}}}},computed: {goodsStatus() {switch (this.goodsItem.sale_status) {case 1:return '⌚️预销售'case 2:return '												

uniapp基础项目相关推荐

  1. uni-app基础知识

    uni-app的基本使用 课程介绍: 基础部分: 环境搭建 页面外观配置 数据绑定 uni-app的生命周期 组件的使用 uni-app中样式学习 在uni-app中使用字体图标和开启scss 条件注 ...

  2. uniapp基础介绍

    uni-app基础 uniapp基础介绍 一.uniapp项目的搭建 (1)下载开发工具HBuilderX (2)创建 uni-app 项目 (3)运行 uni-app (4)发布 uni-app 二 ...

  3. uni-app基础入门

    目录 uni-app介绍 项目目录 全局外观配置 页面外观配置 配置tabbar Condition启动模式配置 组件的基本使用 uni-app中的样式 基本数据绑定 v-bind动态绑定属性 v-f ...

  4. uniapp 基础知识学习

    uniapp 基础知识学习 uniapp 基础知识学习 [uniapp 介绍](https://uniapp.dcloud.io/README) 有哪些uni-app的作品 uni-app的社区规模 ...

  5. 【uni-app基础教程】

    uni-app基础教程 uni-app是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS,Android,H5,以及各种小程序(微信/支付宝/百度/头条/ QQ /钉钉) ...

  6. uni-app基础知识(一) 持续更新

    uni-app基础知识 一.uni-app介绍 1.1 什么是uin-app uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.We ...

  7. Uni-App从入门到实战-黑马程序员【uniapp基础知识讲义笔记】

    想要课程资料的同学可以留言,留下你的邮箱哦 ####uni-app的基本使用 课程介绍: 基础部分: 环境搭建 页面外观配置 数据绑定 uni-app的生命周期 组件的使用 uni-app中样式学习 ...

  8. uniapp基础知识—大总结

    uni-app介绍 官方网页 uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/支付宝/百度/头条/QQ ...

  9. UniAPP社区项目实战教案

    千锋教育 UniAPP 社区论坛项目多端开发实战 学习目的: ​ 通过学习,对标企业级「大前端」开发实践标准,从零到一构建「社区论坛类」客户端应用项目, 输出相关 Web H5.微信小程序.安卓 AP ...

最新文章

  1. 后端必备 Git 分支开发:规范指南
  2. 基于centos4.4的mg手工下载RPM包安装顺序记录
  3. 搭建前端私有npm杂记
  4. [总结篇3]Provider_network的含义
  5. SpringBoot - 构建监控体系02_定义度量指标和 Actuator 端点
  6. ITK:将itk :: CovariantVectors的点积
  7. 肯德基收银系统模式_肯德基的完整形式是什么?
  8. AutoCAD 2010建筑土木制图高清实例视频教程
  9. 7-38 数列求和-加强版(20 分)
  10. 多媒体交互应用基础(7)
  11. 安卓系统管理软件_便捷仓库管理软件智能管理系统
  12. python---字符串的拼接、去重、反转、字母花样排序、单词出现判断、统计文件特定单词频率lambda、硬盘容量、列表转字符串
  13. 屈臣氏供应链数据分析
  14. Android 动画 - TranslateAnimation位移动画
  15. 重磅白皮书发布,华为持续引领未来智慧园区建设新模式
  16. 十大免费PHP编辑器-开发工具
  17. 易捷行云EasyStack携手北联国芯,共筑鲲鹏生态
  18. Re:LieF ~親愛なるあなたへ~ 后感
  19. TCP序列号和确认号
  20. Spring Security进行登录认证和授权

热门文章

  1. 基于二维灰度图的卷积神经网络故障诊断(tensorflow)
  2. aix服务器移动文件系统,AIX文件系统管理汇总:命令+SMIT实战
  3. autopilot_donkey car
  4. 浅析运动健身APP开发的四种模式
  5. Python 螺旋正方形
  6. Python3爬虫——利用百度翻译实现中文翻译英文
  7. 西瓜书课后题4.7(队列控制决策树深度)
  8. Cmake NDK交叉编译Android平台程序
  9. api质量等级_API分级说明
  10. MATLAB画图并将两个图排列在一起