feat: AI改写功能集成角色数据 + UI优化

- 新增story_characters表和seed_characters.sql种子数据(27个角色)
- AI改写/续写功能注入角色信息(性别/年龄/外貌/性格)
- 首页UI下移避让微信退出按钮
- 个人中心页面布局重构
This commit is contained in:
2026-03-11 18:41:56 +08:00
parent 2470cea7e4
commit 4ac47c8474
8 changed files with 478 additions and 47 deletions

View File

@@ -65,7 +65,7 @@ export default class HomeScene extends BaseScene {
const stories = this.getFilteredStories();
const cardHeight = 130;
const gap = 12;
const startY = 175;
const startY = 190;
const tabHeight = 60;
const contentBottom = startY + stories.length * (cardHeight + gap);
const visibleBottom = this.screenHeight - tabHeight;
@@ -130,7 +130,7 @@ export default class HomeScene extends BaseScene {
}
renderContentTabs(ctx) {
const tabY = 60;
const tabY = 75;
const tabWidth = (this.screenWidth - 30) / 4;
const padding = 15;
@@ -160,7 +160,7 @@ export default class HomeScene extends BaseScene {
}
renderCategories(ctx) {
const startY = 95;
const startY = 110;
const tagHeight = 28;
let x = 15 - this.categoryScrollX;
@@ -207,7 +207,7 @@ export default class HomeScene extends BaseScene {
}
renderStoryList(ctx) {
const startY = 140;
const startY = 155;
const cardHeight = 130;
const cardMargin = 12;
const stories = this.getFilteredStories();
@@ -425,7 +425,7 @@ export default class HomeScene extends BaseScene {
this.touchStartY = touch.clientY;
this.hasMoved = false;
if (touch.clientY >= 90 && touch.clientY <= 130) {
if (touch.clientY >= 105 && touch.clientY <= 145) {
this.isCategoryDragging = true;
this.isDragging = false;
} else {
@@ -489,7 +489,7 @@ export default class HomeScene extends BaseScene {
}
// 分类点击
if (y >= 90 && y <= 130) {
if (y >= 105 && y <= 145) {
this.handleCategoryClick(x);
return;
}
@@ -530,7 +530,7 @@ export default class HomeScene extends BaseScene {
}
handleStoryClick(x, y) {
const startY = 140;
const startY = 155;
const cardHeight = 130;
const cardMargin = 12;
const stories = this.getFilteredStories();

View File

@@ -140,6 +140,7 @@ export default class ProfileScene extends BaseScene {
this.renderUserCard(ctx);
this.renderTabs(ctx);
this.renderList(ctx);
this.renderLogoutButton(ctx);
}
renderBackground(ctx) {
@@ -160,12 +161,6 @@ export default class ProfileScene extends BaseScene {
ctx.textAlign = 'center';
ctx.font = 'bold 17px sans-serif';
ctx.fillText('个人中心', this.screenWidth / 2, 35);
// 设置按钮
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.font = '18px sans-serif';
ctx.textAlign = 'right';
ctx.fillText('⚙', this.screenWidth - 20, 35);
}
renderUserCard(ctx) {
@@ -223,10 +218,24 @@ export default class ProfileScene extends BaseScene {
ctx.textAlign = 'left';
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 16px sans-serif';
ctx.fillText(user.nickname || '游客用户', avatarX + avatarSize + 15, avatarY + 22);
const nickname = user.nickname || '游客用户';
ctx.fillText(nickname, avatarX + avatarSize + 15, avatarY + 22);
// 昵称旁边的编辑按钮
const nicknameWidth = ctx.measureText(nickname).width;
const editNicknameBtnX = avatarX + avatarSize + 15 + nicknameWidth + 8;
ctx.fillStyle = 'rgba(255,255,255,0.15)';
this.roundRect(ctx, editNicknameBtnX, avatarY + 8, 24, 20, 10);
ctx.fill();
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.font = '11px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('✎', editNicknameBtnX + 12, avatarY + 22);
this.editNicknameRect = { x: editNicknameBtnX, y: avatarY + 8, width: 24, height: 20 };
ctx.fillStyle = 'rgba(255,255,255,0.4)';
ctx.font = '11px sans-serif';
ctx.textAlign = 'left';
ctx.fillText(`ID: ${user.userId || '未登录'}`, avatarX + avatarSize + 15, avatarY + 42);
// 创作者标签
@@ -367,6 +376,34 @@ export default class ProfileScene extends BaseScene {
ctx.restore();
}
// 渲染底部退出登录按钮
renderLogoutButton(ctx) {
const btnW = 120;
const btnH = 40;
const btnX = (this.screenWidth - btnW) / 2;
const btnY = this.screenHeight - 70;
// 按钮背景
ctx.fillStyle = 'rgba(239, 68, 68, 0.15)';
this.roundRect(ctx, btnX, btnY, btnW, btnH, 20);
ctx.fill();
// 按钮边框
ctx.strokeStyle = 'rgba(239, 68, 68, 0.4)';
ctx.lineWidth = 1;
this.roundRect(ctx, btnX, btnY, btnW, btnH, 20);
ctx.stroke();
// 按钮文字
ctx.fillStyle = '#ef4444';
ctx.font = '14px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('退出登录', this.screenWidth / 2, btnY + 26);
// 保存按钮区域
this.logoutBtnRect = { x: btnX, y: btnY, width: btnW, height: btnH };
}
// 渲染版本列表头部(返回按钮+故事标题)
renderVersionListHeader(ctx, startY) {
const headerY = startY - 5;
@@ -764,17 +801,29 @@ export default class ProfileScene extends BaseScene {
return;
}
// 设置按钮(右上角)
if (y < 50 && x > this.screenWidth - 50) {
this.showSettingsMenu();
return;
// 退出登录按钮
if (this.logoutBtnRect) {
const btn = this.logoutBtnRect;
if (x >= btn.x && x <= btn.x + btn.width && y >= btn.y && y <= btn.y + btn.height) {
this.confirmLogout();
return;
}
}
// 头像点击
// 头像点击(修改头像)
if (this.avatarRect) {
const rect = this.avatarRect;
if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
this.showAvatarOptions();
this.chooseAndUploadAvatar();
return;
}
}
// 昵称编辑按钮点击
if (this.editNicknameRect) {
const rect = this.editNicknameRect;
if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
this.showEditNicknameDialog();
return;
}
}