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

初探用uniapp写微信小程序遇到的问题及解决(vue3+ts)

零、关于开发思路

(一)拿到工作任务,先理清楚需求

1.逻辑部分

不放过原型里说的每一句话,有疑惑的部分该问产品/测试/之前的开发就问

2.页面部分(含国际化)

整体看过需要开发页面的原型后,分类一下哪些组件/样式可以复用,直接提取出来使用

(时间充分的前提下,不要一味先复制粘贴再提取;要先提取直接使用)

开发过程中就国际化,可以仅把中文国际化做了zh.json,英文的最后找ai直接翻译一下给到en.json文件,这样一定程度上节约了时间,并且准确率极高

(否则容易出错-如用cursor直接最后国际化页面里的文本,漏提取or直接中文文本改错,等等问题)

3.swagger接口部分

遇到无厘头但可能相关的接口,问后端!

比如下面这个,登陆的时候勾选同意xxx协议,登陆成功后就要调用这个“用户协议操作记录接口”给到后端,后端记录一下。

(二)理清需求后,调研哪些点可能有阻碍

比如微信小程序权限-系统级别、微信APP级别、微信小程序级别(弄清楚产品要求各情况怎么处理)

比如原后端上传图片接口是否适配微信小程序uploadFile()方式

这些地方都要弄清楚,避免走弯路,尽早将可能遇到的困难问题摆出来,找更有经验的开发or百度or官网寻找解决方案,跟pm明确技术风险,并合理安排时间

避免由于忽视,前期困难点未理清楚导致错误排期and前后端走弯路

一、关于oss图片上传

(一)上传图片本身接口限制

1.微信小程序上传前提

微信小程序本身不直接支持原生的 FormData 对象但可以通过以下几种方式实现类似 form-data 格式的文件上传功能(这里使用了第一种官方推荐的,其他两种没尝试)

2.具体场景分析

原接口1:APP司机注册

POST ​/xxx/driver-app​/v1​/users

表单和上传图片文件都在一起用一个接口(post、formData)上传,2个参数,单文件

这里虽然都是单张图片,但是要分别传人像照和国徽照,且非必传

而uni.uploadFile(obj)的obj中,filePath/files必填,不能为null或者“”

(这里我尝试了用一个固定的下载了线上图片得到的临时地址,可以实现,但并不推荐)

原接口2:APP端运单货物操作: 提货、确认到达

POST ​/xxx​/driver-app​/v1​/waybills​/{id}​/actions​/loadings

表单和上传图片文件都在一起用一个接口(post、formData)上传,2个参数,多文件数组

(这里swagger写的有问题,事实上是数组,且必填)

这里传的是俩file数组,更不能直接用这个接口了。

后端尝试两种解决:

第一种:oss直传(未采纳)

刚开始后端直接抄的鸿蒙app实现,结果差不多的问题,不支持

鸿蒙前端是用put传的文件,微信小程序不支持的

不支持file类型

事实上阿里云分别提供了各种设备的实践demo,各不相同,适配各种环境。

所以以后要注意不能直接鸿蒙抄到微信小程序,不一定适配的。

如何在微信小程序环境下将文件上传到OSS_对象存储(OSS)-阿里云帮助中心微信小程序可以将图片、文档、视频等文件上传到OSS,实现文件的云端存储和分发。https://help.aliyun.com/zh/oss/use-cases/wechat-applet-uploads-files-directly-to-oss?spm=a2c4g.11186623.help-menu-31815.d_6_1_2_0.2944285cQPObLQ&scm=20140722.H_92883._.OR_help-T_cn~zh-V_1

最终后端研究之后决定不采用直传->前端传文件给阿里云这种形式了(觉得比较麻烦),选择单拎文件上传接口慢慢上传->前端传文件给后端,后端传文件给阿里云

第二种:单独创建上传文件的接口+创建小程序司机注册、货物操作接口(采纳)

上传文件接口

POST ​/xxx​/driver-app​/v1​/media​/upload

注册、货物操作-小程序接口

小程序的传参file/file[]改成了传string/string[]

(二)ios微信小程序照片不显示(安卓正常显示)

1.原因

2.解决方案

看一下后端返回的图片地址是否是http开头的,是的话需要让后端配置一下改成https或者前端处理http->https

A 后端处理(问的ai,并没尝试)-后端适配会更合适

B 前端处理(需确保 Bucket 支持 HTTPS)-本次采纳

oss_url = "http://bucket.oss-cn-hangzhou.aliyuncs.com/image.jpg"
https_url = oss_url.replace("http://", "https://")

(三)微信小程序上传下载文件需配置域名白名单

记得在小程序后台开发管理页配置uploadFile和downloadFile用到的合法域名

二、关于权限

(一)相机和相册权限(仍可能在某些设备如红米等机型出现问题)

1.uniapp封装的组件-uni-file-picker(内置了微信app级别的权限判断) 

uni-app官网

实现的效果——微信app有权限即能正常使用,无权限的话内置提示

如下图(安卓ios显示不同问题不大,但是安卓红米K80的相机没有弹出首次提醒)

2.自己写微信级别、微信小程序级别的的权限

代码判断什么的自己写,跟定位权限差不多,参考下文。权限从定位改成相机、相册,不用管系统级别权限而已。

(二)定位权限

1.微信小程序权限

uni.authorize(OBJECT) | uni-app官网

 uni.openSetting(OBJECT) | uni-app官网

2.系统/微信应用权限

系统信息的概念 | uni-app官网

3.代码

流程图

a.先微信小程序级别权限
/** 1.定位* @param callback* @param isChange 是否转换坐标系* @param type 提示语使用哪个
*/
export const getPosition = (isChange: boolean = true) => {return new Promise((resolve) => {// 授权获取地理位置uni.authorize({scope: 'scope.userLocation',success() {getLocation((res: any) => {resolve(res);}, isChange)},// 小程序定位拒绝fail() {uni.showModal({title: i18n.global.t('locationPermissionTitle'),content: i18n.global.t('locationPermissionContent'),confirmText: i18n.global.t('allow'),cancelText: i18n.global.t('deny'),confirmColor: '#218BFE',cancelColor: '#999',success: res => {if (res.confirm) {uni.openSetting({success(res) {if (!res.authSetting['scope.userLocation']) {uni.showModal({content: i18n.global.t('locationNotEnabled'),showCancel: false,confirmText: i18n.global.t('iKnow'),confirmColor: '#1677FF',complete: () => {resolve(undefined);}})} else {resolve(undefined);}}});} else if (res.cancel) {// 不允许resolve(undefined);}},fail: () => {resolve(undefined);}});}});})
};
 b.再系统/微信级别权限+获取定位
/*** 2.获取定位*/
export const getLocation = (callback: Function, isChange: boolean = true) => {uni.getLocation({type: 'gcj02',isHighAccuracy: true,success: function (res) {let result: any = {};const {longitude, latitude} = res;if (isEmpty(longitude) || isEmpty(latitude)) {const messageError = i18n.global.t('getLocationFailed');uni.showToast({title: messageError,icon: 'none',duration: 2000,complete: () => {// 提示关闭后进行回调操作, 这里callback入参是undefinedsetTimeout(callback, 2000);}});} else {if (isChange) {result = qqMapTransBMap(longitude, latitude);} else {result = {longitude,latitude};}callback(result);}},// 一般是微信定位拒绝fail: (error) => {const { locationAuthorized } = uni.getSystemInfoSync();console.error('getLocation error', error);const tip = !locationAuthorized ? i18n.global.t('wechatLocationDenied') : i18n.global.t('getLocationFailedGeneral');uni.showToast({title: tip,icon: 'none',duration: 2000,complete: () => {// 提示关闭后进行回调操作setTimeout(callback, 2000);}});}});
}

三、微信小程序坐标系及地理逆编码调研

(一)坐标系及三方

微信小程序的getLocation可以两种坐标系,国际gps或者国标局gcj02(推荐国标局gcj02,wx.openLoction()要求用gcj02坐标系,且完美适配腾讯/高德地图sdk,百度地图也提供了官方转换方式)

自带没有api实现地理逆编码,要想实现的话需要使用三方sdk/api,比如腾讯/百度/高德地图

微信小程序JavaScript SDK | 腾讯位置服务

微信小程序JavaScript API | 百度地图API SDK

概述-微信小程序插件 | 高德地图API

(二)代码

腾讯gcj02百度互转

// 腾讯地图gcj02经纬度转百度地图
export function qqMapTransBMap(lng: number, lat: number) {let x_pi = 3.14159265358979324 * 3000.0 / 180.0;let x = lng;let y = lat;let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);let lngs = z * Math.cos(theta) + 0.0065;let lats = z * Math.sin(theta) + 0.006;return {latitude: lats,longitude: lngs} 
}
// 百度地图经纬度转腾讯地图gcj02
export function BMapTransQQMap(lng: number, lat: number) {let x_pi = 3.14159265358979324 * 3000.0 / 180.0;let x = lng - 0.0065;let y = lat - 0.006;let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);let lngs = z * Math.cos(theta);let lats = z * Math.sin(theta);return {latitude: lats,longitude: lngs}   
}

四、关于input

正则过滤输入,不支持pattern,pattern属性html才有

最后使用的是@input过滤+debounce实现(todo:寻找更好的方法)

五、关于toast

上一个toast会被下一个toast无缝替换(看不出前面的toast,只能看到最后一个toast)

小程序的提示uni.showToas会在页面跳转时消失,导致一闪而过看不清提示的情况--需加setTimeout延迟一下

六、关于防爆

一直以为就调接口需要防爆???

结果拍照页面点击上传也需要???

业务代码里用到了事件总线,由于异步,接口loading也没用,需要手动设置标志位(类似锁)防爆

ps:使用事件总线$on,$emit——因为navigateBack不能传参,又想特定时候更新上一页数据

相关文章:

  • 如何在 PyTorch 中自定义卷积核参数(亲测,已解决)
  • [免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
  • 设计模式-抽象工厂模式
  • C/Python/Go示例 | Socket Programing与RPC
  • 云原生时代的系统设计:架构转型的战略支点
  • GO语言---init函数
  • Go 语言底层(四) : 深入 Context 上下文
  • 鸿蒙 Stege模型 多模块应用
  • GO 基础语法和数据类型面试题及参考答案(下)
  • 解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护
  • FreeRTOS任务基础知识
  • VLLM : RuntimeError: NCCL error: invalid usage
  • RT_Thread——线程管理(下)
  • 高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。
  • window 显示驱动开发-如何查询视频处理功能(三)
  • 从零手写Java版本的LSM Tree (八):LSM Tree 主程序实现
  • 华为云Flexus+DeepSeek征文 | MaaS平台避坑指南:DeepSeek商用服务开通与成本控制
  • HTML5实现简洁的体育赛事网站源码
  • Nosql之Redis集群
  • 多元隐函数 偏导公式
  • 盐山网站制作/广告联盟app下载赚钱
  • 德州建设网站有/seo实战指导
  • 驻马店做网站哪家好/百度seo关键词排名优化软件
  • 寻花问柳-一个专做男人的网站/阿拉善盟seo
  • 域名注册好了如何做网站/免费seo课程
  • 动态网站制作视频教程/百度云资源搜索平台