feat: AI改写面板样式优化、封面图片显示、max_tokens调整至8192
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
* 个人中心场景 - 支持创作者功能
|
||||
*/
|
||||
import BaseScene from './BaseScene';
|
||||
import { getStaticUrl } from '../utils/http';
|
||||
|
||||
export default class ProfileScene extends BaseScene {
|
||||
constructor(main, params) {
|
||||
@@ -40,6 +41,9 @@ export default class ProfileScene extends BaseScene {
|
||||
this.lastTouchY = 0;
|
||||
this.scrollVelocity = 0;
|
||||
this.hasMoved = false;
|
||||
|
||||
// 封面图片缓存
|
||||
this.coverImages = {}; // { url: Image对象 }
|
||||
}
|
||||
|
||||
async init() {
|
||||
@@ -69,14 +73,45 @@ export default class ProfileScene extends BaseScene {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载封面图片
|
||||
loadCoverImage(url) {
|
||||
if (!url || this.coverImages[url] !== undefined) return;
|
||||
|
||||
// 标记为加载中
|
||||
this.coverImages[url] = null;
|
||||
|
||||
const img = wx.createImage();
|
||||
img.onload = () => {
|
||||
this.coverImages[url] = img;
|
||||
};
|
||||
img.onerror = () => {
|
||||
this.coverImages[url] = false; // 加载失败
|
||||
};
|
||||
|
||||
// 使用 getStaticUrl 处理 URL(与首页一致)
|
||||
img.src = getStaticUrl(url);
|
||||
}
|
||||
|
||||
// 预加载当前列表的封面图片
|
||||
preloadCoverImages() {
|
||||
const list = this.getCurrentList();
|
||||
list.forEach(item => {
|
||||
const coverUrl = item.coverUrl || item.cover_url;
|
||||
if (coverUrl) {
|
||||
this.loadCoverImage(coverUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadData() {
|
||||
if (this.main.userManager.isLoggedIn) {
|
||||
try {
|
||||
const userId = this.main.userManager.userId;
|
||||
// 加载已发布到创作中心的作品(改写+续写)
|
||||
// 加载已发布到创作中心的作品(改写+续写+创作)
|
||||
const publishedRewrites = await this.main.userManager.getPublishedDrafts('rewrite') || [];
|
||||
const publishedContinues = await this.main.userManager.getPublishedDrafts('continue') || [];
|
||||
this.myWorks = [...publishedRewrites, ...publishedContinues];
|
||||
const publishedCreates = await this.main.userManager.getPublishedDrafts('create') || [];
|
||||
this.myWorks = [...publishedRewrites, ...publishedContinues, ...publishedCreates];
|
||||
// 加载 AI 改写草稿
|
||||
this.drafts = await this.main.storyManager.getDrafts(userId) || [];
|
||||
this.collections = await this.main.userManager.getCollections() || [];
|
||||
@@ -93,6 +128,7 @@ export default class ProfileScene extends BaseScene {
|
||||
}
|
||||
}
|
||||
this.calculateMaxScroll();
|
||||
this.preloadCoverImages();
|
||||
}
|
||||
|
||||
// 刷新草稿列表
|
||||
@@ -539,20 +575,59 @@ export default class ProfileScene extends BaseScene {
|
||||
|
||||
// 封面
|
||||
const coverW = 70, coverH = h - 16;
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(x + 8, y + 8, x + 8 + coverW, y + 8 + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, x + 8, y + 8, coverW, coverH, 10);
|
||||
ctx.fill();
|
||||
const coverX = x + 8, coverY = y + 8;
|
||||
const coverUrl = item.coverUrl || item.cover_url;
|
||||
const coverImg = coverUrl ? this.coverImages[coverUrl] : null;
|
||||
|
||||
// 尝试加载封面图片
|
||||
if (coverUrl && this.coverImages[coverUrl] === undefined) {
|
||||
this.loadCoverImage(coverUrl);
|
||||
}
|
||||
|
||||
// 绘制封面
|
||||
if (coverImg && coverImg !== false) {
|
||||
// 有封面图片,裁剪绘制
|
||||
ctx.save();
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 10);
|
||||
ctx.clip();
|
||||
|
||||
// 等比例填充
|
||||
const imgRatio = coverImg.width / coverImg.height;
|
||||
const areaRatio = coverW / coverH;
|
||||
let drawW, drawH, drawX, drawY;
|
||||
if (imgRatio > areaRatio) {
|
||||
drawH = coverH;
|
||||
drawW = drawH * imgRatio;
|
||||
drawX = coverX - (drawW - coverW) / 2;
|
||||
drawY = coverY;
|
||||
} else {
|
||||
drawW = coverW;
|
||||
drawH = drawW / imgRatio;
|
||||
drawX = coverX;
|
||||
drawY = coverY - (drawH - coverH) / 2;
|
||||
}
|
||||
ctx.drawImage(coverImg, drawX, drawY, drawW, drawH);
|
||||
ctx.restore();
|
||||
} else {
|
||||
// 无封面图片,使用渐变色
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(coverX, coverY, coverX + coverW, coverY + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 10);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// 类型标签
|
||||
const typeText = item.draftType === 'continue' ? '续写' : '改写';
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.8)';
|
||||
const typeText = item.draftType === 'continue' ? '续写' : (item.draftType === 'create' ? '创作' : '改写');
|
||||
ctx.fillStyle = 'rgba(0,0,0,0.5)';
|
||||
this.roundRect(ctx, coverX, coverY, 32, 18, 6);
|
||||
ctx.fill();
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 9px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(typeText, x + 8 + coverW / 2, y + 8 + coverH / 2 + 3);
|
||||
ctx.fillText(typeText, coverX + 16, coverY + 13);
|
||||
|
||||
const textX = x + 88;
|
||||
const maxW = w - 100;
|
||||
@@ -618,22 +693,57 @@ export default class ProfileScene extends BaseScene {
|
||||
ctx.fill();
|
||||
|
||||
const coverW = 70, coverH = h - 16;
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(x + 8, y + 8, x + 8 + coverW, y + 8 + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, x + 8, y + 8, coverW, coverH, 10);
|
||||
ctx.fill();
|
||||
const coverX = x + 8, coverY = y + 8;
|
||||
const coverUrl = item.coverUrl || item.cover_url;
|
||||
const coverImg = coverUrl ? this.coverImages[coverUrl] : null;
|
||||
|
||||
// 尝试加载封面图片
|
||||
if (coverUrl && this.coverImages[coverUrl] === undefined) {
|
||||
this.loadCoverImage(coverUrl);
|
||||
}
|
||||
|
||||
// 绘制封面
|
||||
if (coverImg && coverImg !== false) {
|
||||
// 有封面图片,裁剪绘制
|
||||
ctx.save();
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 10);
|
||||
ctx.clip();
|
||||
|
||||
const imgRatio = coverImg.width / coverImg.height;
|
||||
const areaRatio = coverW / coverH;
|
||||
let drawW, drawH, drawX, drawY;
|
||||
if (imgRatio > areaRatio) {
|
||||
drawH = coverH;
|
||||
drawW = drawH * imgRatio;
|
||||
drawX = coverX - (drawW - coverW) / 2;
|
||||
drawY = coverY;
|
||||
} else {
|
||||
drawW = coverW;
|
||||
drawH = drawW / imgRatio;
|
||||
drawX = coverX;
|
||||
drawY = coverY - (drawH - coverH) / 2;
|
||||
}
|
||||
ctx.drawImage(coverImg, drawX, drawY, drawW, drawH);
|
||||
ctx.restore();
|
||||
} else {
|
||||
// 无封面图片,使用渐变色
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(coverX, coverY, coverX + coverW, coverY + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 10);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// AI标签
|
||||
ctx.fillStyle = '#a855f7';
|
||||
this.roundRect(ctx, x + 8, y + 8, 28, 16, 8);
|
||||
this.roundRect(ctx, coverX, coverY, 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.fillText('AI', coverX + 14, coverY + 11);
|
||||
|
||||
const textX = x + 88;
|
||||
|
||||
@@ -733,18 +843,52 @@ export default class ProfileScene extends BaseScene {
|
||||
ctx.fill();
|
||||
|
||||
const coverW = 60, coverH = h - 16;
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(x + 8, y + 8, x + 8 + coverW, y + 8 + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, x + 8, y + 8, coverW, coverH, 8);
|
||||
ctx.fill();
|
||||
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.85)';
|
||||
ctx.font = 'bold 9px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(item.category || '故事', x + 8 + coverW / 2, y + 8 + coverH / 2 + 3);
|
||||
const coverX = x + 8, coverY = y + 8;
|
||||
const coverUrl = item.coverUrl || item.cover_url;
|
||||
const coverImg = coverUrl ? this.coverImages[coverUrl] : null;
|
||||
|
||||
// 尝试加载封面图片
|
||||
if (coverUrl && this.coverImages[coverUrl] === undefined) {
|
||||
this.loadCoverImage(coverUrl);
|
||||
}
|
||||
|
||||
// 绘制封面
|
||||
if (coverImg && coverImg !== false) {
|
||||
ctx.save();
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 8);
|
||||
ctx.clip();
|
||||
|
||||
const imgRatio = coverImg.width / coverImg.height;
|
||||
const areaRatio = coverW / coverH;
|
||||
let drawW, drawH, drawX, drawY;
|
||||
if (imgRatio > areaRatio) {
|
||||
drawH = coverH;
|
||||
drawW = drawH * imgRatio;
|
||||
drawX = coverX - (drawW - coverW) / 2;
|
||||
drawY = coverY;
|
||||
} else {
|
||||
drawW = coverW;
|
||||
drawH = drawW / imgRatio;
|
||||
drawX = coverX;
|
||||
drawY = coverY - (drawH - coverH) / 2;
|
||||
}
|
||||
ctx.drawImage(coverImg, drawX, drawY, drawW, drawH);
|
||||
ctx.restore();
|
||||
} else {
|
||||
const colors = this.getGradientColors(index);
|
||||
const coverGradient = ctx.createLinearGradient(coverX, coverY, coverX + coverW, coverY + coverH);
|
||||
coverGradient.addColorStop(0, colors[0]);
|
||||
coverGradient.addColorStop(1, colors[1]);
|
||||
ctx.fillStyle = coverGradient;
|
||||
this.roundRect(ctx, coverX, coverY, coverW, coverH, 8);
|
||||
ctx.fill();
|
||||
|
||||
// 无图片时显示分类
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.85)';
|
||||
ctx.font = 'bold 9px sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(item.category || '故事', coverX + coverW / 2, coverY + coverH / 2 + 3);
|
||||
}
|
||||
|
||||
const textX = x + 78;
|
||||
|
||||
@@ -967,7 +1111,11 @@ export default class ProfileScene extends BaseScene {
|
||||
// 检测播放按钮点击(仅已完成状态)
|
||||
if (item.status === 'completed') {
|
||||
if (x >= btnStartX && x <= btnStartX + 50 && relativeY >= btnY && relativeY <= btnY + btnH) {
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
this.main.sceneManager.switchScene('story', {
|
||||
storyId: item.storyId,
|
||||
draftId: item.id,
|
||||
draftType: item.draftType || item.draft_type
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -983,7 +1131,11 @@ export default class ProfileScene extends BaseScene {
|
||||
|
||||
// 点击卡片其他区域
|
||||
if (item.status === 'completed') {
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
this.main.sceneManager.switchScene('story', {
|
||||
storyId: item.storyId,
|
||||
draftId: item.id,
|
||||
draftType: item.draftType || item.draft_type
|
||||
});
|
||||
} else if (item.status === 'failed') {
|
||||
wx.showToast({ title: 'AI改写失败', icon: 'none' });
|
||||
} else {
|
||||
@@ -1057,12 +1209,20 @@ export default class ProfileScene extends BaseScene {
|
||||
// 检测播放按钮点击
|
||||
const playBtnX = padding + cardW - 58;
|
||||
if (x >= playBtnX && x <= playBtnX + 48 && relativeY >= btnY && relativeY <= btnY + btnH) {
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
this.main.sceneManager.switchScene('story', {
|
||||
storyId: item.storyId,
|
||||
draftId: item.id,
|
||||
draftType: item.draftType || item.draft_type
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 点击卡片其他区域也进入播放
|
||||
this.main.sceneManager.switchScene('story', { storyId: item.storyId, draftId: item.id });
|
||||
this.main.sceneManager.switchScene('story', {
|
||||
storyId: item.storyId,
|
||||
draftId: item.id,
|
||||
draftType: item.draftType || item.draft_type
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user