From 4f9c28364d80430d036c2fb905cc2d2d6dd4caa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=8C?= <259278618@qq.com> Date: Mon, 22 Jun 2026 09:08:59 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shortdrama/controller/drama_controller.go | 28 +++++- shortdrama/dao/drama_dao.go | 21 +++++ shortdrama/dao/episode_dao.go | 25 ++++++ shortdrama/model/dto/drama_dto.go | 25 +++++- shortdrama/service/drama_service.go | 8 +- shortdrama/view/index.html | 102 ++++++++++++++-------- 6 files changed, 168 insertions(+), 41 deletions(-) diff --git a/shortdrama/controller/drama_controller.go b/shortdrama/controller/drama_controller.go index bffe54f..3a43247 100644 --- a/shortdrama/controller/drama_controller.go +++ b/shortdrama/controller/drama_controller.go @@ -15,11 +15,35 @@ var Drama = new(drama) // ==================== Drama CRUD ==================== func (c *drama) List(ctx context.Context, req *dto.ListDramaReq) (res *dto.ListDramaRes, err error) { - list, err := service.DramaService.List(ctx) + page := req.Page + if page < 1 { + page = 1 + } + pageSize := req.PageSize + if pageSize < 1 { + pageSize = 20 + } + list, total, err := service.DramaService.List(ctx, page, pageSize) if err != nil { return nil, err } - return &dto.ListDramaRes{List: list}, nil + return &dto.ListDramaRes{List: list, Total: total, Page: page, PageSize: pageSize}, nil +} + +func (c *drama) ListEpisode(ctx context.Context, req *dto.ListEpisodeReq) (res *dto.ListEpisodeRes, err error) { + page := req.Page + if page < 1 { + page = 1 + } + pageSize := req.PageSize + if pageSize < 1 { + pageSize = 10 + } + list, total, err := service.DramaService.ListEpisode(ctx, req.DramaId, page, pageSize) + if err != nil { + return nil, err + } + return &dto.ListEpisodeRes{List: list, Total: total, Page: page, PageSize: pageSize}, nil } func (c *drama) Create(ctx context.Context, req *dto.CreateDramaReq) (res *dto.CreateDramaRes, err error) { diff --git a/shortdrama/dao/drama_dao.go b/shortdrama/dao/drama_dao.go index 2386ecf..c2a911c 100644 --- a/shortdrama/dao/drama_dao.go +++ b/shortdrama/dao/drama_dao.go @@ -79,6 +79,27 @@ func (d *dramaDao) List(ctx context.Context) (res []*entity.Drama, err error) { return } +func (d *dramaDao) ListPage(ctx context.Context, page, pageSize int) (res []*entity.Drama, total int, err error) { + m := g.DB().Model(public.TableNameDrama).Ctx(ctx) + total, err = m.Count() + if err != nil { + return + } + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 20 + } + r, err := m.OrderDesc("id").Limit(pageSize).Offset((page - 1) * pageSize).All() + if err != nil { + return + } + res = make([]*entity.Drama, 0) + err = r.Structs(&res) + return +} + // GetCharacters 查询短剧的所有演员 func (d *dramaDao) GetCharacters(ctx context.Context, dramaId int64) (res []*entity.Character, err error) { r, err := g.DB().Model(public.TableNameCharacter).Ctx(ctx).Where("drama_id", dramaId).OrderAsc("id").All() diff --git a/shortdrama/dao/episode_dao.go b/shortdrama/dao/episode_dao.go index 3e8f87f..28d4001 100644 --- a/shortdrama/dao/episode_dao.go +++ b/shortdrama/dao/episode_dao.go @@ -71,3 +71,28 @@ func (d *episodeDao) ListByDrama(ctx context.Context, dramaId int64) (res []*ent err = r.Structs(&res) return } + +func (d *episodeDao) ListPageByDrama(ctx context.Context, dramaId int64, page, pageSize int) (res []*entity.Episode, total int, err error) { + m := g.DB().Model(public.TableNameEpisode).Ctx(ctx).Where("drama_id", dramaId) + total, err = m.Count() + if err != nil { + return + } + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 10 + } + r, err := m.OrderAsc("idx").Limit(pageSize).Offset((page - 1) * pageSize).All() + if err != nil { + return + } + res = make([]*entity.Episode, 0) + err = r.Structs(&res) + return +} + +func (d *episodeDao) CountByDrama(ctx context.Context, dramaId int64) (int, error) { + return g.DB().Model(public.TableNameEpisode).Ctx(ctx).Where("drama_id", dramaId).Count() +} diff --git a/shortdrama/model/dto/drama_dto.go b/shortdrama/model/dto/drama_dto.go index 3169325..a300a76 100644 --- a/shortdrama/model/dto/drama_dto.go +++ b/shortdrama/model/dto/drama_dto.go @@ -9,11 +9,32 @@ import ( // ==================== List ==================== type ListDramaReq struct { - g.Meta `path:"/list" method:"get" tags:"短剧管理" summary:"短剧列表"` + g.Meta `path:"/list" method:"get" tags:"短剧管理" summary:"短剧列表"` + Page int `json:"page" dc:"页码,从1开始"` + PageSize int `json:"pageSize" dc:"每页条数"` } type ListDramaRes struct { - List []*entity.Drama `json:"list"` + List []*entity.Drama `json:"list"` + Total int `json:"total"` + Page int `json:"page"` + PageSize int `json:"pageSize"` +} + +// ==================== 剧集分页 ==================== + +type ListEpisodeReq struct { + g.Meta `path:"/episode/list" method:"get" tags:"短剧管理" summary:"剧集列表"` + DramaId int64 `json:"dramaId"` + Page int `json:"page" dc:"页码,从1开始"` + PageSize int `json:"pageSize" dc:"每页条数"` +} + +type ListEpisodeRes struct { + List []*entity.Episode `json:"list"` + Total int `json:"total"` + Page int `json:"page"` + PageSize int `json:"pageSize"` } // ==================== Create ==================== diff --git a/shortdrama/service/drama_service.go b/shortdrama/service/drama_service.go index 9bd2c06..cf006e1 100644 --- a/shortdrama/service/drama_service.go +++ b/shortdrama/service/drama_service.go @@ -36,8 +36,12 @@ func (s *dramaService) Create(ctx context.Context, title, style string, episodeD }) } -func (s *dramaService) List(ctx context.Context) ([]*entity.Drama, error) { - return dao.Drama.List(ctx) +func (s *dramaService) List(ctx context.Context, page, pageSize int) (list []*entity.Drama, total int, err error) { + return dao.Drama.ListPage(ctx, page, pageSize) +} + +func (s *dramaService) ListEpisode(ctx context.Context, dramaId int64, page, pageSize int) (list []*entity.Episode, total int, err error) { + return dao.Episode.ListPageByDrama(ctx, dramaId, page, pageSize) } func (s *dramaService) Get(ctx context.Context, id int64) (*entity.Drama, []*entity.Character, []*entity.Episode, []*entity.GenerationTask, error) { diff --git a/shortdrama/view/index.html b/shortdrama/view/index.html index cfc1bdf..e1272a0 100644 --- a/shortdrama/view/index.html +++ b/shortdrama/view/index.html @@ -258,17 +258,32 @@ let currentTaskId = null; // ==================== 短剧列表 ==================== +var dramaPage = 1; +var dramaTotal = 0; +var dramaPageSize = 20; + async function loadList() { try { - const resp = await fetch('/drama/list'); + const resp = await fetch('/drama/list?page=' + dramaPage + '&pageSize=' + dramaPageSize); const data = await resp.json(); if (data.code !== 0) throw new Error(data.message); + dramaTotal = data.data.total; renderList(data.data.list); } catch (err) { document.getElementById('dramaList').innerHTML = '
加载失败: ' + err.message + '
'; } } +function renderPageInfo(total, page, pageSize, onPrev, onNext) { + const totalPages = Math.ceil(total / pageSize) || 1; + if (total <= pageSize) return ''; + return '
' + + '' + + '第 ' + page + ' / ' + totalPages + ' 页(共 ' + total + ' 条)' + + '' + + '
'; +} + function renderList(list) { const container = document.getElementById('dramaList'); const empty = document.getElementById('emptyState'); @@ -296,9 +311,12 @@ function renderList(list) { `; - }).join(''); + }).join('') + renderPageInfo(dramaTotal, dramaPage, dramaPageSize, 'dramaPagePrev()', 'dramaPageNext()'); } +function dramaPagePrev() { if (dramaPage > 1) { dramaPage--; loadList(); } } +function dramaPageNext() { var tp = Math.ceil(dramaTotal / dramaPageSize) || 1; if (dramaPage < tp) { dramaPage++; loadList(); } } + // ==================== 短剧 CRUD ==================== function showDramaModal() { @@ -459,11 +477,16 @@ document.getElementById('confirmBtn').addEventListener('click', async function() // ==================== 剧集管理 ==================== +var episodePage = 1; +var episodeTotal = 0; +var episodePageSize = 10; + function openEpisodeModal(id) { currentDramaId = id; document.getElementById('episodeModal').classList.add('show'); document.getElementById('epModalDramaTitle').textContent = '加载中...'; document.getElementById('epModalDramaMeta').textContent = ''; + episodePage = 1; loadEpisodeDrama(id); } @@ -476,29 +499,33 @@ function hideEpisodeModal() { async function loadEpisodeDrama(id) { try { - const resp = await fetch('/drama/get?id=' + id); - const data = await resp.json(); - if (data.code !== 0) throw new Error(data.message); - currentDrama = data.data; + const [dramaResp, epResp] = await Promise.all([ + fetch('/drama/get?id=' + id), + fetch('/drama/episode/list?dramaId=' + id + '&page=' + episodePage + '&pageSize=' + episodePageSize) + ]); + const dramaData = await dramaResp.json(); + const epData = await epResp.json(); + if (dramaData.code !== 0) throw new Error(dramaData.message); + if (epData.code !== 0) throw new Error(epData.message); + currentDrama = dramaData.data; + episodeTotal = epData.data.total; document.getElementById('epModalDramaTitle').textContent = currentDrama.title || '未命名短剧'; document.getElementById('epModalDramaMeta').textContent = (currentDrama.style || '') + ' · ' + (currentDrama.episodeDuration || '-') + 's/集'; - renderEps(); + renderEps(epData.data.list); } catch (err) { document.getElementById('epModalDramaTitle').textContent = '加载失败'; alert('加载剧集失败: ' + err.message); } } -function renderEps() { +function renderEps(eps) { const list = document.getElementById('epList'); - const eps = currentDrama.episodes || []; - if (eps.length === 0) { + if (!eps || eps.length === 0) { list.innerHTML = '
暂无剧集,点击下方添加
'; return; } var taskMap = {}; if (currentDrama.tasks) { currentDrama.tasks.forEach(function(t) { taskMap[t.episodeId] = t; }); } - eps.sort(function(a, b) { return (a.index || 0) - (b.index || 0); }); list.innerHTML = eps.map(function(ep) { const status = ep.status || 'pending'; const statusLabels = { pending:'待生成', generating:'生成中...', review:'待审核', completed:'已完成', failed:'生成失败' }; @@ -516,18 +543,21 @@ function renderEps() { + '
' + (status === 'generating' ? '' : '') + (statusLabels[status] || status) - + (ep.videoUrl ? ' · ' : '') + + (ep.videoUrl ? ' · ' : '') + segHtml + '
' + '
' - + (status === 'pending' || status === 'failed' ? '' : '') - + (status === 'review' ? '' : '') - + '' - + '' + + (status === 'pending' || status === 'failed' ? '' : '') + + (status === 'review' ? '' : '') + + '' + + '' + '
'; - }).join(''); + }).join('') + renderPageInfo(episodeTotal, episodePage, episodePageSize, 'epPagePrev()', 'epPageNext()'); } +function epPagePrev() { if (episodePage > 1) { episodePage--; loadEpisodeDrama(currentDramaId); } } +function epPageNext() { var tp = Math.ceil(episodeTotal / episodePageSize) || 1; if (episodePage < tp) { episodePage++; loadEpisodeDrama(currentDramaId); } } + function segmentPreviews(task, epId) { var sd; try { sd = JSON.parse(task.stepsData); } catch(e) { return ""; } var segs = sd.segments || []; @@ -821,26 +851,28 @@ async function savePrompt() {