@waterwx/dsh-novel-forge 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/styles/arcane-thick-3d.webp +0 -0
- package/assets/styles/chinese-ink.webp +0 -0
- package/assets/styles/clay-stopmotion-3d.webp +0 -0
- package/assets/styles/dark-ghibli.webp +0 -0
- package/assets/styles/dark-gothic-3d.webp +0 -0
- package/assets/styles/film-photo.webp +0 -0
- package/assets/styles/guofeng-heavy.webp +0 -0
- package/assets/styles/horror-game-3d.webp +0 -0
- package/assets/styles/japan-cel-dark.webp +0 -0
- package/assets/styles/korean-webtoon.webp +0 -0
- package/assets/styles/low-cyberpunk-3d.webp +0 -0
- package/assets/styles/nextgen-cg.webp +0 -0
- package/assets/styles/noir-film.webp +0 -0
- package/assets/styles/openworld-survival.webp +0 -0
- package/assets/styles/paper-cut-3d.webp +0 -0
- package/assets/styles/pixar-adult-3d.webp +0 -0
- package/assets/styles/pop-marvel-2d.webp +0 -0
- package/assets/styles/shinkai-anime.webp +0 -0
- package/assets/styles/tactical-stealth.webp +0 -0
- package/assets/styles/vaporwave-3d.webp +0 -0
- package/assets/styles/vhs90.webp +0 -0
- package/lib/client.js +1455 -301
- package/lib/client.js.map +1 -1
- package/lib/index.js +589 -6
- package/lib/index.js.map +1 -1
- package/lib/types/client/api.d.ts +8 -0
- package/lib/types/client/panel/MangaWorkspace.d.ts +9 -0
- package/lib/types/client/panel/NovelPanel.d.ts +1 -1
- package/lib/types/client/panel/StoryboardTab.d.ts +13 -0
- package/lib/types/client/panel/StyleGallery.d.ts +1 -0
- package/lib/types/engine.d.ts +19 -3
- package/lib/types/protocol.d.ts +149 -0
- package/lib/types/style-library.d.ts +33 -0
- package/package.json +2 -1
- package/src/client/api.ts +20 -0
- package/src/client/panel/MangaWorkspace.tsx +185 -0
- package/src/client/panel/NovelPanel.tsx +18 -3
- package/src/client/panel/StoryboardTab.tsx +287 -0
- package/src/client/panel/StyleGallery.tsx +109 -0
- package/src/engine.ts +247 -0
- package/src/protocol.ts +164 -0
- package/src/routes.ts +192 -2
- package/src/style-library.ts +78 -0
package/lib/client.js
CHANGED
|
@@ -51,6 +51,14 @@ window.__ModuleLoader__.load({
|
|
|
51
51
|
bookshelfImportText: "/api/dsh-novel-forge/bookshelf/import-text",
|
|
52
52
|
/** 导入 txt/md 全本:拆章预览(不落盘)。 */
|
|
53
53
|
bookshelfImportTextPreview: "/api/dsh-novel-forge/bookshelf/import-text/preview",
|
|
54
|
+
/** 漫剧方案管理:create/remove/activate。 */
|
|
55
|
+
manhuaPlans: "/api/dsh-novel-forge/manhua/plans",
|
|
56
|
+
/** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
|
|
57
|
+
storyboardSkeleton: "/api/dsh-novel-forge/storyboard/skeleton",
|
|
58
|
+
/** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
|
|
59
|
+
storyboardTable: "/api/dsh-novel-forge/storyboard/table",
|
|
60
|
+
/** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
|
|
61
|
+
storyboardPrompts: "/api/dsh-novel-forge/storyboard/prompts",
|
|
54
62
|
/** 重置项目(可选携带新大纲):清空设定/卷/章节/伏笔/资产/事实库。 */
|
|
55
63
|
reset: "/api/dsh-novel-forge/reset",
|
|
56
64
|
/** 全书一致性质检:LLM 扫描已生成章节,输出矛盾问题清单。 */
|
|
@@ -152,6 +160,32 @@ window.__ModuleLoader__.load({
|
|
|
152
160
|
async outlineReverse(onFrame) {
|
|
153
161
|
await this.streamJob(NOVEL_API.outlineReverse, {}, onFrame);
|
|
154
162
|
}
|
|
163
|
+
/** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
|
|
164
|
+
async storyboardTable(chapterNo, skeleton, styleId, filterId) {
|
|
165
|
+
return postJson(NOVEL_API.storyboardTable, {
|
|
166
|
+
chapterNo,
|
|
167
|
+
skeleton,
|
|
168
|
+
styleId,
|
|
169
|
+
filterId
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** 漫剧方案管理:create / remove / activate。 */
|
|
173
|
+
async manhuaPlans(req) {
|
|
174
|
+
return postJson(NOVEL_API.manhuaPlans, req);
|
|
175
|
+
}
|
|
176
|
+
/** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
|
|
177
|
+
async storyboardPrompts(chapterNo, table, styleId, filterId) {
|
|
178
|
+
return postJson(NOVEL_API.storyboardPrompts, {
|
|
179
|
+
chapterNo,
|
|
180
|
+
table,
|
|
181
|
+
styleId,
|
|
182
|
+
filterId
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
|
|
186
|
+
async storyboardSkeleton(chapterNo) {
|
|
187
|
+
return postJson(NOVEL_API.storyboardSkeleton, { chapterNo });
|
|
188
|
+
}
|
|
155
189
|
/** 开书想法 → AI 大纲:生成 count 个方案(换批时传 exclude 避开已暂留方向)。 */
|
|
156
190
|
async outlineSuggest(idea, count, exclude) {
|
|
157
191
|
return postJson(NOVEL_API.outlineSuggest, {
|
|
@@ -952,288 +986,288 @@ window.__ModuleLoader__.load({
|
|
|
952
986
|
document.head.appendChild(tag);
|
|
953
987
|
}
|
|
954
988
|
var panel_module_css_default = {
|
|
955
|
-
"
|
|
956
|
-
"
|
|
957
|
-
"button": "zE6uZW_button",
|
|
958
|
-
"statCardDDetail": "zE6uZW_statCardDDetail",
|
|
959
|
-
"badgeWritten": "zE6uZW_badgeWritten",
|
|
960
|
-
"chatScroll": "zE6uZW_chatScroll",
|
|
961
|
-
"readerSeg": "zE6uZW_readerSeg",
|
|
962
|
-
"tlSeg": "zE6uZW_tlSeg",
|
|
963
|
-
"bigProgressBarFill": "zE6uZW_bigProgressBarFill",
|
|
964
|
-
"assetStat": "zE6uZW_assetStat",
|
|
965
|
-
"importResult": "zE6uZW_importResult",
|
|
966
|
-
"assetStatDetail": "zE6uZW_assetStatDetail",
|
|
967
|
-
"bookCardTitleRow": "zE6uZW_bookCardTitleRow",
|
|
968
|
-
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
969
|
-
"badgeError": "zE6uZW_badgeError",
|
|
970
|
-
"createBookView": "zE6uZW_createBookView",
|
|
971
|
-
"toolStepError": "zE6uZW_toolStepError",
|
|
989
|
+
"navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
|
|
990
|
+
"entryIcon": "zE6uZW_entryIcon",
|
|
972
991
|
"panelNavCollapsed": "zE6uZW_panelNavCollapsed",
|
|
992
|
+
"navBadgePulse": "zE6uZW_navBadgePulse",
|
|
993
|
+
"toolStepStatus": "zE6uZW_toolStepStatus",
|
|
994
|
+
"dashFact": "zE6uZW_dashFact",
|
|
995
|
+
"bookChipRemove": "zE6uZW_bookChipRemove",
|
|
996
|
+
"row": "zE6uZW_row",
|
|
973
997
|
"readerItemNo": "zE6uZW_readerItemNo",
|
|
974
|
-
"
|
|
975
|
-
"
|
|
976
|
-
"
|
|
977
|
-
"
|
|
978
|
-
"
|
|
979
|
-
"
|
|
980
|
-
"
|
|
998
|
+
"readerSegActive": "zE6uZW_readerSegActive",
|
|
999
|
+
"input": "zE6uZW_input",
|
|
1000
|
+
"statCardD": "zE6uZW_statCardD",
|
|
1001
|
+
"statCardDDown": "zE6uZW_statCardDDown",
|
|
1002
|
+
"tlSegLabel": "zE6uZW_tlSegLabel",
|
|
1003
|
+
"bookCardCover": "zE6uZW_bookCardCover",
|
|
1004
|
+
"workflowRow": "zE6uZW_workflowRow",
|
|
1005
|
+
"progressLineError": "zE6uZW_progressLineError",
|
|
1006
|
+
"shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
|
|
981
1007
|
"chapterActions": "zE6uZW_chapterActions",
|
|
982
|
-
"
|
|
983
|
-
"
|
|
984
|
-
"
|
|
1008
|
+
"tlSegDone": "zE6uZW_tlSegDone",
|
|
1009
|
+
"panel": "zE6uZW_panel",
|
|
1010
|
+
"legendOld": "zE6uZW_legendOld",
|
|
1011
|
+
"chapter": "zE6uZW_chapter",
|
|
1012
|
+
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
1013
|
+
"bookshelf": "zE6uZW_bookshelf",
|
|
1014
|
+
"navAbout": "zE6uZW_navAbout",
|
|
1015
|
+
"progressLineLive": "zE6uZW_progressLineLive",
|
|
1016
|
+
"dashJourneyStages": "zE6uZW_dashJourneyStages",
|
|
1017
|
+
"bookCardBlurb": "zE6uZW_bookCardBlurb",
|
|
1018
|
+
"navTitleBook": "zE6uZW_navTitleBook",
|
|
1019
|
+
"chapterBeats": "zE6uZW_chapterBeats",
|
|
1020
|
+
"bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
|
|
1021
|
+
"chapterMain": "zE6uZW_chapterMain",
|
|
1022
|
+
"wsPreview": "zE6uZW_wsPreview",
|
|
1023
|
+
"workflowHint": "zE6uZW_workflowHint",
|
|
1024
|
+
"diffText": "zE6uZW_diffText",
|
|
1025
|
+
"progressLine": "zE6uZW_progressLine",
|
|
1026
|
+
"createBookIcon": "zE6uZW_createBookIcon",
|
|
985
1027
|
"assistantStatusBusy": "zE6uZW_assistantStatusBusy",
|
|
986
|
-
"
|
|
987
|
-
"todoInfo": "zE6uZW_todoInfo",
|
|
988
|
-
"bookChipActive": "zE6uZW_bookChipActive",
|
|
989
|
-
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
990
|
-
"settingsCard": "zE6uZW_settingsCard",
|
|
991
|
-
"legendNew": "zE6uZW_legendNew",
|
|
1028
|
+
"diffDel": "zE6uZW_diffDel",
|
|
992
1029
|
"panelBody": "zE6uZW_panelBody",
|
|
993
|
-
"
|
|
994
|
-
"
|
|
995
|
-
"
|
|
996
|
-
"
|
|
997
|
-
"
|
|
998
|
-
"
|
|
999
|
-
"readerTitle": "zE6uZW_readerTitle",
|
|
1000
|
-
"dashJourneyStages": "zE6uZW_dashJourneyStages",
|
|
1001
|
-
"readerError": "zE6uZW_readerError",
|
|
1002
|
-
"statCardDUnit": "zE6uZW_statCardDUnit",
|
|
1030
|
+
"navActions": "zE6uZW_navActions",
|
|
1031
|
+
"dashStageCurrent": "zE6uZW_dashStageCurrent",
|
|
1032
|
+
"fadeIn": "zE6uZW_fadeIn",
|
|
1033
|
+
"view": "zE6uZW_view",
|
|
1034
|
+
"diffTagOld": "zE6uZW_diffTagOld",
|
|
1035
|
+
"navAboutRow": "zE6uZW_navAboutRow",
|
|
1003
1036
|
"helpTip": "zE6uZW_helpTip",
|
|
1004
|
-
"
|
|
1005
|
-
"
|
|
1006
|
-
"
|
|
1007
|
-
"
|
|
1008
|
-
"
|
|
1009
|
-
"
|
|
1010
|
-
"
|
|
1011
|
-
"
|
|
1012
|
-
"
|
|
1013
|
-
"
|
|
1014
|
-
"navGroupSep": "zE6uZW_navGroupSep",
|
|
1015
|
-
"dropzone": "zE6uZW_dropzone",
|
|
1016
|
-
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
1017
|
-
"chapterPreview": "zE6uZW_chapterPreview",
|
|
1018
|
-
"workflowDotActive": "zE6uZW_workflowDotActive",
|
|
1019
|
-
"shelfEmpty": "zE6uZW_shelfEmpty",
|
|
1020
|
-
"statCardDValue": "zE6uZW_statCardDValue",
|
|
1021
|
-
"dashGrid": "zE6uZW_dashGrid",
|
|
1022
|
-
"toolStepActive": "zE6uZW_toolStepActive",
|
|
1023
|
-
"importModalOverlay": "zE6uZW_importModalOverlay",
|
|
1024
|
-
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
1025
|
-
"row": "zE6uZW_row",
|
|
1026
|
-
"chapterBeats": "zE6uZW_chapterBeats",
|
|
1027
|
-
"progressLineLive": "zE6uZW_progressLineLive",
|
|
1037
|
+
"tlSegCurrent": "zE6uZW_tlSegCurrent",
|
|
1038
|
+
"bookCreateForm": "zE6uZW_bookCreateForm",
|
|
1039
|
+
"button": "zE6uZW_button",
|
|
1040
|
+
"toolStep": "zE6uZW_toolStep",
|
|
1041
|
+
"importError": "zE6uZW_importError",
|
|
1042
|
+
"wsColumns": "zE6uZW_wsColumns",
|
|
1043
|
+
"bookCardMetaRow": "zE6uZW_bookCardMetaRow",
|
|
1044
|
+
"statRowD": "zE6uZW_statRowD",
|
|
1045
|
+
"navTabBadgeDone": "zE6uZW_navTabBadgeDone",
|
|
1046
|
+
"badgeError": "zE6uZW_badgeError",
|
|
1028
1047
|
"meta": "zE6uZW_meta",
|
|
1029
|
-
"
|
|
1030
|
-
"
|
|
1031
|
-
"
|
|
1032
|
-
"
|
|
1033
|
-
"bookSwitchCover": "zE6uZW_bookSwitchCover",
|
|
1034
|
-
"navTabIcon": "zE6uZW_navTabIcon",
|
|
1035
|
-
"dashHeroTitle": "zE6uZW_dashHeroTitle",
|
|
1048
|
+
"readerItem": "zE6uZW_readerItem",
|
|
1049
|
+
"fileList": "zE6uZW_fileList",
|
|
1050
|
+
"dropzone": "zE6uZW_dropzone",
|
|
1051
|
+
"workflowLabel": "zE6uZW_workflowLabel",
|
|
1036
1052
|
"bookAddCard": "zE6uZW_bookAddCard",
|
|
1037
|
-
"
|
|
1038
|
-
"
|
|
1039
|
-
"
|
|
1040
|
-
"
|
|
1053
|
+
"settingsCard": "zE6uZW_settingsCard",
|
|
1054
|
+
"dashFacts": "zE6uZW_dashFacts",
|
|
1055
|
+
"wsPageHeader": "zE6uZW_wsPageHeader",
|
|
1056
|
+
"dashHeroTitle": "zE6uZW_dashHeroTitle",
|
|
1057
|
+
"chatRole": "zE6uZW_chatRole",
|
|
1058
|
+
"dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
|
|
1041
1059
|
"ideaCard": "zE6uZW_ideaCard",
|
|
1042
|
-
"
|
|
1043
|
-
"
|
|
1044
|
-
"field": "zE6uZW_field",
|
|
1045
|
-
"bookCardProgressFill": "zE6uZW_bookCardProgressFill",
|
|
1046
|
-
"workflowHint": "zE6uZW_workflowHint",
|
|
1047
|
-
"panelNav": "zE6uZW_panelNav",
|
|
1060
|
+
"readerChapterMeta": "zE6uZW_readerChapterMeta",
|
|
1061
|
+
"bookSwitchArrow": "zE6uZW_bookSwitchArrow",
|
|
1048
1062
|
"badgeGenerating": "zE6uZW_badgeGenerating",
|
|
1049
|
-
"
|
|
1050
|
-
"
|
|
1051
|
-
"
|
|
1052
|
-
"
|
|
1053
|
-
"
|
|
1054
|
-
"
|
|
1055
|
-
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
1056
|
-
"chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
|
|
1057
|
-
"wsPage": "zE6uZW_wsPage",
|
|
1058
|
-
"dashStage": "zE6uZW_dashStage",
|
|
1063
|
+
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
1064
|
+
"textarea": "zE6uZW_textarea",
|
|
1065
|
+
"field": "zE6uZW_field",
|
|
1066
|
+
"spaceBetween": "zE6uZW_spaceBetween",
|
|
1067
|
+
"dashHeroActionBody": "zE6uZW_dashHeroActionBody",
|
|
1068
|
+
"buttonPrimary": "zE6uZW_buttonPrimary",
|
|
1059
1069
|
"bookCard": "zE6uZW_bookCard",
|
|
1060
|
-
"importModalActions": "zE6uZW_importModalActions",
|
|
1061
|
-
"importHint": "zE6uZW_importHint",
|
|
1062
|
-
"navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
|
|
1063
|
-
"onlyChanges": "zE6uZW_onlyChanges",
|
|
1064
|
-
"wsEditor": "zE6uZW_wsEditor",
|
|
1065
|
-
"fileList": "zE6uZW_fileList",
|
|
1066
1070
|
"importPreview": "zE6uZW_importPreview",
|
|
1067
|
-
"
|
|
1068
|
-
"
|
|
1069
|
-
"
|
|
1070
|
-
"
|
|
1071
|
-
"
|
|
1072
|
-
"
|
|
1073
|
-
"
|
|
1074
|
-
"
|
|
1075
|
-
"
|
|
1076
|
-
"
|
|
1077
|
-
"bigProgressBar": "zE6uZW_bigProgressBar",
|
|
1078
|
-
"createBookCard": "zE6uZW_createBookCard",
|
|
1079
|
-
"tabBar": "zE6uZW_tabBar",
|
|
1080
|
-
"shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
|
|
1081
|
-
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
1082
|
-
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
1083
|
-
"readerChapterTitle": "zE6uZW_readerChapterTitle",
|
|
1084
|
-
"dashStageDone": "zE6uZW_dashStageDone",
|
|
1085
|
-
"navAboutRow": "zE6uZW_navAboutRow",
|
|
1086
|
-
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
1087
|
-
"dashJourneyFill": "zE6uZW_dashJourneyFill",
|
|
1088
|
-
"bookChip": "zE6uZW_bookChip",
|
|
1089
|
-
"navAbout": "zE6uZW_navAbout",
|
|
1090
|
-
"importModalBody": "zE6uZW_importModalBody",
|
|
1091
|
-
"buttonSmall": "zE6uZW_buttonSmall",
|
|
1092
|
-
"readerText": "zE6uZW_readerText",
|
|
1093
|
-
"importPreviewList": "zE6uZW_importPreviewList",
|
|
1094
|
-
"tlSegDone": "zE6uZW_tlSegDone",
|
|
1095
|
-
"assetGrid": "zE6uZW_assetGrid",
|
|
1096
|
-
"progress": "zE6uZW_progress",
|
|
1097
|
-
"readerChapterMeta": "zE6uZW_readerChapterMeta",
|
|
1098
|
-
"dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
|
|
1099
|
-
"workflowList": "zE6uZW_workflowList",
|
|
1100
|
-
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
1101
|
-
"diffDel": "zE6uZW_diffDel",
|
|
1102
|
-
"diffLegend": "zE6uZW_diffLegend",
|
|
1071
|
+
"wsSelectedText": "zE6uZW_wsSelectedText",
|
|
1072
|
+
"bookCardActions": "zE6uZW_bookCardActions",
|
|
1073
|
+
"readerItemActive": "zE6uZW_readerItemActive",
|
|
1074
|
+
"todoDanger": "zE6uZW_todoDanger",
|
|
1075
|
+
"buttonDanger": "zE6uZW_buttonDanger",
|
|
1076
|
+
"legendNew": "zE6uZW_legendNew",
|
|
1077
|
+
"readerView": "zE6uZW_readerView",
|
|
1078
|
+
"bookChipMeta": "zE6uZW_bookChipMeta",
|
|
1079
|
+
"importModalActions": "zE6uZW_importModalActions",
|
|
1080
|
+
"bookSwitchName": "zE6uZW_bookSwitchName",
|
|
1103
1081
|
"outlineReadonly": "zE6uZW_outlineReadonly",
|
|
1104
|
-
"
|
|
1105
|
-
"
|
|
1106
|
-
"
|
|
1107
|
-
"
|
|
1108
|
-
"chapterMain": "zE6uZW_chapterMain",
|
|
1109
|
-
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
1110
|
-
"readerMain": "zE6uZW_readerMain",
|
|
1111
|
-
"wsSelected": "zE6uZW_wsSelected",
|
|
1082
|
+
"diffList": "zE6uZW_diffList",
|
|
1083
|
+
"badgeRejected": "zE6uZW_badgeRejected",
|
|
1084
|
+
"navGroup": "zE6uZW_navGroup",
|
|
1085
|
+
"wsColumn": "zE6uZW_wsColumn",
|
|
1112
1086
|
"panelTitle": "zE6uZW_panelTitle",
|
|
1113
|
-
"
|
|
1114
|
-
"
|
|
1087
|
+
"shelfFilters": "zE6uZW_shelfFilters",
|
|
1088
|
+
"chapterFocus": "zE6uZW_chapterFocus",
|
|
1089
|
+
"assetGrid": "zE6uZW_assetGrid",
|
|
1090
|
+
"helpTipText": "zE6uZW_helpTipText",
|
|
1091
|
+
"assetStatDetail": "zE6uZW_assetStatDetail",
|
|
1092
|
+
"chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
|
|
1093
|
+
"diffSame": "zE6uZW_diffSame",
|
|
1094
|
+
"importModalTabs": "zE6uZW_importModalTabs",
|
|
1095
|
+
"progressBarFill": "zE6uZW_progressBarFill",
|
|
1096
|
+
"navTitleName": "zE6uZW_navTitleName",
|
|
1097
|
+
"workflowDotActive": "zE6uZW_workflowDotActive",
|
|
1098
|
+
"readerTitle": "zE6uZW_readerTitle",
|
|
1099
|
+
"diffNew": "zE6uZW_diffNew",
|
|
1100
|
+
"iconButton": "zE6uZW_iconButton",
|
|
1101
|
+
"bookCardName": "zE6uZW_bookCardName",
|
|
1102
|
+
"ideaToggle": "zE6uZW_ideaToggle",
|
|
1103
|
+
"navTabBadgeLive": "zE6uZW_navTabBadgeLive",
|
|
1104
|
+
"dashHeroAction": "zE6uZW_dashHeroAction",
|
|
1115
1105
|
"navTabBadge": "zE6uZW_navTabBadge",
|
|
1116
|
-
"
|
|
1117
|
-
"
|
|
1118
|
-
"
|
|
1119
|
-
"
|
|
1120
|
-
"
|
|
1121
|
-
"card": "zE6uZW_card",
|
|
1122
|
-
"diffOld": "zE6uZW_diffOld",
|
|
1123
|
-
"bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
|
|
1106
|
+
"wsSelected": "zE6uZW_wsSelected",
|
|
1107
|
+
"readerItemBadge": "zE6uZW_readerItemBadge",
|
|
1108
|
+
"readerChapterTitle": "zE6uZW_readerChapterTitle",
|
|
1109
|
+
"importFileInfo": "zE6uZW_importFileInfo",
|
|
1110
|
+
"importResult": "zE6uZW_importResult",
|
|
1124
1111
|
"readerGroupCount": "zE6uZW_readerGroupCount",
|
|
1125
|
-
"
|
|
1126
|
-
"
|
|
1127
|
-
"
|
|
1128
|
-
"
|
|
1129
|
-
"
|
|
1112
|
+
"dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
|
|
1113
|
+
"shelfView": "zE6uZW_shelfView",
|
|
1114
|
+
"bookAdd": "zE6uZW_bookAdd",
|
|
1115
|
+
"navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
|
|
1116
|
+
"tlBar": "zE6uZW_tlBar",
|
|
1117
|
+
"tlSeg": "zE6uZW_tlSeg",
|
|
1118
|
+
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
1119
|
+
"toolStepName": "zE6uZW_toolStepName",
|
|
1120
|
+
"bookAddIcon": "zE6uZW_bookAddIcon",
|
|
1130
1121
|
"importModal": "zE6uZW_importModal",
|
|
1131
|
-
"
|
|
1132
|
-
"
|
|
1133
|
-
"
|
|
1134
|
-
"
|
|
1135
|
-
"
|
|
1136
|
-
"
|
|
1137
|
-
"
|
|
1138
|
-
"
|
|
1139
|
-
"
|
|
1140
|
-
"
|
|
1141
|
-
"
|
|
1142
|
-
"
|
|
1122
|
+
"assistantFloatHeader": "zE6uZW_assistantFloatHeader",
|
|
1123
|
+
"bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
|
|
1124
|
+
"navGroupLabel": "zE6uZW_navGroupLabel",
|
|
1125
|
+
"importField": "zE6uZW_importField",
|
|
1126
|
+
"navActionBtn": "zE6uZW_navActionBtn",
|
|
1127
|
+
"dashStageDone": "zE6uZW_dashStageDone",
|
|
1128
|
+
"toolStepError": "zE6uZW_toolStepError",
|
|
1129
|
+
"navTitleLogo": "zE6uZW_navTitleLogo",
|
|
1130
|
+
"diffOld": "zE6uZW_diffOld",
|
|
1131
|
+
"dashHeroSparkle": "zE6uZW_dashHeroSparkle",
|
|
1132
|
+
"readerBody": "zE6uZW_readerBody",
|
|
1133
|
+
"tlSegFill": "zE6uZW_tlSegFill",
|
|
1134
|
+
"reviewBox": "zE6uZW_reviewBox",
|
|
1135
|
+
"diffChange": "zE6uZW_diffChange",
|
|
1136
|
+
"diffTagNew": "zE6uZW_diffTagNew",
|
|
1143
1137
|
"entry": "zE6uZW_entry",
|
|
1144
|
-
"
|
|
1145
|
-
"
|
|
1146
|
-
"
|
|
1147
|
-
"
|
|
1138
|
+
"assetStat": "zE6uZW_assetStat",
|
|
1139
|
+
"bookSwitchCover": "zE6uZW_bookSwitchCover",
|
|
1140
|
+
"readerHeader": "zE6uZW_readerHeader",
|
|
1141
|
+
"chapterNum": "zE6uZW_chapterNum",
|
|
1142
|
+
"todoText": "zE6uZW_todoText",
|
|
1143
|
+
"toolStepIcon": "zE6uZW_toolStepIcon",
|
|
1148
1144
|
"shelfHeader": "zE6uZW_shelfHeader",
|
|
1149
|
-
"
|
|
1150
|
-
"
|
|
1151
|
-
"
|
|
1152
|
-
"
|
|
1145
|
+
"entryLabel": "zE6uZW_entryLabel",
|
|
1146
|
+
"shelfGrid": "zE6uZW_shelfGrid",
|
|
1147
|
+
"statCardDIconRed": "zE6uZW_statCardDIconRed",
|
|
1148
|
+
"diffLegend": "zE6uZW_diffLegend",
|
|
1149
|
+
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
1150
|
+
"toolSteps": "zE6uZW_toolSteps",
|
|
1151
|
+
"chapterPreview": "zE6uZW_chapterPreview",
|
|
1152
|
+
"shelfTitleRow": "zE6uZW_shelfTitleRow",
|
|
1153
|
+
"chatScroll": "zE6uZW_chatScroll",
|
|
1154
|
+
"dashJourneyFill": "zE6uZW_dashJourneyFill",
|
|
1155
|
+
"ideaCandidate": "zE6uZW_ideaCandidate",
|
|
1156
|
+
"dashHeroArrow": "zE6uZW_dashHeroArrow",
|
|
1153
1157
|
"navTab": "zE6uZW_navTab",
|
|
1158
|
+
"bookCreateOutline": "zE6uZW_bookCreateOutline",
|
|
1159
|
+
"statCardDUnit": "zE6uZW_statCardDUnit",
|
|
1160
|
+
"progressLineDone": "zE6uZW_progressLineDone",
|
|
1161
|
+
"workflowDot": "zE6uZW_workflowDot",
|
|
1162
|
+
"bookChipActive": "zE6uZW_bookChipActive",
|
|
1163
|
+
"importModalBody": "zE6uZW_importModalBody",
|
|
1164
|
+
"createBookTitle": "zE6uZW_createBookTitle",
|
|
1165
|
+
"statCardDLabel": "zE6uZW_statCardDLabel",
|
|
1166
|
+
"wsPreviewText": "zE6uZW_wsPreviewText",
|
|
1167
|
+
"todoItem": "zE6uZW_todoItem",
|
|
1168
|
+
"assistantFloat": "zE6uZW_assistantFloat",
|
|
1169
|
+
"bookCardProgressFill": "zE6uZW_bookCardProgressFill",
|
|
1170
|
+
"wsAppliedBanner": "zE6uZW_wsAppliedBanner",
|
|
1171
|
+
"diffAdd": "zE6uZW_diffAdd",
|
|
1172
|
+
"toolStepActive": "zE6uZW_toolStepActive",
|
|
1173
|
+
"fieldLabel": "zE6uZW_fieldLabel",
|
|
1174
|
+
"cardTitle": "zE6uZW_cardTitle",
|
|
1154
1175
|
"navTabLabel": "zE6uZW_navTabLabel",
|
|
1176
|
+
"dashGrid": "zE6uZW_dashGrid",
|
|
1177
|
+
"bookCardActive": "zE6uZW_bookCardActive",
|
|
1178
|
+
"bigProgressBar": "zE6uZW_bigProgressBar",
|
|
1179
|
+
"shelfSearch": "zE6uZW_shelfSearch",
|
|
1180
|
+
"navTabIcon": "zE6uZW_navTabIcon",
|
|
1181
|
+
"navSpacer": "zE6uZW_navSpacer",
|
|
1182
|
+
"todoInfo": "zE6uZW_todoInfo",
|
|
1155
1183
|
"readerArticle": "zE6uZW_readerArticle",
|
|
1156
|
-
"
|
|
1157
|
-
"
|
|
1158
|
-
"
|
|
1159
|
-
"
|
|
1160
|
-
"
|
|
1161
|
-
"
|
|
1162
|
-
"
|
|
1163
|
-
"
|
|
1164
|
-
"
|
|
1165
|
-
"
|
|
1166
|
-
"
|
|
1167
|
-
"
|
|
1168
|
-
"
|
|
1184
|
+
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
1185
|
+
"workflowDotDone": "zE6uZW_workflowDotDone",
|
|
1186
|
+
"bookshelfLabel": "zE6uZW_bookshelfLabel",
|
|
1187
|
+
"navTitle": "zE6uZW_navTitle",
|
|
1188
|
+
"coverPreview": "zE6uZW_coverPreview",
|
|
1189
|
+
"assetStatValue": "zE6uZW_assetStatValue",
|
|
1190
|
+
"bookSwitch": "zE6uZW_bookSwitch",
|
|
1191
|
+
"bigProgressBarFill": "zE6uZW_bigProgressBarFill",
|
|
1192
|
+
"wsPage": "zE6uZW_wsPage",
|
|
1193
|
+
"readerText": "zE6uZW_readerText",
|
|
1194
|
+
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
1195
|
+
"progress": "zE6uZW_progress",
|
|
1196
|
+
"readerSeg": "zE6uZW_readerSeg",
|
|
1169
1197
|
"readerPara": "zE6uZW_readerPara",
|
|
1170
|
-
"
|
|
1171
|
-
"
|
|
1172
|
-
"
|
|
1173
|
-
"
|
|
1174
|
-
"
|
|
1175
|
-
"
|
|
1198
|
+
"tabBar": "zE6uZW_tabBar",
|
|
1199
|
+
"panelContent": "zE6uZW_panelContent",
|
|
1200
|
+
"shelfToolbar": "zE6uZW_shelfToolbar",
|
|
1201
|
+
"card": "zE6uZW_card",
|
|
1202
|
+
"pulse": "zE6uZW_pulse",
|
|
1203
|
+
"statCardDIcon": "zE6uZW_statCardDIcon",
|
|
1204
|
+
"toolLive": "zE6uZW_toolLive",
|
|
1205
|
+
"assistantStatus": "zE6uZW_assistantStatus",
|
|
1206
|
+
"genreDesc": "zE6uZW_genreDesc",
|
|
1207
|
+
"buttonSmall": "zE6uZW_buttonSmall",
|
|
1208
|
+
"readerGroupArrow": "zE6uZW_readerGroupArrow",
|
|
1209
|
+
"navGroupSep": "zE6uZW_navGroupSep",
|
|
1210
|
+
"createBookView": "zE6uZW_createBookView",
|
|
1211
|
+
"badgePending": "zE6uZW_badgePending",
|
|
1212
|
+
"onlyChanges": "zE6uZW_onlyChanges",
|
|
1213
|
+
"bookshelfList": "zE6uZW_bookshelfList",
|
|
1214
|
+
"panelNav": "zE6uZW_panelNav",
|
|
1215
|
+
"dashJourneyBar": "zE6uZW_dashJourneyBar",
|
|
1216
|
+
"dropzoneIcon": "zE6uZW_dropzoneIcon",
|
|
1217
|
+
"workflowList": "zE6uZW_workflowList",
|
|
1218
|
+
"bookCardBody": "zE6uZW_bookCardBody",
|
|
1219
|
+
"readerSidebar": "zE6uZW_readerSidebar",
|
|
1220
|
+
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
1221
|
+
"statCardDValue": "zE6uZW_statCardDValue",
|
|
1222
|
+
"progressBar": "zE6uZW_progressBar",
|
|
1176
1223
|
"chapterList": "zE6uZW_chapterList",
|
|
1177
|
-
"
|
|
1178
|
-
"
|
|
1179
|
-
"
|
|
1180
|
-
"
|
|
1181
|
-
"
|
|
1182
|
-
"
|
|
1183
|
-
"
|
|
1184
|
-
"
|
|
1185
|
-
"
|
|
1186
|
-
"
|
|
1187
|
-
"
|
|
1188
|
-
"
|
|
1189
|
-
"
|
|
1190
|
-
"bookCardCover": "zE6uZW_bookCardCover",
|
|
1191
|
-
"badge": "zE6uZW_badge",
|
|
1192
|
-
"bookSwitchName": "zE6uZW_bookSwitchName",
|
|
1193
|
-
"dashHero": "zE6uZW_dashHero",
|
|
1194
|
-
"cardTitle": "zE6uZW_cardTitle",
|
|
1224
|
+
"createBookTop": "zE6uZW_createBookTop",
|
|
1225
|
+
"volumeGroup": "zE6uZW_volumeGroup",
|
|
1226
|
+
"bookChip": "zE6uZW_bookChip",
|
|
1227
|
+
"todoWarning": "zE6uZW_todoWarning",
|
|
1228
|
+
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
1229
|
+
"readerSegBtn": "zE6uZW_readerSegBtn",
|
|
1230
|
+
"bookCardTitleRow": "zE6uZW_bookCardTitleRow",
|
|
1231
|
+
"workflowBody": "zE6uZW_workflowBody",
|
|
1232
|
+
"tab": "zE6uZW_tab",
|
|
1233
|
+
"volumeGroupToggle": "zE6uZW_volumeGroupToggle",
|
|
1234
|
+
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
1235
|
+
"dashStageDot": "zE6uZW_dashStageDot",
|
|
1236
|
+
"busyRow": "zE6uZW_busyRow",
|
|
1195
1237
|
"bookCreateCard": "zE6uZW_bookCreateCard",
|
|
1196
|
-
"
|
|
1197
|
-
"
|
|
1198
|
-
"
|
|
1238
|
+
"wsEditor": "zE6uZW_wsEditor",
|
|
1239
|
+
"dashHero": "zE6uZW_dashHero",
|
|
1240
|
+
"readerGroupTitle": "zE6uZW_readerGroupTitle",
|
|
1241
|
+
"importModalOverlay": "zE6uZW_importModalOverlay",
|
|
1242
|
+
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
1243
|
+
"chapterFocusPulse": "zE6uZW_chapterFocusPulse",
|
|
1244
|
+
"badgeWritten": "zE6uZW_badgeWritten",
|
|
1245
|
+
"assistantFloatBody": "zE6uZW_assistantFloatBody",
|
|
1246
|
+
"tlSegTrack": "zE6uZW_tlSegTrack",
|
|
1247
|
+
"readerItemTitle": "zE6uZW_readerItemTitle",
|
|
1199
1248
|
"importModalHead": "zE6uZW_importModalHead",
|
|
1200
|
-
"
|
|
1201
|
-
"bookCardBody": "zE6uZW_bookCardBody",
|
|
1202
|
-
"wsColumns": "zE6uZW_wsColumns",
|
|
1203
|
-
"entryIcon": "zE6uZW_entryIcon",
|
|
1204
|
-
"assistantFloatHeader": "zE6uZW_assistantFloatHeader",
|
|
1205
|
-
"navGroup": "zE6uZW_navGroup",
|
|
1206
|
-
"diffChange": "zE6uZW_diffChange",
|
|
1207
|
-
"navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
|
|
1208
|
-
"fadeIn": "zE6uZW_fadeIn",
|
|
1209
|
-
"fieldLabel": "zE6uZW_fieldLabel",
|
|
1210
|
-
"importField": "zE6uZW_importField",
|
|
1211
|
-
"chapterNum": "zE6uZW_chapterNum",
|
|
1212
|
-
"navSpacer": "zE6uZW_navSpacer",
|
|
1213
|
-
"shelfFilters": "zE6uZW_shelfFilters",
|
|
1214
|
-
"navTitle": "zE6uZW_navTitle",
|
|
1215
|
-
"wsAppliedBanner": "zE6uZW_wsAppliedBanner",
|
|
1216
|
-
"importError": "zE6uZW_importError",
|
|
1249
|
+
"badge": "zE6uZW_badge",
|
|
1217
1250
|
"volumeGroupHeader": "zE6uZW_volumeGroupHeader",
|
|
1218
|
-
"
|
|
1219
|
-
"
|
|
1220
|
-
"
|
|
1221
|
-
"
|
|
1222
|
-
"
|
|
1223
|
-
"
|
|
1251
|
+
"dashJourney": "zE6uZW_dashJourney",
|
|
1252
|
+
"statCardDDetail": "zE6uZW_statCardDDetail",
|
|
1253
|
+
"readerFoot": "zE6uZW_readerFoot",
|
|
1254
|
+
"createBookCard": "zE6uZW_createBookCard",
|
|
1255
|
+
"bookChipName": "zE6uZW_bookChipName",
|
|
1256
|
+
"readerLoading": "zE6uZW_readerLoading",
|
|
1257
|
+
"diffSameBody": "zE6uZW_diffSameBody",
|
|
1258
|
+
"dashStage": "zE6uZW_dashStage",
|
|
1259
|
+
"shelfEmpty": "zE6uZW_shelfEmpty",
|
|
1224
1260
|
"diffColumn": "zE6uZW_diffColumn",
|
|
1225
|
-
"
|
|
1226
|
-
"
|
|
1227
|
-
"
|
|
1228
|
-
"
|
|
1229
|
-
"
|
|
1230
|
-
"
|
|
1231
|
-
"
|
|
1232
|
-
"
|
|
1233
|
-
"
|
|
1234
|
-
"
|
|
1235
|
-
"volumeGroupToggle": "zE6uZW_volumeGroupToggle",
|
|
1236
|
-
"diffTagNew": "zE6uZW_diffTagNew"
|
|
1261
|
+
"assistantResize": "zE6uZW_assistantResize",
|
|
1262
|
+
"bookSwitchMeta": "zE6uZW_bookSwitchMeta",
|
|
1263
|
+
"badgeDone": "zE6uZW_badgeDone",
|
|
1264
|
+
"liveText": "zE6uZW_liveText",
|
|
1265
|
+
"chapterTitle": "zE6uZW_chapterTitle",
|
|
1266
|
+
"readerGroup": "zE6uZW_readerGroup",
|
|
1267
|
+
"readerMain": "zE6uZW_readerMain",
|
|
1268
|
+
"readerError": "zE6uZW_readerError",
|
|
1269
|
+
"importPreviewList": "zE6uZW_importPreviewList",
|
|
1270
|
+
"importHint": "zE6uZW_importHint"
|
|
1237
1271
|
};
|
|
1238
1272
|
//#endregion
|
|
1239
1273
|
//#region src/client/panel/AssistantTab.tsx
|
|
@@ -5252,63 +5286,1160 @@ window.__ModuleLoader__.load({
|
|
|
5252
5286
|
className: panel_module_css_default.card,
|
|
5253
5287
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5254
5288
|
className: panel_module_css_default.row,
|
|
5255
|
-
style: { justifyContent: "space-between" },
|
|
5256
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5289
|
+
style: { justifyContent: "space-between" },
|
|
5290
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5291
|
+
className: panel_module_css_default.cardTitle,
|
|
5292
|
+
children: [
|
|
5293
|
+
"势力分布(",
|
|
5294
|
+
draft.factions.length,
|
|
5295
|
+
")"
|
|
5296
|
+
]
|
|
5297
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5298
|
+
type: "button",
|
|
5299
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
5300
|
+
onClick: () => {
|
|
5301
|
+
setFactions([...draft.factions, {
|
|
5302
|
+
name: "",
|
|
5303
|
+
kind: "宗门",
|
|
5304
|
+
description: ""
|
|
5305
|
+
}]);
|
|
5306
|
+
},
|
|
5307
|
+
children: "+ 新增势力"
|
|
5308
|
+
})]
|
|
5309
|
+
}), draft.factions.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5310
|
+
className: panel_module_css_default.meta,
|
|
5311
|
+
children: "暂无势力 — 宗门 / 家族 / 王朝 / 组织…"
|
|
5312
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5313
|
+
style: {
|
|
5314
|
+
display: "flex",
|
|
5315
|
+
flexDirection: "column",
|
|
5316
|
+
gap: 6
|
|
5317
|
+
},
|
|
5318
|
+
children: draft.factions.map((faction, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditableRow, {
|
|
5319
|
+
name: `${faction.name}(${faction.kind})`,
|
|
5320
|
+
detail: faction.description,
|
|
5321
|
+
onName: (v) => {
|
|
5322
|
+
const next = [...draft.factions];
|
|
5323
|
+
const match = /^(.*)((.*))$/.exec(v);
|
|
5324
|
+
next[i] = {
|
|
5325
|
+
...next[i],
|
|
5326
|
+
name: (match?.[1] ?? v).trim(),
|
|
5327
|
+
kind: (match?.[2] ?? next[i].kind).trim() || "宗门"
|
|
5328
|
+
};
|
|
5329
|
+
setFactions(next);
|
|
5330
|
+
},
|
|
5331
|
+
onDetail: (v) => {
|
|
5332
|
+
const next = [...draft.factions];
|
|
5333
|
+
next[i] = {
|
|
5334
|
+
...next[i],
|
|
5335
|
+
description: v
|
|
5336
|
+
};
|
|
5337
|
+
setFactions(next);
|
|
5338
|
+
},
|
|
5339
|
+
onRemove: () => {
|
|
5340
|
+
setFactions(draft.factions.filter((_, idx) => idx !== i));
|
|
5341
|
+
},
|
|
5342
|
+
namePlaceholder: "势力名(类型)如:青云宗(宗门)",
|
|
5343
|
+
detailPlaceholder: "描述…"
|
|
5344
|
+
}, i))
|
|
5345
|
+
})]
|
|
5346
|
+
})
|
|
5347
|
+
]
|
|
5348
|
+
});
|
|
5349
|
+
}
|
|
5350
|
+
//#endregion
|
|
5351
|
+
//#region src/style-library.ts
|
|
5352
|
+
const STYLE_CATEGORIES = [
|
|
5353
|
+
{
|
|
5354
|
+
id: "3d",
|
|
5355
|
+
label: "3D 类",
|
|
5356
|
+
icon: "🧊",
|
|
5357
|
+
desc: "人物稳定性最好,视频不易崩脸"
|
|
5358
|
+
},
|
|
5359
|
+
{
|
|
5360
|
+
id: "game",
|
|
5361
|
+
label: "游戏 3D",
|
|
5362
|
+
icon: "🎮",
|
|
5363
|
+
desc: "游戏渲染质感与镜头语言(生存/恐怖/潜行)"
|
|
5364
|
+
},
|
|
5365
|
+
{
|
|
5366
|
+
id: "2d",
|
|
5367
|
+
label: "2D 二次元绘画",
|
|
5368
|
+
icon: "✏️",
|
|
5369
|
+
desc: "手绘感,人物一致性略弱"
|
|
5370
|
+
},
|
|
5371
|
+
{
|
|
5372
|
+
id: "film",
|
|
5373
|
+
label: "影视实验质感",
|
|
5374
|
+
icon: "🎞️",
|
|
5375
|
+
desc: "滤镜/影像体系,可叠加在 3D/2D 之上"
|
|
5376
|
+
},
|
|
5377
|
+
{
|
|
5378
|
+
id: "craft",
|
|
5379
|
+
label: "国风/特殊工艺",
|
|
5380
|
+
icon: "🏮",
|
|
5381
|
+
desc: "国风与传统工艺质感"
|
|
5382
|
+
}
|
|
5383
|
+
];
|
|
5384
|
+
/** 内置风格模板(18 个)。 */
|
|
5385
|
+
const STYLE_LIBRARY = [
|
|
5386
|
+
{
|
|
5387
|
+
id: "pixar-adult-3d",
|
|
5388
|
+
name: "成人向皮克斯 3D",
|
|
5389
|
+
category: "3d",
|
|
5390
|
+
traits: "CG 三维渲染,材质细腻,微表情表现力强;需压制 Q 版可爱感",
|
|
5391
|
+
keywords: "3D皮克斯动画,成人写实CGI,电影光影,拒绝Q版",
|
|
5392
|
+
weight: 1
|
|
5393
|
+
},
|
|
5394
|
+
{
|
|
5395
|
+
id: "arcane-thick-3d",
|
|
5396
|
+
name: "双城之战美漫厚涂 3D",
|
|
5397
|
+
category: "3d",
|
|
5398
|
+
traits: "粗重轮廓线,高对比硬阴影,材质粗粝,悲剧、压抑、科幻题材适配高",
|
|
5399
|
+
keywords: "双城之战美术,3D美漫厚涂,强轮廓光影,暗调粗粝渲染",
|
|
5400
|
+
weight: .95
|
|
5401
|
+
},
|
|
5402
|
+
{
|
|
5403
|
+
id: "nextgen-cg",
|
|
5404
|
+
name: "次世代游戏 CG",
|
|
5405
|
+
category: "3d",
|
|
5406
|
+
traits: "接近真人的三维渲染,照片级布料、皮肤材质,冷峻写实",
|
|
5407
|
+
keywords: "次世代游戏CG渲染,超写实3D,真实物理材质,电影布光",
|
|
5408
|
+
weight: .9
|
|
5409
|
+
},
|
|
5410
|
+
{
|
|
5411
|
+
id: "low-cyberpunk-3d",
|
|
5412
|
+
name: "底层赛博朋克 3D",
|
|
5413
|
+
category: "3d",
|
|
5414
|
+
traits: "锈蚀工业、破碎霓虹、屏幕噪点;避开华丽高楼,偏向破败底层",
|
|
5415
|
+
keywords: "底层赛博朋克3D,废土工业,破碎霓虹,画面噪点色散",
|
|
5416
|
+
weight: .85
|
|
5417
|
+
},
|
|
5418
|
+
{
|
|
5419
|
+
id: "vaporwave-3d",
|
|
5420
|
+
name: "复古蒸汽波 3D",
|
|
5421
|
+
category: "3d",
|
|
5422
|
+
traits: "粉-蓝-紫霓虹轮廓、90 年代复古网格、胶片色散颗粒,颓废疏离",
|
|
5423
|
+
keywords: "3D复古蒸汽波,90年代三维渲染,霓虹轮廓光,胶片颗粒",
|
|
5424
|
+
weight: .8
|
|
5425
|
+
},
|
|
5426
|
+
{
|
|
5427
|
+
id: "dark-gothic-3d",
|
|
5428
|
+
name: "暗黑哥特 3D",
|
|
5429
|
+
category: "3d",
|
|
5430
|
+
traits: "大面积阴影、冷青色调、衰败破败质感,适合幽暗密闭空间",
|
|
5431
|
+
keywords: "3D暗黑哥特,冷青暗光,衰败质感,大面积阴影",
|
|
5432
|
+
weight: .8
|
|
5433
|
+
},
|
|
5434
|
+
{
|
|
5435
|
+
id: "clay-stopmotion-3d",
|
|
5436
|
+
name: "黏土 / 定格 3D",
|
|
5437
|
+
category: "3d",
|
|
5438
|
+
traits: "捏塑颗粒肌理,手工定格质感;可做压抑向,不局限可爱风",
|
|
5439
|
+
keywords: "3D黏土定格渲染,泥塑肌理,电影打光",
|
|
5440
|
+
weight: .7
|
|
5441
|
+
},
|
|
5442
|
+
{
|
|
5443
|
+
id: "openworld-survival",
|
|
5444
|
+
name: "开放世界生存游戏风",
|
|
5445
|
+
category: "game",
|
|
5446
|
+
traits: "场景破败感强,货架、仓库、管线、灰尘、锈蚀明显;人物带一点“生存者”气质;适合探索感、逃亡感、世界观展示",
|
|
5447
|
+
keywords: "开放世界生存游戏风格,废土场景,破败仓库,锈蚀金属货架,灰尘粒子,冷色写实光影",
|
|
5448
|
+
weight: .8
|
|
5449
|
+
},
|
|
5450
|
+
{
|
|
5451
|
+
id: "horror-game-3d",
|
|
5452
|
+
name: "恐怖游戏 3D",
|
|
5453
|
+
category: "game",
|
|
5454
|
+
traits: "大面积阴影,荧光灯频闪,空间压抑;适合悬疑、压迫、精神异常段落",
|
|
5455
|
+
keywords: "恐怖游戏 3D 风格,昏暗仓库,老旧荧光灯,硬阴影,压迫空间,冷灰蓝调,低饱和",
|
|
5456
|
+
weight: .75
|
|
5457
|
+
},
|
|
5458
|
+
{
|
|
5459
|
+
id: "tactical-stealth",
|
|
5460
|
+
name: "战术潜行游戏风",
|
|
5461
|
+
category: "game",
|
|
5462
|
+
traits: "低视角、第三人称镜头感;人物在货架之间移动,光影克制;适合紧张剧情",
|
|
5463
|
+
keywords: "战术潜行游戏视角,第三人称镜头,货架通道,冷色暗光,真实3D渲染,紧张压迫氛围",
|
|
5464
|
+
weight: .7
|
|
5465
|
+
},
|
|
5466
|
+
{
|
|
5467
|
+
id: "korean-webtoon",
|
|
5468
|
+
name: "韩漫条漫风",
|
|
5469
|
+
category: "2d",
|
|
5470
|
+
traits: "修长人物,低饱和高级灰,氛围感强,都市向漫剧爆款画风",
|
|
5471
|
+
keywords: "韩漫2D绘画,精致人物,低饱和灰调,氛围感插画",
|
|
5472
|
+
weight: 1
|
|
5473
|
+
},
|
|
5474
|
+
{
|
|
5475
|
+
id: "japan-cel-dark",
|
|
5476
|
+
name: "日系赛璐璐动画",
|
|
5477
|
+
category: "2d",
|
|
5478
|
+
traits: "干净勾线,硬阴影;分明亮版、暗调悲剧版(边缘行者质感)",
|
|
5479
|
+
keywords: "日系赛璐璐动画,清晰轮廓线,硬阴影,暗调都市动画",
|
|
5480
|
+
weight: .9
|
|
5481
|
+
},
|
|
5482
|
+
{
|
|
5483
|
+
id: "shinkai-anime",
|
|
5484
|
+
name: "新海诚动画风",
|
|
5485
|
+
category: "2d",
|
|
5486
|
+
traits: "极致环境光影、丁达尔、空气中尘埃粒子,擅长雨夜、夜景外景",
|
|
5487
|
+
keywords: "新海诚动画渲染,细腻环境光,漂浮尘埃粒子",
|
|
5488
|
+
weight: .85
|
|
5489
|
+
},
|
|
5490
|
+
{
|
|
5491
|
+
id: "pop-marvel-2d",
|
|
5492
|
+
name: "波普美漫",
|
|
5493
|
+
category: "2d",
|
|
5494
|
+
traits: "网点半调、强撞色,线条张扬,节奏冲击力强",
|
|
5495
|
+
keywords: "平行宇宙波普美漫,网点半调,漫画粗线条",
|
|
5496
|
+
weight: .8
|
|
5497
|
+
},
|
|
5498
|
+
{
|
|
5499
|
+
id: "dark-ghibli",
|
|
5500
|
+
name: "暗黑吉卜力手绘",
|
|
5501
|
+
category: "2d",
|
|
5502
|
+
traits: "手绘水彩肌理;强制关闭温暖治愈,做残酷冷调版本",
|
|
5503
|
+
keywords: "吉卜力手绘动画,暗黑写实,水彩肌理,拒绝暖光治愈",
|
|
5504
|
+
weight: .75
|
|
5505
|
+
},
|
|
5506
|
+
{
|
|
5507
|
+
id: "noir-film",
|
|
5508
|
+
name: "黑色电影 Noir",
|
|
5509
|
+
category: "film",
|
|
5510
|
+
traits: "高反差黑白,只保留少量色彩作为视觉锚点,张力极强",
|
|
5511
|
+
keywords: "黑色电影,大部分黑白,局部保留色彩,硬侧光,胶片颗粒",
|
|
5512
|
+
stackable: true,
|
|
5513
|
+
weight: 1
|
|
5514
|
+
},
|
|
5515
|
+
{
|
|
5516
|
+
id: "vhs90",
|
|
5517
|
+
name: "VHS 90 录像带复古",
|
|
5518
|
+
category: "film",
|
|
5519
|
+
traits: "扫描线、色彩偏移、磁带噪点,模拟老旧档案录像",
|
|
5520
|
+
keywords: "VHS录像带质感,扫描线,色彩偏移,磁带噪点",
|
|
5521
|
+
stackable: true,
|
|
5522
|
+
weight: .9
|
|
5523
|
+
},
|
|
5524
|
+
{
|
|
5525
|
+
id: "film-photo",
|
|
5526
|
+
name: "胶片电影写真",
|
|
5527
|
+
category: "film",
|
|
5528
|
+
traits: "电影机拍摄质感,轻微颗粒,景深虚化,无夸张特效",
|
|
5529
|
+
keywords: "电影写真质感,35mm胶片,胶片颗粒,浅景深",
|
|
5530
|
+
stackable: true,
|
|
5531
|
+
weight: .85
|
|
5532
|
+
},
|
|
5533
|
+
{
|
|
5534
|
+
id: "chinese-ink",
|
|
5535
|
+
name: "新中式水墨动画",
|
|
5536
|
+
category: "craft",
|
|
5537
|
+
traits: "水墨晕染,留白写意",
|
|
5538
|
+
keywords: "水墨动画渲染,写意晕染,国风2D",
|
|
5539
|
+
weight: 1
|
|
5540
|
+
},
|
|
5541
|
+
{
|
|
5542
|
+
id: "paper-cut-3d",
|
|
5543
|
+
name: "纸雕定格",
|
|
5544
|
+
category: "craft",
|
|
5545
|
+
traits: "多层纸张镂空叠层,光影穿透纸面",
|
|
5546
|
+
keywords: "立体纸雕定格,纸张肌理,层叠镂空光影",
|
|
5547
|
+
weight: .9
|
|
5548
|
+
},
|
|
5549
|
+
{
|
|
5550
|
+
id: "guofeng-heavy",
|
|
5551
|
+
name: "工笔重彩国风",
|
|
5552
|
+
category: "craft",
|
|
5553
|
+
traits: "精细线条,矿物颜料质感,古典华美",
|
|
5554
|
+
keywords: "工笔重彩,国风2D绘画,矿物颜料质感,精细勾线",
|
|
5555
|
+
weight: .8
|
|
5556
|
+
}
|
|
5557
|
+
];
|
|
5558
|
+
/** 按分类取风格。 */
|
|
5559
|
+
function stylesByCategory(category) {
|
|
5560
|
+
return STYLE_LIBRARY.filter((s) => s.category === category);
|
|
5561
|
+
}
|
|
5562
|
+
/** 取单个风格(未找到返回 undefined)。 */
|
|
5563
|
+
function findStyle(id) {
|
|
5564
|
+
return STYLE_LIBRARY.find((s) => s.id === id);
|
|
5565
|
+
}
|
|
5566
|
+
//#endregion
|
|
5567
|
+
//#region src/client/panel/StoryboardTab.tsx
|
|
5568
|
+
/**
|
|
5569
|
+
* 分镜工作台:① 编剧级剧情骨架 → ② 导演级分镜表(镜头级)→ ③ 视频提示词(后续版本)。
|
|
5570
|
+
* 定位:辅助人工——每级可重新生成、可复制,产出可导出。
|
|
5571
|
+
*/
|
|
5572
|
+
function StoryboardTab({ api, project, chapters, onProjectChanged, styleId, filterId }) {
|
|
5573
|
+
const written = (0, react.useMemo)(() => chapters.filter((c) => c.status !== "pending" && c.status !== "generating" && c.status !== "error").sort((a, b) => a.no - b.no), [chapters]);
|
|
5574
|
+
const [chapterNo, setChapterNo] = (0, react.useState)(written[0]?.no ?? null);
|
|
5575
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
5576
|
+
const [error, setError] = (0, react.useState)("");
|
|
5577
|
+
const [skeleton, setSkeleton] = (0, react.useState)(null);
|
|
5578
|
+
const [table, setTable] = (0, react.useState)(null);
|
|
5579
|
+
const [tableBusy, setTableBusy] = (0, react.useState)(false);
|
|
5580
|
+
const [prompts, setPrompts] = (0, react.useState)(null);
|
|
5581
|
+
const [promptsBusy, setPromptsBusy] = (0, react.useState)(false);
|
|
5582
|
+
const [copied, setCopied] = (0, react.useState)("");
|
|
5583
|
+
(0, react.useEffect)(() => {
|
|
5584
|
+
if (chapterNo === null || !written.some((c) => c.no === chapterNo)) {
|
|
5585
|
+
setChapterNo(written[0]?.no ?? null);
|
|
5586
|
+
setSkeleton(null);
|
|
5587
|
+
setTable(null);
|
|
5588
|
+
setPrompts(null);
|
|
5589
|
+
}
|
|
5590
|
+
}, [written, chapterNo]);
|
|
5591
|
+
(0, react.useEffect)(() => {
|
|
5592
|
+
if (chapterNo === null) return;
|
|
5593
|
+
const entry = (project?.storyboards ?? []).find((e) => e.chapterNo === chapterNo);
|
|
5594
|
+
setSkeleton((prev) => prev ?? entry?.skeleton ?? null);
|
|
5595
|
+
setTable((prev) => prev ?? entry?.table ?? null);
|
|
5596
|
+
setPrompts((prev) => prev ?? entry?.prompts ?? null);
|
|
5597
|
+
}, [chapterNo, project?.storyboards]);
|
|
5598
|
+
const generate = async () => {
|
|
5599
|
+
if (chapterNo === null) return;
|
|
5600
|
+
setBusy(true);
|
|
5601
|
+
setError("");
|
|
5602
|
+
setSkeleton(null);
|
|
5603
|
+
setTable(null);
|
|
5604
|
+
setPrompts(null);
|
|
5605
|
+
try {
|
|
5606
|
+
const result = await api.storyboardSkeleton(chapterNo);
|
|
5607
|
+
setSkeleton(result.skeleton);
|
|
5608
|
+
onProjectChanged?.();
|
|
5609
|
+
} catch (err) {
|
|
5610
|
+
setError(err.message);
|
|
5611
|
+
} finally {
|
|
5612
|
+
setBusy(false);
|
|
5613
|
+
}
|
|
5614
|
+
};
|
|
5615
|
+
/** ② 生成分镜表(骨架 → 镜头级)。 */
|
|
5616
|
+
const generateTable = async () => {
|
|
5617
|
+
if (chapterNo === null || skeleton === null) return;
|
|
5618
|
+
setTableBusy(true);
|
|
5619
|
+
setError("");
|
|
5620
|
+
setTable(null);
|
|
5621
|
+
try {
|
|
5622
|
+
const result = await api.storyboardTable(chapterNo, skeleton, styleId, filterId);
|
|
5623
|
+
setTable(result.table);
|
|
5624
|
+
onProjectChanged?.();
|
|
5625
|
+
} catch (err) {
|
|
5626
|
+
setError(err.message);
|
|
5627
|
+
} finally {
|
|
5628
|
+
setTableBusy(false);
|
|
5629
|
+
}
|
|
5630
|
+
};
|
|
5631
|
+
/** ③ 生成视频提示词(分镜表 → 即梦可粘贴)。 */
|
|
5632
|
+
const generatePrompts = async () => {
|
|
5633
|
+
if (chapterNo === null || table === null) return;
|
|
5634
|
+
setPromptsBusy(true);
|
|
5635
|
+
setError("");
|
|
5636
|
+
setPrompts(null);
|
|
5637
|
+
try {
|
|
5638
|
+
const result = await api.storyboardPrompts(chapterNo, table, styleId, filterId);
|
|
5639
|
+
setPrompts(result.prompts);
|
|
5640
|
+
onProjectChanged?.();
|
|
5641
|
+
} catch (err) {
|
|
5642
|
+
setError(err.message);
|
|
5643
|
+
} finally {
|
|
5644
|
+
setPromptsBusy(false);
|
|
5645
|
+
}
|
|
5646
|
+
};
|
|
5647
|
+
if (project === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5648
|
+
className: panel_module_css_default.card,
|
|
5649
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5650
|
+
className: panel_module_css_default.meta,
|
|
5651
|
+
children: "请先开书或选择一本书,再进入分镜工作台。"
|
|
5652
|
+
})
|
|
5653
|
+
});
|
|
5654
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5655
|
+
className: panel_module_css_default.card,
|
|
5656
|
+
children: [
|
|
5657
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5658
|
+
className: panel_module_css_default.row,
|
|
5659
|
+
style: {
|
|
5660
|
+
justifyContent: "space-between",
|
|
5661
|
+
flexWrap: "wrap"
|
|
5662
|
+
},
|
|
5663
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5664
|
+
className: panel_module_css_default.cardTitle,
|
|
5665
|
+
children: "🎬 分镜工作台"
|
|
5666
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5667
|
+
className: panel_module_css_default.meta,
|
|
5668
|
+
children: "① 剧情骨架 → ② 分镜表(本节)→ ③ 视频提示词(后续版本)"
|
|
5669
|
+
})]
|
|
5670
|
+
}),
|
|
5671
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5672
|
+
className: panel_module_css_default.row,
|
|
5673
|
+
style: {
|
|
5674
|
+
alignItems: "flex-end",
|
|
5675
|
+
flexWrap: "wrap"
|
|
5676
|
+
},
|
|
5677
|
+
children: [
|
|
5678
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5679
|
+
className: panel_module_css_default.field,
|
|
5680
|
+
style: {
|
|
5681
|
+
flex: 1,
|
|
5682
|
+
minWidth: 200
|
|
5683
|
+
},
|
|
5684
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
5685
|
+
className: panel_module_css_default.fieldLabel,
|
|
5686
|
+
children: "选择章节"
|
|
5687
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
5688
|
+
className: panel_module_css_default.input,
|
|
5689
|
+
value: chapterNo ?? "",
|
|
5690
|
+
onChange: (e) => {
|
|
5691
|
+
setChapterNo(Number(e.target.value));
|
|
5692
|
+
setError("");
|
|
5693
|
+
},
|
|
5694
|
+
children: [written.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
5695
|
+
value: "",
|
|
5696
|
+
children: "(没有已写章节)"
|
|
5697
|
+
}), written.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
5698
|
+
value: c.no,
|
|
5699
|
+
children: [
|
|
5700
|
+
"第",
|
|
5701
|
+
c.no,
|
|
5702
|
+
"章 ",
|
|
5703
|
+
c.title
|
|
5704
|
+
]
|
|
5705
|
+
}, c.no))]
|
|
5706
|
+
})]
|
|
5707
|
+
}),
|
|
5708
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5709
|
+
type: "button",
|
|
5710
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
|
|
5711
|
+
disabled: busy || chapterNo === null,
|
|
5712
|
+
onClick: () => {
|
|
5713
|
+
generate();
|
|
5714
|
+
},
|
|
5715
|
+
children: busy ? "编剧分析中…" : "✍️ 生成剧情骨架"
|
|
5716
|
+
}),
|
|
5717
|
+
skeleton !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5718
|
+
type: "button",
|
|
5719
|
+
className: panel_module_css_default.button,
|
|
5720
|
+
disabled: busy,
|
|
5721
|
+
onClick: () => {
|
|
5722
|
+
generate();
|
|
5723
|
+
},
|
|
5724
|
+
children: "🔄 重新生成"
|
|
5725
|
+
})
|
|
5726
|
+
]
|
|
5727
|
+
}),
|
|
5728
|
+
error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5729
|
+
className: panel_module_css_default.importError,
|
|
5730
|
+
children: error
|
|
5731
|
+
}),
|
|
5732
|
+
skeleton === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5733
|
+
className: panel_module_css_default.meta,
|
|
5734
|
+
style: { marginTop: 8 },
|
|
5735
|
+
children: "生成后这里显示本章剧情骨架:弧线 + 节拍链(事件 / 情绪走向 / 叙事功能 / 因果)。 骨架是「完整剧情」的根——确认骨架没问题后,后续版本再展开为分镜表与视频提示词。"
|
|
5736
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5737
|
+
style: {
|
|
5738
|
+
display: "flex",
|
|
5739
|
+
flexDirection: "column",
|
|
5740
|
+
gap: 8,
|
|
5741
|
+
marginTop: 8
|
|
5742
|
+
},
|
|
5743
|
+
children: [
|
|
5744
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5745
|
+
className: panel_module_css_default.importPreview,
|
|
5746
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["📖 本章弧线:", skeleton.arc] })
|
|
5747
|
+
}),
|
|
5748
|
+
skeleton.beats.map((b, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5749
|
+
style: {
|
|
5750
|
+
display: "flex",
|
|
5751
|
+
flexDirection: "column",
|
|
5752
|
+
gap: 3,
|
|
5753
|
+
border: "1px solid var(--nf-border)",
|
|
5754
|
+
borderRadius: 10,
|
|
5755
|
+
padding: "8px 10px"
|
|
5756
|
+
},
|
|
5757
|
+
children: [
|
|
5758
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5759
|
+
className: panel_module_css_default.row,
|
|
5760
|
+
style: { flexWrap: "wrap" },
|
|
5761
|
+
children: [
|
|
5762
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: ["节拍 ", i + 1] }),
|
|
5763
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5764
|
+
className: `${panel_module_css_default.badge} ${b.function === "高潮" ? panel_module_css_default.badgeDone : b.function === "转折" ? panel_module_css_default.badgeWritten : panel_module_css_default.badgePending}`,
|
|
5765
|
+
children: b.function
|
|
5766
|
+
}),
|
|
5767
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5768
|
+
className: panel_module_css_default.meta,
|
|
5769
|
+
children: b.emotion
|
|
5770
|
+
})
|
|
5771
|
+
]
|
|
5772
|
+
}),
|
|
5773
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: b.event }),
|
|
5774
|
+
b.cause !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5775
|
+
className: panel_module_css_default.meta,
|
|
5776
|
+
children: ["承接:", b.cause]
|
|
5777
|
+
})
|
|
5778
|
+
]
|
|
5779
|
+
}, b.id)),
|
|
5780
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5781
|
+
className: panel_module_css_default.row,
|
|
5782
|
+
children: [
|
|
5783
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5784
|
+
type: "button",
|
|
5785
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
5786
|
+
onClick: () => {
|
|
5787
|
+
const text = `第${skeleton.chapterNo}章 弧线:${skeleton.arc}\n\n` + skeleton.beats.map((b, i) => `${i + 1}. [${b.function}] ${b.event}(情绪:${b.emotion})${b.cause !== void 0 ? `[承接:${b.cause}]` : ""}`).join("\n");
|
|
5788
|
+
navigator.clipboard?.writeText(text);
|
|
5789
|
+
},
|
|
5790
|
+
children: "📋 复制骨架"
|
|
5791
|
+
}),
|
|
5792
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5793
|
+
type: "button",
|
|
5794
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
5795
|
+
disabled: tableBusy,
|
|
5796
|
+
onClick: () => {
|
|
5797
|
+
generateTable();
|
|
5798
|
+
},
|
|
5799
|
+
children: tableBusy ? "导演分镜中…" : "🎬 ② 生成分镜表"
|
|
5800
|
+
}),
|
|
5801
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5802
|
+
className: panel_module_css_default.meta,
|
|
5803
|
+
children: [
|
|
5804
|
+
"共 ",
|
|
5805
|
+
skeleton.beats.length,
|
|
5806
|
+
" 个节拍 · 骨架可重新生成(后续版本支持直接编辑)"
|
|
5807
|
+
]
|
|
5808
|
+
})
|
|
5809
|
+
]
|
|
5810
|
+
})
|
|
5811
|
+
]
|
|
5812
|
+
}),
|
|
5813
|
+
table !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5814
|
+
style: {
|
|
5815
|
+
display: "flex",
|
|
5816
|
+
flexDirection: "column",
|
|
5817
|
+
gap: 10,
|
|
5818
|
+
marginTop: 10
|
|
5819
|
+
},
|
|
5820
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5821
|
+
className: panel_module_css_default.row,
|
|
5822
|
+
style: {
|
|
5823
|
+
justifyContent: "space-between",
|
|
5824
|
+
flexWrap: "wrap"
|
|
5825
|
+
},
|
|
5826
|
+
children: [
|
|
5827
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
5828
|
+
"🎬 分镜表(",
|
|
5829
|
+
table.shots.length,
|
|
5830
|
+
" 个镜头)"
|
|
5831
|
+
] }),
|
|
5832
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5833
|
+
type: "button",
|
|
5834
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
5835
|
+
onClick: () => {
|
|
5836
|
+
const text = table.shots.map((s) => {
|
|
5837
|
+
const beat = skeleton?.beats.find((b) => b.id === s.beatId);
|
|
5838
|
+
return `镜头 ${s.id}(节拍 ${beat?.id ?? s.beatId} · ${s.shot} · ${s.camera} · ${s.duration}s)\n画面:${s.visual}\n台词:${s.line !== "" ? s.line : "(无)"}\n音效:${s.sound !== "" ? s.sound : "(无)"}\n光效:${s.light !== "" ? s.light : "(无)"}\n承接:${s.prevState} → ${s.nextState}`;
|
|
5839
|
+
}).join("\n\n");
|
|
5840
|
+
navigator.clipboard?.writeText(`第${table.chapterNo}章分镜表\n\n` + text);
|
|
5841
|
+
},
|
|
5842
|
+
children: "📋 复制分镜表"
|
|
5843
|
+
}),
|
|
5844
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5845
|
+
className: panel_module_css_default.meta,
|
|
5846
|
+
children: "按骨架节拍展开 · 镜头间状态连续"
|
|
5847
|
+
}),
|
|
5848
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5849
|
+
type: "button",
|
|
5850
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
5851
|
+
disabled: promptsBusy,
|
|
5852
|
+
onClick: () => {
|
|
5853
|
+
generatePrompts();
|
|
5854
|
+
},
|
|
5855
|
+
children: promptsBusy ? "提示词生成中…" : "🎬 ③ 生成视频提示词"
|
|
5856
|
+
})
|
|
5857
|
+
]
|
|
5858
|
+
}), table.shots.map((s) => {
|
|
5859
|
+
const beat = skeleton?.beats.find((b) => b.id === s.beatId);
|
|
5860
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5861
|
+
style: {
|
|
5862
|
+
display: "flex",
|
|
5863
|
+
flexDirection: "column",
|
|
5864
|
+
gap: 3,
|
|
5865
|
+
border: "1px solid var(--nf-border)",
|
|
5866
|
+
borderRadius: 10,
|
|
5867
|
+
padding: "8px 10px"
|
|
5868
|
+
},
|
|
5869
|
+
children: [
|
|
5870
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5871
|
+
className: panel_module_css_default.row,
|
|
5872
|
+
style: { flexWrap: "wrap" },
|
|
5873
|
+
children: [
|
|
5874
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: ["镜头 ", s.id] }),
|
|
5875
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5876
|
+
className: panel_module_css_default.badge,
|
|
5877
|
+
children: s.shot
|
|
5878
|
+
}),
|
|
5879
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5880
|
+
className: panel_module_css_default.meta,
|
|
5881
|
+
children: [
|
|
5882
|
+
s.camera,
|
|
5883
|
+
" · ",
|
|
5884
|
+
s.duration,
|
|
5885
|
+
"s"
|
|
5886
|
+
]
|
|
5887
|
+
}),
|
|
5888
|
+
beat !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5889
|
+
className: panel_module_css_default.meta,
|
|
5890
|
+
children: [
|
|
5891
|
+
"节拍 ",
|
|
5892
|
+
beat.id,
|
|
5893
|
+
"「",
|
|
5894
|
+
beat.function,
|
|
5895
|
+
"」"
|
|
5896
|
+
]
|
|
5897
|
+
})
|
|
5898
|
+
]
|
|
5899
|
+
}),
|
|
5900
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["🎞️ ", s.visual] }),
|
|
5901
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5902
|
+
className: panel_module_css_default.row,
|
|
5903
|
+
style: { flexWrap: "wrap" },
|
|
5904
|
+
children: [
|
|
5905
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5906
|
+
className: panel_module_css_default.meta,
|
|
5907
|
+
children: ["💬 ", s.line !== "" ? s.line : "(无台词)"]
|
|
5908
|
+
}),
|
|
5909
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5910
|
+
className: panel_module_css_default.meta,
|
|
5911
|
+
children: ["🔊 ", s.sound !== "" ? s.sound : "(无音效)"]
|
|
5912
|
+
}),
|
|
5913
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5914
|
+
className: panel_module_css_default.meta,
|
|
5915
|
+
children: ["💡 ", s.light !== "" ? s.light : "(无光效)"]
|
|
5916
|
+
})
|
|
5917
|
+
]
|
|
5918
|
+
}),
|
|
5919
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5920
|
+
className: panel_module_css_default.meta,
|
|
5921
|
+
children: [
|
|
5922
|
+
"承接:",
|
|
5923
|
+
s.prevState,
|
|
5924
|
+
" → ",
|
|
5925
|
+
s.nextState
|
|
5926
|
+
]
|
|
5927
|
+
})
|
|
5928
|
+
]
|
|
5929
|
+
}, s.id);
|
|
5930
|
+
})]
|
|
5931
|
+
}),
|
|
5932
|
+
prompts !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5933
|
+
style: {
|
|
5934
|
+
display: "flex",
|
|
5935
|
+
flexDirection: "column",
|
|
5936
|
+
gap: 8,
|
|
5937
|
+
marginTop: 10
|
|
5938
|
+
},
|
|
5939
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5940
|
+
className: panel_module_css_default.row,
|
|
5941
|
+
style: {
|
|
5942
|
+
justifyContent: "space-between",
|
|
5943
|
+
flexWrap: "wrap"
|
|
5944
|
+
},
|
|
5945
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
5946
|
+
"🎬 视频提示词(",
|
|
5947
|
+
prompts.length,
|
|
5948
|
+
" 个镜头)"
|
|
5949
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5950
|
+
type: "button",
|
|
5951
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
5952
|
+
onClick: () => {
|
|
5953
|
+
const text = prompts.map((x) => `【镜头 ${x.shotId}】${x.text}`).join("\n\n");
|
|
5954
|
+
navigator.clipboard?.writeText(`第${table?.chapterNo ?? ""}章视频提示词\n\n` + text);
|
|
5955
|
+
},
|
|
5956
|
+
children: "📋 复制全部(即梦可逐条粘贴)"
|
|
5957
|
+
})]
|
|
5958
|
+
}), prompts.map((x) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5959
|
+
style: {
|
|
5960
|
+
display: "flex",
|
|
5961
|
+
flexDirection: "column",
|
|
5962
|
+
gap: 3,
|
|
5963
|
+
border: "1px solid var(--nf-accent)",
|
|
5964
|
+
borderRadius: 10,
|
|
5965
|
+
padding: "8px 10px"
|
|
5966
|
+
},
|
|
5967
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5968
|
+
className: panel_module_css_default.row,
|
|
5969
|
+
style: { flexWrap: "wrap" },
|
|
5970
|
+
children: [
|
|
5971
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: ["镜头 ", x.shotId] }),
|
|
5972
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5973
|
+
className: panel_module_css_default.meta,
|
|
5974
|
+
children: "即梦/Seedance 提示词"
|
|
5975
|
+
}),
|
|
5976
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: { flex: 1 } }),
|
|
5977
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5978
|
+
type: "button",
|
|
5979
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
5980
|
+
onClick: () => {
|
|
5981
|
+
navigator.clipboard?.writeText(x.text);
|
|
5982
|
+
setCopied(x.shotId);
|
|
5983
|
+
setTimeout(() => {
|
|
5984
|
+
setCopied("");
|
|
5985
|
+
}, 1500);
|
|
5986
|
+
},
|
|
5987
|
+
children: copied === x.shotId ? "✅ 已复制" : "📋 复制"
|
|
5988
|
+
})
|
|
5989
|
+
]
|
|
5990
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5991
|
+
style: {
|
|
5992
|
+
fontSize: 13,
|
|
5993
|
+
lineHeight: 1.7
|
|
5994
|
+
},
|
|
5995
|
+
children: x.text
|
|
5996
|
+
})]
|
|
5997
|
+
}, x.shotId))]
|
|
5998
|
+
})
|
|
5999
|
+
]
|
|
6000
|
+
});
|
|
6001
|
+
}
|
|
6002
|
+
//#endregion
|
|
6003
|
+
//#region src/client/panel/MangaWorkspace.tsx
|
|
6004
|
+
/**
|
|
6005
|
+
* 漫剧工作台:方案管理(基底风格 + 可选滤镜)→ 分镜(骨架/分镜表,按方案风格生成)。
|
|
6006
|
+
* 骨架为故事层(所有方案共享);分镜表画面措辞随方案风格。
|
|
6007
|
+
*/
|
|
6008
|
+
function MangaWorkspace({ api, project, chapters, onProjectChanged }) {
|
|
6009
|
+
const plans = (0, react.useMemo)(() => project?.mangaPlans ?? [], [project?.mangaPlans]);
|
|
6010
|
+
const activePlan = plans.find((p) => p.active) ?? null;
|
|
6011
|
+
const [showCreate, setShowCreate] = (0, react.useState)(false);
|
|
6012
|
+
const [name, setName] = (0, react.useState)("");
|
|
6013
|
+
const [styleId, setStyleId] = (0, react.useState)("");
|
|
6014
|
+
const [filterId, setFilterId] = (0, react.useState)("");
|
|
6015
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
6016
|
+
const [error, setError] = (0, react.useState)("");
|
|
6017
|
+
const baseStyles = (0, react.useMemo)(() => STYLE_LIBRARY.filter((s) => s.stackable !== true).sort((a, b) => (b.weight ?? 0) - (a.weight ?? 0)), []);
|
|
6018
|
+
const filterStyles = (0, react.useMemo)(() => STYLE_LIBRARY.filter((s) => s.stackable === true), []);
|
|
6019
|
+
const mutate = async (req) => {
|
|
6020
|
+
setBusy(true);
|
|
6021
|
+
setError("");
|
|
6022
|
+
try {
|
|
6023
|
+
await api.manhuaPlans(req);
|
|
6024
|
+
return true;
|
|
6025
|
+
} catch (err) {
|
|
6026
|
+
setError(err.message);
|
|
6027
|
+
return false;
|
|
6028
|
+
} finally {
|
|
6029
|
+
setBusy(false);
|
|
6030
|
+
}
|
|
6031
|
+
};
|
|
6032
|
+
const createPlan = async () => {
|
|
6033
|
+
const n = name.trim();
|
|
6034
|
+
if (n === "" || styleId === "") {
|
|
6035
|
+
setError("请填写方案名并选择基底风格");
|
|
6036
|
+
return;
|
|
6037
|
+
}
|
|
6038
|
+
if (await mutate({
|
|
6039
|
+
op: "create",
|
|
6040
|
+
name: n,
|
|
6041
|
+
styleId,
|
|
6042
|
+
filterId: filterId !== "" ? filterId : void 0
|
|
6043
|
+
})) {
|
|
6044
|
+
setShowCreate(false);
|
|
6045
|
+
setName("");
|
|
6046
|
+
setStyleId("");
|
|
6047
|
+
setFilterId("");
|
|
6048
|
+
await refreshProject();
|
|
6049
|
+
}
|
|
6050
|
+
};
|
|
6051
|
+
const refreshProject = async () => {
|
|
6052
|
+
await onProjectChanged?.();
|
|
6053
|
+
};
|
|
6054
|
+
if (project === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6055
|
+
className: panel_module_css_default.card,
|
|
6056
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6057
|
+
className: panel_module_css_default.meta,
|
|
6058
|
+
children: "请先开书或选择一本书,再进入漫剧工作台。"
|
|
6059
|
+
})
|
|
6060
|
+
});
|
|
6061
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6062
|
+
style: {
|
|
6063
|
+
display: "flex",
|
|
6064
|
+
flexDirection: "column",
|
|
6065
|
+
gap: 10
|
|
6066
|
+
},
|
|
6067
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6068
|
+
className: panel_module_css_default.card,
|
|
6069
|
+
children: [
|
|
6070
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6071
|
+
className: panel_module_css_default.row,
|
|
6072
|
+
style: {
|
|
6073
|
+
justifyContent: "space-between",
|
|
6074
|
+
flexWrap: "wrap"
|
|
6075
|
+
},
|
|
6076
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5257
6077
|
className: panel_module_css_default.cardTitle,
|
|
5258
|
-
children:
|
|
5259
|
-
"势力分布(",
|
|
5260
|
-
draft.factions.length,
|
|
5261
|
-
")"
|
|
5262
|
-
]
|
|
6078
|
+
children: "🎬 漫剧方案"
|
|
5263
6079
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5264
6080
|
type: "button",
|
|
5265
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.
|
|
6081
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
|
|
6082
|
+
disabled: busy,
|
|
5266
6083
|
onClick: () => {
|
|
5267
|
-
|
|
5268
|
-
name: "",
|
|
5269
|
-
kind: "宗门",
|
|
5270
|
-
description: ""
|
|
5271
|
-
}]);
|
|
6084
|
+
setShowCreate(!showCreate);
|
|
5272
6085
|
},
|
|
5273
|
-
children: "+
|
|
6086
|
+
children: showCreate ? "收起" : "+ 新建方案"
|
|
5274
6087
|
})]
|
|
5275
|
-
}),
|
|
6088
|
+
}),
|
|
6089
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5276
6090
|
className: panel_module_css_default.meta,
|
|
5277
|
-
children: "
|
|
6091
|
+
children: "同一本书可建多套视觉演绎(基底风格 + 可选滤镜);分镜画面措辞随激活方案。"
|
|
6092
|
+
}),
|
|
6093
|
+
showCreate && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6094
|
+
style: {
|
|
6095
|
+
display: "flex",
|
|
6096
|
+
flexDirection: "column",
|
|
6097
|
+
gap: 8,
|
|
6098
|
+
border: "1px solid var(--nf-info)",
|
|
6099
|
+
borderRadius: 12,
|
|
6100
|
+
padding: 10,
|
|
6101
|
+
marginTop: 8
|
|
6102
|
+
},
|
|
6103
|
+
children: [
|
|
6104
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6105
|
+
className: panel_module_css_default.field,
|
|
6106
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
6107
|
+
className: panel_module_css_default.fieldLabel,
|
|
6108
|
+
children: "方案名"
|
|
6109
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6110
|
+
className: panel_module_css_default.input,
|
|
6111
|
+
value: name,
|
|
6112
|
+
placeholder: "例如:《保质期》3D 皮克斯版",
|
|
6113
|
+
onChange: (e) => {
|
|
6114
|
+
setName(e.target.value);
|
|
6115
|
+
}
|
|
6116
|
+
})]
|
|
6117
|
+
}),
|
|
6118
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6119
|
+
className: panel_module_css_default.field,
|
|
6120
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
6121
|
+
className: panel_module_css_default.fieldLabel,
|
|
6122
|
+
children: "基底风格(按推荐度排序)"
|
|
6123
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6124
|
+
style: {
|
|
6125
|
+
display: "flex",
|
|
6126
|
+
flexWrap: "wrap",
|
|
6127
|
+
gap: 6
|
|
6128
|
+
},
|
|
6129
|
+
children: baseStyles.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6130
|
+
type: "button",
|
|
6131
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${styleId === s.id ? panel_module_css_default.buttonPrimary : ""}`,
|
|
6132
|
+
title: s.traits,
|
|
6133
|
+
onClick: () => {
|
|
6134
|
+
setStyleId(s.id);
|
|
6135
|
+
},
|
|
6136
|
+
children: s.name
|
|
6137
|
+
}, s.id))
|
|
6138
|
+
})]
|
|
6139
|
+
}),
|
|
6140
|
+
filterStyles.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6141
|
+
className: panel_module_css_default.field,
|
|
6142
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
6143
|
+
className: panel_module_css_default.fieldLabel,
|
|
6144
|
+
children: "叠加滤镜(可选)"
|
|
6145
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6146
|
+
style: {
|
|
6147
|
+
display: "flex",
|
|
6148
|
+
flexWrap: "wrap",
|
|
6149
|
+
gap: 6
|
|
6150
|
+
},
|
|
6151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6152
|
+
type: "button",
|
|
6153
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${filterId === "" ? panel_module_css_default.buttonPrimary : ""}`,
|
|
6154
|
+
onClick: () => {
|
|
6155
|
+
setFilterId("");
|
|
6156
|
+
},
|
|
6157
|
+
children: "无"
|
|
6158
|
+
}), filterStyles.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6159
|
+
type: "button",
|
|
6160
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${filterId === s.id ? panel_module_css_default.buttonPrimary : ""}`,
|
|
6161
|
+
title: s.traits,
|
|
6162
|
+
onClick: () => {
|
|
6163
|
+
setFilterId(s.id);
|
|
6164
|
+
},
|
|
6165
|
+
children: s.name
|
|
6166
|
+
}, s.id))]
|
|
6167
|
+
})]
|
|
6168
|
+
}),
|
|
6169
|
+
error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6170
|
+
className: panel_module_css_default.importError,
|
|
6171
|
+
children: error
|
|
6172
|
+
}),
|
|
6173
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6174
|
+
className: panel_module_css_default.row,
|
|
6175
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6176
|
+
type: "button",
|
|
6177
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
6178
|
+
disabled: busy || name.trim() === "" || styleId === "",
|
|
6179
|
+
onClick: () => {
|
|
6180
|
+
createPlan();
|
|
6181
|
+
},
|
|
6182
|
+
children: "创建方案"
|
|
6183
|
+
})
|
|
6184
|
+
})
|
|
6185
|
+
]
|
|
6186
|
+
}),
|
|
6187
|
+
plans.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6188
|
+
className: panel_module_css_default.meta,
|
|
6189
|
+
style: { marginTop: 8 },
|
|
6190
|
+
children: "尚无漫剧方案——新建一个方案,选择基底风格开始。"
|
|
5278
6191
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5279
6192
|
style: {
|
|
5280
6193
|
display: "flex",
|
|
5281
6194
|
flexDirection: "column",
|
|
5282
|
-
gap: 6
|
|
6195
|
+
gap: 6,
|
|
6196
|
+
marginTop: 8
|
|
5283
6197
|
},
|
|
5284
|
-
children:
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
6198
|
+
children: plans.map((p) => {
|
|
6199
|
+
const style = findStyle(p.styleId);
|
|
6200
|
+
const filter = p.filterId !== void 0 ? findStyle(p.filterId) : void 0;
|
|
6201
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6202
|
+
style: {
|
|
6203
|
+
display: "flex",
|
|
6204
|
+
alignItems: "center",
|
|
6205
|
+
gap: 8,
|
|
6206
|
+
flexWrap: "wrap",
|
|
6207
|
+
border: `1px solid ${p.active ? "var(--nf-accent)" : "var(--nf-border)"}`,
|
|
6208
|
+
borderRadius: 10,
|
|
6209
|
+
padding: "8px 10px"
|
|
6210
|
+
},
|
|
6211
|
+
children: [
|
|
6212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: p.name }),
|
|
6213
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6214
|
+
className: panel_module_css_default.badge,
|
|
6215
|
+
children: style?.name ?? p.styleId
|
|
6216
|
+
}),
|
|
6217
|
+
filter !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6218
|
+
className: panel_module_css_default.badge,
|
|
6219
|
+
children: ["+", filter.name]
|
|
6220
|
+
}),
|
|
6221
|
+
p.active && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6222
|
+
className: `${panel_module_css_default.badge} ${panel_module_css_default.badgeDone}`,
|
|
6223
|
+
children: "激活中"
|
|
6224
|
+
}),
|
|
6225
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: { flex: 1 } }),
|
|
6226
|
+
!p.active && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6227
|
+
type: "button",
|
|
6228
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
6229
|
+
disabled: busy,
|
|
6230
|
+
onClick: async () => {
|
|
6231
|
+
if (await mutate({
|
|
6232
|
+
op: "activate",
|
|
6233
|
+
id: p.id
|
|
6234
|
+
})) await refreshProject();
|
|
6235
|
+
},
|
|
6236
|
+
children: "激活"
|
|
6237
|
+
}),
|
|
6238
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6239
|
+
type: "button",
|
|
6240
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
6241
|
+
disabled: busy,
|
|
6242
|
+
onClick: async () => {
|
|
6243
|
+
if (await mutate({
|
|
6244
|
+
op: "remove",
|
|
6245
|
+
id: p.id
|
|
6246
|
+
})) await refreshProject();
|
|
6247
|
+
},
|
|
6248
|
+
children: "删除"
|
|
6249
|
+
})
|
|
6250
|
+
]
|
|
6251
|
+
}, p.id);
|
|
6252
|
+
})
|
|
6253
|
+
})
|
|
6254
|
+
]
|
|
6255
|
+
}), plans.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StoryboardTab, {
|
|
6256
|
+
api,
|
|
6257
|
+
project,
|
|
6258
|
+
chapters,
|
|
6259
|
+
onProjectChanged,
|
|
6260
|
+
styleId: activePlan?.styleId,
|
|
6261
|
+
filterId: activePlan?.filterId
|
|
6262
|
+
})]
|
|
6263
|
+
});
|
|
6264
|
+
}
|
|
6265
|
+
//#endregion
|
|
6266
|
+
//#region src/client/panel/StyleGallery.tsx
|
|
6267
|
+
/**
|
|
6268
|
+
* 风格库页面:4 个分类标签 + 风格卡片网格。
|
|
6269
|
+
* 卡片预留:风格效果图占位 + 特点说明 + 关键词(一键复制)。
|
|
6270
|
+
* 后续:新建漫剧方案时从这里选风格(基底 + 滤镜)。
|
|
6271
|
+
*/
|
|
6272
|
+
function StyleGallery() {
|
|
6273
|
+
const [active, setActive] = (0, react.useState)("3d");
|
|
6274
|
+
const [copied, setCopied] = (0, react.useState)("");
|
|
6275
|
+
const copyKeywords = async (id, keywords) => {
|
|
6276
|
+
try {
|
|
6277
|
+
await navigator.clipboard.writeText(keywords);
|
|
6278
|
+
setCopied(id);
|
|
6279
|
+
setTimeout(() => {
|
|
6280
|
+
setCopied("");
|
|
6281
|
+
}, 1500);
|
|
6282
|
+
} catch {}
|
|
6283
|
+
};
|
|
6284
|
+
const list = stylesByCategory(active);
|
|
6285
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6286
|
+
className: panel_module_css_default.card,
|
|
6287
|
+
children: [
|
|
6288
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6289
|
+
className: panel_module_css_default.row,
|
|
6290
|
+
style: {
|
|
6291
|
+
justifyContent: "space-between",
|
|
6292
|
+
flexWrap: "wrap"
|
|
6293
|
+
},
|
|
6294
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6295
|
+
className: panel_module_css_default.cardTitle,
|
|
6296
|
+
children: "🎨 风格库"
|
|
6297
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6298
|
+
className: panel_module_css_default.meta,
|
|
6299
|
+
children: [
|
|
6300
|
+
"共 ",
|
|
6301
|
+
STYLE_LIBRARY.length,
|
|
6302
|
+
" 个内置模板 · 新建漫剧方案时选择(影视类可作滤镜叠加)"
|
|
6303
|
+
]
|
|
5311
6304
|
})]
|
|
6305
|
+
}),
|
|
6306
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6307
|
+
className: panel_module_css_default.row,
|
|
6308
|
+
style: {
|
|
6309
|
+
gap: 8,
|
|
6310
|
+
flexWrap: "wrap"
|
|
6311
|
+
},
|
|
6312
|
+
children: STYLE_CATEGORIES.map((cat) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6313
|
+
type: "button",
|
|
6314
|
+
className: `${panel_module_css_default.button} ${active === cat.id ? panel_module_css_default.buttonPrimary : ""}`,
|
|
6315
|
+
style: {
|
|
6316
|
+
flex: 1,
|
|
6317
|
+
minWidth: 140
|
|
6318
|
+
},
|
|
6319
|
+
onClick: () => {
|
|
6320
|
+
setActive(cat.id);
|
|
6321
|
+
},
|
|
6322
|
+
children: [
|
|
6323
|
+
cat.icon,
|
|
6324
|
+
" ",
|
|
6325
|
+
cat.label,
|
|
6326
|
+
"(",
|
|
6327
|
+
stylesByCategory(cat.id).length,
|
|
6328
|
+
")"
|
|
6329
|
+
]
|
|
6330
|
+
}, cat.id))
|
|
6331
|
+
}),
|
|
6332
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6333
|
+
className: panel_module_css_default.meta,
|
|
6334
|
+
children: STYLE_CATEGORIES.find((c) => c.id === active)?.desc
|
|
6335
|
+
}),
|
|
6336
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6337
|
+
style: {
|
|
6338
|
+
display: "grid",
|
|
6339
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))",
|
|
6340
|
+
gap: 12,
|
|
6341
|
+
marginTop: 6
|
|
6342
|
+
},
|
|
6343
|
+
children: list.map((style) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6344
|
+
style: {
|
|
6345
|
+
display: "flex",
|
|
6346
|
+
flexDirection: "column",
|
|
6347
|
+
gap: 6,
|
|
6348
|
+
border: "1px solid var(--nf-border)",
|
|
6349
|
+
borderRadius: 14,
|
|
6350
|
+
padding: 10,
|
|
6351
|
+
background: "var(--nf-bg-raise)"
|
|
6352
|
+
},
|
|
6353
|
+
children: [
|
|
6354
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6355
|
+
style: {
|
|
6356
|
+
aspectRatio: "3 / 4",
|
|
6357
|
+
borderRadius: 10,
|
|
6358
|
+
position: "relative",
|
|
6359
|
+
overflow: "hidden",
|
|
6360
|
+
display: "flex",
|
|
6361
|
+
alignItems: "center",
|
|
6362
|
+
justifyContent: "center",
|
|
6363
|
+
background: "linear-gradient(145deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 12%, var(--nf-bg-inset)))",
|
|
6364
|
+
border: "1px solid var(--nf-border)",
|
|
6365
|
+
color: "var(--nf-text-3)",
|
|
6366
|
+
fontSize: 12,
|
|
6367
|
+
textAlign: "center"
|
|
6368
|
+
},
|
|
6369
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
6370
|
+
src: `/api/dsh-novel-forge/styles/image?id=${style.id}`,
|
|
6371
|
+
alt: style.name,
|
|
6372
|
+
loading: "lazy",
|
|
6373
|
+
style: {
|
|
6374
|
+
position: "absolute",
|
|
6375
|
+
inset: 0,
|
|
6376
|
+
width: "100%",
|
|
6377
|
+
height: "100%",
|
|
6378
|
+
objectFit: "cover"
|
|
6379
|
+
},
|
|
6380
|
+
onError: (e) => {
|
|
6381
|
+
e.currentTarget.style.display = "none";
|
|
6382
|
+
}
|
|
6383
|
+
}), "🖼️ 效果图待生成"]
|
|
6384
|
+
}),
|
|
6385
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6386
|
+
className: panel_module_css_default.row,
|
|
6387
|
+
style: { flexWrap: "wrap" },
|
|
6388
|
+
children: [
|
|
6389
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: style.name }),
|
|
6390
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6391
|
+
className: panel_module_css_default.badge,
|
|
6392
|
+
children: [
|
|
6393
|
+
STYLE_CATEGORIES.find((c) => c.id === style.category)?.icon,
|
|
6394
|
+
" ",
|
|
6395
|
+
style.category.toUpperCase()
|
|
6396
|
+
]
|
|
6397
|
+
}),
|
|
6398
|
+
style.stackable === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6399
|
+
className: panel_module_css_default.badge,
|
|
6400
|
+
children: "叠加滤镜"
|
|
6401
|
+
})
|
|
6402
|
+
]
|
|
6403
|
+
}),
|
|
6404
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6405
|
+
className: panel_module_css_default.meta,
|
|
6406
|
+
style: {
|
|
6407
|
+
fontSize: 12,
|
|
6408
|
+
lineHeight: 1.6
|
|
6409
|
+
},
|
|
6410
|
+
children: style.traits
|
|
6411
|
+
}),
|
|
6412
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6413
|
+
style: {
|
|
6414
|
+
fontSize: 11.5,
|
|
6415
|
+
lineHeight: 1.5,
|
|
6416
|
+
color: "var(--nf-text-2)",
|
|
6417
|
+
borderTop: "1px solid var(--nf-border)",
|
|
6418
|
+
paddingTop: 6,
|
|
6419
|
+
display: "-webkit-box",
|
|
6420
|
+
WebkitLineClamp: 3,
|
|
6421
|
+
WebkitBoxOrient: "vertical",
|
|
6422
|
+
overflow: "hidden",
|
|
6423
|
+
cursor: "pointer"
|
|
6424
|
+
},
|
|
6425
|
+
title: "点击复制关键词",
|
|
6426
|
+
onClick: () => {
|
|
6427
|
+
copyKeywords(style.id, style.keywords);
|
|
6428
|
+
},
|
|
6429
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6430
|
+
className: panel_module_css_default.meta,
|
|
6431
|
+
children: "关键词:"
|
|
6432
|
+
}), style.keywords]
|
|
6433
|
+
}),
|
|
6434
|
+
copied === style.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6435
|
+
style: {
|
|
6436
|
+
color: "var(--nf-ok, #46a758)",
|
|
6437
|
+
fontSize: 12
|
|
6438
|
+
},
|
|
6439
|
+
children: "✅ 已复制"
|
|
6440
|
+
})
|
|
6441
|
+
]
|
|
6442
|
+
}, style.id))
|
|
5312
6443
|
})
|
|
5313
6444
|
]
|
|
5314
6445
|
});
|
|
@@ -5992,6 +7123,16 @@ window.__ModuleLoader__.load({
|
|
|
5992
7123
|
label: "场景库",
|
|
5993
7124
|
icon: "🏞️"
|
|
5994
7125
|
},
|
|
7126
|
+
{
|
|
7127
|
+
id: "styleLib",
|
|
7128
|
+
label: "风格库",
|
|
7129
|
+
icon: "🎨"
|
|
7130
|
+
},
|
|
7131
|
+
{
|
|
7132
|
+
id: "manhua",
|
|
7133
|
+
label: "漫剧",
|
|
7134
|
+
icon: "🎬"
|
|
7135
|
+
},
|
|
5995
7136
|
{
|
|
5996
7137
|
id: "run",
|
|
5997
7138
|
label: "生产单",
|
|
@@ -6028,7 +7169,7 @@ window.__ModuleLoader__.load({
|
|
|
6028
7169
|
"high",
|
|
6029
7170
|
"max"
|
|
6030
7171
|
];
|
|
6031
|
-
const PLUGIN_VERSION = "1.
|
|
7172
|
+
const PLUGIN_VERSION = "1.5.0";
|
|
6032
7173
|
/** GitHub 仓库地址(关于区块点击跳转)。 */
|
|
6033
7174
|
const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
|
|
6034
7175
|
/** Whether any chapter is being generated right now. */
|
|
@@ -7169,9 +8310,12 @@ window.__ModuleLoader__.load({
|
|
|
7169
8310
|
setBusyLabel(`生成「${name}」形象锚点…`);
|
|
7170
8311
|
setError("");
|
|
7171
8312
|
try {
|
|
8313
|
+
const activePlan = (project?.mangaPlans ?? []).find((pl) => pl.active);
|
|
7172
8314
|
await api.roles({
|
|
7173
8315
|
op: "visual",
|
|
7174
|
-
name
|
|
8316
|
+
name,
|
|
8317
|
+
styleId: activePlan?.styleId,
|
|
8318
|
+
filterId: activePlan?.filterId
|
|
7175
8319
|
});
|
|
7176
8320
|
await refresh(false);
|
|
7177
8321
|
pushProgress(`已生成「${name}」形象锚点`, "done");
|
|
@@ -12478,6 +13622,13 @@ window.__ModuleLoader__.load({
|
|
|
12478
13622
|
api,
|
|
12479
13623
|
totalChapters: chapters.length
|
|
12480
13624
|
}),
|
|
13625
|
+
activeTab === "styleLib" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StyleGallery, {}),
|
|
13626
|
+
activeTab === "manhua" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MangaWorkspace, {
|
|
13627
|
+
api,
|
|
13628
|
+
project,
|
|
13629
|
+
chapters,
|
|
13630
|
+
onProjectChanged: () => refresh(false)
|
|
13631
|
+
}),
|
|
12481
13632
|
activeTab === "breakdown" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12482
13633
|
className: panel_module_css_default.card,
|
|
12483
13634
|
children: [
|
|
@@ -13286,9 +14437,12 @@ window.__ModuleLoader__.load({
|
|
|
13286
14437
|
setBusyLabel(`精修「${detailRole.name}」提示词…`);
|
|
13287
14438
|
setError("");
|
|
13288
14439
|
try {
|
|
14440
|
+
const activePlan = (project?.mangaPlans ?? []).find((pl) => pl.active);
|
|
13289
14441
|
await api.roles({
|
|
13290
14442
|
op: "promptKit",
|
|
13291
|
-
name: detailRole.name
|
|
14443
|
+
name: detailRole.name,
|
|
14444
|
+
styleId: activePlan?.styleId,
|
|
14445
|
+
filterId: activePlan?.filterId
|
|
13292
14446
|
});
|
|
13293
14447
|
await refresh(false);
|
|
13294
14448
|
pushProgress(`已生成「${detailRole.name}」四类精修提示词`, "done");
|