微信小程序三种授权登录以及授权登录流程讲解

🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《微信小程序开发实战》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
Java方文山的个人主页
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖

一、微信授权登录流程
小程序登录
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。

👇👇图解👇👇

步骤流程:
1.小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器
2.开发者服务器以appid+appsecret+code换取 用户唯一标识openid和会话密钥session_key。
3.开发者服务器根据用户标识来生成自定义登录态用于后续业务逻辑中前后端交互时识别用户身份
4.客户端保存后端生成的自定义登录态,并在下一次发送请求的时候带上这个自定义登录态。
注意:临时登录凭证code只能使用一次
二、微信用户授权
下面我以两种方式的代码来给大家论证一下微信用户授权登录的流程,第一种不需要用户确认即可完成用户授权登录在开发中并不是那么的安全,第二种则是需要用户确认方可进行授权登录。
前期准备工作
wxml代码展示
<!--pages/index/index.wxml-->
<view><button wx:if="{{canIUseGetUserProfile}}" type="primary" class="wx-login-btn" bindtap="getUserProfile">微信直接登录1</button><button wx:else open-type="getUserInfo" type="primary" class="wx-login-btn" bindgetuserinfo="wxLogin">微信直接登录2</button><image mode="scaleToFill" src="{{userInfo.avatarUrl}}" /><text>昵称:{{userInfo.nickName}}</text>
</view>
1.wx.login
JS代码展示
wxLogin: function(e) {debuggerconsole.log('wxLogin')console.log(e.detail.userInfo);this.setData({userInfo: e.detail.userInfo})if (e.detail.userInfo == undefined) {app.globalData.hasLogin = false;util.showErrorToast('微信登录失败');return;}
效果展示:

看得出确实是走的这个方法并获取用户信息的,我们继续看一下另一个方法。
2.wx.getUserProfile
JS代码展示
getUserProfile(e) {console.log('getUserProfile')// 推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗wx.getUserProfile({desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写success: (res) => {console.log(res);this.setData({userInfo: res.userInfo,hasUserInfo: true})}})}
效果展示: 
3.用户授权完成后端交互
我们使用用户授权后将用户信息保存到数据库方便下次用户发送请求的时候做身份认证。
封装的代码
utils/util.js
function formatTime(date) {var year = date.getFullYear()var month = date.getMonth() + 1var day = date.getDate()var hour = date.getHours()var minute = date.getMinutes()var second = date.getSeconds()return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}function formatNumber(n) {n = n.toString()return n[1] ? n : '0' + n
}/*** 封封微信的的request*/
function request(url, data = {}, method = "GET") {return new Promise(function (resolve, reject) {wx.request({url: url,data: data,method: method,timeout:3000,header: {'Content-Type': 'application/json','X-OA-Token': wx.getStorageSync('token')},success: function (res) {if (res.statusCode == 200) {if (res.data.errno == 501) {// 清除登录相关内容try {wx.removeStorageSync('userInfo');wx.removeStorageSync('token');} catch (e) {// Do something when catch error}// 切换到登录页面wx.navigateTo({url: '/pages/auth/login/login'});} else {resolve(res.data);}} else {reject(res.errMsg);}},fail: function (err) {reject(err)}})});
}function redirect(url) {//判断页面是否需要登录if (false) {wx.redirectTo({url: '/pages/auth/login/login'});return false;} else {wx.redirectTo({url: url});}
}function showErrorToast(msg) {wx.showToast({title: msg,image: '/static/images/icon_error.png'})
}function jhxLoadShow(message) {if (wx.showLoading) { // 基础库 1.1.0 微信6.5.6版本开始支持,低版本需做兼容处理wx.showLoading({title: message,mask: true});} else { // 低版本采用Toast兼容处理并将时间设为20秒以免自动消失wx.showToast({title: message,icon: 'loading',mask: true,duration: 20000});}
}function jhxLoadHide() {if (wx.hideLoading) { // 基础库 1.1.0 微信6.5.6版本开始支持,低版本需做兼容处理wx.hideLoading();} else {wx.hideToast();}
}module.exports = {formatTime,request,redirect,showErrorToast,jhxLoadShow,jhxLoadHide
}
config/api.js
// 以下是业务服务器API地址// 本机开发API地址
var WxApiRoot = 'http://localhost:8080/oapro/wx/';
// 测试环境部署api地址
// var WxApiRoot = 'http://192.168.191.1:8080/oapro/wx/';
// 线上平台api地址
//var WxApiRoot = 'https://www.oa-mini.com/demo/wx/';module.exports = {IndexUrl: WxApiRoot + 'home/index', //首页数据接口SwiperImgs: WxApiRoot+'swiperImgs',MettingInfos: WxApiRoot+'meeting/list',AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录UserIndex: WxApiRoot + 'user/index', //个人页面用户相关信息AuthLogout: WxApiRoot + 'auth/logout', //账号登出AuthBindPhone: WxApiRoot + 'auth/bindPhone' //绑定微信手机号
};
JS代码
// pages/auth/login/login.js
var util = require('../../../utils/util.js');
var user = require('../../../utils/user.js');
const app = getApp();
Page({/*** 页面的初始数据*/data: {canIUseGetUserProfile: false, // 用于向前兼容lock:false},onLoad: function(options) {// 页面初始化 options为页面跳转所带来的参数// 页面渲染完成if (wx.getUserProfile) {this.setData({canIUseGetUserProfile: true})}//console.log('login.onLoad.canIUseGetUserProfile='+this.data.canIUseGetUserProfile)},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},getUserProfile(e) {console.log('getUserProfile');// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗wx.getUserProfile({desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写success: (res) => {//console.log(res);user.checkLogin().catch(() => {user.loginByWeixin(res.userInfo).then(res => {app.globalData.hasLogin = true;wx.navigateBack({delta: 1})}).catch((err) => {app.globalData.hasLogin = false;if(err.errMsg=="request:fail timeout"){util.showErrorToast('微信登录超时');}else{util.showErrorToast('微信登录失败');}this.setData({lock:false})});});},fail: (res) => {app.globalData.hasLogin = false;console.log(res);util.showErrorToast('微信登录失败');}});},wxLogin: function(e) {console.log('wxLogin');if (e.detail.userInfo == undefined) {app.globalData.hasLogin = false;util.showErrorToast('微信登录失败');return;}user.checkLogin().catch(() => {user.loginByWeixin(e.detail.userInfo).then(res => {app.globalData.hasLogin = true;wx.navigateBack({delta: 1})}).catch((err) => {app.globalData.hasLogin = false;if(err.errMsg=="request:fail timeout"){util.showErrorToast('微信登录超时');}else{util.showErrorToast('微信登录失败');}});});},accountLogin() {console.log('开发中....')}})
WXML代码
<view class="container"><view class="login-box"><button wx:if="{{canIUseGetUserProfile}}" type="primary" class="wx-login-btn" bindtap="getUserProfile">微信直接登录</button><button wx:else open-type="getUserInfo" type="primary" class="wx-login-btn" bindgetuserinfo="wxLogin">微信直接登录</button><button type="primary" class="account-login-btn" bindtap="accountLogin">账号登录</button></view>
</view>
后端配置appid+appsecret与数据库连接
后端代码
/*** 微信登录** @param wxLoginInfo* 请求内容,{ code: xxx, userInfo: xxx }* @param request* 请求对象* @return 登录结果*/@PostMapping("login_by_weixin")public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {//客户端需携带code与userInfo信息String code = wxLoginInfo.getCode();UserInfo userInfo = wxLoginInfo.getUserInfo();if (code == null || userInfo == null) {return ResponseUtil.badArgument();}//调用微信sdk获取openId及sessionKeyString sessionKey = null;String openId = null;try {long beginTime = System.currentTimeMillis();//WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
// Thread.sleep(6000);long endTime = System.currentTimeMillis();log.info("响应时间:{}",(endTime-beginTime));sessionKey = result.getSessionKey();//session idopenId = result.getOpenid();//用户唯一标识 OpenID} catch (Exception e) {e.printStackTrace();}if (sessionKey == null || openId == null) {log.error("微信登录,调用官方接口失败:{}", code);return ResponseUtil.fail();}else{log.info("openId={},sessionKey={}",openId,sessionKey);}//根据openId查询wx_user表//如果不存在,初始化wx_user,并保存到数据库中//如果存在,更新最后登录时间WxUser user = userService.queryByOid(openId);if (user == null) {user = new WxUser();user.setUsername(openId);user.setPassword(openId);user.setWeixinOpenid(openId);user.setAvatar(userInfo.getAvatarUrl());user.setNickname(userInfo.getNickName());user.setGender(userInfo.getGender());user.setUserLevel((byte) 0);user.setStatus((byte) 0);user.setLastLoginTime(new Date());user.setLastLoginIp(IpUtil.client(request));user.setShareUserId(1);userService.add(user);} else {user.setLastLoginTime(new Date());user.setLastLoginIp(IpUtil.client(request));if (userService.updateById(user) == 0) {log.error("修改失败:{}", user);return ResponseUtil.updatedDataFailed();}}// tokenUserToken userToken = null;try {userToken = UserTokenManager.generateToken(user.getId());} catch (Exception e) {log.error("微信登录失败,生成token失败:{}", user.getId());e.printStackTrace();return ResponseUtil.fail();}userToken.setSessionKey(sessionKey);log.info("SessionKey={}",UserTokenManager.getSessionKey(user.getId()));Map<Object, Object> result = new HashMap<Object, Object>();result.put("token", userToken.getToken());result.put("tokenExpire", userToken.getExpireTime().toString());userInfo.setUserId(user.getId());if (!StringUtils.isEmpty(user.getMobile())) {// 手机号存在则设置userInfo.setPhone(user.getMobile());}try {DateFormat df = new SimpleDateFormat("yyyy-MM-dd");String registerDate = df.format(user.getAddTime() != null ? user.getAddTime() : new Date());userInfo.setRegisterDate(registerDate);userInfo.setStatus(user.getStatus());userInfo.setUserLevel(user.getUserLevel());// 用户层级userInfo.setUserLevelDesc(UserTypeEnum.getInstance(user.getUserLevel()).getDesc());// 用户层级描述} catch (Exception e) {log.error("微信登录:设置用户指定信息出错:"+e.getMessage());e.printStackTrace();}result.put("userInfo", userInfo);log.info("【请求结束】微信登录,响应结果:{}", JSONObject.toJSONString(result));return ResponseUtil.ok(result);}
数据库展示

效果演示

三、微信手机号授权
手机授权原理也是如此只不过调用的接口不同罢了。
JS代码
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var user = require('../../../utils/user.js');
var app = getApp();
Page({/*** 页面的初始数据*/data: {userInfo: {},hasLogin: false,userSharedUrl: ''},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {},onShow: function () {let that = this;//获取用户的登录信息let userInfo = wx.getStorageSync('userInfo');this.setData({userInfo: userInfo,hasLogin: true});},getPhoneNumber: function (e) {console.log(e);let that = this;if (e.detail.errMsg !== "getPhoneNumber:ok") {// 拒绝授权return;}if (!this.data.hasLogin) {wx.showToast({title: '绑定失败:请先登录',icon: 'none',duration: 2000});return;}util.request(api.AuthBindPhone, {iv: e.detail.iv,encryptedData: e.detail.encryptedData}, 'POST').then(function (res) {if (res.errno === 0) {let userInfo = wx.getStorageSync('userInfo');userInfo.phone = res.data.phone;//设置手机号码wx.setStorageSync('userInfo', userInfo);that.setData({userInfo: userInfo,hasLogin: true});wx.showToast({title: '绑定手机号码成功',icon: 'success',duration: 2000});}});},exitLogin: function () {wx.showModal({title: '',confirmColor: '#b4282d',content: '退出登录?',success: function (res) {if (!res.confirm) {return;}util.request(api.AuthLogout, {}, 'POST');app.globalData.hasLogin = false;wx.removeStorageSync('token');wx.removeStorageSync('userInfo');wx.reLaunch({url: '/pages/index/index'});}})}
})
WXML代码
<!--pages/ucenter/user/user.wxml-->
<form bindsubmit="formSubmit"><view class='personal-data'><view class='list'><view class='item acea-row row-between-wrapper'><view>头像</view><view class='pictrue'><image src='{{userInfo.avatarUrl}}'></image></view></view><view class='item acea-row row-between-wrapper'><view>名字</view><view class='input'><input type='text' disabled='true' name='nickname' value='{{userInfo.nickName}}'></input></view></view><view class='item acea-row row-between-wrapper'><view>手机号码</view><button name='phone' class='phoneW' value='{{userInfo.phone}}' wx:if="{{!userInfo.phone}}" bindgetphonenumber="getPhoneNumber" hover-class='none' open-type='getPhoneNumber'>点击获取</button><view class='input acea-row row-between-wrapper' wx:else><input type='text' disabled='true' name='phone' value='{{userInfo.phone}}' class='id'></input><text class='iconfont icon-suozi'></text></view></view><view class='item acea-row row-between-wrapper'><view>ID号</view><view class='input acea-row row-between-wrapper'><input type='text' value='1000{{userInfo.userId}}' disabled='true' class='id'></input><text class='iconfont icon-suozi'></text></view></view></view><button class='modifyBnt' bindtap="exitLogin">退 出</button></view>
</form>
后端代码
/*** 绑定手机号码** @param userId* @param body* @return*/@PostMapping("bindPhone")public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) {log.info("【请求开始】绑定手机号码,请求参数,body:{}", body);String sessionKey = UserTokenManager.getSessionKey(userId);String encryptedData = JacksonUtil.parseString(body, "encryptedData");String iv = JacksonUtil.parseString(body, "iv");WxMaPhoneNumberInfo phoneNumberInfo = null;try {phoneNumberInfo = this.wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);} catch (Exception e) {log.error("绑定手机号码失败,获取微信绑定的手机号码出错:{}", body);e.printStackTrace();return ResponseUtil.fail();}String phone = phoneNumberInfo.getPhoneNumber();WxUser user = userService.selectByPrimaryKey(userId);user.setMobile(phone);if (userService.updateById(user) == 0) {log.error("绑定手机号码,更新用户信息出错,id:{}", user.getId());return ResponseUtil.updatedDataFailed();}Map<Object, Object> data = new HashMap<Object, Object>();data.put("phone", phone);log.info("【请求结束】绑定手机号码,响应结果:{}", JSONObject.toJSONString(data));return ResponseUtil.ok(data);}
效果展示

四、注销登录
注销登录的前端代码同上,后端代码如下:
后端代码
/*** 注销登录*/@PostMapping("logout")public Object logout(@LoginUser Integer userId) {log.info("【请求开始】注销登录,请求参数,userId:{}", userId);if (userId == null) {return ResponseUtil.unlogin();}try {UserTokenManager.removeToken(userId);} catch (Exception e) {log.error("注销登录出错:userId:{}", userId);e.printStackTrace();return ResponseUtil.fail();}log.info("【请求结束】注销登录成功!");return ResponseUtil.ok();}
效果演示

到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖

相关文章:
微信小程序三种授权登录以及授权登录流程讲解
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《微信小程序开发实战》。🎯Ἲ…...
C现代方法(第10章)笔记——程序结构
文章目录 第10章 程序结构10.1 局部变量10.1.1 静态局部变量10.1.2 形式参数 10.2 外部变量10.2.1 示例:用外部变量实现栈10.2.2 外部变量的利与弊 10.3 程序块10.4 作用域10.5 构建C程序10.5.1 复杂程序:给一手牌分类 问与答写在最后 第10章 程序结构 …...
解密Web安全:Session、Cookie和Token的不解之谜
解密Web安全:Session、Cookie和Token的不解之谜 前言第一部分:什么是Session、Cookie和Token1. Session(会话):2. Cookie(HTTP Cookie):3. Token(令牌):比较: 第二部分&a…...
1016 部分A+B
#include<bits/stdc.h> using namespace std; int main(){string str1;string str2;int a,b;cin>>str1>>a>>str2>>b;int a10;int a20;for(auto t:str1){if(t-0a){a1a1*10a;}}for(auto t:str2){if(t-0b){a2a2*10b;}}cout<<a1a2; }...
搭建react项目
一、环境准备 1、安装node 官网下载安装:https://nodejs.org/en 注: npm5.2以后,安装node会自动安装npm和npx 2、安装webpack npm install -g webpack3、安装create-react-app npm install -g create-react-app二、创建react项目 1、初…...
Hive跨集群数据迁移过程
文章目录 环境数据迁移需求迁移过程记录 环境 Hive集群AHive集群B跳转机一台 数据迁移需求 本次迁移数据100G,15亿条,数据流转方向从集群A经过跳转机到集群B,通过HDFS拉取和重新建表导入的方式完成数据库迁移。 迁移过程记录 - 当前操作…...
中国移动启动算网大脑“天穹”全网试商用
10月12日,中国移动在2023全球合作伙伴大会主论坛正式启动算网大脑“天穹”全网试商用,全面开启算力网络2.0新征程,标志着中国移动算力网络迈向“融合统一”新阶段。 为落实国家“东数西算”战略,中国移动开创性提出算力网络新理念…...
apk和小程序渗透
apk和小程序域服务器通信使用的还是http协议,只是使用了加密。只要可以获取到http的请求报文,就可以回归到web渗透的层面。apk和小程序的渗透很复杂,涉及逆向时要进行脱壳,脱壳后反编译了,源代码没做加密就能直接逆向出…...
播放svga动画的时候 第一次加载资源,然后切换动画 会动画会重影
如果在切换 SVGA 动画的过程中,第一次加载时出现重影,但第二次及以后的切换没有重影,这可能是由于第一次加载时资源缓存不完整导致的。为了解决这个问题,你可以尝试以下方法: 1.在每次切换动画之前,预先加…...
如何实现前端音频和视频播放?
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...
chatgpt 4V 识图功能
1.获取图片的sig和file_id 2e0edc6e489ed13a3f32f0dd87527d77.jpg是本地图片的名字 头部认证信息自己F12 抓取 1.获取图片的sighttps://chat.openai.com/backend-api/filesAuthorization:Bearer eyJhbGc****************5V-lztYwLb9hr6LP7g Cookie: **********************…...
展馆导览系统之AR互动式导航与展品语音讲解应用
一、项目背景 随着科技的进步和人们对于文化、艺术、历史等方面需求的提升,展馆在人们的生活中扮演着越来越重要的角色。然而,传统的展馆导览方式,如纸质导览、人工讲解等,已无法满足参观者的多元化需求。为了提升参观者的体验&a…...
Rust 中的String与所有权机制
文章目录 一、string二、所有权2.1 所有权与作用域2.2 对所有权的操作2.2.1 转移2.2.3 拷贝2.2.3 传递 2.3 引用2.3.1 借用2.3.2 可变引用 一、string 之前学习过 Rust 只有几种基础的数据类型,但是没有常用的字符串也就是String,今天来学习一下 String…...
多线程环境下如何安全的使用线性表, 队列, 哈希表
小王学习录 今日鸡汤安全使用ArrayList安全使用队列安全使用HashMap 今日鸡汤 安全使用ArrayList 使用synchronized锁或者reentrantLock锁使用CopyOnWriteArrayList(COW写时拷贝)类来代替ArrayList类. 多个线程对CopyOnWriteArrayList里面的ArrayList进行读操作, 不会发生线程…...
机器人SLAM与自主导航
机器人技术的迅猛发展,促使机器人逐渐走进了人们的生活,服务型室内移动机器人更是获得了广泛的关注。但室内机器人的普及还存在许多亟待解决的问题,定位与导航就是其中的关键问题之一。在这类问题的研究中,需要把握三个重点&#…...
Zookeeper集群 + Kafka集群的详细介绍与部署
文章目录 1. Zookeeper 概述1.1 简介1.2 Zookeeper的工作机制1.3 Zookeeper 主要特点1.4 Zookeeper 数据结构1.5 Zookeeper的相关应用场景1.5.1 统一命名服务1.5.2 统一配置管理1.5.3 统一集群管理1.5.4 服务器动态上下线1.5.5 软负载均衡 1.6 Zookeeper 选举机制1.6.1 第一次启…...
STP、堆叠与VRRP如何使用
✍ STP生成树用在哪里? ✍ STP和堆叠有什么区别? ✍ VRRP双网关热备份如何部署? --- 通过交换机组成网络是局域网,连接终端设备的交换机就是接入层交换机。 --- 如上组网结构单一,不需要网工。 容易发生单点故障&…...
Go 函数的健壮性、panic异常处理、defer 机制
Go 函数的健壮性、panic异常处理、defer 机制 文章目录 Go 函数的健壮性、panic异常处理、defer 机制一、函数健壮性的“三不要”原则1.1 原则一:不要相信任何外部输入的参数1.2 原则二:不要忽略任何一个错误1.3 原则三:不要假定异常不会发生…...
Maven的详细介绍(maven的全据配置以及idea中maven的配置)
maven的理解 Maven 是一个强大的项目管理和构建自动化工具,它通过抽象的项目对象模型(POM:Project Object Model)和构建生命周期模型(Project Lifecycle)来对项目及其构建过程进行管理(Dependency Management System),Maven 最大化的消除了构…...
Qt中Json的操作
在 Json的两种格式中介绍了Json的格式以及应用场景。由于这种数据格式与语言无关,下面介绍一下Json在Qt中的使用。 从Qt 5.0开始提供了对Json的支持,我们可以直接使用Qt提供的Json类进行数据的组织和解析。相关的类常用的主要有四个,具体如下: Json类介绍 QJsonDocument |…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
