微信小程序: 获取accessToken,手机号, 小程序二维码,openId与unionId 公共配置类(核心篇)

全文目录,一步到位

  • 1.前言简介
    • 1.1 专栏传送门
  • 2. 微信小程序公用功能
    • 2.1 配置准备工作
      • 2.1.1 配置文件准备(单体放`yml`中 微服务放`配置中心`)
      • 2.1.2 获取配置文件中的小程序配置
      • 2.1.3 设置redis配置
    • 2.2 创建不同功能工具类
      • 2.2.1 创建微信服务工具类`WechatServiceUtils`
      • 2.2.2 创建RedisCache
    • 2.3 各个功能传送门
      • 2.3.1 获取accessToken
      • 2.3.2 获取手机号
      • 2.3.3 获取小程序二维码(不限制)
      • 2.3.4 获取openId与unionId
  • 3. 文章的总结
    • 3.1 本文总结
    • 3.2 本文统一说明


1.前言简介

本文是微信小程序公共类 以下功能均使用 此文章 代码

  • 获取accessToken
  • 手机号
  • 小程序二维码
  • openId与UnionId

最下面有传送门, 传送到每个功能 避免多次封装
远程调用均使用restTemplate (springboot自带, 操作简单)
使用其他请随意…

1.1 专栏传送门

===> 微信小程序相关操作专栏 <===

2. 微信小程序公用功能

2.1 配置准备工作

2.1.1 配置文件准备(单体放yml中 微服务放配置中心)

(特别注意 这里面包含大部分微信小程序配置)
appidsecret 填写上
ps: 里面部分配置可以删除

  • 过期时间
  • 启动执行
  • 登录url
  • 其他业务 如获取手机号, 获取小程序二维码等
# 微信核心参数
wechat:# 小程序mini-app:# 请求urlrequestUrl: /wxMiniLogin# 请求方法requestMethod: POST# appidappId: ?# app秘钥appSecret: ?# 微信基础请求网址wxBaseRequestUrl: https://api.weixin.qq.com# 获取access_token必备参数grantType: client_credential# 微信获取access_token的urlaTokenUrl: ${wechat.mini-app.wxBaseRequestUrl}/cgi-bin/token?grant_type=${wechat.mini-app.grantType}&appid=%s&secret=%s# 要分钟(尽量少于120分钟) 一天上限2000次 这里一天最多请求24次 可增加定时刷新缓存等expiredTime: 70# 是否执行服务启动执行serverStartAutoRun: false# 微信登录提供的接口(GET)wxLoginUrlTemplate: ${wechat.mini-app.wxBaseRequestUrl}/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code# 微信获取手机号接口wxGetPhoneUrl: ${wechat.mini-app.wxBaseRequestUrl}/wxa/business/getuserphonenumber?access_token=%s#微信获取二维码(不限制)post请求wxACodeUnLimitUrl: ${wechat.mini-app.wxBaseRequestUrl}/wxa/getwxacodeunlimit?access_token=%s#微信获取二维码(限制)post请求wxACodeUrl: ${wechat.mini-app.wxBaseRequestUrl}/wxa/getwxacode?access_token=%s# 微信获取二维码(限制)post请求wxAQrcodeUrl: ${wechat.mini-app.wxBaseRequestUrl}/cgi-bin/wxaapp/createwxaqrcode?access_token=%s

2.1.2 获取配置文件中的小程序配置

使用@ConfigurationProperties注解对应

  • 具体介绍我没有写: 找了一篇写的比较全的链接
  • => 传送门: @ConfigurationProperties使用方式
  • 当然 可以使用@Value替换上面这种(二选一)

代码如下, 名字对应配置文件名称, 注释自己加一下吧

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 小程序获取配置类** @author pzy* @version 0.1.0* @description TODO*/
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "wechat.mini-app")
public class WechatConfigProperties {private String requestUrl;private String requestMethod;private String appId;private String appSecret;private String wxBaseRequestUrl;private String grantType;private String aTokenUrl;private Integer expiredTime;private Boolean serverStartAutoRun;private String wxLoginUrlTemplate;/*** 获取手机号*/private String wxGetPhoneUrl;/*** 二维码无限制url(主)*/private String wxACodeUnLimitUrl;private String wxACodeUrl;private String wxAQrcodeUrl;/*** 生成微信登录请求地址** @param code code* @return 请求地址*/public String getWxLoginUrl(String code) {return String.format(wxLoginUrlTemplate, appId, appSecret, code);}/*** 生成微信ACCESS_TOKEN请求地址* <p>* 模板样式: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s** @return 请求地址*/public String getATokenUrl() {return String.format(aTokenUrl, appId, appSecret);}/*** 获取手机号url post请求** @param accessToken* @return*/public String getPhoneUrl(String accessToken) {return String.format(wxGetPhoneUrl, accessToken);}/*** 获取不限制的微信二维码url** @param accessToken* @return*/public String getWxACodeUnLimitUrl(String accessToken) {return String.format(wxACodeUnLimitUrl, accessToken);}/*** 获取(限制一)的微信二维码url** @param accessToken* @return*/public String getWxACodeUrl(String accessToken) {return String.format(wxACodeUrl, accessToken);}/*** 获取(限制二)的微信二维码url** @param accessToken* @return*/public String getWxAQrcodeUrl(String accessToken) {return String.format(wxAQrcodeUrl, accessToken);}
}

2.1.3 设置redis配置

spring: redis:# 地址host: 192.168.1.130# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password: 123456# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 5# 连接池中的最大空闲连接max-idle: 10# 连接池的最大数据库连接数max-active: 50# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: 5000ms

2.2 创建不同功能工具类

2.2.1 创建微信服务工具类WechatServiceUtils

RestTemplate 直接可以使用
WechatConfigProperties 请见 2.1.2
RedisCache 请见2.2.2

/*** 微信服务工具类** @author pzy* @version 0.1.0* @description: TODO*/
@Slf4j
@RequiredArgsConstructor
@Component
public class WechatServiceUtils {/*** 远程调用*/private final RestTemplate restTemplate;/*** redis缓存*/private final RedisCache redisCache;/*** 微信统一配置*/private final WechatConfigProperties wechatConfigProperties;/*** 1. 获取微信登录认证信息** @param wxCommonReqDto* @return*/public Map<String, String> getWxMiniAuth(WxCommonReqDto wxCommonReqDto) {String code = wxCommonReqDto.getWxCode();//秘钥String encryptedIv = wxCommonReqDto.getIv();//加密数据String encryptedData = wxCommonReqDto.getEncryptedData();JSONObject wxAuthResponse = null;String sessionKey = "";String openid = "";try {//1. 想微信服务器发送请求获取用户信息String url = wechatConfigProperties.getWxLoginUrl(code);log.info("===> 请求微信url是: {}", url);//2. 远程调用微信接口String res = restTemplate.getForObject(url, String.class);wxAuthResponse = JSONObject.parseObject(res);//3. 解析返回参数 报错则进行对应处理/*校验1: wx请求不是null*/if (wxAuthResponse != null) {/*校验2: 响应对象是否正确*/CheckUtils.responseCheck(wxAuthResponse);//3.1 获取session_key和openidsessionKey = wxAuthResponse.getString("session_key");openid = wxAuthResponse.getString("openid");log.info("===> openid:  {}", openid);/*校验3: 响应信息是否正常*/if (StringUtils.isBlank(sessionKey) || StringUtils.isBlank(openid)) {log.error("小程序授权失败,session_key或open_id是空!");throw new ServiceException("抱歉, 小程序授权失败,缺少关键返回参数!");}log.info("===> 微信回调信息: {}", wxAuthResponse);}} catch (Exception e) {e.printStackTrace();throw new ServiceException("抱歉, 小程序授权失败!");}//4. 获取微信信息并制作token/*校验:(选用)如果获取union_id 需要进行解密*/Map<String, String> map = new HashMap<>();String token = "";if (StringUtils.isNotBlank(encryptedIv) && StringUtils.isNotBlank(encryptedData)) {String decryptResult = "";try {//如果没有绑定微信开放平台,解析结果是没有unionid的。decryptResult = AESUtils.decrypt(sessionKey, encryptedIv, encryptedData);if (StringUtils.hasText(decryptResult)) {//如果解析成功,获取tokenmap.put("type", String.valueOf(1));map.put("decryptResult", decryptResult);}} catch (Exception e) {e.printStackTrace();throw new ServiceException("微信登录失败!");}} else {//如果前端只传wxCode 没有unionId的需求 只要openId的map.put("type", String.valueOf(2));map.put("decryptResult", openid);}/*校验: 数据为空的情况*/if (StringUtils.isBlank(map.get("type")) || StringUtils.isBlank(map.get("decryptResult"))) {throw new ServiceException(ResponseEnum.A10007);}return map;}/*** 2. 获取缓存中的AccessToken* <p>* 没有从微信拉取[可配合定时]** @return accessToken*/public String getRedisCacheAccessToken() {/*校验: 缓存中有accessToken的key*/if (redisCache.hasKey(CacheConstants.WX_ACCESS_TOKEN)) {log.info("二级缓存数据取出accessToken成功!");return redisCache.getCacheObject(CacheConstants.WX_ACCESS_TOKEN);}//这里不用三目(不好看~~)return getWxMiniAccessToken();}/*** 3. 访问微信官方获取两小时的 accessToken** @return accessToken*/public String getWxMiniAccessToken() {Map<String, String> query = new HashMap<>();query.put("grant_type", wechatConfigProperties.getGrantType());//client_credentialquery.put("secret", wechatConfigProperties.getAppSecret());query.put("appid", wechatConfigProperties.getAppId());try {String aTokenUrl = wechatConfigProperties.getATokenUrl();
//            ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(aTokenUrl, query, JSONObject.class);ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(aTokenUrl, JSONObject.class, query);HttpStatus statusCode = responseEntity.getStatusCode(); //状态码//            System.out.println(responseEntity.getHeaders());//获取到头信息/*校验: 如果接口成功 200*/if (Objects.equals(statusCode.value(), 200)) {JSONObject responseJsonBody = responseEntity.getBody();//响应体log.info("[请求微信小程序官方接口] => 获取accessToken请求成功返回值:{}", responseJsonBody);if (responseJsonBody == null) {log.info("微信小程序获取accessToken请求返回result是null!");throw new ServiceException(ResponseEnum.A10005);}//获取accessTokenString accessToken = responseJsonBody.getString("access_token");if (StringUtils.isBlank(accessToken)) {log.info("微信小程序获取accessToken请求返回access_token是null!");throw new ServiceException(ResponseEnum.A10005);}//放入缓存中redisCache.setCacheObject(CacheConstants.WX_ACCESS_TOKEN, accessToken, wechatConfigProperties.getExpiredTime(), TimeUnit.MINUTES);return accessToken;} else {log.error("微信HttpStatus的StatusCode不是200 {}", statusCode.value());throw new ServiceException(ResponseEnum.A10005);}} catch (Exception e) {e.printStackTrace();log.info("微信小程序获取accessToken请求异常信息 {}", e.getMessage());throw new ServiceException(ResponseEnum.A10005);}}/*** 错误码	错误描述	解决方案* -1	    system error	                                [系统繁忙,此时请开发者稍候再试]* 40029	code 无效	                                    [js_code无效]* 45011	api minute-quota reach limit mustslower retry   [next minute API 调用太频繁,请稍候再试]* 40013	invalid appid	                                [请求appid身份与获取code的小程序appid不匹配]* 错误码** @param code js_code* @return phone*/public String getPhoneByCode(String code) {String phoneUrl = wechatConfigProperties.getPhoneUrl(getRedisCacheAccessToken());Map<String, Object> map = new HashMap<>();map.put("code", code);JSONObject jsonObject = sendPostRestTemplate(phoneUrl, map, JSONObject.class);System.out.println(jsonObject);if (jsonObject.containsKey("errcode")) {/*如果异常码是0 说明正常*/if (!Objects.equals(String.valueOf(jsonObject.get("errcode")), "0")) {log.error("===> 获取手机号的异常信息 : {}", jsonObject + "");throw new ServiceException("获取失败: " + jsonObject.get("errmsg"), (Integer) jsonObject.get("errcode"));}}JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");return phoneInfo.getString("phoneNumber");}/*** 生成小程序带参数二维码* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html#HTTPS%20%E8%B0%83%E7%94%A8*/@SneakyThrowspublic InputStream getUnlimitedWxQrCode(WxCodeUnlimitedReqDTO wxCodeUnlimitedReqDTO, String accessToken) {Map<String, Object> params = new HashMap<>();params.put("scene", wxCodeUnlimitedReqDTO.getScene());params.put("page", wxCodeUnlimitedReqDTO.getPage());params.put("path", wxCodeUnlimitedReqDTO.getPage());params.put("env_version", wxCodeUnlimitedReqDTO.getEnvVersion());params.put("width", wxCodeUnlimitedReqDTO.getWidth());params.put("auto_color", wxCodeUnlimitedReqDTO.getAutoColor());//自动配置线条颜色ResponseEntity<byte[]> response = restTemplate.postForEntity(wechatConfigProperties.getWxACodeUnLimitUrl(accessToken), JSON.toJSONString(params), byte[].class);System.out.println(JSON.toJSONString(params));byte[] buffer = response.getBody();
//        System.out.println(Base64.getEncoder().encodeToString(buffer));assert buffer != null;return new ByteArrayInputStream(buffer);}/*** 远程调用 restTemplate方法 post请求** @param url* @param body* @return*/public <T> T sendPostRestTemplate(String url, Map<String, Object> body, Class<T> responseType) {return restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, null), responseType).getBody();}
}

2.2.2 创建RedisCache

redis的增删改查操作 记得配置序列化与反序列化
文章传送门: ===> redis高级(序列化与反序列化) <===

@Component
public class RedisCache {@Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key   缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value) {redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key      缓存的键值* @param value    缓存的值* @param timeout  时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key     Redis键* @param timeout 超时时间* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout) {return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key     Redis键* @param timeout 超时时间* @param unit    时间单位* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit) {return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));}/*** 获取有效时间** @param key Redis键* @return 有效时间*/public long getExpire(final String key) {if (StringUtils.isBlank(key)) {throw new IllegalArgumentException("key cannot be null");}return redisTemplate.getExpire(key);}/*** 判断 key是否存在** @param key 键* @return true 存在 false不存在*/public Boolean hasKey(String key) {return redisTemplate.hasKey(key);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key) {ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public boolean deleteObject(final String key) {return Boolean.TRUE.equals(redisTemplate.delete(key));}/*** 删除集合对象** @param collection 多个对象* @return*/public boolean deleteObject(final Collection collection) {return redisTemplate.delete(collection) > 0;}/*** 缓存List数据** @param key      缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList) {Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key) {return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key     缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);Iterator<T> it = dataSet.iterator();while (it.hasNext()) {setOperation.add(it.next());}return setOperation;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key) {return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key) {return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key   Redis键* @param hKey  Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value) {redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key  Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey) {HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();return opsForHash.get(key, hKey);}/*** 获取多个Hash中的数据** @param key   Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 删除Hash中的某条数据** @param key  Redis键* @param hKey Hash键* @return 是否成功*/public boolean deleteCacheMapValue(final String key, final String hKey) {return redisTemplate.opsForHash().delete(key, hKey) > 0;}/*** 获得缓存的基本对象列表(全部的key)** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(final String pattern) {return redisTemplate.keys(pattern);}
}

2.3 各个功能传送门

2.3.1 获取accessToken

在这里插入图片描述

官方文档地址: => 获取接口调用凭据 <=
文章传送门:

2.3.2 获取手机号

在这里插入图片描述

官方文档地址: => 获取手机号 <=
文章传送门:

2.3.3 获取小程序二维码(不限制)

在这里插入图片描述

官方文档地址: => 获取不限制的小程序码 <=
文章传送门:

2.3.4 获取openId与unionId

在这里插入图片描述

官方文档地址: => 小程序登录 <=
文章传送门:

3. 文章的总结

3.1 本文总结

本文使用的技术栈

  • springboot相关操作
  • restTemplate远程调用使用方式
  • redisTemplate 操作redis的操作
  • redis的序列化与反序列化

3.2 本文统一说明

本篇涵盖大部分的微信小程序操作(无支付), 统一封装
2.3 中统一传送到具体功能配置
避免多次配置, 传送门内的功能细节不在这篇介绍
特别注意: 文章传送门会在近期完善, 这是本专栏的第一篇, 之后也会围绕此篇进行更新, 接入支付等等



作者: pingzhuyan

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 基于 SpringBoot+Vue 的酒店管理系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

每日五道java面试题之java基础篇(十)

目录: 第一题 JVM有哪些垃圾回收器&#xff1f;第二题 垃圾回收分为哪些阶段&#xff1f;第三题 线程的⽣命周期&#xff1f;线程有⼏种状态&#xff1f;第四题.ThreadLocal的底层原理第五题.并发、并⾏、串⾏之间的区别 第一题 JVM有哪些垃圾回收器&#xff1f; ● 新⽣代收集…

RTDETR改进系列指南

基于Ultralytics的RT-DETR改进项目.(89.9) 为了感谢各位对RTDETR项目的支持,本项目的赠品是yolov5-PAGCP通道剪枝算法.具体使用教程 自带的一些文件说明 train.py 训练模型的脚本main_profile.py 输出模型和模型每一层的参数,计算量的脚本(rtdetr-l和rtdetr-x因为thop库的问…

YOLOv8制作自定义数据集并训练

YOLOv8制作自定义数据集并训练 前言一、制作自定义数据集1、建立相应文件夹2、下载图片3、为图片打标签&#xff08;1&#xff09;安装labelimg&#xff08;2&#xff09;打开labelimg&#xff08;3&#xff09;标记图片 二、按比例移动自定义数据集中的内容三、建立数据集测试…

考虑分库分表的时机与问题

考虑分库分表的时机与问题 什么时候考虑分库分表&#xff1f; 在以下情况下&#xff0c;考虑分库分表可能是一个不错的选择&#xff1a; 数据量大&#xff1a;单一数据库已经无法满足数据存储和查询的需求&#xff0c;数据量巨大导致性能下降。并发量高&#xff1a;单一数据…

vue3-生产部署-性能优化

生产部署 开发环境 vs. 生产环境 在开发过程中&#xff0c;Vue 提供了许多功能来提升开发体验&#xff1a; 对常见错误和隐患的警告 对组件 props / 自定义事件的校验 响应性调试钩子 开发工具集成 然而&#xff0c;这些功能在生产环境中并不会被使用&#xff0c;一些警…

2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品经营单位主要负责人证模拟考试题库是根据危险化学品经营单位主…

Unity3D 游戏开发中如何判断几何形状的位置关系详解

前言 在Unity3D游戏开发中&#xff0c;经常需要判断不同几何形状之间的位置关系&#xff0c;以便进行碰撞检测、物体运动和触发事件等操作。本文将详细介绍几种常见的几何形状位置关系判断方法&#xff0c;并给出相应的技术详解和代码实现。 对惹&#xff0c;这里有一个游戏开…

对链表使用插入排序的C语言实现示例

#include <stdio.h> #include <stdlib.h>// 定义链表节点结构体 struct ListNode {int val;struct ListNode *next; };// 插入排序函数 struct ListNode* insertionSortList(struct ListNode* head) {if (head NULL || head->next NULL) {return head;}struct…

【天衍系列 03】深入理解Flink的Watermark:实时流处理的时间概念与乱序处理

文章目录 01 基本概念02 工作原理03 优势与劣势04 核心组件05 Watermark 生成器 使用06 应用场景07 注意事项08 案例分析8.1 窗口统计数据不准8.2 水印是如何解决延迟与乱序问题&#xff1f;8.3 详细分析 09 项目实战demo9.1 pom依赖9.2 log4j2.properties配置9.3 Watermark水印…

机器学习入门--LSTM原理与实践

LSTM模型 长短期记忆网络&#xff08;Long Short-Term Memory&#xff0c;LSTM&#xff09;是一种常用的循环神经网络&#xff08;RNN&#xff09;变体&#xff0c;特别擅长处理长序列数据和捕捉长期依赖关系。本文将介绍LSTM模型的数学原理、代码实现和实验结果&#xff0c;并…

OpenCV库及在ROS中使用

OpenCV库及在ROS中使用 依赖 cv_bridge image_transport roscpp rospy sensor_msgs std_msgsCMakeLists.txt添加 find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries(pub_img_topic ${catkin_LIBRARIES} ${Opencv_LIBS}) C …

基于springboot大学生租房系统源码和论文

伴随着全球信息化发展&#xff0c;行行业业都与计算机技术相衔接&#xff0c;计算机技术普遍运用于各大行业&#xff0c;大学生租房系统便是其中一种。实施计算机系统来管理可以降低大学生租房管理的成本&#xff0c;使整个大学生租房的发展和服务水平有显著提升。 本论文主要面…

Github Copilot是什么?Ai高效编程!一键远程授权…

GitHub Copilot是一款Ai编程插件&#xff0c;由OpenAi和Github联合推出&#xff0c;目前支持主流的IDE编辑器安装使用&#xff0c;包括JetBrains IDEs、VSCode、Visual Studio、Neovim等。 官方地址&#xff1a;https://github.com/features/copilot 官方文档&#xff1a;http…

VBA即用型代码手册之取消隐藏工作表及删除工作表

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

基于Python的爬取天气数据及可视化分析

项目查看&#xff1a;基于Python的爬取天气数据及可视化分析 摘 要 天气数据视化系统是一种能自动从网络上收集水情信息分析的工具&#xff0c;可根据用户的需求定向采集特定天气数据信息来作可视化分析&#xff0c;自动在网络上获取网页源码。对于天气数据视化系统信息数量较…

【maya 入门笔记】基本视图和拓扑

1. 界面布局 先看基本窗口布局&#xff0c;基本窗口情况如下&#xff1a; 就基本窗口布局的情况来看&#xff0c;某种意义上跟blender更像一点&#xff08;与3ds max相比&#xff09;。 那么有朋友就说了&#xff0c;玛格基&#xff0c;那blender最下面的时间轴哪里去了&…

Shell:终端输入一个字符,判断是大写字母小写字母还是数字字符。

#!/bin/bash # 获取用户输入 read char case $char in [[:upper:]]) echo 大写 ;; [[:lower:]]) echo 小写 ;; [1-9]) echo 数字 ;; esac

使用PaddleNLP UIE模型提取上市公司PDF公告关键信息

项目地址&#xff1a;使用PaddleNLP UIE模型抽取PDF版上市公司公告 - 飞桨AI Studio星河社区 (baidu.com) 背景介绍 本项目将演示如何通过PDFPlumber库和PaddleNLP UIE模型&#xff0c;抽取公告中的相关信息。本次任务的PDF内容是破产清算的相关公告&#xff0c;目标是获取受理…

pubg开启之路

概要&#xff1a; pubg中文名绝地求生&#xff0c;一款免费游戏&#xff0c;本篇主要讲述如何在电脑上开始pubg 要想下载并开始玩pubg有两个方法(具体就是两个软件)&#xff0c;一个是epic games&#xff0c;另一个是steam 一、加速器是必要的吗&#xff1f; 1、不使用加速…