feat: 完善AI改写草稿箱功能 - 修复重头游玩、评分、数据刷新等问题
This commit is contained in:
@@ -6,9 +6,9 @@ import BaseScene from './BaseScene';
|
||||
export default class ProfileScene extends BaseScene {
|
||||
constructor(main, params) {
|
||||
super(main, params);
|
||||
// Tab: 0我的作品 1草稿箱 2收藏 3游玩记录
|
||||
this.currentTab = 0;
|
||||
this.tabs = ['作品', '草稿', '收藏', '记录'];
|
||||
// Tab: 0我的作品 1AI草稿 2收藏 3游玩记录
|
||||
this.currentTab = params.tab || 0; // 支持传入初始tab
|
||||
this.tabs = ['作品', 'AI草稿', '收藏', '记录'];
|
||||
|
||||
// 数据
|
||||
this.myWorks = [];
|
||||
@@ -40,8 +40,10 @@ export default class ProfileScene extends BaseScene {
|
||||
async loadData() {
|
||||
if (this.main.userManager.isLoggedIn) {
|
||||
try {
|
||||
const userId = this.main.userManager.userId;
|
||||
this.myWorks = await this.main.userManager.getMyWorks?.() || [];
|
||||
this.drafts = await this.main.userManager.getDrafts?.() || [];
|
||||
// 加载 AI 改写草稿
|
||||
this.drafts = await this.main.storyManager.getDrafts(userId) || [];
|
||||
this.collections = await this.main.userManager.getCollections() || [];
|
||||
this.progress = await this.main.userManager.getProgress() || [];
|
||||
|
||||
@@ -57,6 +59,19 @@ export default class ProfileScene extends BaseScene {
|
||||
this.calculateMaxScroll();
|
||||
}
|
||||
|
||||
// 刷新草稿列表
|
||||
async refreshDrafts() {
|
||||
if (this.main.userManager.isLoggedIn) {
|
||||
try {
|
||||
const userId = this.main.userManager.userId;
|
||||
this.drafts = await this.main.storyManager.getDrafts(userId) || [];
|
||||
this.calculateMaxScroll();
|
||||
} catch (e) {
|
||||
console.error('刷新草稿失败:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentList() {
|
||||
switch (this.currentTab) {
|
||||
case 0: return this.myWorks;
|
||||
@@ -366,50 +381,85 @@ export default class ProfileScene extends BaseScene {
|
||||
ctx.fill();
|
||||
|
||||
// AI标签
|
||||
if (item.source === 'ai') {
|
||||
ctx.fillStyle = '#a855f7';
|
||||
this.roundRect(ctx, x + 8, y + 8, 28, 16, 8);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 9px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('AI', x + 22, y + 19);
|
||||
}
|
||||
ctx.fillStyle = '#a855f7';
|
||||
this.roundRect(ctx, x + 8, y + 8, 28, 16, 8);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 9px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('AI', x + 22, y + 19);
|
||||
|
||||
const textX = x + 88;
|
||||
|
||||
// 标题(故事标题-改写)
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 14px sans-serif';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.fillText(this.truncateText(ctx, item.title || '未命名草稿', w - 180), textX, y + 25);
|
||||
ctx.fillText(this.truncateText(ctx, item.title || item.storyTitle || 'AI改写', w - 180), textX, y + 25);
|
||||
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.4)';
|
||||
// 状态标签
|
||||
const statusMap = {
|
||||
'pending': { text: '等待中', color: '#888888' },
|
||||
'processing': { text: '生成中', color: '#f59e0b' },
|
||||
'completed': { text: '已完成', color: '#22c55e' },
|
||||
'failed': { text: '失败', color: '#ef4444' }
|
||||
};
|
||||
const status = statusMap[item.status] || statusMap['pending'];
|
||||
const titleWidth = ctx.measureText(this.truncateText(ctx, item.title || item.storyTitle || 'AI改写', w - 180)).width;
|
||||
const statusW = ctx.measureText(status.text).width + 12;
|
||||
ctx.fillStyle = status.color + '33';
|
||||
this.roundRect(ctx, textX + titleWidth + 8, y + 12, statusW, 18, 9);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = status.color;
|
||||
ctx.font = 'bold 10px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(status.text, textX + titleWidth + 8 + statusW / 2, y + 24);
|
||||
|
||||
// 改写指令
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.5)';
|
||||
ctx.font = '11px sans-serif';
|
||||
ctx.fillText(`创建于 ${item.created_at || '刚刚'}`, textX, y + 48);
|
||||
ctx.fillText(`${item.node_count || 0} 个节点`, textX + 100, y + 48);
|
||||
ctx.textAlign = 'left';
|
||||
const promptText = item.userPrompt ? `"「${item.userPrompt}」"` : '';
|
||||
ctx.fillText(this.truncateText(ctx, promptText, w - 100), textX, y + 48);
|
||||
|
||||
// 时间
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.35)';
|
||||
ctx.font = '10px sans-serif';
|
||||
ctx.fillText(item.createdAt || '', textX, y + 68);
|
||||
|
||||
// 未读标记
|
||||
if (!item.isRead && item.status === 'completed') {
|
||||
ctx.fillStyle = '#ef4444';
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + w - 20, y + 20, 5, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// 按钮
|
||||
const btnY = y + 62;
|
||||
const btns = [{ text: '继续编辑', primary: true }, { text: '删除', primary: false }];
|
||||
let btnX = textX;
|
||||
btns.forEach((btn) => {
|
||||
const btnW = btn.primary ? 65 : 45;
|
||||
if (btn.primary) {
|
||||
const btnGradient = ctx.createLinearGradient(btnX, btnY, btnX + btnW, btnY);
|
||||
btnGradient.addColorStop(0, '#a855f7');
|
||||
btnGradient.addColorStop(1, '#ec4899');
|
||||
ctx.fillStyle = btnGradient;
|
||||
} else {
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.1)';
|
||||
}
|
||||
this.roundRect(ctx, btnX, btnY, btnW, 26, 13);
|
||||
|
||||
// 删除按钮(所有状态都显示)
|
||||
ctx.fillStyle = 'rgba(239, 68, 68, 0.2)';
|
||||
this.roundRect(ctx, x + w - 55, btnY, 45, 24, 12);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = '#ef4444';
|
||||
ctx.font = '11px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('删除', x + w - 32, btnY + 16);
|
||||
|
||||
// 播放按钮(仅已完成状态)
|
||||
if (item.status === 'completed') {
|
||||
const btnGradient = ctx.createLinearGradient(textX, btnY, textX + 65, btnY);
|
||||
btnGradient.addColorStop(0, '#a855f7');
|
||||
btnGradient.addColorStop(1, '#ec4899');
|
||||
ctx.fillStyle = btnGradient;
|
||||
this.roundRect(ctx, textX + 120, btnY, 60, 24, 12);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = btn.primary ? 'bold 11px sans-serif' : '11px sans-serif';
|
||||
ctx.font = 'bold 11px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(btn.text, btnX + btnW / 2, btnY + 17);
|
||||
btnX += btnW + 8;
|
||||
});
|
||||
ctx.fillText('播放', textX + 150, btnY + 16);
|
||||
}
|
||||
}
|
||||
|
||||
renderSimpleCard(ctx, item, x, y, w, h, index) {
|
||||
@@ -545,6 +595,11 @@ export default class ProfileScene extends BaseScene {
|
||||
this.currentTab = rect.index;
|
||||
this.scrollY = 0;
|
||||
this.calculateMaxScroll();
|
||||
|
||||
// 切换到 AI 草稿 tab 时刷新数据
|
||||
if (rect.index === 1) {
|
||||
this.refreshDrafts();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -569,22 +624,82 @@ export default class ProfileScene extends BaseScene {
|
||||
const startY = 250;
|
||||
const cardH = this.currentTab <= 1 ? 100 : 85;
|
||||
const gap = 10;
|
||||
const padding = 12;
|
||||
const cardW = this.screenWidth - padding * 2;
|
||||
|
||||
const adjustedY = y + this.scrollY;
|
||||
const index = Math.floor((adjustedY - startY) / (cardH + gap));
|
||||
|
||||
if (index >= 0 && index < list.length) {
|
||||
const item = list[index];
|
||||
const storyId = item.story_id || item.id;
|
||||
const storyId = item.story_id || item.storyId || item.id;
|
||||
|
||||
// 计算卡片内的相对位置
|
||||
const cardY = startY + index * (cardH + gap) - this.scrollY;
|
||||
const relativeY = y - cardY;
|
||||
|
||||
// AI草稿 Tab 的按钮检测
|
||||
if (this.currentTab === 1) {
|
||||
const btnY = 62;
|
||||
const btnH = 24;
|
||||
|
||||
// 检测删除按钮点击(右侧)
|
||||
const deleteBtnX = padding + cardW - 55;
|
||||
if (x >= deleteBtnX && x <= deleteBtnX + 45 && relativeY >= btnY && relativeY <= btnY + btnH) {
|
||||
this.confirmDeleteDraft(item, index);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检测播放按钮点击(左侧,仅已完成状态)
|
||||
if (item.status === 'completed') {
|
||||
const playBtnX = padding + 88 + 120;
|
||||
if (x >= playBtnX && x <= playBtnX + 60 && relativeY >= btnY && relativeY <= btnY + btnH) {
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 点击卡片其他区域
|
||||
if (item.status === 'completed') {
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
} else if (item.status === 'failed') {
|
||||
wx.showToast({ title: 'AI改写失败', icon: 'none' });
|
||||
} else {
|
||||
wx.showToast({ title: '正在生成中,请稍后', icon: 'none' });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.currentTab >= 2) {
|
||||
// 收藏/记录 - 跳转播放
|
||||
this.main.sceneManager.switchScene('story', { storyId });
|
||||
} else if (this.currentTab === 1) {
|
||||
// 草稿 - 跳转编辑(暂用AI创作)
|
||||
this.main.sceneManager.switchScene('aiCreate', { draftId: item.id });
|
||||
}
|
||||
// 作品Tab的按钮操作需要更精确判断,暂略
|
||||
}
|
||||
}
|
||||
|
||||
// 确认删除草稿
|
||||
confirmDeleteDraft(item, index) {
|
||||
wx.showModal({
|
||||
title: '删除草稿',
|
||||
content: `确定要删除「${item.title || 'AI改写'}」吗?`,
|
||||
confirmText: '删除',
|
||||
confirmColor: '#ef4444',
|
||||
cancelText: '取消',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
const userId = this.main.userManager.userId;
|
||||
const success = await this.main.storyManager.deleteDraft(item.id, userId);
|
||||
if (success) {
|
||||
// 从列表中移除
|
||||
this.drafts.splice(index, 1);
|
||||
this.calculateMaxScroll();
|
||||
wx.showToast({ title: '删除成功', icon: 'success' });
|
||||
} else {
|
||||
wx.showToast({ title: '删除失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user