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

2025 后端自学UNIAPP【项目实战:旅游项目】5、个人中心页面:微信登录,同意授权,获取用户信息

一、框架以及准备工作

1、前端项目文件结构展示           2、后端项目文件结构展示

  

3、登录微信公众平台,注册一个个人的程序,获取大appid(前端后端都需要)和密钥(后端需要) 

微信公众平台微信公众平台,给个人、企业和组织提供业务服务与用户管理能力的全新服务平台。https://mp.weixin.qq.com/

4、后端代码配置上自己的appid和密钥以及相关文件

我的是 application.properties,

后端代码逻辑可以从这里获取,自己编写到自己的java后端业务代码中2025 Java 微信小程序根据code获取openid,二次code获取手机号【工具类】拿来就用-CSDN博客文章浏览阅读4次。Spring Boot实现微信小程序登录,含session_key获取和手机号解密功能。 https://blog.csdn.net/m0_47484034/article/details/147993148?spm=1001.2014.3001.5501

#wechat
wx.open.applet.app_id=自己的
wx.open.applet.secret=自己的

5、前端配置上自己的appid

 

二、前端页面源码

1、页面源码personal_center.vue

微信登录重点是:弹出框的相关逻辑

<template><view class="container"><!-- 个人信息 --><view class="info-box"><!-- 签到、设置、聊天一行 --><view class="info-header"><!-- 签到 --><view class="sign-in"><up-icon name="calendar" color="#fff" size="30"></up-icon><view class="sign-text">签到</view></view><!-- 设置和聊天 --><view class="action-icons"><up-icon name="chat" color="#fff" size="30"></up-icon><up-icon name="setting" color="#fff" size="30" style="margin-left: 20rpx;"></up-icon></view></view><!-- 个人信息卡片 --><view class="profile-card" @click="toGetUserInfo"><!-- 个人信息卡片 信息主体 --><view class="profile-main"><!-- 如果未登录/未注册显示默认头像并提示注册/登录 --><template v-if="!userInfo.nickName"><!-- 默认头像 --><image class="avatar" src="../../static/logo.png" mode="aspectFill"></image><!-- 去注册/登录 --><view class="nikename">注册 / 登录</view></template><!-- 如果登录后,显示出头像和昵称 --><template v-else><!-- 获取头像 --><image class="avatar" image :src="userInfo.avatar" mode="aspectFill"></image><!-- 昵称 --><view class="nikename">{{userInfo.nickName}}</view></template></view><view class="profile-other"><view class="profile-other-item favourite"><view class="profile-other-item-num favourite—num">5</view><view class="profile-other-item-text favourite-text">最爱</view></view><view class="profile-other-item browse"><view class="profile-other-item-num browse-num">100</view><view class="profile-other-item-text browse-text">浏览</view></view></view></view></view><!-- 功能列表 --><view class="list-box"><view class="list"><uni-list><uni-list-item title="个人信息" showArrow thumb="/static/user-menu/个人信息.png" thumb-size="sm"clickable /><uni-list-item title="我的购物车" showArrow thumb="/static/user-menu/我的购物车.png" thumb-size="sm"clickable /><uni-list-item title="用户反馈" showArrow thumb="/static/user-menu/用户反馈.png" thumb-size="sm"clickable /><uni-list-item title="我的邮件" showArrow thumb="/static/user-menu/我的邮件.png" thumb-size="sm"clickable /><uni-list-item title="分享有礼" showArrow thumb="/static/user-menu/分享有礼.png" thumb-size="sm"clickable /></uni-list></view></view><!-- 弹出层 --><up-popup :show="show" @close="close"><view class="popup"><view class="popup-title">获取您的昵称、头像</view><!-- 头像选择 --><view class="popup-child-box"><view class="label">获取用户头像</view><button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"><image class="avatar-img" :src="userInfo.avatar || '/static/default-avatar.png'"></image></button></view><!-- 昵称输入 --><view class="popup-child-box"><view class="label">获取用户昵称</view><input class="nickname-input" type="nickname" @input="changeName" /></view><button size="default" type="primary" @click="userSubmit">确认</button></view></up-popup></view>
</template><script setup>import {ref,reactive} from 'vue'// 生命周期,进来就加载import {onLoad} from '@dcloudio/uni-app'// 生命周期,进来就加载import {login} from '../../api/my_api'import avatar from '../../uni_modules/uview-plus/components/u-avatar/avatar';onLoad(() => {// 尝试从本地存储获取用户信息const storedUserInfo = uni.getStorageSync('userInfo');if (storedUserInfo) {userInfo.nickName = storedUserInfo.nickName;userInfo.avatar = storedUserInfo.avatar;}})const userInfo = reactive({nickName: "",avatar: ""})// 控制弹出层的显示const show = ref(false)//关闭弹出层的显示const close = () => {show.value = false}const onChooseAvatar = (e) => {userInfo.avatar = e.detail.avatarUrl}const changeName = (e) => {userInfo.nickName = e.detail.value}// 用户提交信息const userSubmit = async () => {if (!userInfo.nickName || !userInfo.avatar) {uni.showToast({title: '请填写完整信息',icon: 'none'});return;}try {// 保存用户信息到本地存储uni.setStorageSync('userInfo', {nickName: userInfo.nickName,avatar: userInfo.avatar});uni.showToast({title: '信息保存成功',icon: 'success'});show.value = false} catch (e) {uni.showToast({title: '保存失败,请重试',icon: 'none'});}}//微信授权登录,获取微信用户相关信息const toGetUserInfo = () => {// 如果已经有用户信息,直接显示弹窗if (userInfo.nickName && userInfo.avatar) {show.value = true;return;}uni.showModal({title: "温馨提示",content: "授权登录才可以正常使用小程序",success(res) {if (res.confirm) {uni.login({success: async (data) => {uni.getUserInfo({provider: 'weixin',success: async function(infoRes) {const user = await login(data.code, infoRes.userInfo.avatarUrl)userInfo.nickName = infoRes.userInfo.nickNameuserInfo.avatar = infoRes.userInfo.avatarUrl// 保存用户信息到本地存储uni.setStorageSync('userInfo', {nickName: userInfo.nickName,avatar: userInfo.avatar});show.value = true}})}})}}})}
</script><style lang="scss" scoped>.container {height: 100vh;background-color: #f5f5f5;// 个人信息区域.info-box {width: 100%;position: relative;z-index: 1;overflow: hidden;padding: 40rpx 30rpx;box-sizing: border-box;&::after {content: "";width: 140%;height: 400rpx;z-index: -1;position: absolute;top: 0;left: -20%;background-color: #6799FF;border-radius: 0 0 50% 50%;}// 顶部图标行.info-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 40rpx;.sign-in {display: flex;align-items: center;.sign-text {color: white;font-size: 28rpx;margin-left: 10rpx;}}.action-icons {display: flex;align-items: center;}}// 个人信息卡片.profile-card {background-color: #fff;border-radius: 20rpx;padding: 30rpx;box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.08);// 个人信息卡片 信息主体.profile-main {display: flex;align-items: center;// 用户头像.avatar {width: 120rpx;height: 120rpx;border-radius: 50%;margin-right: 30rpx;}// 用户昵称.nikename {font-size: 36rpx;font-weight: bold;color: #333;}}.profile-other {display: flex;justify-content: space-around;align-items: center;.profile-other-item {text-align: center;margin-top: 40rpx;.profile-other-item-num {color: black;font-weight: 700;font-size: 25rpx;}.profile-other-item-text {color: #757575;margin-top: 10rpx;font-size: 20rpx;}}}}}// 功能列表.list-box {height: 200rpx;margin: -10rpx auto 0;padding: 20rpx;box-sizing: border-box;border-radius: 12rpx;}/* 弹出层样式 */.popup {padding: 40rpx;border-radius: 20rpx;background: #fff;/* 标题 */.popup-title {margin-bottom: 40rpx;font-size: 36rpx;font-weight: bold;text-align: center;color: #333;}}/* 每个选项容器 */.popup-child-box {display: flex;justify-content: space-between;align-items: center;padding: 30rpx 0;border-bottom: 1rpx solid #f0f0f0;/* 标签文字 */.label {font-size: 32rpx;color: #666;width: 200rpx;}/* 头像按钮 */.avatar-btn {margin: 0;padding: 0;border: none;background: transparent;line-height: 1;.avatar-img {width: 100rpx;height: 100rpx;border-radius: 50%;background: #f5f5f5;}}/* 昵称输入框 */.nickname-input {flex: 1;text-align: right;font-size: 32rpx;color: #333;}}}
</style>

2、调用的后端各个接口的js文件:my_api.js

// 引入公共的请求封装
import http from './my_http.js'// 登录接口
export const login = async (code, avatar) => {const res = await http('/login/getWXSessionKey', {code,avatar});
};// 获取bannner列表
export const getBannerList = () => {return http('/banner/list')
}// 获取景点类型列表(支持传入typeId参数)
export const getTypeList = () => {return http('/type/list')
}// 获取景点列表
export const getAttractionList = (typeId) => {// 如果有typeId就拼接到URL,没有就不加const url = typeId ? `/attraction/list?typeId=${typeId}` : '/attraction/list'return http(url)
}
// 获取景点详情
export const getAttractionInfo = (attractionId) => {return http(`/attraction/getInfo/${attractionId}`)
}

3、公共http请求封装的js文件:my_http.js

/*** 基础API请求地址(常量,全大写命名规范)* @type {string}* @constant*/
let BASE_URL="http://localhost:9001/travel"
/*** 封装的HTTP请求核心函数* @param {string} url - 请求的接口路径(不需要包含基础接口URL)* @param {Object} [data={}] - 请求参数,默认为空对象* @param {string} [method='GET'] - HTTP方法,默认GET,支持GET/POST/DELETE/PUT等* @returns {Promise} - 返回Promise便于链式调用* */
export default function http(url, data = {}, method = 'GET') {// 返回一个Promise对象,支持外部链式调用return new Promise((resolve, reject) => {// 调用uni-app的底层请求APIuni.request({// 拼接完整请求地址(基础接口URL +  请求的接口路径)url: BASE_URL + url,// 请求参数(GET请求时会自动转为query string)data: data,// 请求方法(转换为大写保证兼容性)method: method.toUpperCase(),// 请求头配置header: {// 从本地存储获取token,没有就位空'token': uni.getStorageSync('token') || '',// 默认JSON格式'Content-Type': 'application/json'},// 请求成功回调(注意:只要收到服务器响应就会触发,无论HTTP状态码)success: (res) => {/* HTTP层状态码处理(4xx/5xx等也会进入success回调) */if (res.statusCode !== 200) {const errMsg = `[${res.statusCode}]${res.errMsg || '请求失败'}`showErrorToast(errMsg)// 使用Error对象传递更多错误信息reject(errMsg)}/* 业务层状态码处理(假设1表示成功) */if (res.data.code === "200") {// 提取业务数据(约定data字段为有效载荷)resolve(res.data.data)} else {// 业务错误处理const errMsg = res.data.msg || `业务错误[${res.data.code}]`showErrorToast(errMsg)reject(res.data.msg)}},// 请求失败回调(网络错误、超时等)fail: (err) => {const errMsg = `网络连接失败: ${err.errMsg || '未知错误'}`showErrorToast(errMsg)reject(new Error(errMsg))},})})
}/*** 显示统一格式的错误提示(私有工具方法)* @param {string} message - 需要显示的错误信息* @private*/
function showErrorToast(message) {uni.showToast({title: message, // 提示内容icon: 'none', // 不显示图标duration: 3000 // 3秒后自动关闭})
}

三、效果

      

     

相关文章:

2025 后端自学UNIAPP【项目实战:旅游项目】5、个人中心页面:微信登录,同意授权,获取用户信息

一、框架以及准备工作 1、前端项目文件结构展示 2、后端项目文件结构展示 3、登录微信公众平台&#xff0c;注册一个个人的程序&#xff0c;获取大appid&#xff08;前端后端都需要&#xff09;和密钥&#xff08;后端需要&#xff09; 微信公众平台微信公众平台&…...

校园网规划与设计方案

一、项目概述 校园网是学校实现信息化教学、科研与管理的重要基础设施,其性能与稳定性直接影响学校的整体发展。随着学校规模不断扩大、教学科研活动日益丰富,对校园网的带宽、可靠性、安全性以及智能化管理等方面提出了更高要求。本规划与设计方案旨在构建一个高速、稳定、…...

蓝桥杯算法题 -蛇形矩阵(方向向量)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 P…...

配置VScodePython环境Python was not found;

Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Manage App Execution Aliases. 候试试重启电脑。 在卸载重装python后会出现难以解决的局面&#xff0c;系统变量&#xff0c;命令行&#…...

ollama 重命名模型

ollama 重命名模型 ollama list# 查看列表 ollama list # 生成原模型的Modelfile文件 ollama show --modelfile qwen3:32b > Modelfile # 从Modelfile文件创建新的模型 ollama create qwen3 -f Modelfile # 删除原模型 ollama rm qwen3:32b...

Qt信号槽机制与UI设计完全指南:从基础原理到实战应用

目录 前言一、信号槽1.1 传参1.2 Qt信号与槽的对应关系1.2.1一对多关系1.2.2 多对一关系 二、Designer三、Layout 布局3.1 基础用法3.2 打破布局3.3 贴合窗口3.4 伸展器&#xff08;Spacer&#xff09;3.5 嵌套布局 四、ui指针五、QWidget六、QLabel 标签使用指南总结 前言 本…...

Anaconda环境中conda与pip命令的区别

文章目录 conda与pip的基本区别在Anaconda环境中的实际差异安装包环境管理依赖解决示例最佳实践建议 常见问题解答 conda与pip的基本区别 包来源与生态系统 conda&#xff1a;从Anaconda默认仓库或conda-forge等渠道获取包 不仅管理Python包&#xff0c;还能管理非Python依赖&…...

XBL6501/02/03在POE设备上的应用方案

前言&#xff1a; 在当今数字化时代&#xff0c;POE&#xff08;Power over Ethernet&#xff09;设备因其能够通过以太网线同时传输数据和电力而被广泛应用。为了满足这些设备日益增长的电源需求&#xff0c;芯伯乐推出了XBL6501/02/03系列DC-DC电源芯片&#xff0c;为POE设备…...

编程题 03-树2 List Leaves【PAT】

文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 Given a tree, you are supposed to list all the leaves in the order of top down, and left to right. 输入格式 Each input file contains one test case. For each case, …...

生信小白学Rust-03

语句和表达式 举个栗子&#x1f330; fn add_with_extra(x: i32, y: i32) -> i32 {let x x 1; // 语句let y y 5; // 语句x y // 表达式 } // 语句执行操作 // 表达式会返回一个值 怎么区分呢&#xff0c;目前我的理解是只要返回了值&#xff0c;那它就是表达式 fn…...

缺乏需求优先级划分时,如何合理分配资源?

当需求优先级不明确时&#xff0c;合理分配资源的关键在于建立统一评估标准、实施敏捷资源管理、提升团队协作效率、加强跨部门沟通机制。尤其是建立统一评估标准至关重要&#xff0c;它能帮助组织快速判断各项需求的重要性与紧迫性&#xff0c;从而实现资源的动态匹配与有效利…...

操作系统学习笔记第3章 内存管理(灰灰题库)

1. 单选题 某页式存储管理系统中&#xff0c;主存为 128KB&#xff0c;分成 32 块&#xff0c;块号为 0、1、2、3、…、31。某作业有 5 块&#xff0c;其页号为 0、1、2、3、4&#xff0c;被分别装入主存的 3、8、4、6、9 块中。有一逻辑地址为 [3, 70]&#xff08;其中方括号中…...

详细分析python 中的deque 以及和list 的用法区别

dqque :双端队列&#xff0c;可以快速的从另外一侧追加和推出对象,deque是一个双向链表&#xff0c;针对list连续的数据结构插入和删除进行优化。它提供了两端都可以操作的序列&#xff0c;这表示在序列的前后你都可以执行添加或删除操作。 通过上图可以看出&#xff0c;deque …...

Stack overflow

本文来源 &#xff1a;腾讯元宝 Stack Overflow - Where Developers Learn, Share, & Build Careers 开发者学习&#xff0c;分享 通过学习、工作和经验积累等方式&#xff0c;逐步建立和发展自己的职业生涯。 Find answers to your technical questions and help othe…...

和为target问题汇总

文章目录 习题377.组合总和 IV494.目标和 和为target的问题&#xff0c;可以有很多种问题的形式的考察&#xff0c;当然&#xff0c;及时的总结与回顾有利于我们熟练掌握这些知识&#xff01; 习题 377.组合总和 IV 377.组合总和 IV 思路分析&#xff1a;通过观察&#xff0…...

STM32单片机内存分配详细讲解

单片机的内存无非就两种&#xff0c;内部FLASH和SRAM&#xff0c;最多再加上一个外部的FLASH拓展。在这里我以STM32F103C8T6为例子讲解FLASH和SRAM。 STM32F103C8T6具有64KB的闪存和20KB的SRAM。 一. Flash 1.1 定义 非易失性存储器&#xff0c;即使在断电后&#xff0c;其所…...

RedHat7 如何更换yum镜像源

RedHat7如何更换yum镜像源&#xff1f; # 删除系统自带 yum rpm -qa|grep -e yum -e python-urlgrabber |xargs rpm -e --nodeps# 下载yum与wget的rpm软件包 curl -O http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/yum-3.4.3-168.el7.centos.noarch.rpm curl -O ht…...

Ubuntu 编译SRS和ZLMediaKit用于视频推拉流

SRS实现视频的rtmp webrtc推流 ZLMediaKit编译生成MediaServer实现rtsp推流 SRS指定某个固定网卡&#xff0c;修改程序后重新编译 打开SRS-4.0.0/trunk/src/app/srs_app_rtc_server.cpp&#xff0c;在 232 行后面添加&#xff1a; ZLMediaKit编译后文件存放在ZLMediakit/rele…...

Intellij报错:the file size(3.47M) exceeds configured limit (2.56MB)

今天在部署一个教学平台的时候&#xff0c;当执行数据库脚本出现了以上问题。 自己把解决的方案分享给大家&#xff1a; 于IntelliJ IDEA或PyCharm&#xff0c;可以通过编辑idea.properties文件来增加文件大小限制。 打开idea.properties文件&#xff0c;通常位于IDE的安装目录…...

大数据技术全景解析:Spark、Hadoop、Hive与SQL的协作与实战

引言&#xff1a;当数据成为新时代的“石油” 在数字经济时代&#xff0c;数据量以每年50%的速度爆发式增长。如何高效存储、处理和分析PB级数据&#xff0c;成为企业竞争力的核心命题。本文将通过通俗类比场景化拆解&#xff0c;带你深入理解四大关键技术&#xff1a;Hadoop、…...

软考软件评测师——软件工程之系统维护

一、系统质量属性 可维护性 衡量软件系统适应修改的难易程度&#xff0c;包括修复缺陷、扩展功能或调整规模的效率。计算公式为&#xff1a;系统可用时间占比 1/(1平均修复时间)&#xff0c;其中平均修复时间(MTTR)指排除故障所需的平均耗时。 可靠性 vs 可用性 可靠性&…...

Unity动画与生命周期函数

一、Animator动画组件 Animator组件是Unity中用于管理和控制动画的主要工具&#xff0c;它可以处理复杂的动画状态机和动画片段之间的过 1.动画状态机 Animator组件的核心是动画状态机&#xff0c;它由多个动画状态和状态之间的过渡组成。可以通过Unity的动画窗口来创建和编辑…...

合并两个有序数组的高效算法详解

合并两个有序数组的高效算法详解 **合并两个有序数组的高效算法详解****1. 问题描述****2. 常见解法分析****方法 1&#xff1a;合并后排序&#xff08;暴力法&#xff09;****方法 2&#xff1a;双指针法&#xff08;额外空间&#xff09;** **3. 最优解法&#xff1a;双指针从…...

虚拟Python 环境构建器virtualenv安装(macOS版)

前提 之前我们使用pyenv安装好了Python 3.13.3&#xff0c;并且&#xff0c;全局都使用这个版本的python。现在我们来安装virtualenv。 pipx安装 brew install pipx pipx ensurepath sudo pipx ensurepath --global # optional to allow pipx actions with --global argumen…...

解决ubuntu20中tracker占用过多cpu,引起的风扇狂转

track是linux中的文件索引工具&#xff0c;ubuntu18之前是默认不安装的&#xff0c;所以在升级到20后会默认安装&#xff0c;它是和桌面程序gnome绑定的&#xff0c;甚至还有很多依赖项&#xff0c;导致无法删除&#xff0c;一旦删除很多依赖项都不能运行&#xff0c;禁用也很难…...

在线文档管理系统 spring boot➕vue|源码+数据库+部署教程

&#x1f4cc; 一、项目简介 本系统采用Spring Boot Vue ElementUI技术栈&#xff0c;支持管理员和员工两类角色&#xff0c;涵盖文档上传、分类管理、公告发布、员工资料维护、部门岗位管理等核心功能。 系统目标是打造一个简洁高效的内部文档管理平台&#xff0c;便于员工…...

在UI 原型设计中,交互规则有哪些核心要素?

在UI 原型设计中&#xff0c;交互规则主要有三个核心要素&#xff0c;分别为重要性、原则与实践&#xff0c;具体表现在&#xff1a; 一、交互规则在 UI 原型设计中的重要性 明确交互逻辑&#xff1a;设计阶段制定交互规则&#xff0c;清晰定义界面元素操作响应。 如社交应用…...

CSS图片垂直居中问题解决方案

在 CSS 中&#xff0c;使用 vertical-align: middle 导致图片略微向下偏移的现象&#xff0c;本质上是由于 行内元素的基线对齐规则 和 父容器上下文环境 共同作用的结果。以下是具体原因和解决方案&#xff1a; 原因详解 1. vertical-align: middle 的真实含义 该属性 不会让…...

STC8H系列单片机STC8H_H头文件功能注释

#ifndef __STC8H_H__ // 条件编译:如果未定义__STC8H_H__宏 #define __STC8H_H__ // 则定义该宏,防止头文件被重复包含 / //包含本头文件后,不用另外再包含"REG51.H" // 提示:本头文件已包含基本寄存器定义 sfr P0 = …...

Python类的力量:第五篇:魔法方法与协议——让类拥有Python的“超能力”

文章目录 前言&#xff1a;从“普通对象”到“Python原生公民”的进化之路 一、魔法方法&#xff1a;赋予对象“超能力”的基因1. 构造与析构&#xff1a;对象生命周期的“魔法开关”2. 字符串表示&#xff1a;对象的“自我介绍”3. 运算符重载&#xff1a;让对象支持“数学魔法…...