在 web/controllers/api中增建py文件,主要是给微信小程序使用的。
# -*- coding: utf-8 -*-
from flask import Blueprint
route_api = Blueprint( 'api_page',__name__ )@ute("/")
def index():return "Mina Api V1.0~~"
llers.api import route_api
如图所示api已经做好了
小程序简介 | 微信开放文档
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</text></view></view></block>
</view>
第一步: 设置小程序用户信息
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</text></view></view></block></view>
没有使用<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}}"做了相关判断。
按钮更改后展示图
微信小程序中的open-type是一个属性,用于定义按钮的点击行为。根据提供的引用内容,有两种常见的open-type值可以使用。
contact:该值用于直接打开客服对话功能。要使用此功能,需要在微信小程序的后台进行配置,并且只能通过真机调试来打开。具体的配置和使用方法可以参考微信小程序开发文档。
launchApp:该值用于在小程序中直接打开其他应用程序。通过设置launchApp的open-type,可以实现在小程序中点击按钮后直接打开指定的应用程序。更多详细信息可以参考微信小程序开发文档中的相关章节。
请注意,open-type属性的具体使用方式和效果可能会因微信小程序的版本和配置而有所不同。建议在开发过程中参考官方文档并进行测试
这里使用了open-type="getUserInfo" 来定义这样一个属性,来获取用户信息
在微信小程序中,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()方法
open-data | 微信开放文档 用于展示微信开放的数据。
在给出的代码中,<block>
是一个条件渲染的标签。它的作用是根据条件来决定是否渲染其中的内容。在这段代码中,<block>
标签的wx:else
属性表示如果remind
为假,则渲染<block>
标签内的内容。如果remind
为真,则不渲染<block>
标签内的内容。
条件渲染 | 微信开放文档
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
view | 微信开放文档 视图容器
在给出的代码中,<view>
是小程序中的一个组件,用于显示一个视图容器。它类似于HTML中的<div>
标签,用于包裹其他元素或者作为一个独立的容器。在这段代码中,<view>
标签被用来创建一个容器,其中包含了其他的视图元素,例如<image>
和<text>
。
<view>
标签有一些常用的属性,例如class
用于指定样式类名,style
用于指定内联样式,wx:if
用于条件渲染,wx:else
用于条件渲染的反向情况。
在这段代码中,<view>
标签被用来创建一个容器,其中包含了一个条件渲染的逻辑。当remind
为真时,显示一个带有loading图片的提醒框;否则显示一个包含图片、按钮和文本的内容框。
//login.js
//获取应用实例
var app = getApp();
Page({data: {remind: '加载中',angle: 0,userInfo: {}},goToIndex:function(){wx.switchTab({url: '/pages/food/index',});},onLoad:function(){wx.setNavigationBarTitle({title: app.globalData.shopName})},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});}});},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 (!de){app.alert({"content":"登陆失败,请再次点击~~"});return;}data['code'] = quest({url:app.buildUrl('/member/login'),RequestHeader(),method:'POST',data:data,success:function(res){if(de != 200){app.alert({'content':res.data.msg });return;}app.setCache("token", res.ken);ToIndex();}});}});}});
});
var app = getApp();
:定义一个变量app
,并将其赋值为getApp()
,即获取小程序的实例。
AppObject getApp(Object object) | 微信开放文档
var app = getApp(); 是小程序中获取全局app对象的一种常见方式。通过这行代码,我们可以在页面中使用app对象中定义的全局数据和方法。
在小程序中,每个页面都有自己的js文件,而app.js是小程序的入口文件,它是全局的,可以在整个小程序中共享数据和方法。通过在页面中使用var app = getApp();我们可以获取到app.js中定义的全局app对象。
这个全局app对象中通常包含了一些全局的数据和方法,比如全局的用户信息、全局的网络请求方法等。通过获取app对象,我们可以在页面中直接使用这些全局数据和方法,而不需要重复定义或传递数据。
下面是一个示例,展示了如何使用var app = getApp();获取app对象并使用其中的全局数据和方法:
// app.js
App({globalData: {userInfo: null,apiUrl: ''},getUserInfo: function() {// 获取用户信息的方法}
})// page.js
var app = getApp();
console.log(app.globalData.userInfo); // 输出全局的用户信息
UserInfo(); // 调用全局的获取用户信息的方法
通过上述代码,我们可以看到,在page.js中使用var app = getApp();获取到了app对象,并可以通过app.globalData访问全局的数据,通过UserInfo()调用全局的方法。
该段代码是一个小程序的登录页面的代码。下面是各部分的作用:
//获取应用实例
:注释,说明下面的代码是获取小程序的实例。
Page({ ... })
:定义一个页面对象,包含了页面的 数据、事件处理函数和生命周期函数等。
data: { ... }
:定义页面的数据,包括remind
、angle
和userInfo
等。
goToIndex: function() { ... }
:定义了一个名为goToIndex
的事件处理函数,用于跳转到首页。
onLoad: function() { ... }
:定义了一个名为onLoad
的生命周期函数,在页面加载时执行,设置导航栏标题为全局变量app.globalData.shopName
的值。
wx.switchTab(Object object) | 微信开放文档 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
在小程序中,可以使用wx.switchTab()
函数来实现页面跳转到指定的tab页。
这段代码将会跳转到名为index
的tab页,该tab页的路径为/pages/food/index
。
这段代码是用于设置小程序页面的导航栏标题。
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 订餐全站系统” 作为 动态设置当前页面的标题的值。
小程序商品推广 | 微信开放文档
获取小程序商品推广素材
接口说明
通过该接口获取商品的推广素材,包括店铺appID、商品详情页Path、推广文案及推广短链、商品图片等
这里用的是已经封装好的js方法
login ...
该段代码是一个登录函数,用于处理用户登录的逻辑。具体介绍如下:
number setTimeout(function callback, number delay, any rest) | 微信开放文档 设定一个定时器。在定时到期以后执行注册的回调函数
这段代码的作用是在1000毫秒(即1秒)后执行一个函数,将remind
属性设置为空字符串。这通常用于在一定时间后执行某个操作,例如延迟显示或隐藏某个元素。
accelerometer 美/əkˌseləˈrɑːmɪtər/ n.加速度计;(飞机、火箭的)加速器
根据提供的引用内容,这段代码是用于监听微信小程序的加速度计变化,并根据变化的角度来更新页面的数据。具体来说,代码中使用了angle
数据中。
这段代码中,res.x
表示加速度计在x轴上的变化值,乘以30后取负数,得到的就是角度值。然后通过判断角度是否超过了限制范围(-14到14之间),如果超过了,则将角度限制在这个范围内。最后,通过setData
函数将更新后的角度值存储到页面的angle
数据中,从而实现页面的更新。
toFixed(1)
是一个用于保留小数位数的方法。它可以将一个数字四舍五入到指定的小数位数,并返回一个字符串表示该数字。
e.detail.userInfo
是一个对象,包含用户的详细信息,例如用户的昵称、头像、性别等。在这个例子中,e.detail.userInfo
是通过微信小程序的getUserInfo
接口获取的用户信息。
从前端js文件发送到后端
RequestTask | 微信开放文档 发起 HTTPS 网络请求。
文档里有其详细的各种属性。
wx.request({url:'192.168.10.10:8999/xxx/xxx',method:'POST',data:data,success:function(res){}})
res
是wx.login
方法的回调函数的参数,它包含了登录凭证code
。
wx.login(Object object) | 微信开放文档
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台账号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台账号)及本次登录的会话密钥(session_key)等。
用户数据的加解密通讯需要依赖会话密钥完成
这里引入了一个新的 层面,域名。域名是做什么的呢?域名有什么作用呢?
通过这两三天的沉思琢磨,忍痛割爱般痛下决心,域名得买!买个最便宜的、最贱的。纵使是一年8块钱的花销,也要勇敢面对它。
当然了,这里编程浪子老师指出:在开发过程中有跳过request合法域名的设置选项,也就是说在程序开发好了以后再买也不迟。确实是这样,好钢用在刀刃上,刀不用,要刀以何?
步骤: 到小程序官网微信小程序开发设置,有个服务器域名。
域名有以下几个主要的作用:
建网站:注册域名最常见的用途就是建网站。域名可以直接用于访问网站,一个好的域名可以让网站在推广过程中更加省力,让用户更容易记住。
投资赚钱:除了建网站,还有很多人注册域名是为了投资。域名具有升值空间,因为注册一个域名就少一个,所以一个好的域名可以成为投资的对象,有一定的投资价值。
品牌保护:对于重视自身品牌的企业来说,他们通常会注册多个域名后缀来保护自己的品牌。除了以外的其他重要域名后缀也会被注册,以免被他人注册后造成不必要的损失。
以下是一个示例代码,演示如何使用Python获取域名的作用:
# 建网站
website_domain = ample"# 投资赚钱
investment_domain = "www.investmentdomain"# 品牌保护
brand_domains = [ample", ample"]print("网站域名:", website_domain)
print("投资域名:", investment_domain)
print("品牌保护域名:", brand_domains)
小程序开发工具和PyCharm可以通过以下步骤共同编辑同一个文件:
这样,你就可以在小程序开发工具和PyCharm中同时编辑同一个文件了。
如图:还没部署路由,在 微信开发者工具中DD报错
common/libs/UrlManager.py 链接管理器中啥也没有
# -*- coding: utf-8 -*-
import time
from application import appclass UrlManager(object):def __init__(self):pass@staticmethoddef buildUrl( path ):return path
web/controllers/api/ __init__.py
# -*- coding: utf-8 -*-
from flask import Blueprint
route_api = Blueprint( 'api_page',__name__ )llers.api.Member import *@ute("/")
def index():return "Mina Api V1.0~~"
这段代码是一个使用Flask框架 为 微信小程序 创建API的示例代码。下面是对代码的解析:
首先,导入了Blueprint
类和route_api
对象。Blueprint
是Flask框架中用于创建蓝图的类,蓝图可以将相关的视图函数、模板和静态文件组织在一起。route_api
是一个蓝图对象,用于定义API的路由和视图函数。
接下来,导入了Member
模块中的所有内容。这个模块可能包含了与会员相关的API视图函数和其他功能。
然后,使用ute("/")
装饰器将index()
函数注册为处理根路径(“/”)的视图函数。当用户访问根路径时,该函数将被调用。
最后,index()
函数返回了一个字符串"Mini Api V1.0~~"作为响应。
这段代码的作用是创建一个名为api_page
的蓝图,并定义了一个处理根路径的视图函数。当用户访问根路径时,将返回字符串"Mini Api V1.0~~"作为响应。
# -*- coding: utf-8 -*-llers.api import route_api
from flask import request, jsonify@ute("/member/login",methods = [ "GET","POST" ])
def login():resp = { 'code':200 ,'msg':'操作成功~','data':{} }req = request.valuescode = req['code'] if 'code' in req else ''if not code or len( code ) < 1:resp['code'] = -1resp['msg'] = "需要code"return jsonify(resp)openid = WeChatOpenId( code )if openid is None:resp['code'] = -1resp['msg'] = "调用微信出错"return jsonify(resp)nickname = req['nickName'] if 'nickName' in req else ''sex = req['gender'] if 'gender' in req else 0avatar = 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 = nicknamemodel_member.sex = sexmodel_member.avatar = avatarmodel_member.salt = Salt()model_member.updated_time = ated_time = getCurrentDate()db.session.add(model_member)db.sessionmit()model_bind = OauthMemberBind()ber_id = model_member.pe = 1model_bind.openid = a = ''model_bind.updated_time = ated_time = getCurrentDate()db.session.add(model_bind)db.sessionmit()bind_info = model_bindmember_info = Member.query.filter_by(id = ber_id).first()token = "%s#%s" % (AuthCode(member_info), member_info.id)resp['data'] = {'token': token}return jsonify( resp )
这段代码是一个基于Flask框架的API接口,主要实现了一个名为"login"的接口。下面是对代码的解析:
/member/login
,并指定了允许的请求方法为GET和POST。resp
,用于存储接口返回的数据。request.values
获取请求参数,并从中获取code
参数。resp
中的code
设置为-1,则返回错误msg信息"需要code",并返回resp
的JSON格式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格式作为接口的响应。# coding: utf-8
from sqlalchemy import Column, DateTime, Integer, String
from sqlalchemy.schema import FetchedValue
from application import db,appclass 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())@propertydef status_desc(self):fig['STATUS_MAPPING'][ str( self.status ) ]@propertydef 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
# coding: utf-8
from sqlalchemy import Column, DateTime, Index, Integer, String, Text
from sqlalchemy.schema import FetchedValue
from application import dbclass 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
UnionID是微信开放平台的一个标识符,用于唯一标识同一用户在不同应用(包括公众号、小程序、移动应用等)中的身份。它是一个 字符串 ,由微信开放平台生成并分配给每个用户。UnionID的作用是方便开发者在不同应用之间进行用户数据的关联和共享。通过UnionID,开发者可以获取用户在不同应用中的信息,实现跨应用的用户数据共享和个性化服务。
UnionID的获取方式有以下几种:
UnionId和OpenId是微信公众平台中的两个重要概念,它们之间有以下不同:
UnionId(统一标识符)是同一主体下不同应用之间的唯一身份标识符。在同一主体的小程序、公众号等下面,一个UnionId只有一个,而一个UnionId可以对应多个wxopenid和多个小程序OpenId。
OpenId(开放标识符)是用户在某个具体应用(如小程序、公众号)下的唯一身份标识符。在同一主体的不同应用之间,用户的OpenId是不同的。
UnionId的覆盖范围更广,可以在用户关注公众号、逛公众号下的H5页面时获取UnionId和wxopenid;在逛小程序时,可以获取小程序UnionId和openid。无论在哪个应用下,都可以获取到UnionId。
OpenId是应用级别的身份标识符,只能在特定的应用中使用,而UnionId是主体级别的身份标识符,可以在同一主体的不同应用之间共享使用。
总结起来,UnionId是同一主体下不同应用之间的唯一身份标识符,而OpenId是用户在某个具体应用下的唯一身份标识符。
# -*- coding: utf-8 -*-
import hashlib,requests,random,string,json
from application import app
class MemberService():@staticmethoddef geneAuthCode( member_info = None ):m = hashlib.md5()str = "%s-%s-%s" % ( member_info.id, member_info.salt,member_info.status)m.de("utf-8"))return m.hexdigest()@staticmethoddef geneSalt( length = 16 ):keylist = [ random.choice( ( string.ascii_letters + string.digits ) ) for i in range( length ) ]return ( "".join( keylist ) )@staticmethoddef getWeChatOpenId( code ):url = "={0}&secret={1}&js_code={2}&grant_type=authorization_code" .fig['MINA_APP']['appid'], fig['MINA_APP']['appkey'], code)r = (url)res = json.)openid = Noneif 'openid' in res:openid = res['openid']return openid
该方法使用了微信提供的API来通过code获取用户的OpenID。
小程序登录
小程序登录 | 微信开放文档
code2Session
登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。
具体步骤如下:
构建请求URL,其中包括了小程序的appid、appkey和code。缺少就报错!其中url中使用{}来获取值,
发送GET请求到微信API,并获取返回结果。
解析返回结果,提取出OpenID。
返回OpenID。
在Python中,反斜杠()被用作续行符,用于将一行代码分成多行书写。当一行代码太长时,可以使用反斜杠将其分成多行,以提高代码的可读性。
在给定的代码段中,反斜杠()的作用是将长的URL字符串分成多行,以便于阅读和理解。通过使用反斜杠,可以将长的URL字符串分成多行,使代码更加清晰易读。
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'
}
requests 用来发送请求
<发送get请求r是返回的值
.text
是一个属性,用于获取 HTTP 响应的内容。在这个例子中,< 返回的是一个字符串,表示 HTTP 响应的内容。在这个例子中,< 是一个 JSON 格式的字符串,通过 json.loads()
方法将其转换为 Python 字典对象 res
。然后,通过 res['openid']
获取字典中的 openid
值,并将其返回。
app.logger.info(res)
是一个使用logger
对象的info
方法来记录res
对象的日志信息的代码。具体的实现可能需要查看完整的代码,以确定logger
对象是如何定义和配置的。
以下是一个示例,展示了如何使用logger
对象的info
方法记录res
对象的日志信息
如图通过 app.logger.info(res)探索res的值的样式
如图openid返回的值是< 是一个 JSON 格式的字符串,通过 json.loads()
方法将其转换为 Python 字典对象 res
。然后,通过 res['openid']
获取字典中的 openid
值,并将其返回。
//app.js
App({onLaunch: function () {},globalData: {userInfo: null,version: "1.0",shopName: "Python3 + Flask 订餐全栈系统",domain:"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 ( firm ) {//点击确定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 (firm) {//用户点击确定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;},});
App(Object object) | 微信开放文档
注册小程序。接受一个 Object
参数,其指定小程序的生命周期回调等。
App() 必须在 app.js
中调用,必须调用且只能调用一次。不然会出现无法预期的后果。
onShow: function() { ... }
:定义了一个名为onShow
的生命周期函数,在页面显示时执行。
onReady: function() { ... }
:定义了一个名为onReady
的生命周期函数,在页面初次渲染完成时执行。
setTimeout(function() { ... }, 1000);
:使用setTimeout
函数设置一个定时器,延迟1秒后执行回调函数,将remind
的值设为空字符串,即隐藏加载中的提示。
这段代码是一个条件表达式,用于 判断对象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。
wx.showModal({title: title,content: content,success: function(res) {if ( firm ) {//点击确定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方法接受一个 对象 作为参数,该对象包含以下属性:
在回调函数中,可以根据用户的操作结果进行相应的处理。
如果用户点击了确定按钮,会执行success函数中的逻辑,
如果用户点击了 取消按钮,会执行else语句中的逻辑。
在该示例中,代码通过判断firm的值来确定用户点击的是确定按钮还是取消按钮。
如果firm为true,表示用户点击了确定按钮,会执行cb_confirm函数;
如果firm为false,表示用户点击了取消按钮,会执行cb_cancel函数。
该段代码的作用是创建一个模态弹窗,并根据用户的操作结果执行相应的回调函数。
在给定的代码中,&&
是逻辑与运算符。它用于判断两个条件是否同时为真。如果两个条件都为真,则整个表达式的结果为真;否则,结果为假。
在给定的代码中,&&
用于判断两个条件:
params.hasOwnProperty('cb_confirm')
:判断params
对象是否具有名为cb_confirm
的属性。typeof( params.cb_confirm ) == "function"
:判断params.cb_confirm
的类型是否为函数。只有当这两个条件都为真时,才会执行params.cb_confirm()
函数。
//获取应用实例
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.cityListfor (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.districtListfor (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: RequestHeader(),method:"POST",data:{id: that.data.id,act:'del'},success:function(res){var resp = res.data;app.alert({"":resp.msg});if (de == 200){// 跳转wx.navigateBack({});}}});}};app.tip(params);},
});
deleteAddress:function(){} 是一个小程序中的一个函数,用于删除地址信息。
下面是对代码的详细解释:
这段代码定义了一个名为deleteAddress
的函数,用于删除地址信息。当用户点击删除按钮时,该函数会被调用。
首先,函数内部定义了一个变量that
,并将其赋值为this
,这是为了在后续的回调函数中能够访问到外部的this
对象。
接下来,定义了一个名为params
的对象,该对象包含两个属性:
content
属性表示删除确认的提示内容,这里设置为"确定删除?"。cb_confirm
属性是一个回调函数,当用户点击确认删除时会执行该函数。在cb_confirm
函数中,发起了一个
RequestTask | 微信开放文档
具体的请求参数如下:
url
属性指定了请求的URL,这里使用了小程序中的app.buildUrl
函数来构建URL。header
属性设置了请求头,使用了小程序中的method
属性指定了请求的方法,这里使用了POST方法。data
属性是一个对象,包含了要发送的数据。其中id
表示要删除的地址的ID,act
表示要执行的操作,这里设置为"del"表示删除操作。在请求成功的回调函数中,首先解析了服务器返回的数据,并将其赋值给变量resp
。然后使用app.alert
函数弹出一个提示框,显示返回的消息内容。
如果服务器返回的状态码为200,表示删除成功,那么会执行以下操作:
wx.navigateBack
函数返回上一页。本文发布于:2024-01-31 04:53:25,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170664800625664.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |