当前位置: 首页 > news >正文

【uniapp】Dcloud的uni手机号一键登录,具体实现及踩过的坑,调用uniCloud.getPhoneNumber(),uni.login()等

一键登录Dcloud官网请戳这里,感兴趣的可以看看官网,有很详细的示例,选择App一键登录,可以看到一些常用的概述
比如:

1、调用uni.login就能弹出一键登录的页面
2、一键登录的流程,可以选择先预登录uni.prelogin()或直接登录uni.login()
3、要先开通Dcloud一键登录服务,在Dcloud开发者中心登录账户开通一键登录服务,这个需要付费的,每调用一次是0.02元,充值多少是无限制的,够你测试用就行。
4、设置uniCloud云函数,一键登录需要调用uniCloud.getPhoneNumber()
5、HBuilderX 3.4.0及之后的版本上传云函数时如果没有指定使用uni-cloud-verify扩展库的云函数将无法调用uniCloud.getPhoneNumber接口,所以要在云函数的package.json内添加uni-cloud-verify的引用
6、一键登录页面是配置出来的,如何配置,可以看univerifyStyle 数据结构
7、关闭一键登录授权界面,调用uni.closeAuthView()
8、用户点击一键登录自定义按钮
9、一键登录成功后,根据自己的后端接口判断是直接进入app页面还是需要去注册的业务处理

在这里插入图片描述

uni一键登录概述请戳这里

在这里插入图片描述
Uni手机号一键登录,请戳这里

在这里插入图片描述

一键登录具体实现:

首先得有Dcloud账号,申请好应用之后,申请开通一键登录服务,开通一键登录服务详细流程,请戳这里,在左侧选择一键登录,点击基础配置,取ApiKey和ApiSecret的值
在这里插入图片描述
1、mainfest.json中选择App模块配置,勾选一键登录
在这里插入图片描述
2、要实现一键登录,需要借助UniCloud 云函数的 API:uniCloud.getPhoneNumber
创建uniCloud.getPhoneNumber云函数步骤如下

1、在项目根目录uniCloud文件夹下找到 cloudfunctions 文件夹。如果没有该文件夹,可以手动创建
2、在 cloudfunctions 文件夹中创建一个新的文件夹,作为你的云函数的名称,例如 getPhoneNumber。我这里名称是login
3、进入 getPhoneNumber 文件夹,并创建一个 JavaScript 文件,例如 index.js。
4、在 index.js 中编写云函数的代码,具体实现获取手机号码的逻辑。

备注:这段代码在下面引起了一个报错,报错已解决,此段代码不要直接复制,用解决后的代码

exports.main = async (event, context) => {
//登录Dcloud账号,左侧选择一键登录,点击基础配置,取ApiKey和ApiSecret的值const res = await uniCloud.getPhoneNumber({provider: 'univerify',apiKey: '对应的apiKey',apiSecret: '对应的apiSecret',access_token: event.access_token,openid: event.openid})// 这里需要改成你们自己后端登录成功后的接口地址 ...const url = event.serversUrl + '/user/login'// md5加密方式:手机号 时间戳 私钥const phone = res.phoneNumberconst timestamp = new Date().getTime()const signKey = '对应的signKey 'const sign = crypto.createHash('md5').update(phone + timestamp + signKey).digest('hex')const result = await uniCloud.httpclient.request(url, {method: 'POST',data: {phone,timestamp,sign},contentType: 'json',dataType: 'json',// 是否在证书不受信任时返回错误rejectUnauthorized: false})console.log('服务端返回结果=', result)if (result.data.code == 200) {return {code: 0,message: '获取手机号成功',data: result.data.data}} else {return {code: result.data.code,message: result.data.msg,data: result.data.data}}
}

5、在项目根目录的uniCloud文件夹下,在云函数的package.json内添加uni-cloud-verify的引用即可为云函数启用此扩展,无需做其他调整
在这里插入图片描述

{"name": "login","dependencies": {},"extensions": {"uni-cloud-verify": {} // 启用一键登录扩展,值为空对象即可}
}

3、页面中具体使用
关于如何使用,我自己踩了些坑
1、首先一键登录页面类似于一个弹窗,在app刚打开的时候先弹出这个一键登录的页面
如果不想选一键登录,点左上角的叉号,关闭弹窗。
我遇到的第一个坑是,我对一键登录不了解,
我自己按ui图画了一个一键登录的页面,在实现过程中一直很疑惑,如何获得加密的手机号和对应的供应商认证服务来渲染到页面上,误区在于一键登录页面是配置出来的。
既然它是弹窗,关闭之后就得有一个展示的页面,我这里是关闭之后显示的是账号登录页面

2、uniapp介绍中,左侧菜单栏点击uni一键登录
在这里插入图片描述
里面有张流程图,先预登录然后是一键登录

在这里插入图片描述
关于预登录,需要调用 uni.preLogin(), 主要是检查预登录环境
然后紧接着就是调用uni.login(),
这个地方就很疑惑,我一直觉得是点击一键登录按钮才会调用login方法
误区就在于,uni.login()获取用户的登录凭证 code。然后将这个 code 发送给后端服务器,服务器使
用这个凭证进行登录验证,并返回用户的身份信息或生成用户的会话凭证,直白的说就是调用
uni.login()之后才能拿到手机号和对应的供应商认证服务
,一键登录页面上的手机号和对应的供应商认证服务才会显示出来
紧接着是一键登录按钮,当点击按钮的时候会触发uniCloud.callFunction,就是去调用云函数,云函
数返回的参数有用户的完整手机号,拿着这个手机号,去调我们自己后端的接口,根据后端给的标识
判断是放行到主页还是需要用户去注册页

function preLogin(isShowMsg = false) {//预登陆检查是否符合一键登录的环境uni.preLogin({provider: "univerify",success: (res) => {//调用login方法,我是vue3,没有thi实例,vue2框架this.login()login()},fail(err) {// 如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,都有可能造成预登录校验失败。if (isShowMsg && err.errMsg != "login:ok") {// 不同运营商 返回的报错字段不同uni.showModal({title: "当前设备环境不支持一键登录",content:err.errMsg ||err.metastate.resultMsg ||err.metastate.error_data ||err.metastate.resultDesc ||"请检查是否插入有效sim卡及开启蜂窝数据网络",showCancel: false,});}},});}
function login() {uni.login({provider: 'univerify',univerifyStyle: {"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff  "icon": {"path": "static/images/logo.png",// 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo   "width": "60px",  //图标宽度 默认值:60px"height": "60px",//图标高度 默认值:60px,				},"phoneNum": {"color": "#525252",// 手机号文字颜色 默认值:#202020  "fontSize": "22",// 手机号字体大小 默认值:18},"slogan": {"color": "#525252", //  slogan 字体颜色 默认值:#8a8b90"fontSize": "14"},"authButton": {"normalColor": "#FF9CAE", // 授权按钮正常状态背景颜色 默认值:#3479f5  "highlightColor": "#FF9CAE", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)  "disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)  "textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff  "title": "一键登录/注册" // 授权按钮文案 默认值:“本机号码一键登录”  },"otherLoginButton": {"visible": "true", // 是否显示其他登录按钮,默认值:true  "normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明 "highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明 "textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565  "title": "验证码登录", // 其他登录方式按钮文字 默认值:“其他登录方式”  "borderColor": "",  //边框颜色 默认值:透明(仅iOS支持)  "borderRadius": "0px",// 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)},"privacyTerms": {"defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true"uncheckedImage": "", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)   "checkedImage": "", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)   "checkBoxSize": 12, // 可选 条款勾选框大小,仅android支持"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB  "termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3  "prefix": "请阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”  "suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”  "privacyItems": [  // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效  {"url": "/pages/privacy/use", // 点击跳转的协议详情页面  "title": "《xxx用户注册协议》" //用户注册协议名称  },{"url": "/pages/privacy/privacy", // 点击跳转的协议详情页面  "title": "《xx隐私政策》" // 隐私政策名称  }]}},success: (res) => {uniCloud.callFunction({name: 'login', // 你的云函数名称data: {access_token: res.authResult.access_token, // 客户端一键登录接口返回的access_tokenopenid: res.authResult.openid // 客户端一键登录接口返回的openid}}).then(dataRes => {console.log('云函数返回的参数', dataRes)data.form.mobile = dataRes.result.data.phoneNumber$Api.post("user/direct",data.form).then((res) => {console.log(res,'调后端接口判断登录后操作');if(res&&res.code==0){if(res.id){uni.switchTab({url: "/pages/square/square",});}else{uni.navigateTo({url: "/pages/user/register?mobile=" + data.form.mobile,});}}});}).catch(err => {console.log('云函数报错', err)})uni.showToast({title: res.authResult,icon: "none"})uni.closeAuthView() //关闭一键登录弹出窗口},fail(res) { // 登录失败			uni.closeAuthView() //关闭一键登录弹出窗口console.log('失败')},})}

3、当uni.login()调用成功之后,一键登录页面就出现了,然后就是调整样式,大框架是没法改变的,只能调整一些类似于字体大小,颜色之类的,如何调整icon和phoneNumber之间的间距,我一直没有实现,有实现的可以给我留言,感谢感谢

通过univerifyStyle 配置,官网是这样的,我自己的配置看上面的代码

{  "fullScreen": false, // 是否全屏显示,默认值: false"backgroundColor": "#ffffff",  // 授权页面背景颜色,默认值:#ffffff"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)  "icon": {  "path": "static/xxx.png", // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo"width":  "60px",  //图标宽度 默认值:60px"height": "60px"   //图标高度 默认值:60px},  "closeIcon": {  "path": "static/xxx.png" // 自定义关闭按钮,仅支持本地图片。 HBuilderX3.3.7+版本支持},  "phoneNum": {  "color": "#202020"  // 手机号文字颜色 默认值:#202020  },  "slogan": {  "color": "#BBBBBB"  //  slogan 字体颜色 默认值:#BBBBBB  },  "authButton": {  "normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5  "highlightColor": "#2861c5",  // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)  "disabledColor": "#73aaf5",  // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)  "textColor": "#ffffff",  // 授权按钮文字颜色 默认值:#ffffff  "title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”  "borderRadius": "24px"	// 授权按钮圆角 默认值:"24px" (按钮高度的一半)},  "otherLoginButton": {  "visible": true, // 是否显示其他登录按钮,默认值:true  "normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明 "highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明 "textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565  "title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”  "borderColor": "",  //边框颜色 默认值:透明(仅iOS支持)  "borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)},  "privacyTerms": {  "defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true"isCenterHint":false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)"uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)   "checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)   "checkBoxSize":12, // 可选 条款勾选框大小"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB  "termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3  "prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”  "suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”  "privacyItems": [  // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效  {  "url": "https://", // 点击跳转的协议详情页面  "title": "用户服务协议" // 协议名称  }  ]  },"buttons": {  // 自定义页面下方按钮仅全屏模式生效(3.1.14+ 版本支持)"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px"list": [{"provider": "apple","iconPath": "/static/apple.png" // 图标路径仅支持本地图片}, {"provider": "weixin","iconPath": "/static/wechat.png" // 图标路径仅支持本地图片}]}
}

这里遇到一个报错,云函数中这个接口的前缀是underfiend,导致找不到,云函数index.js中的代码之前是其他人写的,我打印之后才发现,event只返回两个参数,access_token和openid,没有event.serversUrl这个参数,所以导致显示的是undefined
在这里插入图片描述
代码改为:

exports.main = async (event, context) => {
//登录Dcloud账号,左侧选择一键登录,点击基础配置,取ApiKey和ApiSecret的值const res = await uniCloud.getPhoneNumber({appid: '_xxxxA3', // 替换成自己开通一键登录的应用的DCloud appidprovider: 'univerify',apiKey: '对应的apiKey',apiSecret: '对应的apiSecret',access_token: event.access_token,openid: event.openid})
return {code: 0,message: '获取手机号成功',data:res}}

然后调用成功后会返回这样的数据格式

在这里插入图片描述
我们需要的就是完整的手机号
在这里插入图片描述
在自己的页面中调用uni.login,uniCloud.callFunction({}).then((dataRes=>{
console.log(‘云函数返回的参数’, dataRes)
})),打印之后就能拿到:

{"result": {"code": 0,"message": "获取手机号成功","data": {"code": 0,"success": true,"phoneNumber": "1510000xxxx"}}
}

再说个小细节点,如果你想在云函数中打印看结果的话,一定要右击云函数选择上传部署,不然的话云函数不会更新,我就是自己傻傻的等着看结果,试了好几次才反应过来
在这里插入图片描述
欢迎留言沟通或私信沟通~~~~

相关文章:

【uniapp】Dcloud的uni手机号一键登录,具体实现及踩过的坑,调用uniCloud.getPhoneNumber(),uni.login()等

一键登录Dcloud官网请戳这里,感兴趣的可以看看官网,有很详细的示例,选择App一键登录,可以看到一些常用的概述 比如: 1、调用uni.login就能弹出一键登录的页面 2、一键登录的流程,可以选择先预登录uni.prelo…...

Qt Quick Layouts Overview

Qt快速布局概述 #【中秋征文】程序人生,中秋共享# Qt快速布局是用于在用户界面中排列项目的项目。由于Qt快速布局还可以调整其项目的大小,因此它们非常适合可调整大小的用户界面。 开始 可以使用文件中的以下导入语句将 QML 类型导入到应用程序中。.qml…...

星臾计划 | 第六期优秀实习生访谈合集

此处划重点:优秀实习生评比活动将每三个月进行一次,获评同学可获得优秀实习生证书和丰厚的奖励 —— 是心动的感觉! 作为实习生培养计划,星臾计划不但能帮助在校生提前了解企业、熟悉工作环境,还能提前锁定正式 Offer…...

《数字图像处理-OpenCV/Python》连载(7)视频文件的读取与保存

《数字图像处理-OpenCV/Python》连载(7)视频文件的读取与保存 本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 第1章 图像的基本操作 为…...

安防监控/视频汇聚/云存储/AI智能视频分析平台EasyCVR显示CPU过载,该如何解决?

视频云存储/安防监控/视频汇聚平台EasyCVR基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频监控系统EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云…...

如何彻底卸载mysql

要彻底卸载 MySQL,您可以按照以下步骤进行操作。这些步骤适用于大多数 Linux 发行版,如 Ubuntu、CentOS、Debian 等。请注意,这些步骤可能会删除您的 MySQL 数据库和配置文件,所以请务必备份您的数据。 注意:在执行这些…...

【深度学习实验】线性模型(二):使用NumPy实现线性模型:梯度下降法

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 初始化参数 2. 线性模型 linear_model 3. 损失函数loss_function 4. 梯度计算函数compute_gradients 5. 梯度下降函数gradient_descent 6. 调用函数 一、实验介绍 使用Nu…...

带你熟练使用list

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻强烈推荐优质专栏: 🍔🍟🌯C的世界(持续更新中) 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔…...

排序——希尔排序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、希尔排序二、希尔排序动态图三、希尔排序程序代码四、希尔排序习题总结 前言 希尔排序定义希尔排序算法分析希尔排序程序代码希尔排序练习题 一、希尔排序…...

为什么文件夹里的文件看不到?了解原因及应对措施

无论是在个人电脑中还是在其他存储介质上,我们经常会遇到文件夹中的文件突然不可见的情况。这种问题给我们的工作和生活带来了不便,并可能导致数据丢失。本文将分析文件夹中文件看不见的原因,并介绍相应的解决方法,以帮助大家更好…...

KVM嵌套虚拟化实现

KVM嵌套虚拟化实现 理论 Libvirt主要支持三种 CPU mode host-passthrough: libvirt 令 KVM 把宿主机的 CPU 指令集全部透传给虚拟机。因此虚拟机能够最大限度的使用宿主机 CPU 指令集,故性能是最好的。但是在热迁移时,它要求目的节点的 CPU 和源节点的…...

驱动开发,IO模型,信号驱动IO实现过程

1.信号驱动IO框架图 分析: 信号驱动IO是一种异步IO方式。linux预留了一个信号SIGIO用于进行信号驱动IO。进程主程序注册一个SIGIO信号的信号处理函数,当硬件数据准备就绪后会发起一个硬件中断,在中断的处理函数中向当前进程发送一个SIGIO信号…...

左神高级进阶班3(TreeMap顺序表记录线性数据的使用, 滑动窗口的使用,前缀和记录结构, 可能性的舍弃)

目录 【案例1】 【题目描述】 【思路解析】 【代码实现】 【案例2】 【题目描述】 【思路解析】 【代码实现】 【案例3】 【题目描述】 【思路解析】 【代码实现】 【案例4】 【题目描述】 【思路解析】 【代码实现】 【案例1】 【题目描述】 【思路解析】 这里…...

Linux线程

1.进程是资源管理的最小单位,线程是程序执行的最小单位。 2.每个进程有自己的数据段、代码段和堆栈段。线程通常叫做轻型的进程,它包含独立的栈和CPU寄存器状态,线程是进程的一条执行路径,每个线程共享其所附属进程的所有资源,包括…...

C++ 太卷,转 Java?

最近看到知乎、牛客等论坛上关于 C 很多帖子,比如: 2023年大量劝入C 2023年还建议走C方向吗? 看了一圈,基本上都是说 C 这个领域唯一共同点就是都使用 C 语言,其它几乎没有相关性。 的确是这样,比如量化交…...

《Java并发编程实战》第2章-线程安全性

0.概念理解 对象状态:存储在状态变量(例如实例或静态域)中的数据; 线程安全性:当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的; 竞态条件&…...

二蛋赠书三期:《C#入门经典(第9版)》

文章目录 前言活动规则参与方式本期赠送书籍介绍作者介绍内容简介读者对象获奖名单 结语 前言 大家好!我是二蛋,一个热爱技术、乐于分享的工程师。在过去的几年里,我一直通过各种渠道与大家分享技术知识和经验。我深知,每一位技术…...

Augmented Large Language Models with Parametric Knowledge Guiding

本文是LLM系列文章,针对《Augmented Large Language Models with Parametric Knowledge Guiding》的翻译。 参数知识引导下的增强大型语言模型 摘要1 引言2 相关工作3 LLM的参数化知识引导4 实验5 结论 摘要 大型语言模型(LLM)凭借其令人印…...

Docker启动Mysql容器并进行目录挂载

一、创建挂载目录 mkdir -p 当前层级下创建 mkdir -p mysql/data mkdir -p mysql/conf 进入到conf目录下创建配置文件touch hym.conf 并把配置文件hmy.conf下增加以下内容使用vim hym.conf即可添加(cv进去就行) Esc :wq 保存 [mysqld] skip-name-resolve character_set_…...

力扣刷题(简单篇):两数之和、两数相加、无重复字符的最长子串

坚持就是胜利 一、两数之和 题目链接:https://leetcode.cn/problems/two-sum/ 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】,这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...