通过用户授权登录带你了解支付宝小程序云开发流程

流程目录

  • 前言
    • 什么是支付宝小程序云开发
    • 支付宝小程序云开发的优势
  • 一、开发前云环境准备工作
    • 1、首选你应该有一个云环境
    • 2、配置云环境
      • 第一、开启HTTP访问服务。
      • 第二、云调用开放接口服务与授权。
  • 二、进行开发工作
    • 1、新建一个云数据库集合
    • 2、配置代码层的云开发
    • 3、同步当前云环境
    • 4、 新建云函数
  • 三、案例代码
    • axml文件
    • acss文件
    • 云函数NoSqlAdd
    • 云函数queryNoCondition
  • 四、下期:支付宝用户登陆业务流程与详情开发

前言

什么是支付宝小程序云开发

支付宝小程序云开发是基于 Serverless 的一站式小程序后端服务开发平台,支持动态扩缩容低投入,前后端一体化高效研发,简化开发流程,提高研发效率。

支付宝小程序云开发的优势

● 单一技术栈:前端为 Js语言,云开发后端采用 NodeJS,前后端统一技术栈,便于全栈研发。
● IDE 内一栈式开发:小程序的前后端 开发、测试、发布、部署都可以在 IDE 端中完成,免登陆、免鉴权。
● 免域名注册备案:小程序前端 SDK 直接调用 Function,无需域名注册备案,方便使用。
● 按需付费动态扩容。
● 纯业务开发告别框架技术学习成本,提高上手效率。

通过用户授权登录带你了解支付宝小程序云开发流程_第1张图片

一、开发前云环境准备工作

1、首选你应该有一个云环境

方式一IDEA版操作台、打开支付宝小程序开发工具进入项目,点击右上角云开,新建一个云环境,目前云环境有免费版本对于初学者来说,练手足够了!!!
方式二网页版操作台、登录支付宝开发者平台进入控制台搜索找到云开发,新建一个云环境,开发者平台控制台地址已放下面:
https://cloudbase.cloud.alipay.com/console

2、配置云环境

下面以网页版操作台为例

第一、开启HTTP访问服务。

此处有一个默认的域名作为接口路由,这个是我们调用云函数是否成功的一个关键。注意小程序如果上线需要在这个地方配置一个已经备案好,并且有SSL证书可以开启HTTPS服务的域名。
通过用户授权登录带你了解支付宝小程序云开发流程_第2张图片

第二、云调用开放接口服务与授权。

环境管理中的云调用将接口服务开启,并添加接口权限。我们以用户授权登录为例,添加接口“alipay.system.oauth.token”。注意添加接口前必须要在支付宝开放平台的产品中先添加产品。我们以登录为例:开通“获取会员信息”产品

通过用户授权登录带你了解支付宝小程序云开发流程_第3张图片

当以上都完成我们直接进入开发流程,手撕代码阶段!!!!
通过用户授权登录带你了解支付宝小程序云开发流程_第4张图片

二、进行开发工作

1、新建一个云数据库集合

新建一个NoSQL数据库的集合名称。我们依然以登录为例,存储用户信息。新建一个"userInfo"集合,并设置一个索引值_id,选择升序方式。
通过用户授权登录带你了解支付宝小程序云开发流程_第5张图片
通过用户授权登录带你了解支付宝小程序云开发流程_第6张图片

2、配置代码层的云开发

根目录下:mini.project文件

{
  "format": 2,
  "compileOptions": {
    "component2": true
  },
  "miniprogramRoot": "./miniprogram",
  "cloudbaseRoot": "cloud" //云函数目录
}

3、同步当前云环境

通过用户授权登录带你了解支付宝小程序云开发流程_第7张图片

4、 新建云函数

支付宝小程序目前所有的云服务业务流程都是基于云函数调用的方式(这一点还是跟微信小程序不一样的一点,微信小程序除了云函数还可以在pages目录下的页面js文件中编写云开发API)。
我们依然以登录案例作为线索,在IDEA中新建一个云函数addUserInfo,用来上传用户信息到云数据库userInfo当中。
通过用户授权登录带你了解支付宝小程序云开发流程_第8张图片
我们可以在index.js当中编写云函数代码。到此处返回网页端云环境,点击云函数,你就可以看见你所创建的所有云函数。并且可以点击每个云函数进行更详细的配置,自己浏览编辑云函数代码。以及进行云函数的发布与版本更新。
通过用户授权登录带你了解支付宝小程序云开发流程_第9张图片

三、案例代码

axml文件


<view a:if="{{ loginFlag==true }}">
  <view class="topBox">
    <view class="topBgc">
        <image class="face" src="{{face}}" />
        <view style="margin-top:30rpx;color:white;font-weight:550">
            {{userName}}
        view>
    view>
    <view class="be_a_Runner">
          <image mode="widthFix" style="width:100%;position:relative;z-index:0;top:0;left:0" src="/image/lwhvipbgc.png" />    
          <view class="toBe">
                <view style="line-height:150rpx;margin-left:70rpx;color:wheat;font-size:40rpx;font-weight:550;width:50%">
                    认证为跑者 
                view>
                <view style="width:50%;display:flex;align-items:center">
                      <view class="renzheng" onTap="renzheng" data-id="{{userId}}">
                          立即认证
                      view>
                view>
          view>
          
    view>
    
  view>
  <view class="mine">
    <view>
          <view>
                <image style="width:100rpx;height:100rpx" src="/image/lwhdetal.png" />
          view>
          
          <view>
              食堂订单
          view>
    view>
    <view style="border-left:1rpx solid rgb(200,200,200);border-right:1rpx solid rgb(200,200,200)">
          <view>
                <image style="width:100rpx;height:100rpx" src="/image/shopNav.png" />
          view>
          
          <view>
                二手订单
          view>
    view>
    <view style="border-right:1rpx solid rgb(200,200,200)">
          <view>
                <image style="width:100rpx;height:100rpx" src="/image/schoolAc.png" />
          view>
          <view>
                校园活动
          view>
    view>
    <view>
          <view>
                <image style="width:100rpx;height:100rpx" src="/image/order01.png" />
          view>
          
          <view>
                我的跑腿
          view>
    view>
  view>
  <view class="settings">
    <view class="settingItem">
         <view style="width:14rpx;height:40rpx;background-color:#389ef5;margin-right:20rpx">view>
         <text style="width:90%">设置text>
         <image style="width:40rpx;height:40rpx" src="/image/lwhmore.png" />
    view>
    <view class="settingItem">
         <view style="width:14rpx;height:40rpx;background-color:#389ef5;margin-right:20rpx">view>
         <text style="width:90%">客服中心text>
         <image style="width:40rpx;height:40rpx" src="/image/lwhmore.png" />
    view>
    <view class="settingItem">
         <view style="width:14rpx;height:40rpx;background-color:#389ef5;margin-right:20rpx">view>
         <text style="width:90%">我的地址text>
         <image style="width:40rpx;height:40rpx" src="/image/lwhmore.png" />
    view>
    <view class="settingItem">
         <view style="width:14rpx;height:40rpx;background-color:#389ef5;margin-right:20rpx">view>
         <text style="width:90%">退出登录text>
         <image style="width:40rpx;height:40rpx" src="/image/lwhmore.png" />
    view>
  view>
  
view>




<view a:if="{{ loginFlag==false}}">
  <view style="width:100%;height:150rpx">
    
  view>
  
  <view class="login_photo">
    <image src="https://636c-cloud1-4gsna3lu4fd8e5fb-1313325135.tcb.qcloud.la/xpblog/IMG_5104.PNG?sign=dba60d02dcb7cd6fec1aa3b12b7bf891&t=1677937533">image>
  view>
  <view class="login_txt">
    <view class="txt_row01" style="font-size: 40rpx;">扫榻以待view>
    <view class="txt_row02">view>
    <view class="txt_row03" style="color: rgb(107, 107, 107);font-size: 28rpx;">让生活更便捷,让大学更丰富view>
  view>
  <button open-type="getAuthorize" scope="userInfo"
    onGetAuthorize="getOpenUserInfo"
    onError="handleAuthError" 
    style="width:70%;margin:40rpx auto" 
    class="login" 
    >登录button>
view>


<view class="loginging" a:if="{{ logining==true }}">
  
view>

acss文件

page{
    background-color: rgb(247, 247, 247);
  }
.topBox{
  width: 100%;
  height: 520rpx;
  background-image: linear-gradient( 180deg, #ffffff 0%, #9ed5fc 50%,#49d2f8 100%);
}
.topBgc{
  display:flex;
  flex-direction:column;
  width:100%;
  justify-content:center;
  align-items:center;
  padding-top:140rpx;
}

.face{
  width:180rpx;
  height:180rpx;
  border-radius:50%;
  
  border:solid 16rpx rgba(255, 255, 255, 0.925);
}

/* 成为跑者 */
.be_a_Runner{
  margin-top: 30rpx;
  position: relative;
  width: 90%;
  margin-left: 5%;
  height: 150rpx;
  border-radius: 50rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 8rpx rgba(91, 203, 247, 0.798);

}
.toBe{
  position:absolute;
  top:0;left:0;z-index:1;
  display:flex;
  flex-direction: row;
  width: 100%;
}
/* 认证按钮 */
.renzheng{
  font-weight:600;
  color:white;
  background-color:rgb(246, 217, 52);
  border-radius:50rpx;
  overflow:hidden;
  line-height:90rpx;
  width:200rpx;
  text-align:center;
  margin-left: 60rpx;
}
.mine{
  width: 90%;
  margin-left: 5%;
  margin-top: 100rpx;
  /* height: 120rpx; */
  display: flex;
  flex-direction: row;
  border-radius: 20rpx;
  overflow: hidden;
  background-color: rgb(249, 252, 253);
  /* box-shadow: 0 3rpx 5rpx rgba(38, 187, 245, 0.798); */
  padding-bottom: 30rpx;
}
.mine>view{
  margin-top: 30rpx;
  width: 33.33333%;
  text-align: center;
  line-height: 40rpx;
  color: #303030;
  font-size: 30rpx;
  font-weight: 500;
}

.settings{
  margin-top: 30rpx;
  width: 90%;
  margin-left: 5%;


}

.settingItem{
  background-color: rgb(250, 254, 255);
  line-height: 50rpx;
  padding: 30rpx;
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-bottom: 20rpx;
  border-radius: 15rpx;
  /* box-shadow: 0 2rpx 8rpx #5bcbf7b1; */
}

.login_photo{
  width: 100%;
}
.login_photo>image{
  width: 100%;
}
.login_txt{
  display: flex;
  flex-direction: column;
  justify-content: left;
  margin-left: 80rpx;
  margin-top: 100rpx;
}
.login_txt>view{
  margin-bottom: 20rpx;
}
.txt_row02{
  width: 200rpx;
  height: 10rpx;
  border-radius: 30rpx;
  background:-webkit-linear-gradient(left,rgb(92,104,206),rgb(171,179,241),white);
}
.login{
  background-color: rgb(92, 104, 206);
  border-radius: 50rpx;
  color: white;
  margin-top: 100rpx;
}

/* 登陆中 */
.loginging{
  width: 100%;
  height: 100vh;
  position: fixed;
  z-index: 999;
  background-color: black;
  opacity: 0.4;
  top: 0;
}

##js文件

Page({
  data: {
    shitang:"3",  //食堂订单
    ershou:"6",   //二手
    active:"8",   //活动
    run:"10",     //跑腿
    userId:"",
    userName:"",
    face:"",
    loginFlag:false,
    canIUseAuthButton: my.canIUse('button.open-type.getAuthorize'),
    formattedDateTime:'',
    loginUserInfo:'',
    logining:false
  },
  onLoad(){
    /* 登录标志 */
    try{
      console.log(my.getStorageSync({key:"userInfo"}));
      let userInfo=my.getStorageSync({key:"userInfo"})
      if(userInfo.data){
        this.setData({
          loginFlag:true,
          userName:userInfo.data.userName,
          face:userInfo.data.avatar
        })
      }
    }catch(error){
      my.showModal({
        title:'您似乎还未登录,确定登录?',
        success:(res)=>{
          if(res.confirm){
            my.switchTab({
              url:"/pages/user/user"
            })
          }
        }
      })
     
    }
    
  },
  /* 登录按钮 */
  getOpenUserInfo(){
    const self=this
    //判断新老用户
    self.setData({
      logining:true
    })
    my.showLoading({
      content:'身份鉴别中'
    })
    my.fncontext.callFunction({
      name:"queryNoCondition",
      data:{
        coll:"userInfo",
      },success:(userinfo)=>{
          my.hideLoading({})
          console.log("新老用户返回数据",userinfo);
          if(userinfo.result.length!=0){
            self.oldUser(userinfo.result[0].username,userinfo.result[0].avatar,userinfo.result[0]._openid)
           
          }else{
            self.NewUser({})
          }
      },fail:(userinfo)=>{
        my.hideLoading({})
        console.log("新老用户返回数据错误",userinfo);
      }
    })
  },
  /* 获取当前的时间 */
  getNowTime(){
    // 获取当前日期和时间
    var now = new Date();
    // 格式化年份
    var year = now.getFullYear();
    // 格式化月份,JavaScript中月份是从0开始的,所以要加1
    var month = now.getMonth() + 1;
    month = month < 10 ? '0' + month : month; // 添加前导零
    // 格式化日期
    var date = now.getDate();
    date = date < 10 ? '0' + date : date; // 添加前导零
    // 格式化小时
    var hours = now.getHours();
    hours = hours < 10 ? '0' + hours : hours; // 添加前导零
    // 格式化分钟
    var minutes = now.getMinutes();
    minutes = minutes < 10 ? '0' + minutes : minutes; // 添加前导零
    // 组合最终的日期时间字符串
    var formattedDateTime = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes;
    // 输出或保存格式化后的日期时间
    console.log(formattedDateTime);
    this.setData({
      formattedDateTime:formattedDateTime
    })
  },
  //新老用户判断
  oldUser(name,avatar,openid){
    const self=this
    self.setData({
      logining:false
    })
    var userInfoTemp={}
    userInfoTemp.userName=name
    userInfoTemp.avatar=avatar
    userInfoTemp.openid=openid
    my.setStorageSync({
      data:userInfoTemp,
      key:'userInfo'
    })
    my.reLaunch({
      url:"/pages/user/user"
    })
  },
  NewUser(){
    const self=this
    self.getNowTime({})
    my.getAuthCode({
      success:(res)=>{
        //console.log("authCode",res);
        let authCode=res.authCode
        my.showLoading({
          content:'新用户,注册中'
        })
        //动态令牌换取userid||openid
        my.fncontext.callFunction({
          name:'userID',
          data:{
            auth_code:authCode
          },success:(userid)=>{
            //console.log(userid);
            const openidTemp=userid.result.open_id

            my.getOpenUserInfo({
              success: (info) => {
                // console.log(info);
                console.log(self.data.formattedDateTime);
                
                const userInfo = JSON.parse(info.response).response
                my.fncontext.callFunction({
                      name:"noSqlAdd",
                      data:{
                        openid:userid.result.open_id,
                        username:userInfo.nickName,
                        avatar:userInfo.avatar,
                        registerTime:self.data.formattedDateTime
                      },
                      success:(e)=>{
                        my.hideLoading({})
                        console.log("注册成功,返回信息:",e);
                        //缓存到本地
                        var userInfoTemp={}
                        userInfoTemp.userName=userInfo.nickName
                        userInfoTemp.avatar=userInfo.avatar
                        userInfoTemp.openid=openidTemp

                        my.setStorageSync({
                          data:userInfoTemp,
                          key:'userInfo'
                        })
                        self.setData({
                          logining:false
                        })
                        my.reLaunch({
                          url:"/pages/user/user"
                        })
                      },fail:(e)=>{
                        self.setData({
                          logining:false
                        })
                        console.log("注册失败,错误:",e);
                        my.hideLoading({})
                      }
                  })
              },
              fail: (err) => {
                self.setData({
                  logining:false
                })
                  console.log(err)
              }
          });
          } 
        })
      }
    })
  }
});

云函数NoSqlAdd

const cloud = require('@alipay/faas-server-sdk'); 
exports.main = async (event, context) => {   
  const db=cloud.database();
  db.collection("userInfo").add({
    data:{
      openid:event.openid,
      username:event.username,
      avatar:event.avatar,
      registerTime:event.registerTime
    },success:(res)=>{
      return res
    },fail:(error)=>{
      return error
    }
  })
};

云函数queryNoCondition

const cloud = require('@alipay/faas-server-sdk'); 
exports.main = async (event, context) => {
  const db = cloud.database();
  const coll=event.coll
  return await db.collection(coll).where({
    _openid: cloud.getAlipayContext().OPENID
  }).get({})
};

四、下期:支付宝用户登陆业务流程与详情开发

你可能感兴趣的:(小程序,javascript,nosql,前端,servlet)