Flask 与微信小程序的对接
在 web/controllers/api中增建py文件,主要是给微信小程序使用的。
web/controllers/init.py
# -*- coding: utf-8 -*-
from flask import Blueprint
route_api = Blueprint( 'api_page',__name__ )
@route_api.route("/")
def index():
return "Mina Api V1.0~~"
www.py
from web.controllers.api import route_api
如图所示api已经做好了
微信小程序mina
mina/pages/index
mina/pages/index /index.wxml
wxml中 屏蔽注释用 <!-- --!>
<!--start.wxml-->
<view class="container">
<view class="remind-box" wx:if="{{remind}}">
<image class="remind-img" src="/images/more/loading.gif"></image>
</view>
<block wx:else>
<image class="title" src="/images/more/title8.png"></image>
<view class="content">
<view class="hd" style="transform:rotateZ({{angle}}deg);">
<image class="logo" src="/images/more/logo.png"></image>
<image class="wave" src="/images/more/wave.png" mode="aspectFill"></image>
<image class="wave wave-bg" src="/images/more/wave.png" mode="aspectFill"></image>
</view>
<view class="bd">
<image class="smalltitle" src="/images/more/confirm-word1.png"></image>
<view class="confirm-btn" bindtap='goToIndex'>
<text >走吧,订餐去</text>
</view>
<text class="copyright">@编程浪子 54php.cn</text>
</view>
</view>
</block>
</view>
第一步: 设置小程序用户信息
wx.getUserInfo(Object object) | 微信开放文档 用户信息
avatar
n.化身(印度教中化作人形或兽形的神);(人或思想的)化身,体现;(在电脑游戏或网络中代表使用者的)图标,头像;<正式>代表人物
这段代码中,使用了条件语句wx:if="{{canIUse}}"
来判断是否支持该API。
如果支持 则显示一个按钮用于授权登录,点击按钮会触发bindgetuserinfo
事件,可以在事件处理函数bindGetUserInfo
中获取用户信息。
如果不支持 该API,则显示一条提示信息,请用户升级微信版本。
我们这里使用class="confirm-btn", 并去掉wx:if"{{canIUse}}"
<!--start.wxml-->
<view class="container">
<view class="remind-box" wx:if="{{remind}}">
<image class="remind-img" src="/images/more/loading.gif"></image>
</view>
<block wx:else>
<image class="title" src="/images/more/title8.png"></image>
<view class="content">
<view class="hd" style="transform:rotateZ({{angle}}deg);">
<image class="logo" src="/images/more/logo.png"></image>
<image class="wave" src="/images/more/wave.png" mode="aspectFill"></image>
<image class="wave wave-bg" src="/images/more/wave.png" mode="aspectFill"></image>
</view>
<view class="bd">
<image class="smalltitle" src="/images/more/confirm-word1.png"></image>
<!-- <view class="confirm-btn" bindtap='goToIndex'>-->
<!-- <text >走吧,订餐去</text>-->
<!-- </view>-->
<button class="confirm-btn" open-type="getUserInfo" bindgetuserinfo="login">授权登录</button>
<text class="copyright">@编程浪子 54php.cn</text>
</view>
</view>
</block>
</view>
问题1: 为什么wx:if 可以去掉? wx:if的作用是什么呢?
没有使用<wx:if="{{canIUse}}">
的原因是因为在data
中没有定义canIUse
这个属性。在data
中定义了remind
属性,用于控制是否显示加载中的提示框。因此,在wxml
中使用了wx:if="{{remind}}"
来判断是否显示加载中的提示框。
代码中,确实没有使用<wx:if="{{canIUse}}">
。
wx:if
是一个条件渲染的指令,用于根据条件来决定是否渲染某个组件或元素。
canIUse
是一个变量,用于存储一个布尔值,根据这个布尔值来决定是否渲染<wx:if>
所在的组件或元素。
wx:if
的作用是根据条件来动态渲染页面的不同部分。
当条件为真时,渲染该组件或元素;
当条件为假时,不渲染该组件或元素。
这样可以根据不同的条件来显示不同的内容,提高页面的灵活性和交互性。
在给出的代码中,没有使用<wx:if="{{canIUse}}">
,可能是因为canIUse
变量的值在该代码段中没有被定义或赋值。所以,该代码段中没有使用<wx:if="{{canIUse}}">
。
其实上面代码已经使用wx:if="{{remind}}"做了相关判断。
按钮更改后展示图
问题2: open-type 有什么作用?
微信小程序中的open-type是一个属性,用于定义按钮的点击行为。根据提供的引用内容,有两种常见的open-type值可以使用。
-
contact:该值用于直接打开客服对话功能。要使用此功能,需要在微信小程序的后台进行配置,并且只能通过真机调试来打开。具体的配置和使用方法可以参考微信小程序开发文档。
-
launchApp:该值用于在小程序中直接打开其他应用程序。通过设置launchApp的open-type,可以实现在小程序中点击按钮后直接打开指定的应用程序。更多详细信息可以参考微信小程序开发文档中的相关章节。
请注意,open-type属性的具体使用方式和效果可能会因微信小程序的版本和配置而有所不同。建议在开发过程中参考官方文档并进行测试
这里使用了open-type="getUserInfo" 来定义这样一个属性,来获取用户信息
问题3: bindgetuserinfo="" 也是一个属性吗?这个属性起到什么作用?
在微信小程序中,bindgetuserinfo是一个用于 获取用户信息的事件 绑定 属性。
当用户点击 授权按钮 并允许小程序获取用户信息时,该事件会被触发,并将 用户信息 作为 参数 传递给 绑定的 事件处理函数。
下面是一个示例代码,演示了如何在微信小程序中使用bindgetuserinfo属性:
<!-- index.wxml -->
<view class="container">
<button bindgetuserinfo="getUserInfo">获取用户信息</button>
</view>
// index.js
Page({
getUserInfo: function(e) {
console.log(e.detail.userInfo);
// 在这里可以对用户信息进行处理
}
})
在上述示例中,当用户点击"获取用户信息"按钮时,会触发getUserInfo函数,并将用户信息传递给该函数的参数e。你可以在该函数中对用户信息进行处理,比如打印到控制台或者发送到服务器。
这里使用bindgetuserinfo="login",当用户点击这个授权登录按钮时,绑定login()方法
问题4: open-data 是什么?
open-data | 微信开放文档 用于展示微信开放的数据。
问题5: <block wx:else> </block> 中block是什么?
在给出的代码中,<block>
是一个条件渲染的标签。它的作用是根据条件来决定是否渲染其中的内容。在这段代码中,<block>
标签的wx:else
属性表示如果remind
为假,则渲染<block>
标签内的内容。如果remind
为真,则不渲染<block>
标签内的内容。
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
问题6: <view></view>是什么?
view | 微信开放文档 视图容器
在给出的代码中,<view>
是小程序中的一个组件,用于显示一个视图容器。它类似于HTML中的<div>
标签,用于包裹其他元素或者作为一个独立的容器。在这段代码中,<view>
标签被用来创建一个容器,其中包含了其他的视图元素,例如<image>
和<text>
。
<view>
标签有一些常用的属性,例如class
用于指定样式类名,style
用于指定内联样式,wx:if
用于条件渲染,wx:else
用于条件渲染的反向情况。
在这段代码中,<view>
标签被用来创建一个容器,其中包含了一个条件渲染的逻辑。当remind
为真时,显示一个带有loading图片的提醒框;否则显示一个包含图片、按钮和文本的内容框。
mina/pages/index /index.js
登录思路逻辑:
onLoad完毕运行this.checkLogin(), 首先通过checkLogin(){}调取wx.login方法获取code,然后将code传到后方去,后方通过code获取openid,如果通过openid可以查到用户信息,则该用户已经登陆了,通过regFlag来切换需要显示的登录按钮
//login.js
//获取应用实例
var app = getApp();
Page({
data: {
remind: '加载中',
angle: 0,
userInfo: {},
regFlag:true
},
goToIndex:function(){
wx.switchTab({
url: '/pages/food/index',
});
},
onLoad:function(){
wx.setNavigationBarTitle({
title: app.globalData.shopName
});
this.checkLogin();
},
onShow:function(){
},
onReady: function(){
var that = this;
setTimeout(function(){
that.setData({
remind: ''
});
}, 1000);
wx.onAccelerometerChange(function(res) {
var angle = -(res.x*30).toFixed(1);
if(angle>14){ angle=14; }
else if(angle<-14){ angle=-14; }
if(that.data.angle !== angle){
that.setData({
angle: angle
});
}
});
},
checkLogin:function () {
var that = this;
wx.login({
success:function(res){
if (!res.code){
app.alert({'content':"登录失败,请再次点击~~"});
return;
}
wx.request({
url:app.buildUrl('/member/check-reg'),
header:app.getRequestHeader(),
method:'POST',
data:{code:res.code},
success:function(res){
if(res.data.code != 200){
that.setData({
regFlag:false
});
return;
}
app.setCache("token", res.data.data.token);
//that.goToIndex();
}
});
}
});
},
login:function(e){
var that = this;
if (!e.detail.userInfo){
app.alert({ "content": "登陆失败,请在此点击~~"});
return;
}
var data = e.detail.userInfo;
wx.login({
success:function(res){
if (!res.code){
app.alert({"content":"登陆失败,请再次点击~~"});
return;
}
data['code'] = res.code;
wx.request({
url:app.buildUrl('/member/login'),
header:app.getRequestHeader(),
method:'POST',
data:data,
success:function(res){
if(res.data.code != 200){
app.alert({'content':res.data.msg });
return;
}
app.setCache("token", res.data.data.token);
that.goToIndex();
}
});
}
});
}
});
问题1: getApp() 是什么意思?
var app = getApp();
:定义一个变量app
,并将其赋值为getApp()
,即获取小程序的实例。
AppObject getApp(Object object) | 微信开放文档
var app = getApp(); 是小程序中获取全局app对象的一种常见方式。通过这行代码,我们可以在页面中使用app对象中定义的全局数据和方法。
在小程序的js文件中,var app = getApp();的作用是获取全局唯一的应用实例。通过这个语句,我们可以获取到小程序的全局变量和方法,以及全局的数据和状态。
在小程序中,每个页面都有自己的js文件,而app.js是小程序的入口文件,它是全局的,可以在整个小程序中共享数据和方法。通过在页面中使用var app = getApp();我们可以获取到app.js中定义的全局app对象。
这个全局app对象中通常包含了一些全局的数据和方法,比如全局的用户信息、全局的网络请求方法等。通过获取app对象,我们可以在页面中直接使用这些全局数据和方法,而不需要重复定义或传递数据。
下面是一个示例,展示了如何使用var app = getApp();获取app对象并使用其中的全局数据和方法:
// app.js
App({
globalData: {
userInfo: null,
apiUrl: 'https://api.example.com'
},
getUserInfo: function() {
// 获取用户信息的方法
}
})
// page.js
var app = getApp();
console.log(app.globalData.userInfo); // 输出全局的用户信息
app.getUserInfo(); // 调用全局的获取用户信息的方法
通过上述代码,我们可以看到,在page.js中使用var app = getApp();获取到了app对象,并可以通过app.globalData访问全局的数据,通过app.getUserInfo()调用全局的方法。
该段代码是一个小程序的登录页面的代码。下面是各部分的作用:
-
//获取应用实例
:注释,说明下面的代码是获取小程序的实例。 -
Page({ ... })
:定义一个页面对象,包含了页面的 数据、事件处理函数和生命周期函数等。 -
data: { ... }
:定义页面的数据,包括remind
、angle
和userInfo
等。 -
goToIndex: function() { ... }
:定义了一个名为goToIndex
的事件处理函数,用于跳转到首页。 -
onLoad: function() { ... }
:定义了一个名为onLoad
的生命周期函数,在页面加载时执行,设置导航栏标题为全局变量app.globalData.shopName
的值。
问题1.1: 如何在小程序中定义全局的数据和状态?
在小程序中,可以通过使用全局变量或者全局状态管理来定义全局的数据和状态。
- 全局变量:可以在app.js文件中定义全局变量,然后在其他页面中引用和修改这些变量。例如,在app.js中定义一个全局变量globalData:
App({
globalData: {
userInfo: null,
count: 0
}
})
然后在其他页面中可以通过getApp().globalData
来获取和修改这些全局变量:
// 获取全局变量
const app = getApp()
console.log(app.globalData.userInfo)
// 修改全局变量
app.globalData.count++
console.log(app.globalData.count)
全局状态管理:可以使用第三方库如Redux、Mobx等来管理全局状态。这些库提供了一种集中式的状态管理机制,可以在任何页面中访问和修改全局状态。具体使用方法可以参考相应库的文档
问题1.2 remind 是如何定义的?
onReady: function () {
var that = this;
setTimeout(function () {
that.setData({
remind: ''
});
}, 1000);
这段代码是一个小程序中的onReady函数,它在页面加载完成后执行。在这个函数中,首先创建了一个变量that,用来保存当前页面的上下文。然后通过setTimeout函数设置一个定时器,在1秒后执行回调函数。回调函数中使用setData方法更新页面的数据,将remind字段设置为空字符串。这段代码的作用是在页面加载完成后,延迟1秒钟将页面的remind字段设置为空,从而隐藏某个提醒信息。
问题2: wx.switchTab({})函数起到了什么作用?
wx.switchTab(Object object) | 微信开放文档 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
在小程序中,可以使用wx.switchTab()
函数来实现页面跳转到指定的tab页。
这段代码将会跳转到名为index
的tab页,该tab页的路径为/pages/food/index
。
问题3: wx.setNavigationBarTitle({title: app.globalData.shopName})是什么函数?
这段代码是用于设置小程序页面的导航栏标题。
wx.setNavigationBarTitle(Object object) | 微信开放文档 动态设置当前页面的标题
具体来说,它使用了wx.setNavigationBarTitle()
函数,并传入一个对象作为参数。该对象包含一个title
属性,其值为app.globalData.shopName
。
app.globalData.shopName
是一个全局变量,用于存储商店的名称。通过将该变量的值赋给title
属性,wx.setNavigationBarTitle()
函数就可以将商店名称作为页面的导航栏标题进行显示。
需要注意的是,该代码需要在小程序的页面中使用,并且前提是在全局中定义了app
对象,并且该对象中包含了globalData
属性和shopName
属性。
这里是调动了mina/app.js文件里的app里的globalData里的shopName 即“python3 + Flask 订餐全站系统” 作为 动态设置当前页面的标题的值。
问题3.1: shopName 是什么?
获取小程序商品推广素材
接口说明
通过该接口获取商品的推广素材,包括店铺appID、商品详情页Path、推广文案及推广短链、商品图片等
这里用的是已经封装好的js方法
checkLogin..
这段代码是一个小程序中的一个函数,名为checkLogin。该函数用于检查用户是否已经登录。具体的实现逻辑如下:
- 首先,通过wx.login()函数获取用户的登录凭证code。
- 如果获取code失败,则弹出提示信息"登录失败,请再次点击~~"。
- 如果成功获取到code,则通过wx.request()函数向服务器发送请求,校验用户是否已经注册。
- 如果服务器返回的状态码不等于200,则将页面的regFlag属性设置为false,表示用户未注册。
- 如果服务器返回的状态码等于200,则将服务器返回的token缓存到小程序的本地存储中。
- 最后,可以根据需要执行其他操作,比如跳转到首页。
问题3.2: data:{code:res.code} 是什么意思?
data:{code:res.code}是一个请求参数,用于向服务器发送数据。其中,code是一个变量,它的值是wx.login()方法返回的用户登录凭证。通过将code作为参数传递给服务器,服务器可以根据这个凭证来验证用户的身份,并返回相应的结果。wx.login(Object object) | 微信开放文档
在这个例子中,服务器会根据code来检查用户是否已经注册:
如果没有注册,则返回相应的提示信息;
如果已经注册,则返回一个包含用户token的数据。
在成功获取到token后,代码中的app.setCache(“token”, res.data.data.token)将会把token存储在缓存中,以便后续使用。
login ...
该段代码是一个登录函数,用于处理用户登录的逻辑。具体介绍如下:
- 首先,函数接收一个事件对象e作为参数。
- 在函数内部,通过判断事件对象e中的用户信息是否存在来确定用户是否登录成功。如果用户信息不存在,则会弹出一个提示框提示登录失败,并返回。
- 如果用户信息存在,将用户信息赋值给变量data。
- 接着,调用wx.login()函数进行微信登录,获取登录凭证code。
- 如果登录凭证code不存在,则会弹出一个提示框提示登录失败,并返回。
- 如果登录凭证code存在,将code添加到data中。
- 然后,通过wx.request()函数向服务器发送登录请求,请求的URL为’/member/login’,请求头部包含app.getRequestHeader()返回的请求头信息,请求方法为POST,请求数据为data。
- 如果服务器返回的状态码不等于200,则会弹出一个提示框显示返回的错误信息,并返回。
- 如果服务器返回的状态码等于200,则将返回的token存储到缓存中,键名为"token",键值为res.data.data.token。
- 最后,调用goToIndex()函数进行页面跳转。
问题4: 概述一下setTimeout({})起到的功能?
number setTimeout(function callback, number delay, any rest) | 微信开放文档 设定一个定时器。在定时到期以后执行注册的回调函数
这段代码的作用是在1000毫秒(即1秒)后执行一个函数,将remind
属性设置为空字符串。这通常用于在一定时间后执行某个操作,例如延迟显示或隐藏某个元素。
问题5: wx.onAccelerometerChange()代码有什么作用?
accelerometer 美/əkˌseləˈrɑːmɪtər/ n.加速度计;(飞机、火箭的)加速器
根据提供的引用内容,这段代码是用于监听微信小程序的加速度计变化,并根据变化的角度来更新页面的数据。具体来说,代码中使用了wx.onAccelerometerChange
函数来监听加速度计的变化,当加速度计的x轴变化时,会计算出对应的角度,并将角度更新到页面的angle
数据中。
这段代码中,res.x
表示加速度计在x轴上的变化值,乘以30后取负数,得到的就是角度值。然后通过判断角度是否超过了限制范围(-14到14之间),如果超过了,则将角度限制在这个范围内。最后,通过setData
函数将更新后的角度值存储到页面的angle
数据中,从而实现页面的更新。
toFixed(1)
是一个用于保留小数位数的方法。它可以将一个数字四舍五入到指定的小数位数,并返回一个字符串表示该数字。
问题6:e.detail.userInfo的值是什么?
wx.getUserInfo(Object object) | 微信开放文档
e.detail.userInfo
是一个对象,包含用户的详细信息,例如用户的昵称、头像、性别等。在这个例子中,e.detail.userInfo
是通过微信小程序的getUserInfo
接口获取的用户信息。
问题7: wx.request({})方法 的作用是什么?
从前端js文件发送到后端
RequestTask | 微信开放文档 发起 HTTPS 网络请求。
文档里有其详细的各种属性。
wx.request的作用是发送网络请求。它可以向指定的URL发送HTTP请求,并在请求成功后执行相应的回调函数。在给定的示例中,wx.request被用于向服务器发送登录请求,并在请求成功后将返回的token存储在缓存中。
wx.request({
url:'http://192.168.10.10:8999/xxx/xxx',
method:'POST',
data:data,
success:function(res){
}
})
问题8: wx.login 函数中的res是什么?
res
是wx.login
方法的回调函数的参数,它包含了登录凭证code
。
wx.login(Object object) | 微信开放文档
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台账号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台账号)及本次登录的会话密钥(session_key)等。
用户数据的加解密通讯需要依赖会话密钥完成
知识点1: 小程序到微信公众平台需要进行相关request合法域名的设置
这里引入了一个新的 层面,域名。域名是做什么的呢?域名有什么作用呢?
通过这两三天的沉思琢磨,忍痛割爱般痛下决心,域名得买!买个最便宜的、最贱的。纵使是一年8块钱的花销,也要勇敢面对它。
当然了,这里编程浪子老师指出:在开发过程中有跳过request合法域名的设置选项,也就是说在程序开发好了以后再买也不迟。确实是这样,好钢用在刀刃上,刀不用,要刀以何?
步骤: 到小程序官网微信小程序开发设置,有个服务器域名。
问题8: 域名有什么作用呢?
域名有以下几个主要的作用:
-
建网站:注册域名最常见的用途就是建网站。域名可以直接用于访问网站,一个好的域名可以让网站在推广过程中更加省力,让用户更容易记住。
-
投资赚钱:除了建网站,还有很多人注册域名是为了投资。域名具有升值空间,因为注册一个域名就少一个,所以一个好的域名可以成为投资的对象,有一定的投资价值。
-
品牌保护:对于重视自身品牌的企业来说,他们通常会注册多个域名后缀来保护自己的品牌。除了.com以外的其他重要域名后缀也会被注册,以免被他人注册后造成不必要的损失。
以下是一个示例代码,演示如何使用Python获取域名的作用:
# 建网站
website_domain = "www.example.com"
# 投资赚钱
investment_domain = "www.investmentdomain.com"
# 品牌保护
brand_domains = ["www.example.net", "www.example.org"]
print("网站域名:", website_domain)
print("投资域名:", investment_domain)
print("品牌保护域名:", brand_domains)
知识点2: 小程序开发工具 和 pycharm 怎么共同编辑同一个文件
小程序开发工具和PyCharm可以通过以下步骤共同编辑同一个文件:
- 打开小程序开发工具,创建一个新的小程序项目。
- 在PyCharm中打开同一个项目文件夹。
- 在小程序开发工具中,找到需要共同编辑的文件,右键点击选择“在资源管理器中打开”。
- 在资源管理器中,找到该文件的路径。
- 在PyCharm中,打开相同的文件。
- 现在你可以在PyCharm中进行编辑,并且小程序开发工具会自动检测到文件的更改并进行同步。
这样,你就可以在小程序开发工具和PyCharm中同时编辑同一个文件了。
知识点3: 小程序路由在pycharm中的flask框架中的部署
如图:还没部署路由,在 微信开发者工具中DD报错
问题9: 微信小程序的路由如何在flask中部署呢?
common/libs/UrlManager.py 链接管理器中啥也没有
# -*- coding: utf-8 -*-
import time
from application import app
class UrlManager(object):
def __init__(self):
pass
@staticmethod
def buildUrl( path ):
return path
web/controllers/api/ 此文件夹是专门给小程序配置用的
web/controllers/api/ __init__.py
# -*- coding: utf-8 -*-
from flask import Blueprint
route_api = Blueprint( 'api_page',__name__ )
from web.controllers.api.Member import *
@route_api.route("/")
def index():
return "Mina Api V1.0~~"
这段代码是一个使用Flask框架 为 微信小程序 创建API的示例代码。下面是对代码的解析:
-
首先,导入了
Blueprint
类和route_api
对象。Blueprint
是Flask框架中用于创建蓝图的类,蓝图可以将相关的视图函数、模板和静态文件组织在一起。route_api
是一个蓝图对象,用于定义API的路由和视图函数。 -
接下来,导入了
Member
模块中的所有内容。这个模块可能包含了与会员相关的API视图函数和其他功能。 -
然后,使用
route_api.route("/")
装饰器将index()
函数注册为处理根路径(“/”)的视图函数。当用户访问根路径时,该函数将被调用。 -
最后,
index()
函数返回了一个字符串"Mini Api V1.0~~"作为响应。
这段代码的作用是创建一个名为api_page
的蓝图,并定义了一个处理根路径的视图函数。当用户访问根路径时,将返回字符串"Mini Api V1.0~~"作为响应。
web/controllers/api Member.py
# -*- coding: utf-8 -*-
from web.controllers.api import route_api
from flask import request, jsonify
@route_api.route("/member/login",methods = [ "GET","POST" ])
def login():
resp = { 'code':200 ,'msg':'操作成功~','data':{} }
req = request.values
code = req['code'] if 'code' in req else ''
if not code or len( code ) < 1:
resp['code'] = -1
resp['msg'] = "需要code"
return jsonify(resp)
openid = MemberService.getWeChatOpenId( code )
if openid is None:
resp['code'] = -1
resp['msg'] = "调用微信出错"
return jsonify(resp)
nickname = req['nickName'] if 'nickName' in req else ''
sex = req['gender'] if 'gender' in req else 0
avatar = req['avatarUrl'] if 'avatarUrl' in req else ''
'''
判断是否已经测试过,注册了直接返回一些信息
'''
bind_info = OauthMemberBind.query.filter_by( openid = openid,type = 1 ).first()
if not bind_info:
model_member = Member()
model_member.nickname = nickname
model_member.sex = sex
model_member.avatar = avatar
model_member.salt = MemberService.geneSalt()
model_member.updated_time = model_member.created_time = getCurrentDate()
db.session.add(model_member)
db.session.commit()
model_bind = OauthMemberBind()
model_bind.member_id = model_member.id
model_bind.type = 1
model_bind.openid = openid
model_bind.extra = ''
model_bind.updated_time = model_bind.created_time = getCurrentDate()
db.session.add(model_bind)
db.session.commit()
bind_info = model_bind
member_info = Member.query.filter_by(id = bind_info.member_id).first()
token = "%s#%s" % (MemberService.geneAuthCode(member_info), member_info.id)
resp['data'] = {'token': token}
return jsonify( resp )
这段代码是一个基于Flask框架的API接口,主要实现了一个名为"login"的接口。下面是对代码的解析:
- 首先,导入了必要的模块和库:
- 定义了一个路由装饰器,将该接口绑定到"/member/login"的URL上:定义了一个路由
/member/login
,并指定了允许的请求方法为GET和POST。 - 定义了一个名为"login"的函数,用于处理登录请求:
- 初始化一个字典类型的变量"resp",创建了一个字典
resp
,用于存储接口返回的数据。 - 通过
request.values
获取请求参数,并从中获取code
参数。 - 判断"code"参数是否存在,如果不存在或长度小于1,将
resp
中的code
设置为-1,则返回错误msg信息"需要code",并返回resp
的JSON格式 - 调用MemberService的getWeChatOpenId方法,传入"code"参数,获取微信的openid:
- 判断openid是否为空,如果为空,将
resp
中的code
设置为-1,则返回错误信息msg:"调用微信出错",并返回resp
的JSON格式。 - 从请求参数中获取
nickName
、gender
和avatarUrl
参数,并分别赋值给nickname
、sex
和avatar
变量。 - 判断是否已经存在与
openid
对应的OauthMemberBind
记录,如果不存在,则表示用户是第一次登录,需要创建新的用户记录。 - 创建新的用户记录时,首先创建一个
Member
对象,并设置其属性值为nickname
、sex
、avatar
等参数值。 - 生成一个随机的盐值,并将其赋值给
model_member
的salt
属性。 - 设置
model_member
的updated_time
和created_time
属性为当前时间。 - 将
model_member
添加到数据库会话中,并提交会话,完成用户记录的创建。 - 创建一个
OauthMemberBind
对象,并设置其属性值为model_member
的id
、1(表示微信登录)、openid
等参数值。 - 设置
model_bind
的updated_time
和created_time
属性为当前时间。 - 将
model_bind
添加到数据库会话中,并提交会话,完成OauthMemberBind
记录的创建。 - 将
bind_info
赋值为model_bind
,用于后续获取用户信息。 - 根据
bind_info
中的member_id
查询Member
表,获取用户信息。 - 生成用户的认证码,并将其与
member_info
的id
拼接成一个字符串,赋值给token
变量。 - 将
token
赋值给resp
的data
字段。 - 返回
resp
的JSON格式作为接口的响应。
common/models/member/Member.py 数据库Member
# coding: utf-8
from sqlalchemy import Column, DateTime, Integer, String
from sqlalchemy.schema import FetchedValue
from application import db,app
class Member(db.Model):
__tablename__ = 'member'
id = db.Column(db.Integer, primary_key=True)
nickname = db.Column(db.String(100), nullable=False, server_default=db.FetchedValue())
mobile = db.Column(db.String(11), nullable=False, server_default=db.FetchedValue())
sex = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())
avatar = db.Column(db.String(200), nullable=False, server_default=db.FetchedValue())
salt = db.Column(db.String(32), nullable=False, server_default=db.FetchedValue())
reg_ip = db.Column(db.String(100), nullable=False, server_default=db.FetchedValue())
status = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())
updated_time = db.Column(db.DateTime, nullable=False, server_default=db.FetchedValue())
created_time = db.Column(db.DateTime, nullable=False, server_default=db.FetchedValue())
@property
def status_desc(self):
return app.config['STATUS_MAPPING'][ str( self.status ) ]
@property
def sex_desc(self):
sex_mapping = {
"0":"未知",
"1":"男",
"2":"女"
}
return sex_mapping[str(self.sex)]
数据库配置相关信息
DROP TABLE IF EXISTS `member`;
CREATE TABLE `member` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`nickname` varchar(100) NOT NULL DEFAULT '' COMMENT '会员名',
`mobile` varchar(11) NOT NULL DEFAULT '' COMMENT '会员手机号码',
`sex` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别 1:男 2:女',
`avatar` varchar(200) NOT NULL DEFAULT '' COMMENT '会员头像',
`salt` varchar(32) NOT NULL DEFAULT '' COMMENT '随机salt',
`reg_ip` varchar(100) NOT NULL DEFAULT '' COMMENT '注册ip',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 1:有效 0:无效',
`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间',
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表';
flask-sqlacodegen 'mysql://root:root@127.0.0.1/food_db' --tables member --outfile "common/models/member/Member.py" --flask
common/models/member/OauthMemberBind.py OauthMemberBind数据库
# coding: utf-8
from sqlalchemy import Column, DateTime, Index, Integer, String, Text
from sqlalchemy.schema import FetchedValue
from application import db
class OauthMemberBind(db.Model):
__tablename__ = 'oauth_member_bind'
__table_args__ = (
db.Index('idx_type_openid', 'type', 'openid'),
)
id = db.Column(db.Integer, primary_key=True)
member_id = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())
client_type = db.Column(db.String(20), nullable=False, server_default=db.FetchedValue())
type = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())
openid = db.Column(db.String(80), nullable=False, server_default=db.FetchedValue())
unionid = db.Column(db.String(100), nullable=False, server_default=db.FetchedValue())
extra = db.Column(db.Text, nullable=False)
updated_time = db.Column(db.DateTime, nullable=False, server_default=db.FetchedValue())
created_time = db.Column(db.DateTime, nullable=False, server_default=db.FetchedValue())
DROP TABLE IF EXISTS `oauth_member_bind`;
CREATE TABLE `oauth_member_bind` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL DEFAULT '0' COMMENT '会员id',
`client_type` varchar(20) NOT NULL DEFAULT '' COMMENT '客户端来源类型。qq,weibo,weixin',
`type` tinyint(3) NOT NULL DEFAULT '0' COMMENT '类型 type 1:wechat ',
`openid` varchar(80) NOT NULL DEFAULT '' COMMENT '第三方id',
`unionid` varchar(100) NOT NULL DEFAULT '',
`extra` text NOT NULL COMMENT '额外字段',
`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后更新时间',
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入时间',
PRIMARY KEY (`id`),
KEY `idx_type_openid` (`type`,`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='第三方登录绑定关系';
flask-sqlacodegen 'mysql://root:root@127.0.0.1/food_db' --tables oauth_member_bind --outfile "common/models/member/OauthMemberBind.py" --flask
问题1: unionid 是什么?
UnionID是微信开放平台的一个标识符,用于唯一标识同一用户在不同应用(包括公众号、小程序、移动应用等)中的身份。它是一个 字符串 ,由微信开放平台生成并分配给每个用户。UnionID的作用是方便开发者在不同应用之间进行用户数据的关联和共享。通过UnionID,开发者可以获取用户在不同应用中的信息,实现跨应用的用户数据共享和个性化服务。
UnionID的获取方式有以下几种:
- 调用接口wx.getUserInfo,从解密数据中获取UnionID。需要用户授权。
- 如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号,可以通过wx.login + code2Session获取到该用户的UnionID,无需用户再次授权。
- 如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用,也可以通过wx.login + code2Session获取到该用户的UnionID,无需用户再次授权。
问题2:unionid 和 openid 有什么不同?
UnionId和OpenId是微信公众平台中的两个重要概念,它们之间有以下不同:
-
UnionId(统一标识符)是同一主体下不同应用之间的唯一身份标识符。在同一主体的小程序、公众号等下面,一个UnionId只有一个,而一个UnionId可以对应多个wxopenid和多个小程序OpenId。
-
OpenId(开放标识符)是用户在某个具体应用(如小程序、公众号)下的唯一身份标识符。在同一主体的不同应用之间,用户的OpenId是不同的。
-
UnionId的覆盖范围更广,可以在用户关注公众号、逛公众号下的H5页面时获取UnionId和wxopenid;在逛小程序时,可以获取小程序UnionId和openid。无论在哪个应用下,都可以获取到UnionId。
-
OpenId是应用级别的身份标识符,只能在特定的应用中使用,而UnionId是主体级别的身份标识符,可以在同一主体的不同应用之间共享使用。
总结起来,UnionId是同一主体下不同应用之间的唯一身份标识符,而OpenId是用户在某个具体应用下的唯一身份标识符。
common/libs/member/MemberService.py
# -*- coding: utf-8 -*-
import hashlib,requests,random,string,json
from application import app
class MemberService():
@staticmethod
def geneAuthCode( member_info = None ):
m = hashlib.md5()
str = "%s-%s-%s" % ( member_info.id, member_info.salt,member_info.status)
m.update(str.encode("utf-8"))
return m.hexdigest()
@staticmethod
def geneSalt( length = 16 ):
keylist = [ random.choice( ( string.ascii_letters + string.digits ) ) for i in range( length ) ]
return ( "".join( keylist ) )
@staticmethod
def getWeChatOpenId( code ):
url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code" \
.format(app.config['MINA_APP']['appid'], app.config['MINA_APP']['appkey'], code)
r = requests.get(url)
res = json.loads(r.text)
openid = None
if 'openid' in res:
openid = res['openid']
return openid
是一个flask获取微信OpenID的静态方法的示例:
该方法使用了微信提供的API来通过code获取用户的OpenID。
问题0: 如何实现小程序登录?
小程序登录
接口英文名
code2Session
功能描述
登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。
具体步骤如下:
-
构建请求URL,其中包括了小程序的appid、appkey和code。缺少就报错!其中url中使用{}来获取值,
-
发送GET请求到微信API,并获取返回结果。
-
解析返回结果,提取出OpenID。
-
返回OpenID。
问题1: 该段url中\的作用是什么?
在Python中,反斜杠(\)被用作续行符,用于将一行代码分成多行书写。当一行代码太长时,可以使用反斜杠将其分成多行,以提高代码的可读性。
在给定的代码段中,反斜杠(\)的作用是将长的URL字符串分成多行,以便于阅读和理解。通过使用反斜杠,可以将长的URL字符串分成多行,使代码更加清晰易读。
问题2: format的作用是什么?
format()是一个字符串方法,用于将字符串中的占位符替换为指定的值。在这个例子中,format()方法用于替换url字符串中的占位符{0}、{1}和{2},分别为appid、appkey和code的值。通过使用format()方法,可以动态地将变量的值插入到字符串中,使得字符串具有动态性和可读性。
如在flask中设置所示
config/base_setting.py
MINA_APP = {
'appid':'wx360d7b8ff0881fd3',
'appkey':'xxxxxxxxxxxxx换自己的',
'paykey':'xxxxxxxxxxxxxx换自己的',
'mch_id':'xxxxxxxxxxxx换自己的',
'callback_url':'/api/order/callback'
}
问题3: requests 的作用是什么?
requests 用来发送请求
request.get发送get请求
r是request.get返回的值
问题4: .text的作用是什么?
.text
是一个属性,用于获取 HTTP 响应的内容。在这个例子中,r.text
返回的是一个字符串,表示 HTTP 响应的内容。在这个例子中,r.text
是一个 JSON 格式的字符串,通过 json.loads()
方法将其转换为 Python 字典对象 res
。然后,通过 res['openid']
获取字典中的 openid
值,并将其返回。
知识点1: app.logger.info(res)
app.logger.info(res)
是一个使用logger
对象的info
方法来记录res
对象的日志信息的代码。具体的实现可能需要查看完整的代码,以确定logger
对象是如何定义和配置的。
以下是一个示例,展示了如何使用logger
对象的info
方法记录res
对象的日志信息
如图通过 app.logger.info(res)探索res的值的样式
如图openid返回的值是r.text
是一个 JSON 格式的字符串,通过 json.loads()
方法将其转换为 Python 字典对象 res
。然后,通过 res['openid']
获取字典中的 openid
值,并将其返回。
mina/app.js
//app.js
App({
onLaunch: function () {
},
globalData: {
userInfo: null,
version: "1.0",
shopName: "Python3 + Flask 订餐全栈系统",
domain:"http://192.168.10.10:8999/api"
},
tip:function( params ){
var that = this;
var title = params.hasOwnProperty('title')?params['title']:'提示信息';
var content = params.hasOwnProperty('content')?params['content']:'';
wx.showModal({
title: title,
content: content,
success: function(res) {
if ( res.confirm ) {//点击确定
if( params.hasOwnProperty('cb_confirm') && typeof( params.cb_confirm ) == "function" ){
params.cb_confirm();
}
}else{//点击否
if( params.hasOwnProperty('cb_cancel') && typeof( params.cb_cancel ) == "function" ){
params.cb_cancel();
}
}
}
})
},
alert:function( params ){
var title = params.hasOwnProperty('title')?params['title']:'提示信息';
var content = params.hasOwnProperty('content')?params['content']:'';
wx.showModal({
title: title,
content: content,
showCancel:false,
success: function(res) {
if (res.confirm) {//用户点击确定
if( params.hasOwnProperty('cb_confirm') && typeof( params.cb_confirm ) == "function" ){
params.cb_confirm();
}
}else{
if( params.hasOwnProperty('cb_cancel') && typeof( params.cb_cancel ) == "function" ){
params.cb_cancel();
}
}
}
})
},
console:function( msg ){
console.log( msg);
},
getRequestHeader:function(){
return {
'content-type': 'application/x-www-form-urlencoded'
}
},
buildUrl:function (path,params) {
var url = this.globalData.domain + path;
var _paramUrl = "";
if(params){
_paramUrl = Object.keys(params).map(function(k){
return [encodeURIComponent(k), encodeURIComponent(params[k])].join("=");
}).join("&");
_paramUrl ="?" + _paramUrl;
}
return url + _paramUrl;
},
});
注册小程序。接受一个 Object
参数,其指定小程序的生命周期回调等。
App() 必须在 app.js
中调用,必须调用且只能调用一次。不然会出现无法预期的后果。
-
onShow: function() { ... }
:定义了一个名为onShow
的生命周期函数,在页面显示时执行。 -
onReady: function() { ... }
:定义了一个名为onReady
的生命周期函数,在页面初次渲染完成时执行。 -
setTimeout(function() { ... }, 1000);
:使用setTimeout
函数设置一个定时器,延迟1秒后执行回调函数,将remind
的值设为空字符串,即隐藏加载中的提示。 -
wx.onAccelerometerChange(function(res) { ... })
:监听加速度计数据变化的事件,当加速度计数据变化时执行回调函数。
问题@1: var title = params.hasOwnProperty('title')?params['title']:'提示信息'; 该段代码是什么意思?各部分元素的作用是什么? @代表对app.js文件内的提问
这段代码是一个条件表达式,用于 判断对象params中是否存在属性’title’。
如果存在,则将该属性的值赋给变量title;
如果不存在,则将字符串’提示信息’赋给变量title。
var title = params.hasOwnProperty('title') ? params['title'] : '提示信息';
params.hasOwnProperty('title')
:这是一个判断对象params是否有属性’title’的方法。如果params对象中存在名为’title’的属性,则返回true;否则返回false。?
:这是一个条件运算符,也称为三元运算符。它的作用是根据条件的真假来选择不同的值。params['title']
:如果params对象中存在名为’title’的属性,则返回该属性的值。:
:这是条件运算符的分隔符,用于分隔条件为真和条件为假时的两个值。'提示信息'
:如果params对象中不存在名为’title’的属性,则返回字符串’提示信息’。
因此,这段代码的作用是判断对象params中是否存在属性’title’,如果存在则将其值赋给变量title,如果不存在则将字符串’提示信息’赋给变量title。
问题@2: wx.showModal({})是什么方法?
wx.showModal({
title: title,
content: content,
success: function(res) {
if ( res.confirm ) {//点击确定
if( params.hasOwnProperty('cb_confirm') && typeof( params.cb_confirm ) == "function" ){
params.cb_confirm();
}
}else{//点击否
if( params.hasOwnProperty('cb_cancel') && typeof( params.cb_cancel ) == "function" ){
params.cb_cancel();
}
}
}
})
},
该段代码是一个使用 小程序框架 中的 wx.showModal方法 创建模态弹窗 的示例。
wx.showModal(Object object) | 微信开放文档 显示模态对话框
模态弹窗 是一种可以 阻止 用户继续操作的弹窗,需要用户进行 确认 或 取消 操作后才能关闭。
代码中的wx.showModal方法接受一个 对象 作为参数,该对象包含以下属性:
- title:弹窗的标题。
- content:弹窗的内容。
- success:弹窗操作成功后的回调函数。
在回调函数中,可以根据用户的操作结果进行相应的处理。
如果用户点击了确定按钮,会执行success函数中的逻辑,
如果用户点击了 取消按钮,会执行else语句中的逻辑。
在该示例中,代码通过判断res.confirm的值来确定用户点击的是确定按钮还是取消按钮。
如果res.confirm为true,表示用户点击了确定按钮,会执行cb_confirm函数;
如果res.confirm为false,表示用户点击了取消按钮,会执行cb_cancel函数。
该段代码的作用是创建一个模态弹窗,并根据用户的操作结果执行相应的回调函数。
问题@3: &&是什么?它的作用是什么?
在给定的代码中,&&
是逻辑与运算符。它用于判断两个条件是否同时为真。如果两个条件都为真,则整个表达式的结果为真;否则,结果为假。
在给定的代码中,&&
用于判断两个条件:
params.hasOwnProperty('cb_confirm')
:判断params
对象是否具有名为cb_confirm
的属性。typeof( params.cb_confirm ) == "function"
:判断params.cb_confirm
的类型是否为函数。
只有当这两个条件都为真时,才会执行params.cb_confirm()
函数。
buildUrl:function(path, params){ }
该段代码是一个JavaScript函数,名为buildUrl。它接受两个参数:path和params。函数的目的是构建一个URL。
函数首先将全局变量domain与path拼接起来,得到完整的URL。然后,它会检查params是否存在。如果params存在,函数会遍历params对象的所有属性,并将每个属性的键和值进行URL编码。然后,它将编码后的键值对用等号连接起来,并用&符号连接多个键值对。最后,函数会在拼接好的参数字符串前加上问号。最终,函数将拼接好的参数字符串与URL拼接起来,并返回结果。
该函数的作用是根据给定的path和params构建一个带有参数的URL。
wx.setStorageSync(string key, any data) | 微信开放文档
any wx.getStorageSync(string key) | 微信开放文档 从本地缓存中同步获取指定 key 的内容。
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
wx.setStorage(Object object) | 微信开放文档
wx.getStorage(Object object) | 微信开放文档 从本地缓存中异步获取指定 key 的内容。
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
如app.js中代码所示
getCache:function (key){
var value = undefined;
try {
value = wx.getStorageSync(key);
} catch (e) {
}
return value;
},
setCache:function (key,value) {
wx.setStorage({
key:key,
data:value
});
}
问题@4 setStorage和 getStorageSync 有什么不一样呢?同步和不同步有什么区别呢?
setStorage和getStorageSync是微信小程序中用于存储数据的两个方法,它们的主要区别在于同步和异步的执行方式。
setStorage是一个异步方法,用于将数据存储到本地缓存中。它接受两个参数,key和value,分别表示要存储的数据的键和值。setStorage方法会将数据异步存储到本地缓存中,存储完成后会执行回调函数。
getStorageSync是一个同步方法,用于从本地缓存中获取指定键的数据。它接受一个参数key,表示要获取数据的键。getStorageSync方法会同步地从本地缓存中获取数据,并将获取到的数据作为返回值返回。
因此,setStorage方法是异步的,它会在后台执行存储操作,不会阻塞主线程的执行。而getStorageSync方法是同步的,它会阻塞主线程的执行,直到获取到数据或者发生错误。
所以,当需要存储数据时,可以使用setStorage方法,它不会阻塞主线程的执行。而当需要获取数据时,可以使用getStorageSync方法,它会同步地返回获取到的数据。
问题5: setData是怎样的一个函数?
在微信小程序中,setData函数用于更新页面的数据并触发页面的重新渲染。当页面的数据发生变化时,通过调用setData函数可以将新的数据更新到页面上,从而实现数据的动态展示。
具体来说,setData函数的作用有以下几个方面:
- 更新数据:通过传入一个对象,可以更新页面中的某个或多个数据字段的值。
- 触发页面渲染:当调用setData函数更新数据后,小程序会自动触发页面的重新渲染,将更新后的数据展示在页面上。
- 更新视图:页面的重新渲染会导致视图的更新,即页面上的元素会根据更新后的数据重新展示。
需要注意的是,setData函数是异步执行的,即调用setData函数后,并不会立即更新页面,而是将更新操作放入一个队列中,等待下一次的页面渲染时才会执行更新操作。因此,在调用setData函数后,如果需要立即获取更新后的数据,可以使用回调函数或在setData函数的第二个参数中进行处理。
mina/pages/my/addressSet.js
//获取应用实例
var commonCityData = require('../../utils/city.js');
var app = getApp();
Page({
data: {
provinces: [],
citys: [],
districts: [],
selProvince: '请选择',
selCity: '请选择',
selDistrict: '请选择',
selProvinceIndex: 0,
selCityIndex: 0,
selDistrictIndex: 0
},
onLoad: function (e) {
var that = this;
this.initCityData(1);
},
//初始化城市数据
initCityData:function( level, obj ){
if (level == 1) {
var pinkArray = [];
for (var i = 0; i < commonCityData.cityData.length; i++) {
pinkArray.push(commonCityData.cityData[i].name);
}
this.setData({
provinces: pinkArray
});
} else if (level == 2) {
var pinkArray = [];
var dataArray = obj.cityList
for (var i = 0; i < dataArray.length; i++) {
pinkArray.push(dataArray[i].name);
}
this.setData({
citys: pinkArray
});
} else if (level == 3) {
var pinkArray = [];
var dataArray = obj.districtList
for (var i = 0; i < dataArray.length; i++) {
pinkArray.push(dataArray[i].name);
}
this.setData({
districts: pinkArray
});
}
},
bindPickerProvinceChange: function (event) {
var selIterm = commonCityData.cityData[event.detail.value];
this.setData({
selProvince: selIterm.name,
selProvinceIndex: event.detail.value,
selCity: '请选择',
selCityIndex: 0,
selDistrict: '请选择',
selDistrictIndex: 0
});
this.initCityData(2, selIterm);
},
bindPickerCityChange: function (event) {
var selIterm = commonCityData.cityData[this.data.selProvinceIndex].cityList[event.detail.value];
this.setData({
selCity: selIterm.name,
selCityIndex: event.detail.value,
selDistrict: '请选择',
selDistrictIndex: 0
});
this.initCityData(3, selIterm);
},
bindPickerChange: function (event) {
var selIterm = commonCityData.cityData[this.data.selProvinceIndex].cityList[this.data.selCityIndex].districtList[event.detail.value];
if (selIterm && selIterm.name && event.detail.value) {
this.setData({
selDistrict: selIterm.name,
selDistrictIndex: event.detail.value
})
}
},
bindCancel: function () {
wx.navigateBack({});
},
bindSave: function (e) {
},
deleteAddress: function (e) {
var that = this;
var params={
"content": "确定删除?",
"cb_confirm": function () {
wx.request({
url:app.buildUrl("/my/address/ops"),
header: app.getRequestHeader(),
method:"POST",
data:{
id: that.data.id,
act:'del'
},
success:function(res){
var resp = res.data;
app.alert({"":resp.msg});
if (resp.code == 200){
// 跳转
wx.navigateBack({});
}
}
});
}
};
app.tip(params);
},
});
deleteAddress:function(){} 是一个小程序中的一个函数,用于删除地址信息。
下面是对代码的详细解释:
这段代码定义了一个名为deleteAddress
的函数,用于删除地址信息。当用户点击删除按钮时,该函数会被调用。
首先,函数内部定义了一个变量that
,并将其赋值为this
,这是为了在后续的回调函数中能够访问到外部的this
对象。
接下来,定义了一个名为params
的对象,该对象包含两个属性:
content
属性表示删除确认的提示内容,这里设置为"确定删除?"。cb_confirm
属性是一个回调函数,当用户点击确认删除时会执行该函数。
在cb_confirm
函数中,发起了一个wx.request
请求,用于向服务器发送删除地址的请求。
具体的请求参数如下:
url
属性指定了请求的URL,这里使用了小程序中的app.buildUrl
函数来构建URL。header
属性设置了请求头,使用了小程序中的app.getRequestHeader
函数来获取请求头。method
属性指定了请求的方法,这里使用了POST方法。data
属性是一个对象,包含了要发送的数据。其中id
表示要删除的地址的ID,act
表示要执行的操作,这里设置为"del"表示删除操作。
在请求成功的回调函数中,首先解析了服务器返回的数据,并将其赋值给变量resp
。然后使用app.alert
函数弹出一个提示框,显示返回的消息内容。
如果服务器返回的状态码为200,表示删除成功,那么会执行以下操作:
- 使用
wx.navigateBack
函数返回上一页。 - wx.navigateBack(Object object) | 微信开放文档