首页
归档
留言
广告合作
友链
美女主播
Search
1
博瑞GE车机升级/降级
5,173 阅读
2
修改elementUI中el-table树形结构图标
4,540 阅读
3
Mac打印机设置黑白打印
4,535 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,372 阅读
5
intelliJ Idea 2022.2.X破解
4,092 阅读
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Spring Cloud
Mac
mybatis
WordPress
Nacos
Spring Cloud Alibaba
Mybatis-Plus
jQuery
Java Script
asp.net
微信小程序
Sentinel
UniApp
MySQL
asp.net core
IntelliJ IDEA
Jpa
树莓派
Laughing
累计撰写
576
篇文章
累计收到
1,425
条评论
首页
栏目
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
广告合作
友链
美女主播
搜索到
3
篇与
的结果
2022-11-14
微信小程序获取用户头像后上传到七牛云
一、事情起因【油耗笔记OilNote】小程序好久没有升级了,最近打算对代码进行一些优化,但是新版本突然发现无法获取到用户微信头像及微信昵称了。查阅官方文档才知道,官方有对getUserProfile接口进行调整了。自 2022 年 10 月 25 日 24 时后(以下统称 “生效期” ),用户头像昵称获取规则将进行如下调整:自生效期起,小程序 wx.getUserProfile 接口将被收回:生效期后发布的小程序新版本,通过 wx.getUserProfile 接口获取用户头像将统一返回默认灰色头像,昵称将统一返回 “微信用户”。生效期前发布的小程序版本不受影响,但如果要进行版本更新则需要进行适配。自生效期起,插件通过 wx.getUserInfo 接口获取用户昵称头像将被收回:生效期后发布的插件新版本,通过 wx.getUserInfo 接口获取用户头像将统一返回默认灰色头像,昵称将统一返回 “微信用户”。生效期前发布的插件版本不受影响,但如果要进行版本更新则需要进行适配。通过 wx.login 与 wx.getUserInfo 接口获取 openId、unionId 能力不受影响。「头像昵称填写能力」支持获取用户头像昵称:如业务需获取用户头像昵称,可以使用「头像昵称填写能力」(基础库 2.21.2 版本开始支持,覆盖iOS与安卓微信 8.0.16 以上版本),具体实践可见下方《最佳实践》。小程序 wx.getUserProfile 与插件 wx.getUserInfo 接口兼容基础库 2.27.1 以下版本的头像昵称获取需求:对于来自低版本的基础库与微信客户端的访问,小程序通过 wx.getUserProfile 接口将正常返回用户头像昵称,插件通过 wx.getUserInfo 接口将正常返回用户头像昵称,开发者可继续使用以上能力做向下兼容。现在只要是发布的新版本,默认都需要调整,不然就显示下面灰色头像,已经发布的版本不受影响。既然官方调整了,那么我们也只有被动接受的份。二、油耗笔记的开发框架油耗笔记OilNote不是直接使用微信开发者工具开发的,而是使用UniApp开发的,后端是SpringBoot。三、改进思路3.1、获取用户头像由于官方指导意见是,使用button组件 open-type 的值设置为 chooseAvatar,当用户选择需要使用的头像之后,可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径。从官方的指导我们可以看到,微信并没有给我们返回一个具体的路径,只是返回了一个临时的路径,因此我们就必须自己获取到这个临时的文件,然后存储起来。3.2、使用七牛云由于使用的腾讯云的低配服务器,带宽、存储都比较捉襟见肘,所以我打算把头像都存储到七牛云上,既能减轻带宽压力也能节省服务器空间。四、具体改进4.1、UniApp页面改进当用户通过微信登录时,此时获取用户头像信息,如果头像存在,登录之后跳转到首页,否则跳转到个人信息界面,让用户维护头像及昵称,此方法适用于新用户,同时也适用于老用户重新登录。//微信授权登录 getUserInfo(e) { let that = this; var p = this.getSetting(); p.then(function(isAuth) { console.log('是否已经授权', isAuth); if (isAuth) { console.log('用户信息,加密数据', e); //eData 包括//微信头像//微信名称 还有加密的数据. // let eData = JSON.parse(e.detail.rawData); uni.getUserProfile({ desc: 'Wexin', // 这个参数是必须的 success: function(infoRes) { //接下来就是访问接口. that.$request( 'wechat/authCode2Session?code=' + that.weChatCode, 'POST' ).then(function(res) { if (res.code == 200) { //将接口返回的数据保存在全局变量中. let userInfo = {} // 用户id userInfo.id = res.data.id userInfo.username = res.data.username userInfo.tel = res.data.tel userInfo.email = res.data.email userInfo.wechatOpenId = res.data.wechatOpenId userInfo.nickName = res.data.nickName userInfo.avatarUrl = res.data.avatarUrl ? res.data .avatarUrl : infoRes.userInfo.avatarUrl userInfo.gender = infoRes.userInfo.gender userInfo.password = '' if (!userInfo.province) { userInfo.province = uni.getStorageSync('province') } if (!userInfo.city) { userInfo.city = uni.getStorageSync('city') } uni.setStorageSync('userInfo', userInfo); if (!res.data.avatarUrl) { //没有头像时,跳转到用户信息维护界面 uni.redirectTo({ url: '/pages/profile/profile' }) } else { uni.redirectTo({ url: '/pages/index/index' }) } } }, function(err) { uni.showToast({ title: '授权登录失败!', mask: true, icon: 'none' }) } ) } }); } else { uni.showToast({ title: '授权失败,请确认授权已开启', mask: true, icon: 'none' }) } }); },4.1.1、登录界面改造4.1.2、个人信息界面改造油耗笔记之前有一个【个人信息】页面,因此我打算把修改头像的功能发放到里面。在合适的位置放入选择头像的按钮<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> <view class="cu-avatar xl round margin-center" :style="{backgroundImage:'url('+userInfo.avatarUrl+')'}"></view> </button>增加回调方法用户选择微信头像之后,会回调chooseavatar方法,因此我们增加一个chooseavatar用于用户选择头像之后上传到服务器(进一步上传到七牛)//选择头像回调 onChooseAvatar(e) { const that = this; this.$set(this.userInfo, "avatarUrl", e.detail.avatarUrl); uni.uploadFile({ url: operate.api + 'user/uploadAvatar/', //上传接口 header: { token: that.userInfo.id ? that.userInfo.id : '', }, formData: { 'userInfo': JSON.stringify(that.userInfo) }, filePath: e.detail.avatarUrl, name: 'file', success: (uploadFileRes) => { uni.hideLoading(); const back = JSON.parse(uploadFileRes.data); if (back.code == 200) { that.$set(that.userInfo, 'avatarUrl', back.data.avatarUrl) } else { uni.showToast(back.msg) } }, fail: (error) => { uni.hideLoading(); uni.showToast("图片上传失败,请联系开发!") }, complete: function() { uni.hideLoading(); } }); }4.2、后端改造我们首先在后端增加一个方法,用于接受前端传递的附件及其他参数(我这里主要传递的是用户信息,用户更新用户表,记录头像地址)。4.2.1、Controller增加接受用户上传头像的Api,具体的实现我们稍后在说。/** * 上传头像 * * @param multipartFile 文件信息 * @return 用户信息 */ @PostMapping("uploadAvatar") public AjaxResult uploadAvatar(@RequestParam("file") MultipartFile multipartFile,@RequestParam("userInfo") String oilUser) { return AjaxResult.success(oilUserService.uploadAvatar(multipartFile)); }4.2.2、增加七牛云依赖经过上面改造,我们已经可以将用户头像上传到我们的后端了,接下来的任务就是将头像上传到我们的七牛云了。现在pom.xml中增加七牛云的依赖<!-- 七牛云--> <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>7.2.28</version> </dependency>4.2.3、增加七牛云配置为了方便使用,我们将七牛云的一些配置信息放入yaml文件中,方便维护。# ========================== ↓↓↓↓↓↓ 七牛云配置 ↓↓↓↓↓↓ ========================== qiniu: accessKey: XXX # Key secretKey: XXX # 密钥 bucket: XXX # 空间名称 domain: XXX # 访问域名 dir: XXX/ # 目录参数说明:accessKey:AK,在七牛云,个人中心,密钥管理中可以看到secretKey:SK,在七牛云,个人中心,密钥管理中可以看到bucket:空间名称,根据自己创建的空间填写domain:访问域名,根据控件绑定的域名实际填写dir:存储路径,因为七牛云默认是直接存储到根目录,为了方便管理,我们可以创建子目录,比如avatar,可以填写avatar/4.2.4、增加配置类为了方便使用,我们将yaml的值,映射到配置类上。/** * 七牛云实体 */ @Component @ConfigurationProperties(prefix = "qiniu") public class QiNiuConfig { /** * Key */ private static String accessKey; /** * 密钥 */ private static String secretKey; /** * 空间名称 */ private static String bucket; /** * 访问域名 */ private static String domain; /** * 目录 */ private static String dir; public static String getAccessKey() { return accessKey; } public void setAccessKey(String accessKey) { QiNiuConfig.accessKey = accessKey; } public static String getSecretKey() { return secretKey; } public void setSecretKey(String secretKey) { QiNiuConfig.secretKey = secretKey; } public static String getBucket() { return bucket; } public void setBucket(String bucket) { QiNiuConfig.bucket = bucket; } public static String getDomain() { return domain; } public void setDomain(String domain) { QiNiuConfig.domain = domain; } public static String getDir() { return dir; } public void setDir(String dir) { QiNiuConfig.dir = dir; } } 4.2.5、封装公共方法为了方便调用,我们将上传、删除等方法封装到单独的服务中。接口/** * 七牛接口 */ public interface IQiNiuService { /** * 以文件的形式上传 * * @param file * @param fileName: * @return: java.lang.String */ String uploadFile(File file, String fileName) throws QiniuException; /** * 以流的形式上传 * * @param inputStream * @param fileName: * @return: java.lang.String */ String uploadFile(InputStream inputStream, String fileName) throws QiniuException; /** * 删除文件 * * @param key: * @return: java.lang.String */ String delete(String key) throws QiniuException; } 实现@Service public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { // 七牛文件上传管理器 private final Configuration cfg; private final Auth auth; public QiNiuServiceImpl() { // //构造一个带指定 Region 对象的配置类 cfg = new Configuration(Region.huadong()); auth = Auth.create(QiNiuConfig.getAccessKey(), QiNiuConfig.getSecretKey()); } /** * 定义七牛云上传的相关策略 */ private StringMap putPolicy; @Override public String uploadFile(File file, String fileName) throws QiniuException { if (!StringUtils.isEmpty(QiNiuConfig.getDir())) { fileName = QiNiuConfig.getDir() + fileName; } UploadManager uploadManager = new UploadManager(cfg); Response response = uploadManager.put(file, fileName, getUploadToken()); int retry = 0; while (response.needRetry() && retry < 3) { response = uploadManager.put(file, fileName, getUploadToken()); retry++; } if (response.statusCode == 200) { return "http://" + QiNiuConfig.getDomain() + "/" + fileName; } return "上传失败!"; } @Override public String uploadFile(InputStream inputStream, String fileName) throws QiniuException { if (!StringUtils.isEmpty(QiNiuConfig.getDir())) { fileName = QiNiuConfig.getDir() + fileName; } UploadManager uploadManager = new UploadManager(cfg); Response response = uploadManager.put(inputStream, fileName, getUploadToken(), null, null); int retry = 0; while (response.needRetry() && retry < 3) { response = uploadManager.put(inputStream, fileName, getUploadToken(), null, null); retry++; } if (response.statusCode == 200) { return "http://" + QiNiuConfig.getDomain() + "/" + fileName; } return "上传失败!"; } @Override public String delete(String key) throws QiniuException { BucketManager bucketManager = new BucketManager(auth, cfg); Response response = bucketManager.delete(QiNiuConfig.getBucket(), key); int retry = 0; while (response.needRetry() && retry++ < 3) { response = bucketManager.delete(QiNiuConfig.getBucket(), key); } return response.statusCode == 200 ? "删除成功!" : "删除失败!"; } @Override public void afterPropertiesSet() throws Exception { this.putPolicy = new StringMap(); putPolicy.put("insertOnly", 0); } /** * 获取上传凭证 */ private String getUploadToken() { return this.auth.uploadToken(QiNiuConfig.getBucket(), null, 3600, putPolicy); } } 有几个需要注意的点:在构造函数中,构造Configuration时,需要指定区域,因为我是华东区域的,因此使用的是Region.huadong(),如果使用的其他区域的,需要根据自己实际区域指定。在指定策略时,因为我一个用户只允许一个头像,因此上传时,如果存在我们直接覆盖的,所以在afterPropertiesSet方法中,设置上传策略时,直接指定的putPolicy.put("insertOnly", 0);,即如果存在就覆盖,如果不想覆盖,可以设置putPolicy.put("insertOnly", 1);,但是此时需要注意,如果上传重名文件,会返回异常。4.2.6、完善后用户上传头像方法用户上传头像后,更新用户实体(但是此时不更新数据库),将更新后的实体返回到前端,点击保存时,再更新数据库。 @Override public OilUser uploadAvatar(MultipartFile multipartFile, OilUser oilUser) throws IOException { String originalFilename = multipartFile.getOriginalFilename(); if (originalFilename == null || !originalFilename.contains(".")) { throw new CustomException("文件名不正确"); } String fileName = "avatar" + oilUser.getId() + originalFilename.substring(originalFilename.lastIndexOf(".")); String avatarUrl = qiNiuService.uploadFile(multipartFile.getInputStream(), fileName); oilUser.setAvatarUrl(avatarUrl); // LambdaUpdateWrapper<OilUser> userUpdateWrapper = new LambdaUpdateWrapper<>(); // userUpdateWrapper.set(OilUser::getAvatarUrl, oilUser.getAvatarUrl()); // userUpdateWrapper.eq(OilUser::getId, oilUser.getId()); // oilUserMapper.update(null, userUpdateWrapper); return oilUser; }4.2.7、用户保存方法分改造用户保存方法主要增加userUpdateWrapper.set(OilUser::getAvatarUrl, user.getAvatarUrl());,当用户有头像时,同步更新用户的头像信息。/** * 新增或保存用户 * * @param user 用户 * @return 结果 */ public OilUser saveUser(OilUser user) { if (user == null) { throw new CustomException("用户信息不能为空"); } if (user.getId() == null) { user.setId(""); } if (checkUserNameExist(user)) { throw new CustomException("用户名已存在"); } if (StringUtils.isEmpty(user.getId())) { user.setId(UUID.randomUUID().toString()); if (!StringUtils.isEmpty(user.getPassword())) { user.setPassword(passwordEncoder.encode(user.getPassword())); } oilUserMapper.insert(user); } else { LambdaUpdateWrapper<OilUser> userUpdateWrapper = new LambdaUpdateWrapper<>(); userUpdateWrapper.set(OilUser::getUsername, user.getUsername()); userUpdateWrapper.set(OilUser::getNickName, user.getNickName()); userUpdateWrapper.set(OilUser::getTel, user.getTel()); userUpdateWrapper.set(OilUser::getEmail, user.getEmail()); if (!StringUtils.isEmpty(user.getPassword())) { userUpdateWrapper.set(OilUser::getPassword, passwordEncoder.encode(user.getPassword())); } if (!StringUtils.isEmpty(user.getProvince())) { userUpdateWrapper.set(OilUser::getProvince, user.getProvince()); } if (!StringUtils.isEmpty(user.getCity())) { userUpdateWrapper.set(OilUser::getCity, user.getCity()); } if (!StringUtils.isEmpty(user.getAvatarUrl())) { userUpdateWrapper.set(OilUser::getAvatarUrl, user.getAvatarUrl()); } userUpdateWrapper.eq(OilUser::getId, user.getId()); oilUserMapper.update(null, userUpdateWrapper); user.setPassword(""); } return user; }五、效果微信用户登录后,如果没有上传过头像,会自动跳转到【个人信息】页面在个人信息上传头像后,自动跳转到首页。六、其他注意事项七牛云域名需要配置HTTPS小程序域名白名单uploadFile合法域名需要配置后台上传附件的域名。
2022年11月14日
1,997 阅读
0 评论
3 点赞
2022-11-07
Mac Typora配置七牛图床
最近安装了黑苹果,原来写博客一直是使用的typecho的七牛插件把七牛作为图床,奈何typecho的编辑器实在太难用了,所以还是决定使用typora作为写作工具,配合七牛作为图床,写完之后直接粘贴到博客上。在Mac上Typora使用七牛作为图床时,需要借助PicGo,剩下的配置都是图形化的,比较简单了。一、安装PicGoPicGo下载地址:Releases · Molunerfinn/PicGo (github.com)上面是GitHub的地址,如果被墙了,可以腾讯云COS下载地址,不同版本如下PicGo-2.3.1-beta.8-arm64.dmgPicGo-2.3.1-beta.8-x64.dmgPicGo-2.3.1-beta.8.AppImagePicGo-Setup-2.3.1-beta.8-ia32.exePicGo-Setup-2.3.1-beta.8-x64.exePicGo-Setup-2.3.1-beta.8.exepicgo_2.3.1-beta.8_amd64.snap下载完成后正常安装并打开即可,没有什么特别需要说明的。二、配置PicGo打开PicGo,左侧找到图床设置,找到七牛图床可以看到主要需要的信息包括:AccessKey、SecreKey、存储空间名、访问网址、存储区域这些都是必填的,网址后缀、存储路径是选填的。OK,看到这些信息之后,我们去七牛网站查找需要的信息。打开七牛云并登录七牛云 - 对象存储 - 空间管理 (qiniu.com),然后打开个人中心,找到密钥管理,这里面有我们需要的AccessKey、SecreKey如果没有,我们可以点击右下角的【创建密钥】来创建我们的密钥。然后找到对象存储Kodo,找到空间管理,查看我们的空间当然,如果没有,可以点击【新建空间】创建一个我们的空间,需要注意的是,绑定域名时,域名必须是已备案的域名。点击我们的空间名称,进入详情页面可以看到我们的域名。也就是访问网址以及存储区域。需要注意的是,存储区域不能是汉字的,必须是区域ID。具体存储区域可以看文末说明,比如我是华南-广东,存储区域ID就是Z2支持,其实所有的必填项我们都已经找到了,因为我个人博客都是放到空间的具体位置了,所以我就要配置最后一项存储路径我们切换上面的页签到【文件管理】因为我个人博客的都是放到/blog/typecho/下面的,所以我的路径配置的就是/blog/typecho/将以上内容全部复制到PicGo后,点击确认并设置默认图床。如果没有设置默认,也可以右键点击Mac工具栏的PicGo图标,选择默认图床三、设置Typora打开Typora偏好设置,切换到图像进行如下设置【插入图片时...】选择上传图片勾选【对本地位置的图片应用上诉规则】网络图片如果也上传,可以勾选【对网络位置的图片应用上述规则】上传服务选择【PicGo.app】设置完成后,点击【验证图片上传选项】,如果出现下面的图片,代表设置的没问题,此时可以直接在Typora复制粘贴图片或文件了,Trpora会自动将图片上传到七牛并将文件路径替换成七牛云的路径。如果开启了PicGo通知,Mac右上角也会有提示信息图片上传后,可以在PicGo的xia相册页签,查看所有上传过的图片。附七牛储存区域ID说明存储区域 Region区域 Region ID域名华东-浙江z0空间管理:http(s)://uc.qbox.me 加速上传 :http(s)://upload.qiniup.com 源站上传:http(s)://up.qiniup.com 源站下载:http(s)://iovip.qbox.me 对象管理:http(s)://rs-z0.qiniuapi.com 对象列举:http(s)://rsf-z0.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com华东-浙江2cn-east-2空间管理:http(s)://uc.qbox.me 加速上传:http(s)://upload-cn-east-2.qiniup.com 源站上传:http(s)://up-cn-east-2.qiniup.com 源站下载:http(s)://iovip-cn-east-2.qiniuio.com 对象管理:http(s)://rs-cn-east-2.qiniuapi.com 对象列举:http(s)://rsf-cn-east-2.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com华北-河北z1空间管理:http(s)://uc.qbox.me 加速上传:http(s)://upload-z1.qiniup.com 源站上传:http(s)://up-z1.qiniup.com 源站下载:http(s)://iovip-z1.qbox.me 对象管理:http(s)://rs-z1.qiniuapi.com 对象列举:http(s)://rsf-z1.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com华南-广东z2空间管理:http(s)://uc.qbox.me 加速上传:http(s)://upload-z2.qiniup.com 源站上传:http(s)://up-z2.qiniup.com 源站下载:http(s)://iovip-z2.qbox.me 对象管理:http(s)://rs-z2.qiniuapi.com 对象列举:http(s)://rsf-z2.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com北美-洛杉矶na0空间管理:http(s)://uc.qbox.me 加速上传 :http(s)://upload-na0.qiniup.com 源站上传:http(s)://up-na0.qiniup.com 源站下载:http(s)://iovip-na0.qbox.me 对象管理:http(s)://rs-na0.qiniuapi.com 对象列举:http(s)://rsf-na0.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com亚太-新加坡(原东南亚)as0空间管理:http(s)://uc.qbox.me 加速上传:http(s)://upload-as0.qiniup.com 源站上传:http(s)://up-as0.qiniup.com 源站下载:http(s)://iovip-as0.qbox.me 对象管理:http(s)://rs-as0.qiniuapi.com 对象列举:http(s)://rsf-as0.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com亚太-首尔ap-northeast-1空间管理:http(s)://uc.qbox.me 加速上传:http(s)://upload-ap-northeast-1.qiniup.com 源站上传:http(s)://up-ap-northeast-1.qiniup.com 源站下载:http(s)://iovip-ap-northeast-1.qiniuio.com 对象管理:http(s)://rs-ap-northeast-1.qiniuapi.com 对象列举:http(s)://rsf-ap-northeast-1.qiniuapi.com 计量查询:http(s)://api.qiniuapi.com
2022年11月07日
1,239 阅读
0 评论
0 点赞
2017-10-24
常见CDN比较
什么是CDNCDN的全称是Content Delivery Network,即内容分发网络。其基本原理就是把网站内容放到不同的网络节点,在进行网络访问时,可以通过最近的节点访问内容,加快网络速度。更直白点讲,有点像淘宝跟京东,京东的都是各地都有仓库,所以送货比较快。常见的CDN百度云加速每天50G流量,应该是流量最多得了节点6~12个不支持https又拍云CDN需要在自己网站首页挂在又拍云的连接每年给67元的代金券,按实际金额扣费支持https七牛云七牛的CDN我没有使用过,不太好做太多介绍每月10G流量免费,亚太流量不支持https腾讯云CDN所有 CDN 用户每月均可享受 10GB 免费流量包,新开通 CDN 的用户还会在开通后的 6 个月内每月收到腾讯云赠送的 50GB 流量包比较适合静态资源的网站个人配置比较繁琐阿里云CDN收费的收费的收费的配置不是特别灵活最近有活动,但是如果是https还是需要单独收费的,不在套餐内,比较坑
2017年10月24日
1,893 阅读
2 评论
1 点赞