Skip to main content

tdm_server_rust/repository/
episode_mapper.rs

1//! 话数查询行映射 (Episode Row Mapper)
2//!
3//! 将 `mangaepisodetb` workflow JOIN 查询结果映射为各 VO 结构体。
4//! 对齐 Java `listEpisode` 的联表查询逻辑。
5
6use crate::entity::{
7    episode::{EpisodeDetailVo, EpisodeListVo, EpisodeSimpleListVo, NewestEpisodeVo, UploadPageVo},
8    member::MemberEpisodeVo,
9};
10use chrono::{DateTime, Utc};
11use sqlx::{mysql::MySqlRow, Row};
12
13/// 话数 workflow JOIN 片段
14pub const EPISODE_WORKFLOW_FROM: &str = r#"
15FROM mangaepisodetb me
16LEFT JOIN mangaepisodedetail med ON me.Id = med.episodeId
17LEFT JOIN membertb provider ON me.providerId = provider.Id
18LEFT JOIN membertb translator ON me.translatorId = translator.Id
19LEFT JOIN membertb proofreader ON me.proofreaderId = proofreader.Id
20LEFT JOIN membertb letterer ON me.lettererId = letterer.Id
21LEFT JOIN membertb timer ON me.timerId = timer.Id
22LEFT JOIN membertb reviewer ON me.reviewerId = reviewer.Id
23LEFT JOIN oss providerFile ON providerFile.id = me.provider_file_oss_id
24LEFT JOIN oss translatorFile ON translatorFile.id = me.translator_file_oss_id
25LEFT JOIN oss proofreaderFile ON proofreaderFile.id = me.proofreader_file_oss_id
26LEFT JOIN oss lettererFile ON lettererFile.id = me.letterer_file_oss_id
27LEFT JOIN oss timerFile ON timerFile.id = me.timer_file_oss_id
28"#;
29
30/// 话数 workflow SELECT 列
31pub const EPISODE_WORKFLOW_SELECT: &str = r#"
32me.*,
33med.translatorSetupTime, med.translatorUpdateTime,
34med.proofreaderSetupTime, med.proofreaderUpdateTime,
35med.lettererSetupTime, med.lettererUpdateTime,
36med.timerSetupTime, med.timerUpdateTime,
37med.reviewerSetupTime, med.reviewerUpdateTime,
38provider.username AS providerName,
39translator.username AS translatorName,
40proofreader.username AS proofreaderName,
41letterer.username AS lettererName,
42timer.username AS timerName,
43reviewer.username AS reviewerName,
44providerFile.filename AS providerFilename,
45translatorFile.filename AS translatorFilename,
46proofreaderFile.filename AS proofreaderFilename,
47lettererFile.filename AS lettererFilename,
48timerFile.filename AS timerFilename
49"#;
50
51fn try_dt(row: &MySqlRow, col: &str) -> Option<DateTime<Utc>> {
52    row.try_get(col).ok()
53}
54
55fn try_i32(row: &MySqlRow, col: &str) -> Option<i32> {
56    row.try_get(col).ok()
57}
58
59fn try_str(row: &MySqlRow, col: &str) -> Option<String> {
60    row.try_get(col).ok()
61}
62
63/// 映射为话数列表 VO
64pub fn row_to_episode_list(row: &MySqlRow) -> EpisodeListVo {
65    EpisodeListVo {
66        id: row.try_get("Id").unwrap_or(0),
67        manga_id: row.try_get("mangaId").unwrap_or(0),
68        manga_episode: try_str(row, "mangaEpisode"),
69        manga_episode_name: try_str(row, "mangaEpisodeName"),
70        provider_id: try_i32(row, "providerId"),
71        translator_id: try_i32(row, "translatorId"),
72        proofreader_id: try_i32(row, "proofreaderId"),
73        letterer_id: try_i32(row, "lettererId"),
74        timer_id: try_i32(row, "timerId"),
75        reviewer_id: try_i32(row, "reviewerId"),
76        setup_time: try_dt(row, "setupTime"),
77        update_time: try_dt(row, "updateTime"),
78        translator_file: try_str(row, "translatorFile"),
79        proofreader_file: try_str(row, "proofreaderFile"),
80        timer_file: try_str(row, "timerFile"),
81        publish_link: try_str(row, "publishLink"),
82        provider_file_oss_id: try_i32(row, "provider_file_oss_id"),
83        translator_file_oss_id: try_i32(row, "translator_file_oss_id"),
84        proofreader_file_oss_id: try_i32(row, "proofreader_file_oss_id"),
85        letterer_file_oss_id: try_i32(row, "letterer_file_oss_id"),
86        timer_file_oss_id: try_i32(row, "timer_file_oss_id"),
87        translator_setup_time: try_dt(row, "translatorSetupTime"),
88        translator_update_time: try_dt(row, "translatorUpdateTime"),
89        proofreader_setup_time: try_dt(row, "proofreaderSetupTime"),
90        proofreader_update_time: try_dt(row, "proofreaderUpdateTime"),
91        letterer_setup_time: try_dt(row, "lettererSetupTime"),
92        letterer_update_time: try_dt(row, "lettererUpdateTime"),
93        timer_setup_time: try_dt(row, "timerSetupTime"),
94        timer_update_time: try_dt(row, "timerUpdateTime"),
95        reviewer_setup_time: try_dt(row, "reviewerSetupTime"),
96        reviewer_update_time: try_dt(row, "reviewerUpdateTime"),
97        provider_name: try_str(row, "providerName"),
98        translator_name: try_str(row, "translatorName"),
99        proofreader_name: try_str(row, "proofreaderName"),
100        letterer_name: try_str(row, "lettererName"),
101        timer_name: try_str(row, "timerName"),
102        reviewer_name: try_str(row, "reviewerName"),
103        provider_filename: try_str(row, "providerFilename"),
104        translator_filename: try_str(row, "translatorFilename"),
105        proofreader_filename: try_str(row, "proofreaderFilename"),
106        letterer_filename: try_str(row, "lettererFilename"),
107        timer_filename: try_str(row, "timerFilename"),
108    }
109}
110
111/// 映射为话数简单列表 VO
112pub fn row_to_episode_simple(row: &MySqlRow) -> EpisodeSimpleListVo {
113    let full = row_to_episode_list(row);
114    EpisodeSimpleListVo {
115        id: full.id,
116        manga_episode: full.manga_episode,
117        manga_episode_name: full.manga_episode_name,
118        translator_file: full.translator_file,
119        proofreader_file: full.proofreader_file,
120        timer_file: full.timer_file,
121        provider_file_oss_id: full.provider_file_oss_id,
122        translator_file_oss_id: full.translator_file_oss_id,
123        proofreader_file_oss_id: full.proofreader_file_oss_id,
124        letterer_file_oss_id: full.letterer_file_oss_id,
125        timer_file_oss_id: full.timer_file_oss_id,
126        publish_link: full.publish_link,
127    }
128}
129
130/// 映射为话数详情 VO
131pub fn row_to_episode_detail(row: &MySqlRow) -> EpisodeDetailVo {
132    let full = row_to_episode_list(row);
133    EpisodeDetailVo {
134        id: full.id,
135        manga_id: full.manga_id,
136        manga_episode: full.manga_episode,
137        manga_episode_name: full.manga_episode_name,
138        provider_id: full.provider_id,
139        translator_id: full.translator_id,
140        proofreader_id: full.proofreader_id,
141        letterer_id: full.letterer_id,
142        timer_id: full.timer_id,
143        reviewer_id: full.reviewer_id,
144        setup_time: full.setup_time,
145        update_time: full.update_time,
146        publish_link: full.publish_link,
147    }
148}
149
150/// 映射为最新话 VO
151pub fn row_to_newest(row: &MySqlRow) -> NewestEpisodeVo {
152    NewestEpisodeVo {
153        manga_episode: try_str(row, "mangaEpisode"),
154        translator_id: try_i32(row, "translatorId"),
155        proofreader_id: try_i32(row, "proofreaderId"),
156        letterer_id: try_i32(row, "lettererId"),
157        reviewer_id: try_i32(row, "reviewerId"),
158    }
159}
160
161/// 映射为组员话数 VO
162pub fn row_to_member_episode(row: &MySqlRow) -> MemberEpisodeVo {
163    let full = row_to_episode_list(row);
164    MemberEpisodeVo {
165        id: full.id,
166        manga_id: full.manga_id,
167        manga_name: try_str(row, "mangaName"),
168        manga_episode: full.manga_episode,
169        manga_episode_name: full.manga_episode_name,
170        setup_time: full.setup_time,
171        update_time: full.update_time,
172        provider_id: full.provider_id,
173        provider_name: full.provider_name,
174        provider_setup_time: try_dt(row, "providerSetupTime"),
175        provider_update_time: try_dt(row, "providerUpdateTime"),
176        translator_id: full.translator_id,
177        translator_name: full.translator_name,
178        translator_setup_time: full.translator_setup_time,
179        translator_update_time: full.translator_update_time,
180        proofreader_id: full.proofreader_id,
181        proofreader_name: full.proofreader_name,
182        proofreader_setup_time: full.proofreader_setup_time,
183        proofreader_update_time: full.proofreader_update_time,
184        letterer_id: full.letterer_id,
185        letterer_name: full.letterer_name,
186        letterer_setup_time: full.letterer_setup_time,
187        letterer_update_time: full.letterer_update_time,
188        timer_id: full.timer_id,
189        timer_name: full.timer_name,
190        timer_setup_time: full.timer_setup_time,
191        timer_update_time: full.timer_update_time,
192        reviewer_id: full.reviewer_id,
193        reviewer_name: full.reviewer_name,
194        reviewer_setup_time: full.reviewer_setup_time,
195        reviewer_update_time: full.reviewer_update_time,
196        provider_file_oss_id: full.provider_file_oss_id,
197        provider_filename: full.provider_filename,
198        translator_file_oss_id: full.translator_file_oss_id,
199        translator_filename: full.translator_filename,
200        proofreader_file_oss_id: full.proofreader_file_oss_id,
201        proofreader_filename: full.proofreader_filename,
202        letterer_file_oss_id: full.letterer_file_oss_id,
203        letterer_filename: full.letterer_filename,
204        timer_file_oss_id: full.timer_file_oss_id,
205        timer_filename: full.timer_filename,
206        translator_file: full.translator_file,
207        proofreader_file: full.proofreader_file,
208        timer_file: full.timer_file,
209    }
210}
211
212/// 映射为上传页 VO(仅读取藏宝处查询列,避免 med/workflow 无效 lookup)
213pub fn row_to_upload_page(row: &MySqlRow) -> UploadPageVo {
214    UploadPageVo {
215        id: row.try_get("Id").unwrap_or(0),
216        manga_id: row.try_get("mangaId").unwrap_or(0),
217        manga_name: try_str(row, "mangaName"),
218        manga_episode: try_str(row, "mangaEpisode"),
219        update_time: try_dt(row, "updateTime"),
220        translator_file: try_str(row, "translatorFile"),
221        proofreader_file: try_str(row, "proofreaderFile"),
222        timer_file: try_str(row, "timerFile"),
223        provider_id: try_i32(row, "providerId"),
224        translator_id: try_i32(row, "translatorId"),
225        proofreader_id: try_i32(row, "proofreaderId"),
226        letterer_id: try_i32(row, "lettererId"),
227        timer_id: try_i32(row, "timerId"),
228        reviewer_id: try_i32(row, "reviewerId"),
229        provider_name: None,
230        translator_name: try_str(row, "translatorName"),
231        proofreader_name: try_str(row, "proofreaderName"),
232        letterer_name: try_str(row, "lettererName"),
233        timer_name: try_str(row, "timerName"),
234        reviewer_name: try_str(row, "reviewerName"),
235        provider_file_oss_id: try_i32(row, "provider_file_oss_id"),
236        translator_file_oss_id: try_i32(row, "translator_file_oss_id"),
237        proofreader_file_oss_id: try_i32(row, "proofreader_file_oss_id"),
238        letterer_file_oss_id: try_i32(row, "letterer_file_oss_id"),
239        timer_file_oss_id: try_i32(row, "timer_file_oss_id"),
240        provider_filename: try_str(row, "providerFilename"),
241        translator_filename: try_str(row, "translatorFilename"),
242        proofreader_filename: try_str(row, "proofreaderFilename"),
243        letterer_filename: try_str(row, "lettererFilename"),
244        timer_filename: try_str(row, "timerFilename"),
245        email: try_str(row, "email"),
246        email_now: try_str(row, "emailNow"),
247    }
248}