在H5和UniApp项目中实现微信扫码登录的完整解决方案

前言 在一个项目中需要增加“微信扫码登录”,以前没有弄过这个功能,然后网上的各种资源都非常的乱,导致走了很多的弯路,现在将可行方案记录一下。 相关的文档地址:微信登录功能 / 网站应用微信登录开发指南 环境 前端: 使用uniapp-vue框架,是做的H5和小程序多端开发,这里只是说的H5部分。 后端: go 开始 先明白流程是什么样的: 微信扫码相关设置 申请“微信开发者平台”的AppID和AppSecret 在“微信开发者平台”–>“管理中心”–>“网站应用”中配置回调地址,回调地址只需要配置域名就可以,不需要http或者https开头!!,例如:www.abc.com。 获取扫码二维码 在需要显示二维码的页面直接执行下面代码: function setWxerwma() { const s = document.createElement('script') s.type = 'text/javascript' s.src = 'https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js' const wxElement = document.body.appendChild(s) wxElement.onload = function () { const obj = new WxLogin({ self_redirect: false, id: 'weixinLogin', // 需要显示的容器id appid: 'xxxxxx', // 微信开放平台appid wx******* scope: 'snsapi_login', // 网页默认即可 redirect_uri: encodeURIComponent('xxxxxxxxxxxxxx'), // 授权成功后回调的url state: Math.ceil(Math.random() * 1000), // 可设置为简单的随机数加session用来校验 style: 'black', // 提供"black"、"white"可选。二维码的样式 href: 'data:text/css;base64,LmltcG93ZXJCb3ggLnFyY29kZSB7bWFyZ2luLXRvcDowO30KLmltcG93ZXJCb3ggLnRpdGxlIHtkaXNwbGF5OiBub25lO30=', // 外部css文件url,需要https }) } } href:样式的设置,如果是外部css,则需要https,直接写样式就需要转换成base64,Base64编码转换工具,Base64加密解密,追加在“data:text/css;base64,”后面。 样式例如: .impowerBox .qrcode {width: 200px;} .impowerBox .title {display: none;} .impowerBox .info {width: 200px;} .status_icon {display: none} .impowerBox .status {text-align: center;} redirect_uri:回调地址,如果与当前网站域名不同就会在扫码后出现跨域错误,所以最好是给一个当前网站的单独页面触发回调接口。例如:https://a.abc.com/login 回调页面 直接代码。因为是中间页面,所以不用设计,只是闪跳一下。 <template> <div>处理登录中……</div> </template> <script> import { wxLoginCallback, getUserInfo } from '@/api/user.ts'; export default { onLoad () { // 解析 URL 中的 code 参数 const query = this.$route.query; const code = query.code; if (code) { this.handleWXLoginCallback(code); // 处理回调 } }, methods: { handleWXLoginCallback (code) { wxLoginCallback(code).then(async (res) => { if (res.code === 0) { uni.setStorageSync('token', res.data.token); uni.redirectTo({ url: '/pages/index/index' }); } else { uni.redirectTo({ url: '/pages/index/index?openSign=1' }); uni.setStorageSync('unionId', res.msg); } }); }, } } </script> 我当前实现的逻辑为: ...

2025年04月05日 · 2 分钟 · 315 字 · Silas

H5、uniapp、VUE+TS使用火山引擎-流式语音识别,进行语音转文字

H5、uniapp使用火山引擎-流式语音识别,进行语音转文字。后端使用go语言,我使用的是前端vue中录制,然后讲音频数据传递给go,go在直接上传返回识别的文字内容。 前端实现: 在前端,使用recorder-core插件来实现录制MP3文件。 npm install recorder-core 完整代码如下: <template> <view class="ar-footer"> <slot> <view class="ar-footer-button"> <image class="ar-footer-img" :src="keyboardPng" v-if="mode === 1" @click="setMode(2)" /> <image class="ar-footer-img" :src="voicePng" v-else @click="setMode(1)" /> </view> <view class="ar-footer-wrapper"> <view class="ar-footer-text" v-if="mode === 1"> <input type="text" class="ar-footer-input" v-model="text" placeholder="输入文字..." @keydown="handleKeydown" /> <view class="ar-footer-send" @click="send">发送</view> </view> <button class="ar-footer-voice" v-else @touchstart="startVoiceRecord" @touchend="endVoiceRecord" @mousedown="startVoiceRecord" @mouseup="endVoiceRecord">按住说话</button> </view> </slot> </view> </template> <script setup lang="ts"> import { ref } from 'vue' import keyboardPng from '../../../static/ai-images/keyboard.png' import voicePng from '../../../static/ai-images/voice.png' import { getPartnerList } from '@/api/ars_api'; import Recorder from 'recorder-core' import 'recorder-core/src/engine/mp3' import 'recorder-core/src/engine/mp3-engine' import 'recorder-core/src/extensions/waveview' const mode = ref(1) const text = ref('') const props = defineProps({ onSend: { type: Function, required: true } }) // 处理键盘事件 const handleKeydown = (event: KeyboardEvent) => { if (event.key === 'Enter') { send() } } const setMode = (val: number) => { if (val === 2) { recOpen(); } else { rec.close(); rec = null; } mode.value = val } const send = () => { props.onSend(text.value) text.value = '' } // 模拟按住说话功能 let rec: any; let wave: any; const startVoiceRecord = async () => { if (!rec) { console.error("未打开录音"); return } rec.start(); console.log("已开始录音"); }; const endVoiceRecord = () => { if (!rec) { console.error("未打开录音"); return } rec.stop(async (blob: Blob, duration: number) => { const result = await getPartnerList(blob); props.onSend(result.data.result[0].text) text.value = '' }, (err: any) => { console.error("结束录音出错:" + err); rec.close(); rec = null; }); }; const recOpen = async () => { try { rec = Recorder({ type: "mp3", sampleRate: 16000, bitRate: 16, onProcess: (buffers: any, powerLevel: any, bufferDuration: any, bufferSampleRate: any, newBufferIdx: any, asyncEnd: any) => { // 可实时绘制波形,实时上传(发送)数据 if (wave) wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate); } }); // 打开录音,获得权限 rec.open(() => { console.log("录音已打开"); if (wave) { // 创建音频可视化图形绘制对象 wave = Recorder.WaveView({ elem: wave }); } }, (msg: string, isUserNotAllow: boolean) => { console.log((isUserNotAllow ? "UserNotAllow," : "") + "无法录音:" + msg); }); } catch (error) { console.error('无法获取麦克风权限:', error); } } </script> ars_api上传接口: ...

2024年12月17日 · 7 分钟 · 1412 字 · Silas