完成用户登录和全局token

This commit is contained in:
2025-08-11 00:40:21 +08:00
parent f7261e1915
commit 1cc9bfb8ab
15 changed files with 167 additions and 30 deletions

View File

@@ -1,19 +1,31 @@
// app.ts // app.ts
App<IAppOption>({ App<IAppOption>({
globalData: { globalData: {
token: "",
userInfo: null
}, },
onLaunch() { onLaunch() {
// 展示本地存储能力 const token = wx.getStorageSync("token");
const logs = wx.getStorageSync('logs') || [] if (token) {
logs.unshift(Date.now()) this.globalData.token = token;
wx.setStorageSync('logs', logs) }
// 登录
wx.login({
success: res => {
console.log(res.code)
// 发送 res.code 到后台换取 openId, sessionKey, unionId
},
})
}, },
setToken(token: string) {
this.globalData.token = token;
wx.setStorageSync("token", token); // 同步到缓存,持久化存储
},
// 提供清除 token 的方法(退出登录时使用)
clearToken() {
this.globalData.token = "";
wx.removeStorageSync("token");
},
setUserInfo(userInfo: WechatMiniprogram.CustomUserInfo){
this.globalData.userInfo = userInfo;
// 可选:持久化存储到缓存(根据需求决定是否需要)
wx.setStorageSync("userInfo", userInfo);
},
clearUserInfo(){
this.globalData.userInfo = null;
wx.removeStorageSync("userInfo")
}
}) })

View File

@@ -2,7 +2,7 @@
<scroll-view class="scrollarea" scroll-y type="list"> <scroll-view class="scrollarea" scroll-y type="list">
<view hidden="{{label_value !== 'label_1'}}"><home-component></home-component></view> <view hidden="{{label_value !== 'label_1'}}"><home-component></home-component></view>
<view hidden="{{label_value !== 'label_2'}}"><chat-component></chat-component></view> <view hidden="{{label_value !== 'label_2'}}"><chat-component></chat-component></view>
<view hidden="{{label_value !== 'label_3'}}"><user-component></user-component></view> <view hidden="{{label_value !== 'label_3'}}"><user-component id="userComp"></user-component></view>
<t-tab-bar t-class="t-tab-bar" value="{{label_value}}" bindchange="onChange" shape="round" theme="tag" split="{{false}}"> <t-tab-bar t-class="t-tab-bar" value="{{label_value}}" bindchange="onChange" shape="round" theme="tag" split="{{false}}">
<t-tab-bar-item <t-tab-bar-item
wx:for="{{list}}" wx:for="{{list}}"

View File

@@ -23,12 +23,13 @@ Component({
}, },
async wxPhone(e: { detail: any; }){ async wxPhone(e: { detail: any; }){
console.log("授权回调结果:", e); console.log("授权回调结果:", e);
if (e.detail.errMsg === "getPhoneNumber:ok") { if (e.detail.errMsg === "getPhoneNumber:ok") {
const { encryptedData, iv} = e.detail; const { encryptedData, iv} = e.detail;
console.log("encryptedData:",encryptedData) console.log("encryptedData:",encryptedData)
const code = await this.getLoginCode(); const code = await this.getLoginCode();
console.log("获得的code为",code) console.log("获得的code为",code)
wx.request({ wx.request<WechatMiniprogram.LoginUserMsg>({
url: `${envConfig.apiBaseUrl}/user/login`, url: `${envConfig.apiBaseUrl}/user/login`,
method: "POST", method: "POST",
data: { data: {
@@ -45,11 +46,60 @@ Component({
theme: 'success', theme: 'success',
direction: 'column', direction: 'column',
}); });
// 登录成功,存储用户信息并跳转首页 const app = getApp()
//wx.setStorageSync("userInfo", res.data.userInfo); app.setToken(res.data.token)
//wx.navigateTo({ url: "/pages/index/index" }); app.setUserInfo({
} else { uid: res.data.userinfo.uid,
wx.showToast({ title: "登录失败", icon: "none" }); username: res.data.userinfo.username,
telephone: res.data.userinfo.telephone,
gender: 2,
})
setTimeout(() => {
// 3.1 刷新user组件
const pages = getCurrentPages();
let homePage = null;
pages.forEach(page => {
if (page.route === 'pages/index/index') {
homePage = page;
}
});
if (homePage) {
const userComponent = homePage.selectComponent('#userComp');
if (userComponent) {
userComponent.refreshUserStatus();
}
} else {
// 首页不在栈中,跳转首页
wx.redirectTo({
url: '/pages/home/home'
});
// 注意:如果跳转后不需要执行下面的返回逻辑,可在此处加 return
// return;
}
// 3.2 页面跳转/返回
if (pages.length > 1) {
// 返回上一页
wx.navigateBack({
delta: 1
});
} else {
// 跳转到首页tabBar页面用switchTab
wx.switchTab({
url: '/pages/index/index'
});
}
}, 1500); // 延迟时间1500毫秒1.5秒),可根据需要调整
}else{
Toast({
selector: '#t-toast',
message: '登录失败',
theme: 'error',
direction: 'column',
});
} }
}, },
fail() { fail() {
@@ -61,6 +111,30 @@ Component({
wx.showToast({ title: "请允许授权以完成登录", icon: "none" }); wx.showToast({ title: "请允许授权以完成登录", icon: "none" });
} }
}, },
testSend(){
const token = wx.getStorageSync("token");
wx.request({
url: `${envConfig.apiBaseUrl}/user/test`,
method: "POST",
data: {
},
header:{
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
,
success(res){
console.log(res)
Toast({
selector: '#t-toast',
message: '测试成功',
theme: 'success',
direction: 'column',
});
}
})
},
onBack() { onBack() {
// 获取当前页面栈 // 获取当前页面栈
const pages = getCurrentPages(); const pages = getCurrentPages();

View File

@@ -52,7 +52,7 @@
<!-- 手机号登录按钮 --> <!-- 手机号登录按钮 -->
<button <button
class="login-btn phone-btn" class="login-btn phone-btn"
bindtap="goPhoneLogin" bindtap="testSend"
hover-class="btn-hover" hover-class="btn-hover"
> >
<icon class="btn-icon" type="phone" size="20"></icon> <icon class="btn-icon" type="phone" size="20"></icon>

View File

@@ -4,6 +4,7 @@
"t-grid": "tdesign-miniprogram/grid/grid", "t-grid": "tdesign-miniprogram/grid/grid",
"t-grid-item": "tdesign-miniprogram/grid-item/grid-item", "t-grid-item": "tdesign-miniprogram/grid-item/grid-item",
"t-avatar": "tdesign-miniprogram/avatar/avatar", "t-avatar": "tdesign-miniprogram/avatar/avatar",
"t-avatar-group": "tdesign-miniprogram/avatar-group/avatar-group" "t-avatar-group": "tdesign-miniprogram/avatar-group/avatar-group",
"t-toast": "tdesign-miniprogram/toast/toast"
} }
} }

View File

@@ -1,13 +1,38 @@
import Toast from 'tdesign-miniprogram/toast/index';
Component({ Component({
data: { data: {
img1: 'https://tdesign.gtimg.com/mobile/demos/example1.png', img1: 'https://tdesign.gtimg.com/mobile/demos/example1.png',
img2: 'https://tdesign.gtimg.com/mobile/demos/example2.png', img2: 'https://tdesign.gtimg.com/mobile/demos/example2.png',
img3: 'https://tdesign.gtimg.com/mobile/demos/example3.png', img3: 'https://tdesign.gtimg.com/mobile/demos/example3.png',
image: 'https://tdesign.gtimg.com/mobile/demos/avatar1.png', image: 'https://tdesign.gtimg.com/mobile/demos/avatar1.png',
hasToken: false,
username: ''
}, },
methods: { methods: {
userlogin(){ userlogin(){
wx.navigateTo({url:'/pages/user-login/user-login'}) wx.navigateTo({url:'/pages/user-login/user-login'})
} },
refreshUserStatus(){
console.log("主动刷新user界面")
const app = getApp();
console.log("全局userinfo",app.globalData.userInfo)
console.log("全局用户信息:", app.globalData.userInfo.username); // 这里打印的是 userInfo
const userInfo = app.globalData.userInfo || {};
console.log("user中的userInfo",userInfo)
this.setData({
hasToken: !!app.globalData.token, // 从全局变量获取token状态
username: userInfo.username
});
// 调试:确认页面数据是否正确
console.log("页面username赋值后:", this.data.username);
},
}, },
lifetimes:{
attached(){
console.log("user界面刷新")
this.refreshUserStatus()
}
}
}) })

View File

@@ -1,7 +1,8 @@
<view class="user-contain"> <view class="user-contain">
<view class="user-avatar"> <view class="user-avatar">
<t-avatar class="avatar-example" image="{{image}}" size="large" /> <t-avatar class="avatar-example" image="{{image}}" size="large" />
<a class="avatar-font" bind:tap="userlogin">点击登录/注册</a> <a class="avatar-font" bind:tap="userlogin">{{hasToken ? (username || '用户中心') : '点击登录/注册'}}</a>
<t-toast id="t-toast" />
</view> </view>
<view class="block" class="server1"> <view class="block" class="server1">
<t-grid column="{{4}}" theme="card" > <t-grid column="{{4}}" theme="card" >

3
typings/index.d.ts vendored
View File

@@ -2,7 +2,8 @@
interface IAppOption { interface IAppOption {
globalData: { globalData: {
userInfo?: WechatMiniprogram.UserInfo, userInfo?: WechatMiniprogram.CustomUserInfo | null,
token: string
} }
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback, userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback,
} }

View File

@@ -21,6 +21,22 @@ SOFTWARE.
***************************************************************************** */ ***************************************************************************** */
declare namespace WechatMiniprogram { declare namespace WechatMiniprogram {
interface CustomUserInfo {
uid: string;
username: string;
telephone: string; // 可选字段
gender: number;
}
interface LoginUserInfo {
uid: string;
username: string;
telephone: string; // 可选字段(可能不存在)
}
interface LoginUserMsg {
userinfo: LoginUserInfo
token: string
code: string
}
interface AccessFailCallbackResult { interface AccessFailCallbackResult {
/** 错误信息 /** 错误信息
* *
@@ -6255,11 +6271,11 @@ wx.getSetting({
/** 用户信息 */ /** 用户信息 */
interface UserInfo { interface UserInfo {
/** 用户头像图片的 URL。URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选0 代表 640x640 的正方形头像46 表示 46x46 的正方形头像剩余数值以此类推。默认132用户没有头像时该项为空。若用户更换头像原有头像 URL 将失效。 */ /** 用户头像图片的 URL。URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选0 代表 640x640 的正方形头像46 表示 46x46 的正方形头像剩余数值以此类推。默认132用户没有头像时该项为空。若用户更换头像原有头像 URL 将失效。 */
avatarUrl: string avatarUrl?: string
/** 用户所在城市 */ /** 用户所在城市 */
city: string city?: string
/** 用户所在国家 */ /** 用户所在国家 */
country: string country?: string
/** 用户性别 /** 用户性别
* *
* 可选值: * 可选值:
@@ -6273,11 +6289,14 @@ wx.getSetting({
* - 'en': 英文; * - 'en': 英文;
* - 'zh_CN': 简体中文; * - 'zh_CN': 简体中文;
* - 'zh_TW': 繁体中文; */ * - 'zh_TW': 繁体中文; */
language: 'en' | 'zh_CN' | 'zh_TW' language?: 'en' | 'zh_CN' | 'zh_TW'
/** 用户昵称 */ /** 用户昵称 */
nickName: string username: string
/** 用户所在省份 */ /** 用户所在省份 */
province: string province?: string
telephone: string
uid: string
} }
interface VibrateLongOption { interface VibrateLongOption {
/** 接口调用结束的回调函数(调用成功、失败都会执行) */ /** 接口调用结束的回调函数(调用成功、失败都会执行) */

View File

View File

@@ -199,6 +199,10 @@ declare namespace WechatMiniprogram.App {
} }
interface Option { interface Option {
setToken: (token: string) => void;
clearToken:()=>void;
setUserInfo(userInfo: WechatMiniprogram.CustomUserInfo): void;
clearUserInfo:()=>void;
/** 生命周期回调—监听小程序初始化 /** 生命周期回调—监听小程序初始化
* *
* 小程序初始化完成时触发,全局只触发一次。 * 小程序初始化完成时触发,全局只触发一次。