Files
ZhiQiXiaoYuan/utils/auth.js
ChuXun eaab9a762a 1
2025-10-19 20:28:31 +08:00

317 lines
6.3 KiB
JavaScript

/**
* 用户认证和权限管理系统
*/
const { Storage } = require('./storage.js')
const { logger } = require('./logger.js')
const { store } = require('./store.js')
class AuthManager {
constructor() {
this.token = null
this.userInfo = null
this.permissions = []
this.init()
}
/**
* 初始化
*/
init() {
this.token = Storage.get('token')
this.userInfo = Storage.get('userInfo')
this.permissions = Storage.get('permissions', [])
if (this.token && this.userInfo) {
store.setState({
isLogin: true,
userInfo: this.userInfo
})
}
}
/**
* 微信登录
*/
async wxLogin() {
try {
// 1. 获取微信登录code
const { code } = await this._wxLogin()
logger.info('微信登录code获取成功', { code })
// 2. 获取用户信息
const userInfo = await this._getUserProfile()
logger.info('用户信息获取成功', { userInfo })
// 3. 调用后端登录接口
// TODO: 替换为实际的后端登录接口
const response = await this._mockLogin(code, userInfo)
// 4. 保存登录状态
this.setAuth(response.token, response.userInfo, response.permissions)
logger.info('登录成功', { userId: response.userInfo.id })
return response
} catch (error) {
logger.error('登录失败', error)
throw error
}
}
/**
* 微信登录 - 获取code
*/
_wxLogin() {
return new Promise((resolve, reject) => {
wx.login({
success: resolve,
fail: reject
})
})
}
/**
* 获取用户信息
*/
_getUserProfile() {
return new Promise((resolve, reject) => {
wx.getUserProfile({
desc: '用于完善用户资料',
success: (res) => resolve(res.userInfo),
fail: reject
})
})
}
/**
* 模拟登录(开发用)
*/
async _mockLogin(code, userInfo) {
// TODO: 替换为实际的API调用
return new Promise((resolve) => {
setTimeout(() => {
resolve({
token: 'mock_token_' + Date.now(),
userInfo: {
id: Math.random().toString(36).substr(2, 9),
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
studentId: '2021001',
grade: '2021级',
major: '计算机科学与技术',
email: 'student@example.com'
},
permissions: ['user', 'student']
})
}, 500)
})
}
/**
* 设置认证信息
*/
setAuth(token, userInfo, permissions = []) {
this.token = token
this.userInfo = userInfo
this.permissions = permissions
Storage.set('token', token)
Storage.set('userInfo', userInfo)
Storage.set('permissions', permissions)
store.setState({
isLogin: true,
userInfo: userInfo
})
logger.info('认证信息已保存')
}
/**
* 退出登录
*/
logout() {
this.token = null
this.userInfo = null
this.permissions = []
Storage.remove('token')
Storage.remove('userInfo')
Storage.remove('permissions')
store.setState({
isLogin: false,
userInfo: null
})
logger.info('已退出登录')
wx.showToast({
title: '已退出登录',
icon: 'success'
})
}
/**
* 检查是否登录
*/
isLogin() {
return !!this.token && !!this.userInfo
}
/**
* 获取用户信息
*/
getUserInfo() {
return this.userInfo
}
/**
* 获取Token
*/
getToken() {
return this.token
}
/**
* 检查权限
*/
hasPermission(permission) {
return this.permissions.includes(permission)
}
/**
* 检查多个权限(需要全部满足)
*/
hasAllPermissions(permissions) {
return permissions.every(p => this.hasPermission(p))
}
/**
* 检查多个权限(满足任一即可)
*/
hasAnyPermission(permissions) {
return permissions.some(p => this.hasPermission(p))
}
/**
* 更新用户信息
*/
async updateUserInfo(updates) {
try {
// TODO: 调用后端API更新用户信息
const updatedUserInfo = { ...this.userInfo, ...updates }
this.userInfo = updatedUserInfo
Storage.set('userInfo', updatedUserInfo)
store.setState({ userInfo: updatedUserInfo })
logger.info('用户信息更新成功', updates)
wx.showToast({
title: '更新成功',
icon: 'success'
})
return updatedUserInfo
} catch (error) {
logger.error('用户信息更新失败', error)
throw error
}
}
/**
* 刷新Token
*/
async refreshToken() {
try {
// TODO: 调用后端API刷新token
const newToken = 'new_token_' + Date.now()
this.token = newToken
Storage.set('token', newToken)
logger.info('Token刷新成功')
return newToken
} catch (error) {
logger.error('Token刷新失败', error)
this.logout()
throw error
}
}
}
/**
* 页面权限守卫
*/
class RouteGuard {
/**
* 检查页面访问权限
*/
static check(requiredPermissions = []) {
const authManager = new AuthManager()
// 检查是否登录
if (!authManager.isLogin()) {
wx.showModal({
title: '提示',
content: '请先登录',
success: (res) => {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login'
})
} else {
wx.navigateBack()
}
}
})
return false
}
// 检查权限
if (requiredPermissions.length > 0) {
if (!authManager.hasAllPermissions(requiredPermissions)) {
wx.showToast({
title: '没有访问权限',
icon: 'none'
})
wx.navigateBack()
return false
}
}
return true
}
/**
* 页面装饰器
*/
static requireAuth(requiredPermissions = []) {
return function(target) {
const originalOnLoad = target.prototype.onLoad
target.prototype.onLoad = function(options) {
if (RouteGuard.check(requiredPermissions)) {
if (originalOnLoad) {
originalOnLoad.call(this, options)
}
}
}
return target
}
}
}
// 创建全局实例
const authManager = new AuthManager()
module.exports = {
AuthManager,
authManager,
RouteGuard
}