Xuan's blog - 微信小程序
type: channel
link: https://blog.ybyq.wang/tag/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/
items: WeFootStep：微信运动步数同步到Typecho博客的完整解决方案
items: 智慧零工平台后端开发实战：SpringBoot + MyBatis-Flex 现代化架构
items: 智慧零工平台前端开发实战：从uni-app到跨平台应用
items: 解决uniapp小程序轮播图尺寸问题
items: uniapp-文件查找失败: ‘@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue‘
items: 云函数 vs. 传统后端：微信小程序开发该怎么选？
items: 从零开始搭建微信推送服务
items: H5网站接入微信登录详细步骤
items: 基于uniapp+vant的健身会员管理系统h5前端

WeFootStep：微信运动步数同步到Typecho博客的完整解决方案
type: item
date: 2025-07-15T23:57:00+08:00
description: 1. 项目概述WeFootStep 是一个 Typecho 插件，它能够将用户的微信运动步数同步到您的 Typecho 博客并在前端展示。本项目由 Typecho 插件（后端）和微信小程序（前端）两部分组成。通过这两部分的协同工作，实现了微信运动数据的采集、传输、存储和展示的完整流程。1.1 功能特点步数同步：通过微信小程序安全地获取并同步微信运动步数。数据统计：在导航栏提供今日步数、周/月平均、累计步数和最佳纪录等统计功能。历史图表：以图表形式直观展示历史步数变化趋势。后台管理：支持在后台查看和管理已同步的步数记录。高度自定义：支持将步数模块显示在侧边栏、页脚或主题任意自定义位置。安全可靠：严格遵循微信官方加密和验证机制，确保数据安全。1.2 技术架构2. 安装与配置2.1 插件安装从 GitHub 下载 WeFootStep 项目的 ZIP 压缩包并解压。将解压后得到的 WeFootStep 文件夹上传到您 Typecho 博客的 /usr/plugins/ 目录下。在 Typecho 后台管理界面的“控制台” > “插件”中，找到 WeFootStep 并启用它。2.2 插件配置启用插件后，点击“设置”进入配置页面：微信小程序 AppID / AppSecret：（必填） 填写您的小程序 AppID 和 AppSecret。显示样式与位置：选择步数在前台的显示样式（如进度条、文本）和位置（侧边栏、页脚或自定义）。卸载时是否删除数据：建议保留数据，除非您确定不再需要历史步数记录。2.3 微信小程序配置WeFootStep 目录中包含的 miniprogram 文件夹是小程序的前端项目。创建小程序：如果您还没有小程序，请先在 微信公众平台 注册并创建一个。获取凭证：在“开发” > “开发管理” > “开发设置”中，找到并记录您的 AppID 和 AppSecret。开启接口权限：在“开发” > “开发管理” > “接口设置”中，务必手动开启“微信运动步数”接口权限。配置服务器域名：在“开发” > “开发管理” > “开发设置” > “服务器域名”中，将您的博客域名添加到 request合法域名 列表中。这是小程序能成功请求到您博客的必要前提。配置小程序代码：使用“微信开发者工具”导入 miniprogram 文件夹。打开 pages/index/index.js 文件，将第 8 行的 url 修改为您博客的同步接口地址。地址必须是公网可访问的 HTTPS 地址。//... url: 'https://您的博客地址/index.php/action/wefootstep?do=sync', //...确保 app.json 中已添加获取微信运动数据的权限声明：{ "requiredPrivateInfos": ["getRunData"] }上传和预览：在微信开发者工具中，点击“上传”将代码上传到微信后台，然后设置为“体验版”供自己或朋友测试使用。3. 使用方法3.1 博客端数据展示自动显示：如果您在插件设置中选择了“侧边栏”或“页脚”，插件会自动在相应位置显示。自定义位置：如果选择“自定义位置”，您需要在主题的模板文件（如 sidebar.php, footer.php 或 header.php）中，在您希望展示步数的地方添加以下调用代码：<?php WeFootStep_Plugin::render(); ?>或者使用 HTML 注释作为标记（适用于不方便修改 PHP 的场景）： 导航栏统计：导航栏的步数统计功能是自动集成的，启用插件后即可在前台看到效果。3.2 小程序端数据同步小程序支持两种同步方式：自动同步：每次打开小程序时，它会自动尝试从微信服务器获取最新步数并同步到您的博客。手动同步：可以随时点击界面上的“同步步数”按钮来触发一次同步。成功同步后，小程序界面会显示“同步成功”的提示，同时您的博客前端数据也会刷新。4. 功能与接口4.1 后台管理插件在 Typecho 后台的“独立页面”菜单旁增加了一个“微信步数”管理面板，您可以在此：查看所有已同步的步数历史记录。对特定日期的步数记录进行编辑或删除。4.2 API 接口WeFootStep 提供了两个核心的 API 接口：POST /index.php/action/wefootstep?do=sync：小程序专用接口，用于接收小程序发送的加密步数数据并执行同步操作。GET /index.php/action/wefootstep?do=getStepData：前端专用接口，用于为导航栏的统计模块提供格式化的 JSON 数据。5. 主题集成：以 Handsome 主题为例本教程将指导您如何直接修改 Handsome 主题，在顶部导航栏中添加一个交互式的微信运动步数统…

智慧零工平台后端开发实战：SpringBoot + MyBatis-Flex 现代化架构
type: item
date: 2025-06-02T17:46:00+08:00
description: 本文将详细分享我使用Spring Boot 3.3.5 + MyBatis-Flex + SQLite构建零工平台后端系统的完整经验，包含架构设计、技术选型、核心功能实现和生产部署。项目背景随着零工经济的快速发展，我决定开发一个现代化的零工服务平台。后端系统需要支持工作发布、申请匹配、用户管理、支付结算等复杂业务场景，同时要保证高性能、高可用和易扩展。项目概览项目名称: 智慧零工平台后端系统技术栈: Spring Boot 3.3.5 + Java 21 + MyBatis-Flex + SQLite项目地址: GitHub - Gigplatform_backendAPI文档: 24个业务模块，100+接口部署方式: 宝塔面板 + PM2 + Nginx技术选型分析为什么选择Spring Boot 3？Java 21支持: 享受最新的语言特性和性能优化原生镜像: 支持GraalVM原生编译，启动更快响应式编程: 内置WebFlux支持可观测性: 增强的监控和链路追踪安全性: 升级的Spring SecurityMyBatis-Flex vs MyBatis-Plus经过对比，我选择了MyBatis-Flex：// MyBatis-Flex 优势示例 // 1. 类型安全的查询 List<Job> jobs = queryWrapper .select(JOB.ALL_COLUMNS) .from(JOB) .where(JOB.STATUS.eq("ACTIVE")) .and(JOB.SALARY.ge(5000)) .orderBy(JOB.CREATE_TIME.desc()) .limit(10) .list(); // 2. 智能字段映射 @Table("t_job") public class Job { @Id(keyType = KeyType.Auto) private Long id; @Column("job_title") private String title; // 自动处理驼峰命名 private String companyName; // -> company_name }SQLite的选择对于中小型项目，SQLite具有独特优势：零配置: 无需独立数据库服务器高性能: 本地文件访问，减少网络开销事务支持: 完整的ACID特性跨平台: 易于开发和部署成本低: 降低运维复杂度架构设计整体架构┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 前端应用 │ │ API网关 │ │ 负载均衡 │ │ (uni-app) │◄───│ (Nginx) │◄───│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────────────┐ │ Spring Boot │ │ (业务逻辑层) │ └─────────────────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 认证授权 │ │ 业务服务 │ │ 数据访问 │ │ (JWT) │ │ (Service) │ │ (MyBatis) │ └─────────────┘ └─────────────┘ └─────────────┘ │ ▼ ┌─────────────────┐ │ SQLite 数据库 │ └─────────────────┘项目模块结构com.example.backend/ ├── controller/ # 控制器层 │ ├── AuthController # 认证授权 │ ├── JobsController # 工作管理 │ ├── UsersController # 用户管理 │ └── ... # 其他业务控制器 ├── service/ # 业务逻辑层 │ ├── impl/ # 实现类 │ └── interfaces/ # 接口定义 ├── mapper/ # 数据访问层 ├── entity/ # 实体类 ├── config/ # 配置类 ├── common/ # 公共组件 │ ├── Result.java # 统一返回结果 │ ├── JwtUtil.java # JWT工具 │ └── JwtFilter.java # JWT过滤器 └── BackendApplication.java # 启动类核心功能实现1. JWT认证体系@Componen…

智慧零工平台前端开发实战：从uni-app到跨平台应用
type: item
date: 2025-06-02T17:42:00+08:00
description: 本文将详细介绍我如何使用uni-app框架开发一个支持微信小程序和H5的零工平台前端应用，包含技术选型、架构设计、核心功能实现及部署经验。前言在当今移动互联网时代，跨平台开发已成为提高开发效率的重要手段。本次我选择uni-app框架开发了一个智慧零工平台的前端应用，该平台致力于为零工与雇主搭建高效便捷的双向服务桥梁。项目概况项目名称: 智慧零工平台前端系统技术栈: Vue.js 2.6 + uni-app 3.0 + ColorUI支持平台: 微信小程序 + H5项目地址: GitHub - Gigplatform_front在线预览: https://lgpt.xuan.cyou/技术选型分析为什么选择uni-app？在众多跨平台解决方案中，我最终选择了uni-app，主要基于以下考虑：一套代码多端运行: 支持编译到微信小程序、H5、App等10+平台学习成本低: 基于Vue.js语法，前端开发者容易上手生态完善: 拥有丰富的组件库和插件市场性能优异: 接近原生应用的性能表现社区活跃: DCloud官方维护，社区支持良好核心技术栈{ "前端框架": "Vue.js 2.6.11", "跨平台框架": "uni-app 3.0", "UI组件库": "ColorUI 2.1.6", "样式预处理": "SCSS/SASS", "状态管理": "Vuex", "构建工具": "webpack", "开发工具": "HBuilderX" }项目架构设计整体架构项目采用模块化架构设计，清晰分离业务逻辑和技术实现：smart-gig-platform-front/ ├── api/ # API接口层 ├── components/ # 公共组件 ├── pages/ # 页面文件 ├── employerPackage/ # 雇主端分包 ├── static/ # 静态资源 ├── store/ # 状态管理 ├── colorui/ # UI组件库 └── utils/ # 工具函数分包策略为了优化小程序包体积，我采用了分包加载策略：{ "subPackages": [ { "root": "employerPackage", "name": "employer", "pages": [ "pages/center/index", "pages/postJob/index", "pages/resume/index" ] } ] }这样可以将雇主端功能独立打包，减少主包体积，提升首屏加载速度。核心功能实现1. 双重身份系统这是项目的一大特色功能，用户可以在零工和雇主身份间无缝切换： <view class="identity-switch"> <view class="switch-container"> <view class="switch-item" :class="{ active: currentRole === 'worker' }" @click="switchRole('worker')" > <image src="/static/img/worker-icon.png" /> <text>我是零工</text> </view> <view class="switch-item" :class="{ active: currentRole === 'employer' }" @click="switchRole('employer')" > <image src="/static/img/employer-icon.png" /> <text>我是雇主</text> </view> </view> </view> 2. 地理位置服务实现基于位置的工作推荐功能：// 获取用户位置 async getUserLocation() { try { const res = await uni.getLocation({ type: 'wgs84' }) this.userLocation = { latitude: res.latitude, longitude: res.longitude } // 获取附近工作 await this.getNearbyJobs() } catch (error) { console.error('获取位置失败:', error) uni.showToast({ title: '位置获取失败', icon: 'none' }) } }, // 计算距离 calculateDistance(lat1, lon1, lat2, lon2) { const R = 6371 // 地球半径(km) const dLat = (lat2 - lat1) * Math.PI / 180 const…

解决uniapp小程序轮播图尺寸问题
type: item
date: 2025-05-09T21:03:00+08:00
description: 在微信小程序开发过程中，轮播图组件(swiper)是常用的UI元素，但在实际应用中经常遇到高度不匹配导致的空白问题。本文详细记录了一次轮播图高度优化的完整过程，特别是针对固定宽高比图片的精确适配方案。问题背景在开发"零工市场"微信小程序时，首页包含一个轮播图组件。轮播图使用了三张尺寸为516×145像素的图片，但在实际显示时，轮播图区域为414×207，导致底部出现了大量空白区域，影响了整体页面美观度。初步尝试方案1. 使用自动高度方式最初尝试使用mode="widthFix"来保持图片宽高比，但默认的轮播图组件不会自动适应图片高度，仍然会出现空白。<swiper class="screen-swiper square-dot" :indicator-dots="true" :autoplay="true" :circular="true" :interval="3000" :duration="500"> <swiper-item v-for="(item, index) in banners" :key="index"> <image :src="item.imageUrl" mode="widthFix" class="swiper-image"></image> </swiper-item> </swiper>效果：图片本身按原始比例显示，不会变形但轮播图容器的高度没有随图片高度自动调整，底部依然存在大量空白指示点位置可能不正确，过于靠下2. 尝试强制变形适应接着尝试使用scaleToFill模式强制图片填充整个容器区域，但这种方法会导致图片变形。<swiper class="screen-swiper" :indicator-dots="true" :autoplay="true" :circular="true" :interval="3000" :duration="500" :style="{height: bannerHeight}"> <swiper-item v-for="(item, index) in banners" :key="index"> <image :src="item.imageUrl" mode="scaleToFill" class="swiper-image"></image> </swiper-item> </swiper>效果：图片被强制拉伸填充整个容器，没有空白内容显示不完整视觉效果较差3. 尝试使用aspectFit模式为了保持图片比例不变形，尝试使用aspectFit模式，但这种方式会在上下两侧产生空白。<swiper class="screen-swiper" :indicator-dots="true" :autoplay="true" :circular="true" :interval="3000" :duration="500" :style="{height: bannerHeight}"> <swiper-item v-for="(item, index) in banners" :key="index"> <image :src="item.imageUrl" mode="aspectFit" class="swiper-image"></image> </swiper-item> </swiper>效果：图片保持原始比例，不会变形但图片两侧或上下出现空白，实际显示尺寸较小没有完全利用容器空间最终解决方案经过多次尝试后，找到了最佳解决方案：结合使用外层容器和精确比例计算。核心代码实现1. HTML结构改进：使用外层容器<view class="banner-wrapper" :style="{height: bannerHeight}"> <swiper class="screen-swiper" :indicator-dots="true" :indicator-color="'rgba(255, 255, 255, .3)'" :indicator-active-color="'#ffffff'" :autoplay="true" :circular="true" :interval="3000" :duration="500"> <swiper-item v-for="(item, index) in banners" :key="index" @tap="bannerTap(item)"> <image :src="item.imageUrl" mode="widthFix" class="swiper-image"></image> </swiper-item> </swiper> </view>效果：轮播图外层容器高度通过精确计算，刚好与图片等…

uniapp-文件查找失败: ‘@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue‘
type: item
date: 2025-05-08T17:19:00+08:00
description: 今天在HBuilderX中使用uniapp开发微信小程序时遇到了这个问题：uniapp-文件查找失败：'@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue'，就是找不到uni-ui组件我当时创建项目，选择了一个中间带+的底部带选项卡模板，并没有选择内置uni-ui的项目模板，因为是第一次用，并不知道前者中没有引入uni-ui看了看官方文档，有三种导入方式1、新建项目时，直接选择uni-ui模板2、使用 uni_modules 方式安装组件库，可以直接通过插件市场导入3、使用npm+easycom引入，在终端执行npm i @dcloudio/uni-ui 或 yarn add @dcloudio/uni-ui报错原因我用的是npm+easycom引入的，pages.json中已经引入了easycom，但是文件夹中的内容是空的，找不到文件。解决办法注释掉easycom那几行代码，删掉左边的文件夹，然后使用上面说的第二种方式导入组件即可。

云函数 vs. 传统后端：微信小程序开发该怎么选？
type: item
date: 2025-05-08T13:16:00+08:00
description: 当你要为微信小程序添加后台功能时，比如处理用户数据、响应用户操作，你可能会遇到两种主要的选择：云函数（也叫Serverless函数）和传统后端服务（比如用Node.js、Java等语言开发和自己搭建的服务器）。它们都能帮你实现业务逻辑，但在工作方式、开发和维护上却有很大不同。下面我们来详细对比一下。一、核心区别：它们是如何工作的？对比维度云函数 (Serverless)传统后端运行方式按需启动：只有在需要时（如有用户请求）才运行，用完即停。一直在线：服务器持续运行，时刻准备处理请求。服务器管理无需操心：你只管写代码，平台会自动调整资源应对用户多少，不用你买和管理服务器。自己负责：你需要购买云主机、配置服务器环境、考虑如何应对访问高峰（如负载均衡）。花钱方式用多少付多少：按实际运行次数和消耗的资源计费，如果用得少就很省钱。包时段付费：通常按服务器运行时间计费，不管有没有人用，服务器开着就要钱。首次响应速度可能稍慢：如果一个云函数很久没被调用，第一次用它时可能会有短暂延迟（叫做"冷启动"，一般零点几秒到1秒）。一直很快：因为服务一直在线，所以没有冷启动问题。代码组织小而专：把功能拆成一个个独立的"小函数"，每个函数负责一件小事。大而全：通常是一个完整的"大应用"，包含很多功能和接口。二、实现业务逻辑：具体有什么不一样？1. 开发体验云函数独立开发，事件触发：每个函数可以单独开发和部署。它们通常由某个"事件"触发，比如用户在小程序里点了个按钮（HTTP请求）、数据库里的数据变了，或者到了预设的时间。例子：用户下单 → 触发一个云函数 → 这个函数负责生成订单 → 然后把订单信息写入数据库。代码特点：代码通常比较简单，每个函数专注于单一任务（比如一个叫 payOrder 的函数专门处理支付，一个叫 sendEmail 的函数专门发邮件）。传统后端构建完整应用：你需要搭建一个完整的应用程序框架（比如用Node.js的Express框架，或Java的Spring Boot框架）。这包括定义请求如何被处理（路由）、一些公共功能（中间件）、以及如何连接和管理数据库等。例子：你启动一个Node.js服务，用户下单时，请求会发送到服务器上类似 /api/order 这样的地址，然后由服务器上的代码处理订单逻辑。代码特点：整体代码结构可能更复杂，但好处是方便集中管理多个功能接口和一些需要多个步骤一起完成的复杂操作。2. 操作数据库云函数在微信小程序里，有时前端可以直接通过微信提供的工具包（SDK）来读写云数据库（前提是要配置好安全规则，防止数据泄露）。但对于复杂的操作，比如需要保证好几步数据库操作要么都成功要么都失败（这叫"事务"），或者需要从好几个数据表里查数据，还是得在云函数里完成。传统后端数据库完全由后端服务器控制，小程序前端不能直接访问，必须通过后端提供的接口（API）来间接操作。这样做的好处是更灵活，可以用各种数据库工具（比如ORM简化数据库代码）、写复杂的SQL查询语句，还能优化数据库连接等。3. 安全性云函数 (特指微信云开发中的云函数)自带微信安全特性：能比较容易地获得用户的微信身份信息（比如 OPENID）。敏感操作更安全：像处理支付、调用一些有密钥的敏感服务，都必须放在云函数里，这样可以避免在小程序前端暴露核心逻辑和密钥，更安全。传统后端安全靠自己：你需要自己实现用户身份验证（比如用JWT、OAuth等技术），还要防范常见的网络攻击（比如SQL注入、XSS攻击等）。三、用在什么场景更合适？场景云函数优势传统后端优势快速做一个小程序试试水（MVP）快：不用管服务器，可能几小时或一天就能让核心功能跑起来。慢：得买服务器、配域名、弄HTTPS证书，比较折腾。不常用的功能（如半夜定时跑个小任务）省钱：只在运行时花钱，平时不用不花钱。浪费：服务器一直开着，就算没事干也耗钱。用户量突然暴增（如搞秒杀活动）能扛住：平台会自动增加资源应对，不容易崩。可能崩：得提前估计流量，手动预防，不然可能顶不住。需要几步操作绝对可靠（如银行转账）有点难：跨多个函数保证所有步骤都成功比较麻烦。更可靠：可以用数据库的"事务"功能保证操作要么全成功要么全失败。需要长时间运行的任务（如视频转换）有时间限制：比如微信云函数一次最多运行几十秒或几分钟。没问题：可以自己控制程序运行多久。注：MVP (Minimum Viable Product)，指最小可行产品，用最核心的功能快速验证想法，学过项目管理的应该都知道四、举个例子：用户下单支付用云函数怎么做？小程序前端：用户点击"下单"，就调用一个叫 createOrder 的云函数，告诉它买了什么商品。createOrder 云函数：检查用户信息、生成订单号、然后调用微信支付。支付成功后：微信支付系统会通知另一个叫 upd…

从零开始搭建微信推送服务
type: item
date: 2025-05-04T17:28:00+08:00
description: 一、准备阶段注册微信公众号登录微信公众平台选择「服务号」类型（需企业资质）或「订阅号」（个人可用但功能受限）完成资质认证（服务号需300元认证费）服务器准备# 推荐配置 CPU: 2核+ ｜ 内存: 2GB+ ｜ 带宽: 3Mbps+ 系统: Ubuntu 22.04 LTS 安装组件: Nginx + MySQL + Redis + Python3.10+购买云服务器（阿里云/腾讯云）配置域名并申请SSL证书（Let's Encrypt免费证书）备案域名（国内服务器必需）微信后台配置开发 → 基本配置 → 启用服务器配置生成AppID和AppSecret设置IP白名单（服务器公网IP）配置消息加密密钥（EncodingAESKey）二、核心开发阶段Token生成与绑定系统# Token生成逻辑（示例） import uuid from datetime import datetime, timedelta def generate_token(openid): token = str(uuid.uuid4()).replace('-','')[:16] expire_time = datetime.now() + timedelta(days=365) # 存储到数据库 sql = ''' INSERT INTO user_tokens (openid, token, expire_time) VALUES (%s, %s, %s) ''' cursor.execute(sql, (openid, token, expire_time)) return token用户关注处理# 微信消息处理框架（使用werobot库） import werobot robot = werobot.WeRoBot(token='YOUR_WECHAT_TOKEN') robot.config["APP_ID"] = "YOUR_APPID" robot.config["APP_SECRET"] = "YOUR_APPSECRET" @robot.subscribe def subscribe_handler(message): openid = message.source token = generate_token(openid) return f"Token已生成：{token}\n请妥善保存"消息推送接口开发# Flask消息处理接口 from flask import Flask, request import requests app = Flask(__name__) @app.route('/<token>.send', methods=['GET', 'POST']) def send_message(token): # 验证Token openid = redis.get(f"token:{token}") if not openid: return "Invalid Token", 403 # 获取消息内容 text = request.args.get('text') or request.form.get('text') desp = request.args.get('desp') or request.form.get('desp', '') # 调用微信API access_token = get_access_token() # 需实现AccessToken获取 url = f"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}" payload = { "touser": openid, "msgtype": "text", "text": {"content": f"{text}\n\n{desp}"} } response = requests.post(url, json=payload) return "Message Sent" if response.json().get('errcode') == 0 else "Error"三、服务部署Nginx配置server { listen 443 ssl; server_name wx.yourdomain.com; ssl_certificate /path/to/fullchain.pem; ssl_certificate_key /path/to/privkey.pem; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_…

H5网站接入微信登录详细步骤
type: item
date: 2025-04-22T21:18:00+08:00
description: 前期准备1. 注册微信开放平台访问微信开放平台注册开发者账号完成开发者资质认证创建网站应用2. 获取必要的参数AppID：应用的唯一标识AppSecret：应用密钥网站域名：需要配置的网站域名回调域名：用户授权后跳转的域名3. 配置安全域名登录微信开放平台进入"网站应用"管理添加网站域名下载验证文件并上传到网站根目录开发步骤1. 引入微信JS-SDK 2. 配置微信JS-SDKwx.config({ debug: false, // 开启调试模式 appId: '你的AppID', timestamp: '', // 生成签名的时间戳 nonceStr: '', // 生成签名的随机串 signature: '', // 签名 jsApiList: [] // 需要使用的JS接口列表 });3. 实现登录流程3.1 获取授权码function getWechatAuth() { const appid = '你的AppID'; const redirect_uri = encodeURIComponent('你的回调地址'); const scope = 'snsapi_login'; // 授权作用域 const state = '随机字符串'; // 防CSRF攻击 const url = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`; window.location.href = url; }3.2 获取访问令牌async function getAccessToken(code) { const appid = '你的AppID'; const secret = '你的AppSecret'; try { const response = await fetch(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${code}&grant_type=authorization_code`); const data = await response.json(); return data; } catch (error) { console.error('获取访问令牌失败:', error); return null; } }3.3 获取用户信息async function getUserInfo(access_token, openid) { try { const response = await fetch(`https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${openid}`); const data = await response.json(); return data; } catch (error) { console.error('获取用户信息失败:', error); return null; } }4. 处理回调// 在回调页面处理授权码 const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); const state = urlParams.get('state'); if (code && state) { // 验证state防止CSRF攻击 if (state === '你之前生成的随机字符串') { // 获取访问令牌 const tokenData = await getAccessToken(code); if (tokenData) { // 获取用户信息 const userInfo = await getUserInfo(tokenData.access_token, tokenData.openid); if (userInfo) { // 处理用户信息，如保存到本地存储或发送到服务器 handleUserInfo(userInfo); } } } }注意事项1. 安全相关state参数：必须使用随机字符串，防止CSRF攻击HTTPS：必须使用HTTPS协议域名验证：确保域名与开放平台配置一致密钥保护：AppSecret必须妥善保管，不要暴露在前端2. 用户…

基于uniapp+vant的健身会员管理系统h5前端
type: item
date: 2025-04-17T01:52:00+08:00
description: 基于uni-app的健身会员管理系统前端技术分析项目背景本来是打算做一个会员管理的wx小程序，由于我开始前未弄清楚wx小程序原生语言和uniapp都分别支持什么组件，只知道uniapp可以开发小程序，直接就使用了vue3+vant4组件。做到最后要打包为微信小程序时傻了眼，成堆报错，查了查错误后才知道几乎都是vant4组件的错，根本用不了。查了查才知道vant weapp是专门用于小程序和app的组件，所以我就全部替换了，发现还是不行：页内跳转方法不对，底部导航栏导航方法也不对。。。于是索性不改了，还好备份过，h5就h5吧。业主后来想通过微信小程序来给他的会员发送到期请续费的通知（服务号通知）。但是经过我对这块狠狠地补习后，我发现目前的系统并不能做到这点，需要让会员们通过微信授权登录进来（但是感觉纯H5网站实现微信授权登录挺麻烦的），这样的话可以获取到他们的微信用户信息，就能通过服务号发送给每位授权登录的会员。我突然想到可不可以使用微信原生框架开发一个只做登录，登录的请求和返回都对应做好的这个h5网站，这样的话既能用微信官方登录接口，登录后的画面是这个h5网站，两全其美。但是哪有我想的这莫简单，微信虽然有一个<webview>可以做外部网站的显示容器，但是需要设置授权，所以行不通。后面我会单独发一篇文章，关于微信小程序开发方式以及我碰到的全部麻烦。最后我找到了一个公众号，专门转发这种通知，但有限制。所以最后到期通知只能发给业主自己，且没有会员登录的功能。后面会发一篇后端和数据库的实现以及如何部署。项目概述这是一个基于uni-app开发的健身会员管理系统，主要用于管理会员信息、课程进度以及发送到期提醒等功能。项目采用了Vue 3 + Vite的技术栈，整体架构清晰，代码组织规范。技术栈前端框架：Vue 3构建工具：ViteUI组件库：Vant weappHTTP请求：Axios跨端框架：uni-appAPI设计与实现1. 请求配置与拦截器项目使用了axios进行HTTP请求，并配置了完整的请求拦截和响应拦截机制。让我们来看看具体的实现：// 后端API配置 const backendAPI = { baseUrl: "/api", } // 创建axios实例 const instance = axios.create({ baseURL: backendAPI.baseUrl, timeout: 30000, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, withCredentials: true })这段代码创建了一个axios实例，设置了基本的请求配置：baseURL: 设置API的基础路径timeout: 设置请求超时时间为30秒headers: 设置请求头，指定内容类型为JSONwithCredentials: 允许跨域请求携带cookieAPI路径配置详解在代码中出现的 /api 是一个API的基础路径（base URL），它表示：代理路径：在开发环境中，这个 /api 通常会被配置为代理路径比如当你在本地开发时，请求 /api/member/list 实际上会被代理到 http://localhost:3000/member/list 这样的实际后端地址实际作用：它作为所有API请求的前缀比如 getMemberList 方法实际请求的完整URL是 /api/member/list这样可以统一管理所有API的路径配置方式：在 vite.config.js 中通常会配置代理，类似这样：server: { proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } } }实际部署时：在生产环境中，这个 /api 可能会指向实际的服务器地址比如 https://api.yourdomain.com这样设计的好处是：开发时可以使用代理避免跨域问题部署时只需要修改代理配置，不需要改代码统一管理所有API请求的路径前缀2. 请求拦截器instance.interceptors.request.use( config => { const token = uni.getStorageSync('token') if (token) { config.headers['Authorization'] = `Bearer ${token.trim()}` } return config }, error => { return Promise.reject(error) } )请求拦截器的主要作用是：在每次请求前自动添加token到请求头…