小程序
快来分享你的内容吧~
- 01-30 00:18·Java后端
- 2025-12-04·后端
- 2025-11-07·网站开发
- 想做一个细分领域的签到 + 论坛微信小程序,纠结技术选型中问题描述我想做一个细分领域的签到打卡 + 论坛微信小程序,之前没有小程序开发经验,纠结技术选型中。同领域目前做的比较好的只有 APP 版本,运营时间 5+ 年,还没有微信小程序版本。观察了一段时间,总用户量 30W 左右,日活 1K 左右。自己也不知道这个小程序能走到哪一步,用户量依据同行做参考。我是 4 年 Java + Vue 开发经验。目前暂定的 2 个技术选型是:1. unicloud s...查看全文程序员鱼皮:挺不错的问题,描述的也很清楚。首先想清楚自己做这个产品的目的,是为了练手学习那就无所谓选择什么技术了;是为了做产品那就优先选择自己最熟悉的、相对稳定成熟的、开发快速的技术栈。如果你熟悉 vue,用 uniapp 开发小程序是完全 ok 的,也不需要什么学习成本,按照官方文档做就行。关于你具体的问题,我觉得你有点未雨绸缪了,先把功能最快做出来,真的扛不住性能了,你可以再去做优化,别没什么用户还提前操

- 2024-07-29
- 微信小程序一键登录问题,和登录方案问题描述使用uniapp 开发微信小程序,微信小程序的一键手机号登录个体不让用,然后 uniapp 的一键登录好像支持微信小程序背景信息具体疑问1. 目前除了uniapp 和微信小程序官方的一键手机号登录外还有其他方法实现一键手机号登录吗。2. 如果没有是不是只能像 web 应用那样使用账号密码登录了已有理解预期目标希望能有一个比较好的登录方案,最好是像小程序那样可以一键获取手机号登录的相关资料...查看全文编程导航小智:1. 目前除了uniapp和微信小程序官方的一键手机号登录外,还有其他方法实现一键手机号登录。你可以考虑使用第三方的登录SDK,比如阿里云一键登录、腾讯云一键登录等。这些SDK提供了一键手机号登录的功能,可以帮助你快速实现用户手机号的获取和登录功能。2. 如果没有使用一键手机号登录的选项,你可以考虑使用第三方登录(比如微信登录、QQ登录、微博登录)作为替代方案。用户通过第三方登录后,可以获取到用户
微信小程序踩坑实录
大家好(๑╹◡╹)ノ”,我是萍雨 这篇文章来聊一聊微信小程序开发的一些问题和我踩的坑以及解决方案 关于前面的部分大家可以点击下面的链接直达 『 Lovart + Nano Banana Pro + Seeddream 的独立开发 UI 公式 』 https://www.codefather.cn/post/2016908868998717442 『 用 Vibe Coding 做完一个小程序之后,聊一聊 』 https://www.codefather.cn/post/2016922810902962177 **首先先说一下,这是我第一次做微信小程序,做小程序的原因是参加了挑战杯的比赛,之前也没有看过任何和微信小程序开发相关的任何教程,所以一些教程当中可能提到的坑,我大概率踩了** ### 1. 要不要选择云开发 关于这个点,可以问自己一个简单的问题: **做的这个小程序需要用到音频,视频或者五张以上的图片吗?** 如果需要的话,那还是选择云开发吧,我最初就不知道没有选择云开发而踩了坑 **因为微信小程序对于主包的大小限制为 2MB,也意味着主包当中几乎就只有代码**,随便有一个音频,视频或者图片基本都会超过这个 2MB 的限制,我在微信开放社区看到不少人子啊吐槽这个限制的,应该是有不少人踩了和我一样的坑 即在最开始的时候,把各种非代码的文件都存储在本地路径当中,最后发现主包的大小远远超过了 2MB(比如我自己**在基本做完这个小程序时发现主包大小大概是 157MB......到最后主包的大小被我压缩到了 0.67MB,关于压缩主包文件的方法我后面会说**)  ### 2. 如何解决主包过大的问题 微信开发者工具会提醒我们主包过大,但如果我们想要知道主包到底有多大,主包当中的哪些文件过大我们应该去哪里看呢?答案是代码依赖分析 **微信开发者工具右上角 -> 详情 -> 基本信息 -> 代码依赖分析**  这里展示主包当中具体组成,还可以导出 json 格式的文件,给 AI 分析以及如何处理  **解决主包过大的问题/压缩主包大小的主要方式就是将主包当中的非代码文件都放在云开发的存储当中**,如果在最开始做小程序的时候没有选择云开发的话,是没有 "云开发" 这个选项的 需要在小程序的官网去获取一个正式的 AppID,填写到 src\manifest.json 当中的 "appid :" 才会在微信开发者工具当中出现 "云开发" 选项 **关于如何获取一个正式的 AppID 这里就不展开了,问一下 AI 就很容易知道怎么做了** 在有了 "云开发" 找到 "存储",和阿里云,腾讯云的对象存储是类似的,存储权限如果需要 "所有用户可读,仅创建者可读写" 是需要开会员的,会员是一个月 19.9,不过我觉得用阿里云,腾讯云这些存储也是可以的,**主要目的就是让视频,音频,图片等非代码文件不在主包当中**   ### 3. 如何把两百多个非代码文件从本地转换到云 如果你也很不幸的很我一样,把最开始的时候把非代码资源存储在本地,代码当中也是访问的本地路径,再将这些文件导入文件将原来的本地路径替换云存储的路径(非代码文件比较少的情况下) **如果更不幸的,你有二百多个非代码文件都是用的本地路径访问,没错还是我,那么可以按照下面的步骤操作** 具体的步骤,我直接把 Gemini 输出的摘过来了,**对于需要注意的地方我会进行加粗**: 📦 第一步:云端镜像 (Upload) —— 保持结构一致 这一步是“省力”的关键! 打开 云开发控制台 -> 存储。 新建一个文件夹,命名为 images **(这里需要注意的是仿照本地路径,只要结构对得上,代码就能批量改)** 打开这个 images 文件夹。 【关键操作】: 在你电脑上打开 src/static/images 文件夹。 全选 里面的所有内容(包括 daily, index, wiki 这些子文件夹)。 直接拖拽 到云开发控制台的 images 文件夹里。 --- ✂️ 第二步:一键替换 (Replace) —— 30秒搞定 不用一个个找,我们用 Trae / VS Code 的核武器 1. 准备好你的“云端前缀” 去云存储里随便点一张图(比如 images/index/logo.png)。 复制它的 下载地址 (HTTPS)。 提取出 前缀部分 (即 /images/ 之前的所有内容)。 假设你的前缀是: https://636c-cloud1-8gizllp3a0666dde-1400097024.tcb.qcloud.la (请以你实际复制的为准) 这里多解释一下,找到下载路径,比如下面这个的下载地址是 https://636c-cloud1-8gizllp3a0666dde-1400097024.tcb.qcloud.la/audio/bgm-hall-intro.mp3?sign=bce342c904cdcccaa01c7b09543afbe7&t=1769705069 **前缀就是文件夹之前的内容,比如我的这个文件夹叫做 audio,/audio 之前的内容即为前缀**  2. 启动全局替换 在 Trae 中按下快捷键 Ctrl + Shift + H (全局替换) 查找内容 (第一行) 输入:/static/images/ 替换为 (第二行) 输入:https://你的云环境域名/images/ 举例:https://636c-cloud1-8gizllp3a0666dde-1400097024.tcb.qcloud.la/images/ 点击【全部替换】(Replace All) (那个不仅是单纯的图标,通常是两个矩形重叠的图标)。 💥 轰! 这一下点击,代码里所有 200 多个 /static/images/... 瞬间全部变成了云链接。因为文件名没变,路径结构没变,所以绝对不会错! --- 🧹 第三步:清理现场 (Delete) —— 必须做! 如果只改代码不删文件,体积还是减不下来! 回到电脑文件夹 src/static/images 保留 tabbar 文件夹(底部的 5 个小图标建议留本地,体验更好)。 删除 其他所有已经上传的文件夹(daily, index, market, theater, wiki, workshop 等) **虽然已经替换成云存储的文件路径,但之前的本地路径依然存在,依然占据着空间,务必记得删除,在删除之前如果觉得不放心的话,可以再做一个备份,就 CV 一下的事情** 回顾一下其实踩坑的地方不是很多hh,这次就分享这么多吧,希望大家不要踩我踩过坑了~
用 Vibe Coding 做完一个小程序之后,聊一聊
大家好(๑╹◡╹)ノ”,我是萍雨,我们继续来聊 Vibe Coding 的部分 关于前面的部分大家可以点击下面的链接直达 『 Lovart + Nano Banana Pro + Seeddream 的独立开发 UI 公式 』 https://www.codefather.cn/post/2016908868998717442 **这个小程序的开发部分是我,Gemini,Trae 来完成的,之前跟着鱼皮做项目基本就是我和 Gemini**,那变为三者的协作之后,有什么具体的变化吗? 讲真的,我觉得没啥实质性的变化,在之前两者的协作模式之下,我负责提供大致的设计分析,对于 Gemini 生成的代码进行审查,反馈代码更新之后的信息,解决一些 Bug 等等 Gemini 负责将我原本的想法具象化,输出代码,修改 Bug 等等 现在变为三者之后,Trae 主要替代了 IDEA 的工作,多数代码直接由 Trae 的 SOLO 模式输出(算是一个 Agent),我主要负责的事情其实没太多的变化,G**emini 主要负责的事情从原来的输出代码变成了输出明确的,结构清晰的给 Trae 的 Prompt**,顺带还是要解决一些小 Bug,有的时候 Trae 也会把自己绕进去,就还是需要我和 Gemini 来解决这些 Bug 我在想是不是我 Vibe Coding 的方式有些问题(鱼皮新出的 Vibe Coding 教程我还没看) **之前我是有接触过 Vibe Coding 的,想来做一些不是一两句 Prompt 就能完成的小项目,但之前的效果都不是很好,至少之前的我是没有完成的**,之前的协作模式就是我和 Cursor 或者我和其他的 AI 编程工具,我觉得有以下几个原因 1. 之前自己的专业技能确实可以说是负基础 2. 我很难特别清晰的,结构化的表述清楚我的需求是什么,我需要 AI 编程工具来做什么 3. 面对 AI agent 输出的海量代码,我是有一种失控的感觉,因为看不懂,不知道怎么改 这次不说比较好吧,至少是完成了一个不是一两句 Prompt 就能完成的小项目,三者的协作模式的几个优势,其实就是成功的解决掉了我上面的三个问题 **1. 我看不懂,Gemini 看得懂啊,Gemini 给我讲清楚就好 2. 前面也有提到 Gemini 的主要职责从输出代码变成了输出给 Trae 明确的,结构清晰的 Prompt** 3. 小步快跑,现在的我会拆分了 **不知道看到这里大家有没有一种感觉,是不是很像 AI 绘图啊,在 Gemini 或者 GPT 和 AI 对齐好提示词,再把优质的提示词给专业的 AI 绘图工具**,明明之前就经常做的事情,到了 Vibe Coding 这块就不会了hh,真的就是这几天我才有这种明显的感受,感觉自己蠢爆了hh
Lovart + Nano Banana Pro + Seeddream 的独立开发 UI 设计公式
因为合在一起字数可能比较多,就拆成几篇发吧,先发 UI 设计这一篇,之后还有 Vibe Coding 和微信小程序开发的注意项两篇 这个独立开发的 UI 设计公式,我第一次是在下面的文章当中看到的 https://mp.weixin.qq.com/s/s6Am3tKvB9haP257xRe8SQ?scene=1 **当初看完之后也是热血沸腾,于是就没有后续了...** 但至少是埋下了一颗种子,这颗种子在四个月之后发芽了,关于这个独立开发 UI 设计公式我就不展开了,大家感兴趣的话,可以直接打开上面链接 下面我就只聊几点我自己的经验之谈,不一定有用,因为验证的样本不是很多 ### 1. 如果你也心疼自己的积分,Lovart 一定要选择模型偏好 就是下面红框当中类似微信收藏图标的交互按钮,否则 Lovart 默认调用的就是 Nano Banana Pro,而调用一次 Nano Banana Pro 消耗 10 点积分!没有什么概念是吧,Lovart 免费用户每天的可使用积分是 80 点,也就是只能画 8 张图  **可能还不是很直观,做个对比,Seeddream 4.0 画一张图只需要 2 点积分,每天可以画 40 张图,而选择 Nano Banana Pro 只能画 8 张,五倍的差距,各个模型所消耗的积分数量,可以看下面这张图** **如果是想用 Nano Banana Pro 的话,我是更加建议直接在 Gemini 当中使用的**,开发过程当中很多图我就是用 Gemini 当中的 Nano Banana Pro 来做的,在 Lovart 当中主要应用的是 Seeddream 4.0,也因此我充值了一个初级套餐——2000 积分,首冲再额外送 2000,也就是我总共有 4000 积分,期间每天会增加 100 点积分 我在做完这个小程序之后还剩下 3000 点积分没有用,**而且这个积分从充值开始算,一个月后无论剩余多少就直接清零了,更准确的说是回归到免费套餐**,举个例子,比如我还有三千积分没有使用,但明天就到期了,明天我的积分就会变为免费套餐的 80 点积分,所以大家的绘图需求不是特别多的话,Nano Banana Pro 也是完全就可以在 Lovart 当中做的  ### 2. Lovart 的一些小功能 1. 先说免费的:移除背景 & 擦除 在 Lovart 当中是可以上传自己的图片的,免费去背景对于主要靠 UI 素材的小程序简直太重要了  2. 编辑文字 需要花积分的,我觉得算有用的功能——编辑文字,这个可以把图片当中的文字提取出来,进行更改,一次是花费 10 点积分,但仅限于文字相对好识别,比如下面的这张图当中的 "西游记" 就是很容易识别的  再举个不是很好识别的例子,可以从图片当中看出来,图片当中的文字其实是 "白太蛇",而识别出来的文字内容是 "白蛇"  3. 垫图功能 这个主流的 AI 绘图工具基本都是支持的,比如即梦,Midjourney 等等,Lovart 也是支持的,但垫图确实是经常使用到,这里还是简单提一嘴,大家知道 Lovart 也支持就好 ### 3. 其他 个人觉得在 Lovart 当中的 Nano Banana Pro 是更加适合用来微调 把你想要实现的效果,找个示例图好模仿
我要吐了,现在上线个小程序这么麻烦吗?!
大家好,我是程序员鱼皮。 前段时间我用 AI 搞了个《学习英雄》小程序,让学习像玩游戏一样轻松有趣。  开发没花多少时间,基本上摸摸鱼、抠抠脚、喝喝茶,差不多 1 天吧,一个包含完整前后端和 AI 能力的小程序就诞生了。 原本枯燥的概念通过问答的形式变得生动有趣,学习焦虑瞬间消失了~  👉🏻 感兴趣的同学可以看 [这篇文章](https://mp.weixin.qq.com/s/UYfskJvXsLLON0nMOWLz_g) 来了解开发过程。 但是你敢信,我竟然花了 **差不多 2 个月**,才把这个小程序正式上线?!  换到以前,我自己都不敢相信,记得大学的时候上线个小程序很快的,看来真的是时代变了。 接下来分享一下我坎坷的小程序上线过程,给一些准备搞小程序的朋友打打预防针,提前规划好时间。 第一步是【小程序备案】,以前压根儿是没有这一步的,但是自 2023 年 9 月 1 日起,所有新开发的微信小程序必须完成备案后才能上架。 备案操作是免费的,主要就是在后台填写一些个人 / 企业信息。但是审核周期大约 **2 ~ 22 个工作日**(含工信部审核) 。 我是在国庆节前提了备案,过了 12 天后才通过;如果不是假期,可能会快点吧,大概吧。 然后是第二步【小程序类目申请】,由于我的小程序用到了 AI 大模型来做问答功能,需要添加 “深度合成-AI问答类目”,否则无法通过代码发布审核。  那我就按照修改指引添加类目呗,结果添加 AI 相关的类目是需要资质文件的! 因为我用的是别人的大模型,需要有技术主体的《互联网信息服务算法备案》和《小程序主体与技术主体的合作协议》。。。  **什么?还要合作协议?!** 到这一步我估计会劝退一大波萌新,我刚看到的时候也头疼了。  不过别慌,你用哪家的 AI 大模型服务,就直接去找对应的工作人员要就好了。 比如我用的是阿里云大模型,直接去官网联系客服,他们的技术支持响应很快,也很热心。你只需要做到把自己的需求描述清楚,对方会帮你处理的。  大概花费了 10 天左右,我顺利拿到了申请类目的材料,提交申请就好。 接下来是第三步【代码发布审核】,感觉现在小程序的审核越来越严格了,尤其是刚开始做的小程序,很容易因为一些意想不到的原因被打回来。 比如我遇到的这个情况,由于小程序的某个按钮点击后没有响应,就被打回来了。  这锅我不背,谁让 AI 偷懒了呢?!  于是我让团队的同学帮忙补了个点击弹窗,然后重新提交了审核。  经过 2 ~ 3 天左右,代码审核终于通过了。然而由于我的小程序还涉及 “社交” 类目,需要进入第四步【小程序报备】。  当时看到这个 7 天 * 24h 的审核时长,我嘴里正在撕咬的鸡腿都变得索然无味了。。。 好在过了 7 天后,我的小程序终于发布上线了,真是不容易啊! 来回顾下完整的流程吧:  虽然我这次小程序上线花了近 2 个月,但其实中间有些空余的时间是我自己没来得及看到通知。不过就算只考虑必须的流程,差不多也要 1 个月了。 如果你只是想做个简单的工具小程序,不涉及 AI 功能和下面这些需要报备的类目,应该能省不少时间。  不过我估计现在很多同学都有用 AI 做个《有 AI 功能的小程序》的想法,所以还是建议大家 **提前申请小程序的类目**,并且先搞出一个最小可用版本的 Demo 拿来过审、走完一次上线发布的流程,从而缩短整体的周期。这就是经典的统筹方法吧~ OK 就先写到这里,写下一个视频稿去了,拜拜~ 👋🏻  ## 更多 💻 编程学习交流:[编程导航](https://www.codefather.cn/) 📃 简历快速制作:[老鱼简历](https://www.laoyujianli.com) ✏️ 面试刷题神器:[面试鸭](https://www.mianshiya.com) 📖 AI 学习指南:[AI 知识库](https://ai.codefather.cn/)
微信小程序语音实时转文字
注意:此文档是基于 uniapp 开发微信小程序的总结 微信小程序实现语音实时转文字功能,引入微信小程序自研的同声传译插件(官方文档:[插件服务 / 微信同声传译](https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/extended/translator.html)) # 引入 ## 1. 小程序后台 微信小程序后台-> 设置->第三方设置-> 插件管理(添加插件)-> 搜索微信同声传译  ## 2. maneifest.json 下面一段代码添加到mp-weixin,version,provider在插件管理中可以看到具体信息 ```json "plugins": { "WechatSI": { "version": "0.3.6", "provider": "wx069ba97219f66d99" } } ``` # 完整流程图  # 实现流程 ## 1. 核心界面实现  ```html <view class="input-container"> <image class="record-icon" :class="{ 'recording': isRecording }" src="/static/icon/record.png" mode="aspectFit" @click="toggleRecording" ></image> <input class="message-input" v-model="inputMessage" :placeholder="inputPlaceholder" :disabled="isLoading" @confirm="sendMessage" confirm-type="send" /> <button class="send-btn" :class="{ 'send-btn-disabled': !inputMessage.trim() || isLoading }" @click="sendMessage" :disabled="!inputMessage.trim() || isLoading" > <text v-if="!isLoading">发送</text> <text v-else>...</text> </button> </view> ``` ## 2. 变量添加 ```js // 录音相关 isRecording: false, // 是否正在录音 plugin: null, // 微信同声传译插件实例 manager: null // 录音管理器 ``` ## 3. 页面加载 ```js onLoad(options) { // 初始化微信同声传译插件 this.initVoicePlugin() }, /** * 初始化微信同声传译插件 */ initVoicePlugin() { try { // 引入微信同声传译插件 this.plugin = requirePlugin("WechatSI") // 获取录音管理器 this.manager = this.plugin.getRecordRecognitionManager() // 监听识别开始事件 this.manager.onStart = (res) => { console.log('录音识别开始', res) this.isRecording = true } // 监听识别结果事件(实时返回) this.manager.onRecognize = (res) => { console.log('实时识别结果:', res) if (res.result) { // 实时更新到输入框 this.inputMessage = res.result } } // 监听识别结束事件 this.manager.onStop = (res) => { console.log('录音识别结束', res) this.isRecording = false if (res.result) { // 最终结果更新到输入框 this.inputMessage = res.result } } // 监听识别错误事件 this.manager.onError = (res) => { console.error('录音识别错误:', res) this.isRecording = false uni.showToast({ title: '识别失败,请重试', icon: 'none', duration: 2000 }) } } catch (error) { console.error('微信同声传译插件初始化失败:', error) uni.showToast({ title: '语音功能不可用', icon: 'none', duration: 2000 }) } console.warn('当前环境不支持微信同声传译插件') }, ``` ## 4. 用户点击录音按钮 ```js /** * 切换录音状态 */ toggleRecording() { if (!this.manager) { uni.showToast({ title: '语音功能未初始化', icon: 'none', duration: 2000 }) return } if (this.isRecording) { // 停止录音 this.stopRecording() } else { // 开始录音 this.startRecording() } uni.showToast({ title: '仅支持微信小程序', icon: 'none', duration: 2000 }) }, /** * 开始录音 */ startRecording() { try { // 先清空输入框 this.inputMessage = '' // 开始录音识别 this.manager.start({ duration: 60000, // 最长录音时长(毫秒) lang: 'zh_CN' // 语言:中文 }) uni.showToast({ title: '开始录音...', icon: 'none', duration: 1000 }) } catch (error) { console.error('开始录音失败:', error) this.isRecording = false uni.showToast({ title: '录音失败,请重试', icon: 'none', duration: 2000 }) } }, /** * 停止录音 */ stopRecording() { try { this.manager.stop() uni.showToast({ title: '录音结束', icon: 'none', duration: 1000 }) } catch (error) { console.error('停止录音失败:', error) this.isRecording = false } }, ``` ## 5. 切换页面 ```js onUnload() { // 清理录音资源 if (this.manager) { this.manager.stop() } }, ```
开箱即用!unaipp微信开发合集,登录/支付/订阅消息,一键获取手机号/头像/昵称
## 前言 大家好,我是王天,做uniapp三年了,这一路踩坑无数,但也收获满满。尤其是微信小程序,花了我不少心思。 今天分享的是,在使用uniapp开发中,积累的一些微信业务组件,希望能帮助到大家。 ## 背景 uniapp很多小程序组件库、功能丰富,可以帮我们快速做开发。但是呢,这些组件库,缺了点儿跟微信业务直接相关的、比如怎么在微信里收钱、怎么让用户登录,还有怎么发订阅消息给他们。这些业务功能,组件库里都没有现成的。 所以啊,我自己动手,开发了一套微信业务组件合集,起了名字叫【uboxui】,专门解决这些问题。这样大家在做微信小程序的时候,就能更方便、更快捷地搞定这些业务上的事儿了。 ## 功能合集 本文重点是介绍微信小程序相关的业务组件,已发布线上,扫码可查看,完整项目代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/6615HNU2QxQ3PLRK.webp" alt="画板" width="100%" /> ## 微信小程序登录 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/2kF0zlORj8vEvIcJ.webp" alt="" width="100%" /> ### 运行效果 项目行效果如下,完整代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/X1enRkXj20Q7ac8K.webp" alt="" width="100%" /> 小程序登录本质是获取用户openid,流程可大致分为4部分,其中前端需要做如下: ### 前端负责部分 + 调用 wx.login API 获取 code 。 + 将 code 发送给后端。 + 接收后端返回的登录态标识(如 token)。 + 将登录态标识存储在本地。 + 在后续请求中携带登录态标识进行身份验证。 + 维护登录态,如检查登录态是否过期并重新发起登录请求。 ### 小程序完整登录流程 #### 1、前端发起登录请求 + 用户点击登录按钮。 + 前端调用微信小程序的 wx.login API 获取临时的登录凭证 code 。 + 前端将 code 发送给后端。 #### 2、后端处理登录凭证 + 后端接收到前端发送的 code 。 + 后端使用 code 向微信服务器请求 session_key 和 openid 。 + 微信服务器返回 session_key 和 openid 给后端。 + 后端将 openid 作为用户的唯一标识,与自身的用户系统关联或创建新用户。 + (可选)后端生成自定义的登录态标识(如 token),并返回给前端。 #### 3、前端存储登录态标识 + 前端接收到后端返回的登录态标识(如 token)。 + 前端将登录态标识存储在本地(如使用 wx.setStorageSync )。 + 在后续的请求中,前端携带登录态标识(如放在请求头中)进行身份验证。 #### 4、前端维护登录态 + 在用户每次使用小程序时,前端检查本地是否存储了有效的登录态标识。 + 如果登录态标识过期或不存在,前端重复步骤 1 重新发起登录请求。 ## 获取微信昵称、头像 ### 运行效果 项目行效果如下,完整代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/pFw55b2FDxoyKO1d.webp" alt="" width="100%" /> 获取微信用户头像昵称,需要用到微信开放能力 ### 头像选择 头像获取需要配置 button组件的 open-type设置为 chooseAvatar,当用户选择需要使用的头像之后,可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径 ### 昵称获取 获取用户昵称,需要将 input组件type类型设置nickname,用户输入内容时,会在键盘上方展示昵称 ## 一键获取手机号 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/HY6btVVpN1sMLqDv.webp" alt="" width="100%" /> ### 运行效果 项目行效果如下,完整代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/fc3vXJSNEV5ivVMq.webp" alt="" width="100%" /> ### 开发步骤: <font style="color:#000000;background-color:#FBDE28;">前置条件!认证小程序账号才有获取手机号能力</font> 1. 设置项目 appid 2. Button 配置开放能力 为getnumbetphone 3. 点击button,获取code口令 4. 调用微信开放api解码手机号 注意!微信开放api为服务端接口,需要后端服务调用,熟悉node的前端小伙伴也可以搭建一个本地node做测试,我这里用的uniapp的云开发免环境配置比较方便。 ## 微信支付基本流程 ### 运行效果 项目行效果如下,完整代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/ksgUkTMnqq6EXU3M.webp" alt="" width="100%" /> ### 环境配置 + 1、微信公众平台(小程序、公众号主体必须是企业认证) + 2、开通微信商户平台 (收款平台),关联小程序appid ### 支付步骤 + ⚠[前置条件]——必须先微信登录,获取用户openid + ① 生成支付参数;以服务端方式调用微信api生成支付参数 + ② 拉起微信支付弹框;前端接收到支付参数,调用微信支付 + ③ 监听支付状态、success / error ## 微信订阅消息推送 本项目微信订阅后端是通过云函数,建议根据自身项目切换后端服务。 ### 运行效果 项目行效果如下,完整代码在文末 <img src="https://pic.code-nav.cn/post_picture/1842538896137445377/PfjUqCoPyfPEbtPU.webp" alt="" width="100%" /> ### 步骤 1. 开通订阅消息、选择模板 2. 使用uniclound 订阅消息插件,推送消息 3. 前端先订阅 4. 后端云函数安装 订阅消息插件+token统一管理模块 ** 注意!测试阶段将 微信ip白名单关闭,否则无法推送** ## 项目源码 小程序插件已经发布到uniapp插件市场,有兴趣的朋友可以下载了解下哈 👉[uboxui 一个功能丰富的小程序业务插件库 - DCloud 插件市场](https://ext.dcloud.net.cn/plugin?id=17178) <font style="color:#000000;">代码如有问题,联系王天哈</font><font style="color:#FAFAFA;background-color:#8A8F8D;"> wangtian3111</font>
想做一个细分领域的签到 + 论坛微信小程序,纠结技术选型中
### 问题描述 我想做一个细分领域的签到打卡 + 论坛微信小程序,之前没有小程序开发经验,纠结技术选型中。 同领域目前做的比较好的只有 APP 版本,运营时间 5+ 年,还没有微信小程序版本。 观察了一段时间,总用户量 30W 左右,日活 1K 左右。 自己也不知道这个小程序能走到哪一步,用户量依据同行做参考。 我是 4 年 Java + Vue 开发经验。目前暂定的 2 个技术选型是: 1. unicloud serverless(零经验)。 2. uniapp + Java(没写过 uniapp)。 ### 选型对比 #### 1、unicloud - 快速开发,提供登录、支付组件,可以直接使用。 - 前端通过云函数操作数据库,底层是 Mongodb。 - 部署在云服务空间,前一个月免费,之后我打算按量付费,后期看用户量调整(前期主打节省成本,Redis 单独按月收费,能不用就不用)。 #### 2、uniapp + Java - 后端打算使用 pig + WxJava,登录、支付等都得自己一步步调试。 - 数据库 MySQL。 - 阿里云单机部署,前后端分离。按年或按量(费用相对来说高一点)。 ### 具体疑问 1. 我之前没有 Mongodb 开发经验,考虑一个场景:做一个签到排行榜,统计一个月内签到次数,前 100 名,以及当前用户排名。极端情况下,30W * 30 条签到数据,分组统计 Mongodb 性能上是否能扛住? 2. 论坛部分,假设每天 500 个用户发帖子,500 * 365 天 * 5 年 ≈ 90W,随时间增长,Mongodb 是否有存储上、查询上的瓶颈?
微信小程序使用session(详细、亲测有效)
1、背景 ---- 解决[微信小程序](https://so.csdn.net/so/search?q=%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F&spm=1001.2101.3001.7020)session不能使用,session 不唯一问题。 ### 操作流程 > 1.调用登录请求 > > 2.获取登录请求中的set-cookie 信息 > > 3\. 保存到[本地缓存](https://so.csdn.net/so/search?q=%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98&spm=1001.2101.3001.7020) > > 4.每次调用加入[请求头](https://so.csdn.net/so/search?q=%E8%AF%B7%E6%B1%82%E5%A4%B4&spm=1001.2101.3001.7020)中 例如: 微信小程序调用用户信息。 ### login. wxml ```javascript <button bindtap="getUserInfo">getUserInfo</button> ``` ### login.js ```javascript getUserInfo(){ // 获取用户信息 httpUtils.request({ showLoading: true, url: `/user/get/login`, message: "正在获取用户数据..." }).then(res => { this.setData( res.data.data ) ui.showToast(res.data.errorMsg) }).catch(err => { console.log('ERROR') }); }, ``` 控制台显示未登录 发现后台没有session传入  2、步骤 ---- ### 2.1首次请求 首次请求获取 header 中的Set-Cookie 作为cookie信息  直接开始登录流程 ```javascript wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId if (res.code) { //发起网络请求 httpUtils.request({ method: "GET", showLoading: true,url: `/wx/user/wxLogin`,message: "正在登录", data: { code: res.code } }).then(res => { if(res.header["Set-Cookie"]){ wx.setStorageSync('sessionid', res.header["Set-Cookie"]); } this.globalData.userInfo = res.data.data ui.showToast(res.data.errorMsg) }).catch(err => { console.log('ERROR') }); } else { console.log('登录失败!' + res.errMsg) } } }) ``` 注意:每次重新登录前要删除缓存信息 wx.removeStorageSync('sessionid') ### 2.2存入微信小程序缓存 ```javascript if(res.header["Set-Cookie"]){ wx.setStorageSync('sessionid', res.header["Set-Cookie"]);} ``` SESSION=MjMxZDM3NmYtYzgzYy00NDc0LWExODYtOWRmODI0N2M1NTMy; Path=/api; HttpOnly; SameSite=Lax ### 2.3将cookie加入请求头 ```javascript let header = { 'content-type': 'application/json', // 默认值 } let session_id = wx.getStorageSync('sessionid'); //本地取存储的sessionID if (session_id != "" && session_id != null) { //本地session存在,则放到header里 header.Cookie = session_id; } ``` ### 2.4请求 最后直接使用wx.request API调用接口,大功告成。 重新调用后  附录 -- ### httpUtils.js ```cobol const ui = require('./ui'); const BASE_URL = 'http://XXXXXX:8890/api' /** * 网络请求request * obj.data 请求接口需要传递的数据 * obj.showLoading 控制是否显示加载Loading 默认为false不显示 * obj.contentType 默认为 application/json * obj.method 请求的方法 默认为GET * obj.url 请求的接口路径 * obj.message 加载数据提示语 */ function request(obj) { return new Promise(function (resolve, reject) { if (obj.showLoading) { ui.showLoading(obj.message ? obj.message : '加载中...'); } var data = {}; if (obj.data) { data = obj.data; } var contentType = 'application/json'; if (obj.contentType) { contentType = obj.contentType; } var method = 'GET'; if (obj.method) { method = obj.method; } let header = { 'content-type': 'application/json', // 默认值 } let session_id = wx.getStorageSync('sessionid');//本地取存储的sessionID if (session_id != "" && session_id != null) { //本地session存在,则放到header里 header.Cookie = session_id; } wx.request({ url: BASE_URL + obj.url, data: data, method: method, //添加请求头 header: header, contentType: contentType, //请求成功 success: function (res) { console.log('===========================================================================================') console.log('== 接口地址:' + obj.url); console.log('== 接口参数:' + JSON.stringify(data)); console.log('== 请求类型:' + method); console.log("== 接口状态:" + res.statusCode); console.log("== 接口数据:" + JSON.stringify(res.data)); console.log('===========================================================================================') if (res.statusCode == 200) { resolve(res); } else if (res.statusCode == 401) {//授权失效 reject("登录已过期"); jumpToLogin();//跳转到登录页 } else { //请求失败 reject("请求失败:" + res.statusCode) } }, fail: function (err) { //服务器连接异常 console.log('==========================================================================================') console.log('== 接口地址:' + url) console.log('== 接口参数:' + JSON.stringify(data)) console.log('== 请求类型:' + method) console.log("== 服务器连接异常") console.log('==========================================================================================') reject("服务器连接异常,请检查网络再试"); }, complete: function () { ui.hideLoading(); } }) }); } //跳转到登录页 小程序每次启动登录 暂时没有登录页面 function jumpToLogin() { } module.exports = { request, } ``` ### ui.js 控制模态框 ```php export const showToast = function(content,duration) { if(!duration) duration = 2000 wx.showToast({ title: content, icon: 'none', duration: duration, }) } var isShowLoading = false export const showLoading = function(title) { if(isShowLoading) return wx.showLoading({ title: title?title:'', mask:true, success:()=>{ isShowLoading = true } }) } export const hideLoading = function() { if(!isShowLoading) return isShowLoading = false wx.hideLoading() } ``` ### app.js ```cobol // app.js const httpUtils = require('./utils/httpUtils') const ui = require('./utils/ui') App({ onLaunch() { //删除缓存 重新登录 获取会话 wx.removeStorageSync('sessionid') // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId if (res.code) { //发起网络请求 httpUtils.request({ method: "GET", showLoading: true,url: `/wx/user/wxLogin`,message: "正在登录", data: { code: res.code } }).then(res => { // 保存set-cookie到缓存中 if(res.header["Set-Cookie"]){ wx.setStorageSync('sessionid', res.header["Set-Cookie"]); } // 用户信息保存在全局变量 this.globalData.userInfo = res.data.data ui.showToast(res.data.errorMsg) }).catch(err => { console.log('ERROR') }); } else { console.log('登录失败!' + res.errMsg) } } }) wx.getSystemInfo({ success: e => { this.globalData.StatusBar = e.statusBarHeight; let custom = wx.getMenuButtonBoundingClientRect(); this.globalData.Custom = custom; this.globalData.CustomBar = custom.bottom + custom.top - e.statusBarHeight; } }) }, globalData: { userInfo: null, } }) ```
这两天在学 uniapp 写了一个番茄钟打卡小程序,欢迎大家体验。
### 概述 微信小程序的名字:番茄时序<br> 项目是基于 uniapp + vue3 写的小程序,后端就是常用的那些技术,Spring Boot + Msyql等,后端是部署在宝塔上的。页面是使用 HBuilderX 写的,写小程序是真方便,测试发布都是傻瓜式。没有什么高深的技术,都是最基础的,主要是想搞个实际项目写在简历上。<br> 原谅我技术好不到位,前端页面可能不好看以及会有适配问题,希望大家给点反馈以及建议。其实主要是希望大家能给我刷点访问量,让我写简历上🫣。 ### 功能 目前只做了番茄钟,每日打卡功能。<br> 番茄钟就是那个出名的番茄工作法,25分钟工作,然后休息5分钟,接着循环。<br> 每日打卡:能够选择日期,每天执行规划内容的时间,以及具体执行工作学习的内容。<br> 功能都是按照我自己的使用习惯设计的,希望同学们能给些意见。<br> 番茄钟统计功能抽时间在做,然后之后再做一个记账,以及把星球的伙伴项目整合上去,还有树洞功能。欢迎大伙来帮我涨涨访问量。 最后附两张截图,页面等以后审美变高了,技术变强了再设计吧。🫡 <img src="https://pic.code-nav.cn/post_picture/1748213138605522946/E4zMDr2l-image.webp" alt="undefined" width="145" /> <img src="https://pic.code-nav.cn/post_picture/1748213138605522946/VFqqPJZO-image.webp" alt="undefined" width="139" />
微信小程序一键登录问题,和登录方案
### 问题描述 使用uniapp 开发微信小程序,微信小程序的一键手机号登录个体不让用,然后 uniapp 的一键登录好像支持微信小程序 ### 背景信息 ### 具体疑问 1. 目前除了uniapp 和微信小程序官方的一键手机号登录外还有其他方法实现一键手机号登录吗。 2. 如果没有是不是只能像 web 应用那样使用账号密码登录了 ### 已有理解 ### 预期目标 希望能有一个比较好的登录方案,最好是像小程序那样可以一键获取手机号登录的 ### 相关资料
