完成用户登录和全局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<IAppOption>({
globalData: {
token: "",
userInfo: null
},
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
console.log(res.code)
// 发送 res.code 到后台换取 openId, sessionKey, unionId
},
})
const token = wx.getStorageSync("token");
if (token) {
this.globalData.token = token;
}
},
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">
<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_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-item
wx:for="{{list}}"

View File

@@ -23,12 +23,13 @@ Component({
},
async wxPhone(e: { detail: any; }){
console.log("授权回调结果:", e);
if (e.detail.errMsg === "getPhoneNumber:ok") {
const { encryptedData, iv} = e.detail;
console.log("encryptedData:",encryptedData)
const code = await this.getLoginCode();
console.log("获得的code为",code)
wx.request({
wx.request<WechatMiniprogram.LoginUserMsg>({
url: `${envConfig.apiBaseUrl}/user/login`,
method: "POST",
data: {
@@ -45,11 +46,60 @@ Component({
theme: 'success',
direction: 'column',
});
// 登录成功,存储用户信息并跳转首页
//wx.setStorageSync("userInfo", res.data.userInfo);
//wx.navigateTo({ url: "/pages/index/index" });
} else {
wx.showToast({ title: "登录失败", icon: "none" });
const app = getApp()
app.setToken(res.data.token)
app.setUserInfo({
uid: res.data.userinfo.uid,
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() {
@@ -61,6 +111,30 @@ Component({
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() {
// 获取当前页面栈
const pages = getCurrentPages();

View File

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

View File

@@ -4,6 +4,7 @@
"t-grid": "tdesign-miniprogram/grid/grid",
"t-grid-item": "tdesign-miniprogram/grid-item/grid-item",
"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({
data: {
img1: 'https://tdesign.gtimg.com/mobile/demos/example1.png',
img2: 'https://tdesign.gtimg.com/mobile/demos/example2.png',
img3: 'https://tdesign.gtimg.com/mobile/demos/example3.png',
image: 'https://tdesign.gtimg.com/mobile/demos/avatar1.png',
hasToken: false,
username: ''
},
methods: {
userlogin(){
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-avatar">
<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 class="block" class="server1">
<t-grid column="{{4}}" theme="card" >

3
typings/index.d.ts vendored
View File

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

View File

@@ -21,6 +21,22 @@ SOFTWARE.
***************************************************************************** */
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 {
/** 错误信息
*
@@ -6255,11 +6271,11 @@ wx.getSetting({
/** 用户信息 */
interface UserInfo {
/** 用户头像图片的 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': 英文;
* - 'zh_CN': 简体中文;
* - '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 {
/** 接口调用结束的回调函数(调用成功、失败都会执行) */

View File

View File

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