server/prisma/schema.prisma - 已更新,添加新字段server/src/modules/preferences/preferences.service.ts - 已更新server/src/modules/preferences/preferences.controller.ts - 已更新my-uniapp-vue3/src/pages/settings/index.vue - 已完全重写my-uniapp-vue3/src/pages/create/index.vue - 已更新新建文件: server/src/modules/history/history-batch.controller.ts
import Router from '@koa/router';
import { Context } from 'koa';
import { optionalAuth } from '../../middleware/auth';
import { prisma } from '../../models';
const TEST_USER_ID = '1';
const router = new Router();
// 批量删除历史记录
router.delete('/batch', optionalAuth, async (ctx: Context) => {
const userId = ctx.state.user?.userId || TEST_USER_ID;
const { ids } = ctx.request.body as { ids: string[] };
const result = await prisma.audioRecord.deleteMany({
where: { audioId: { in: ids } },
});
ctx.body = {
code: 0,
message: 'success',
data: { deletedCount: result.count },
};
});
export default router;
注册路由 - 在 server/src/app.ts 添加:
import historyBatchRoutes from './modules/history/history-batch.controller';
router.use('/api/history', historyBatchRoutes.routes());
修改文件: my-uniapp-vue3/src/pages/history/index.vue
新建文件: server/src/modules/book-generator/album-management.controller.ts
import Router from '@koa/router';
import { Context } from 'koa';
import { optionalAuth } from '../../middleware/auth';
import { prisma } from '../../models';
const router = new Router();
// 重命名专辑
router.put('/:id/rename', optionalAuth, async (ctx: Context) => {
const { id } = ctx.params;
const { title } = ctx.request.body as { title: string };
const book = await prisma.book.update({
where: { id: parseInt(id) },
data: { title },
});
ctx.body = { code: 0, message: 'success', data: book };
});
// 重命名章节
router.put('/:bookId/chapters/:chapterId/rename', optionalAuth, async (ctx: Context) => {
const { bookId, chapterId } = ctx.params;
const { title } = ctx.request.body as { title: string };
const chapter = await prisma.bookChapter.update({
where: { id: parseInt(chapterId) },
data: { title },
});
ctx.body = { code: 0, message: 'success', data: chapter };
});
export default router;
修改文件: my-uniapp-vue3/src/pages/album/index.vue
model Playlist {
id Int @id @default(autoincrement())
userId Int
name String
coverUrl String?
description String?
isPublic Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
items PlaylistItem[]
}
model PlaylistItem {
id Int @id @default(autoincrement())
playlistId Int
chapterId Int?
audioId String?
order Int @default(0)
addedAt DateTime @default(now())
playlist Playlist @relation(fields: [playlistId], references: [id], onDelete: Cascade)
chapter BookChapter? @relation(fields: [chapterId], references: [id])
}
新建文件: server/src/modules/player/playlist.controller.ts
GET /api/playlists - 获取列表POST /api/playlists - 创建POST /api/playlists/:id/items - 添加项目PUT /api/playlists/:id/items/reorder - 重排序新建文件: my-uniapp-vue3/src/pages/playlists/index.vue
新建文件: my-uniapp-vue3/src/pages/playlists/detail.vue
model Draft {
id Int @id @default(autoincrement())
userId Int
type String // "audio", "book", "chapter"
title String?
content String? @db.LongText
metadata String? @db.Text // JSON
autoSavedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([userId, type])
}
新建文件: server/src/modules/drafts/drafts.controller.ts
GET /api/drafts - 获取列表POST /api/drafts - 保存PUT /api/drafts/:id - 更新DELETE /api/drafts/:id - 删除新建文件: my-uniapp-vue3/src/pages/drafts/index.vue
修改文件: my-uniapp-vue3/src/pages/create/index.vue
修改文件: server/src/modules/notifications/notifications.service.ts
audio_completed, book_completed, member_expiring, daily_reminder修改文件: server/src/modules/notifications/notifications.controller.ts
PUT /api/notifications/read-all - 全部标为已读新建文件: my-uniapp-vue3/src/pages/notifications/index.vue
修改文件: my-uniapp-vue3/src/pages/mine/index.vue
所有功能的完整代码已准备好,按以下顺序实现: