Files
WXProgram/miniprogram/services/userService.ts
2025-10-19 13:40:20 +08:00

356 lines
9.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 用户服务文件
// 用户服务 - 处理用户认证、会话管理、权限验证等
import { UserInfo, EmployeeInfo } from '../types';
import { Role } from '../utils/roleUtils';
import apiService from './apiService';
/**
* 用户服务类
* 提供用户认证、信息管理、权限验证等功能
*/
class UserService {
/**
* 构造函数
*/
constructor() {
// 不再使用模拟数据
}
/**
* 获取用户信息
* @returns 用户信息
*/
async getUserInfo(): Promise<UserInfo> {
return apiService.getUserInfo();
}
/**
* 用户退出登录
*/
async logout(): Promise<void> {
return apiService.logout();
}
/**
* 检查用户是否已登录
* @returns 是否已登录
*/
isLoggedIn(): boolean {
const app = getApp<any>();
return app.globalData.isLoggedIn && !!app.globalData.userInfo;
}
/**
* 获取用户角色
* @returns 用户角色或null
*/
getUserRole(): string | null {
const app = getApp<any>();
return app.globalData.userInfo && app.globalData.userInfo.role || null;
}
/**
* 检查用户是否为管理员
* @returns 是否为管理员
*/
isAdmin(): boolean {
return this.getUserRole() === Role.ADMIN;
}
/**
* 检查用户是否为货运人员
* @returns 是否为货运人员
*/
isDeliveryPerson(): boolean {
return this.getUserRole() === Role.DELIVERY_PERSON;
}
/**
* 检查位置权限
* @returns 是否拥有位置权限
*/
checkLocationPermission(): Promise<boolean> {
return new Promise((resolve) => {
wx.getSetting({
success: (res) => {
const hasPermission = res.authSetting && res.authSetting['scope.userLocation'];
resolve(!!hasPermission);
},
fail: () => {
resolve(false);
}
});
});
}
/**
* 请求位置权限
* @returns 请求是否成功
*/
requestLocationPermission(): Promise<boolean> {
return new Promise((resolve) => {
wx.authorize({
scope: 'scope.userLocation',
success: () => {
resolve(true);
},
fail: () => {
resolve(false);
}
});
});
}
/**
* 获取全局用户信息
* @returns 全局用户信息或null
*/
getGlobalUserInfo(): UserInfo | null {
const app = getApp<any>();
return app.globalData.userInfo as UserInfo | null;
}
/**
* 执行静默登录流程:微信登录->个人服务器登录->进入基础界面->签到/注册
* @returns 登录结果
*/
async wxLogin(): Promise<{
success: boolean;
userInfo?: UserInfo;
openid?: string;
session_key?: string;
token?: string;
}> {
try {
// 获取微信登录code
console.log('步骤1: 获取微信登录code');
const code = await this.getWxLoginCode();
if (!code) {
console.error('步骤1失败: 获取微信登录code失败');
throw new Error('获取微信登录code失败');
}
console.log('步骤1成功: 获取到微信登录code');
// 调用微信登录API
console.log('步骤2: 调用微信登录API');
const wxLoginResult = await this.ServerLogin(code);
if (wxLoginResult.success) {
console.log('步骤2成功: 微信登录API调用成功');
// 静默登录模式下,不主动获取用户信息
let userInfo = wxLoginResult.userInfo;
return {
success: true,
userInfo,
openid: wxLoginResult.openid,
session_key: wx.getStorageSync('session_key'), //TODO:服务器已经下发
token: wxLoginResult.token
};
} else {
console.error('步骤2失败: 微信登录API返回失败');
return {
success: false,
openid: wxLoginResult.openid
};
}
} catch (error) {
console.error('登录流程异常:', error);
return { success: false };
}
}
/**
* 微信登录成功后调用个人服务器登录消息
* @param code 微信登录授权码
* @returns 登录结果
*/
async ServerLogin(code: string): Promise<{ success: boolean; openid?: string; token?: string; userInfo?: UserInfo }> {
try {
// 真实API模式
//TODO: 登录成功的基础数据:服务器下发的公共游客可看的数据
const result = await apiService.ServerLogin(code);
// 保存到本地存储
wx.setStorageSync('userInfo', result.user);
wx.setStorageSync('token', result.token);
wx.setStorageSync('openid', result.openid);
wx.setStorageSync('session_key', result.session_key);
// 同时保存到全局数据确保后续API调用能正确获取token
const app = getApp<any>();
app.globalData.token = result.token;
return {
success: true,
openid: result.openid,
token: result.token,
userInfo: result.user
};
} catch (error) {
console.error('微信登录失败:', error);
return { success: false };
}
}
/**
* 获取微信登录code
*/
private async getWxLoginCode(): Promise<string | null> {
return new Promise((resolve) => {
wx.login({
success: (res) => {
if (res.code) {
console.log('成功获取到登录code');
resolve(res.code);
} else {
console.error('获取登录code失败返回值为空');
resolve(null);
}
},
fail: (error) => {
console.error('wx.login调用失败:', error);
resolve(null);
}
});
});
}
/**
* 更新用户信息
* @param userInfo 待更新的用户信息
* @returns 更新后的用户信息
*/
async updateUserInfo(userInfo: Partial<UserInfo>): Promise<UserInfo> {
return apiService.updateUserInfo(userInfo);
}
/**
* 获取用户签到状态
* @returns 用户状态信息
*/
async getUserStatus(): Promise<{ status: 'signed_in' | 'signed_out' | 'registered' | 'unregistered'; lastSignInTime?: string; lastSignOutTime?: string }> {
try {
// 调用服务器接口获取用户状态
const response = await apiService.getUserStatus();
return response;
} catch (error: any) {
console.error('获取用户状态失败:', error);
// 如果是404错误接口不存在返回null让前端使用本地逻辑
if (error.message && error.message.includes('404')) {
console.log('服务器状态接口不存在,使用本地逻辑');
return null as any; // 返回null表示服务器接口不可用
}
// 其他网络错误时返回默认状态
return {
status: 'registered'
};
}
}
/**
* 用户签到
* @param initialLocation 初始位置数据(必须)
* @returns 签到结果和更新后的用户信息
*/
async signIn(initialLocation: { latitude: number; longitude: number; timestamp: number }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
const userInfo = this.getGlobalUserInfo();
if (!userInfo || !userInfo.id) {
throw new Error('用户未登录,无法签到');
}
// 检查是否有有效的token防止后端空指针异常
const app = getApp<any>();
if (!app.globalData.token) {
throw new Error('用户认证信息缺失,请重新登录');
}
return apiService.userSignIn(userInfo.id, initialLocation);
}
/**
* 用户签退
* @returns 签退结果
*/
async signOut(): Promise<{ success: boolean; message?: string }> {
const userInfo = this.getGlobalUserInfo();
if (!userInfo || !userInfo.id) {
throw new Error('用户未登录,无法签退');
}
// 检查是否有有效的token防止后端空指针异常
const app = getApp<any>();
if (!app.globalData.token) {
throw new Error('用户认证信息缺失,请重新登录');
}
return apiService.userSignOut(userInfo.id);
}
/**
* 用户注册
* @param registerInfo 注册信息
* @returns 注册结果和员工信息
*/
async register(registerInfo: { name: string; phone: string }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
return apiService.userRegister(registerInfo);
}
/**
* 获取用户权限列表
* @returns 权限列表
*/
async getUserPermissions(): Promise<string[]> {
return apiService.getUserPermissions();
}
/**
* 检查用户是否在线
* @returns 是否在线
*/
async checkUserOnline(): Promise<boolean> {
return apiService.checkUserOnline();
}
/**
* 获取用户会话信息
* @returns 会话信息
*/
async getSessionInfo(): Promise<{
userId: number;
sessionId: string;
expiresAt: number;
permissions: string[];
}> {
return apiService.getSessionInfo();
}
/**
* 刷新用户令牌
* @param oldToken 旧令牌
* @returns 新令牌及过期时间
*/
async refreshToken(oldToken: string): Promise<{ token: string; expiresAt: number }> {
return apiService.refreshToken(oldToken);
}
/**
* 验证用户权限
* @param permission 待验证的权限
* @returns 是否拥有该权限
*/
async verifyPermission(permission: string): Promise<boolean> {
return apiService.verifyPermission(permission);
}
}
/**
* 用户服务单例实例
* 导出供应用程序全局使用
*/
export default new UserService();