Files
ai_game/client/js/data/UserManager.js

383 lines
8.8 KiB
JavaScript
Raw Permalink Normal View History

/**
* 用户数据管理器
*/
import { get, post, put, del } from '../utils/http';
export default class UserManager {
constructor() {
this.userId = null;
this.openid = null;
this.nickname = '';
this.avatarUrl = '';
this.token = '';
this.isLoggedIn = false;
}
/**
* 检查是否已登录只检查本地缓存
* @returns {boolean} 是否已登录
*/
checkLogin() {
const cached = wx.getStorageSync('userInfo');
if (cached && cached.userId && cached.token) {
this.userId = cached.userId;
this.openid = cached.openid;
this.nickname = cached.nickname || '游客';
this.avatarUrl = cached.avatarUrl || '';
this.token = cached.token;
this.isLoggedIn = true;
return true;
}
return false;
}
/**
* 初始化用户只恢复缓存不自动登录
*/
async init() {
// 只检查本地缓存,不自动登录
this.checkLogin();
}
/**
* 执行登录供登录按钮调用
* @param {Object} userInfo - 微信用户信息头像昵称等可选
*/
async doLogin(userInfo = null) {
try {
// 获取登录code
const { code } = await this.wxLogin();
// 调用后端登录接口,传入用户信息
const result = await post('/user/login', {
code,
userInfo: userInfo ? {
nickname: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
gender: userInfo.gender || 0
} : null
});
this.userId = result.userId;
this.openid = result.openid;
// 优先使用后端返回的,其次用授权获取的
this.nickname = result.nickname || (userInfo?.nickName) || '游客';
this.avatarUrl = result.avatarUrl || (userInfo?.avatarUrl) || '';
this.token = result.token || '';
this.isLoggedIn = true;
// 缓存用户信息(包含 token
wx.setStorageSync('userInfo', {
userId: this.userId,
openid: this.openid,
nickname: this.nickname,
avatarUrl: this.avatarUrl,
token: this.token
});
return {
userId: this.userId,
nickname: this.nickname,
avatarUrl: this.avatarUrl
};
} catch (error) {
console.error('登录失败:', error);
throw error;
}
}
/**
* 退出登录
*/
logout() {
this.userId = null;
this.openid = null;
this.nickname = '';
this.avatarUrl = '';
this.token = '';
this.isLoggedIn = false;
wx.removeStorageSync('userInfo');
}
/**
* 更新用户资料
*/
async updateProfile(nickname, avatarUrl) {
if (!this.isLoggedIn) return false;
try {
await post('/user/profile', {
nickname,
avatarUrl,
gender: 0
}, { params: { userId: this.userId } });
// 更新本地数据
this.nickname = nickname;
this.avatarUrl = avatarUrl;
// 更新缓存(保留 token
wx.setStorageSync('userInfo', {
userId: this.userId,
openid: this.openid,
nickname: this.nickname,
avatarUrl: this.avatarUrl,
token: this.token
});
return true;
} catch (e) {
console.error('更新资料失败:', e);
return false;
}
}
/**
* 微信登录带超时
*/
wxLogin() {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('登录超时'));
}, 5000);
wx.login({
success: (res) => {
clearTimeout(timeout);
if (res.code) {
resolve(res);
} else {
reject(new Error('获取code失败'));
}
},
fail: (err) => {
clearTimeout(timeout);
reject(err);
}
});
});
}
/**
* 获取用户游玩进度
*/
async getProgress(storyId = null) {
if (!this.isLoggedIn) return null;
return await get('/user/progress', { userId: this.userId, storyId });
}
/**
* 保存用户进度
*/
async saveProgress(storyId, currentNodeKey, isCompleted = false, endingReached = '') {
if (!this.isLoggedIn) return;
await post('/user/progress', {
userId: this.userId,
storyId,
currentNodeKey,
isCompleted,
endingReached
});
}
/**
* 点赞故事
*/
async likeStory(storyId, isLiked) {
if (!this.isLoggedIn) return;
await post('/user/like', {
userId: this.userId,
storyId,
isLiked
});
}
/**
* 收藏故事
*/
async collectStory(storyId, isCollected) {
if (!this.isLoggedIn) return;
await post('/user/collect', {
userId: this.userId,
storyId,
isCollected
});
}
/**
* 获取收藏列表
*/
async getCollections() {
if (!this.isLoggedIn) return [];
return await get('/user/collections', { userId: this.userId });
}
/**
* 获取最近游玩的故事
*/
async getRecentPlayed() {
if (!this.isLoggedIn) return [];
try {
return await get('/user/recent-played', { userId: this.userId, limit: 10 });
} catch (e) {
return [];
}
}
/**
* 获取AI创作历史
*/
async getAIHistory() {
if (!this.isLoggedIn) return [];
try {
return await get('/user/ai-history', { userId: this.userId, limit: 20 });
} catch (e) {
return [];
}
}
/**
* 获取AI配额
*/
async getAIQuota() {
if (!this.isLoggedIn) return { daily: 3, used: 0, purchased: 0 };
try {
return await get('/user/ai-quota', { userId: this.userId });
} catch (e) {
return { daily: 3, used: 0, purchased: 0 };
}
}
/**
* 获取我的作品
*/
async getMyWorks() {
if (!this.isLoggedIn) return [];
try {
return await get('/user/my-works', { userId: this.userId });
} catch (e) {
return [];
}
}
/**
* 获取草稿箱
*/
async getDrafts() {
if (!this.isLoggedIn) return [];
try {
return await get('/user/drafts', { userId: this.userId });
} catch (e) {
return [];
}
}
/**
* 获取已发布到创作中心的草稿
* @param {string} draftType - 草稿类型: rewrite/continue
*/
async getPublishedDrafts(draftType) {
if (!this.isLoggedIn) return [];
try {
console.log('[UserManager] 获取已发布草稿, userId:', this.userId, 'draftType:', draftType);
const res = await get('/drafts/published', { userId: this.userId, draftType });
console.log('[UserManager] 已发布草稿响应:', res);
return res || [];
} catch (e) {
console.error('获取已发布草稿失败:', e);
return [];
}
}
/**
* 发布草稿到创作中心
* @param {number} draftId - 草稿ID
*/
async publishDraft(draftId) {
if (!this.isLoggedIn) return false;
try {
await put(`/drafts/${draftId}/publish`, null, { params: { userId: this.userId } });
return true;
} catch (e) {
console.error('发布草稿失败:', e);
return false;
}
}
/**
* 从创作中心取消发布
* @param {number} draftId - 草稿ID
*/
async unpublishDraft(draftId) {
if (!this.isLoggedIn) return false;
try {
await put(`/drafts/${draftId}/unpublish`, null, { params: { userId: this.userId } });
return true;
} catch (e) {
console.error('取消发布失败:', e);
return false;
}
}
// ========== 游玩记录相关 ==========
/**
* 保存游玩记录
*/
async savePlayRecord(storyId, endingName, endingType, pathHistory) {
if (!this.isLoggedIn) return null;
try {
return await post('/user/play-record', {
userId: this.userId,
storyId,
endingName,
endingType: endingType || '',
pathHistory: pathHistory || []
});
} catch (e) {
console.error('保存游玩记录失败:', e);
return null;
}
}
/**
* 获取游玩记录列表
* @param {number} storyId - 可选指定故事ID获取该故事的所有记录
*/
async getPlayRecords(storyId = null) {
if (!this.isLoggedIn) return [];
try {
const params = { userId: this.userId };
if (storyId) params.storyId = storyId;
return await get('/user/play-records', params);
} catch (e) {
console.error('获取游玩记录失败:', e);
return [];
}
}
/**
* 获取单条记录详情
*/
async getPlayRecordDetail(recordId) {
if (!this.isLoggedIn) return null;
try {
return await get(`/user/play-records/${recordId}`);
} catch (e) {
console.error('获取记录详情失败:', e);
return null;
}
}
// 删除游玩记录
async deletePlayRecord(recordId) {
if (!this.isLoggedIn) return false;
try {
await del(`/user/play-records/${recordId}`);
return true;
} catch (e) {
console.error('删除记录失败:', e);
return false;
}
}
}