@waterwx/dsh-novel-forge 1.2.0 → 1.3.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/README.md +5 -0
- package/lib/client.js +2100 -651
- package/lib/client.js.map +1 -1
- package/lib/index.js +567 -173
- package/lib/index.js.map +1 -1
- package/lib/types/client/api.d.ts +4 -4
- package/lib/types/client/panel/NovelPanel.d.ts +1 -1
- package/lib/types/comic-presets.d.ts +12 -0
- package/lib/types/engine.d.ts +16 -13
- package/lib/types/index.d.ts +6 -0
- package/lib/types/protocol.d.ts +128 -89
- package/package.json +1 -1
- package/src/client/api.ts +10 -10
- package/src/client/panel/NovelPanel.tsx +650 -172
- package/src/comic-presets.ts +67 -0
- package/src/engine.ts +344 -188
- package/src/index.ts +15 -0
- package/src/protocol.ts +121 -96
- package/src/routes.ts +173 -52
package/lib/client.js
CHANGED
|
@@ -67,6 +67,8 @@ window.__ModuleLoader__.load({
|
|
|
67
67
|
plotlines: "/api/dsh-novel-forge/plotlines",
|
|
68
68
|
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
69
69
|
roles: "/api/dsh-novel-forge/roles",
|
|
70
|
+
scenes: "/api/dsh-novel-forge/scenes",
|
|
71
|
+
visualRules: "/api/dsh-novel-forge/visual-rules",
|
|
70
72
|
/** 作者复盘补跑:对已写章节补齐 authorReview(全书流式 / 单章 JSON)。 */
|
|
71
73
|
reviewBackfill: "/api/dsh-novel-forge/review/backfill",
|
|
72
74
|
/** 章节复位:generating 卡死 → pending(可重新生成)。 */
|
|
@@ -80,9 +82,8 @@ window.__ModuleLoader__.load({
|
|
|
80
82
|
/** 拆书分析:对已写章节做结构/人物/文风/卖点四维体检(两阶段:源笔记→分节分析)。 */
|
|
81
83
|
breakdown: "/api/dsh-novel-forge/breakdown",
|
|
82
84
|
/** 漫剧分镜生成:章节 → 角色锚点 + 分镜表(可适配豆包/Seedance/SD)。 */
|
|
83
|
-
storyboard: "/api/dsh-novel-forge/storyboard",
|
|
84
85
|
/** 漫剧分集计划:读一卷 → 按故事弧线分集(高潮拆集/过渡并章)。 */
|
|
85
|
-
|
|
86
|
+
/** 漫画脚本:章节 → 分页分格漫画脚本(含角色视觉锚点)。 */
|
|
86
87
|
/** 生产单:启动批量生产(计划补足 + 逐章生成 + 被拒分级处理)。 */
|
|
87
88
|
runStart: "/api/dsh-novel-forge/run/start",
|
|
88
89
|
/** 生产单控制:pause / resume / stop。 */
|
|
@@ -155,23 +156,6 @@ window.__ModuleLoader__.load({
|
|
|
155
156
|
budgetTokens
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
|
-
/** 漫剧分镜生成:章节 → 角色锚点 + 分镜表。 */
|
|
159
|
-
async storyboard(chapterNo, genre, platform, tool) {
|
|
160
|
-
return postJson(NOVEL_API.storyboard, {
|
|
161
|
-
chapterNo,
|
|
162
|
-
genre,
|
|
163
|
-
platform,
|
|
164
|
-
tool
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/** 漫剧分集计划:读一卷 → 按故事弧线分集。 */
|
|
168
|
-
async storyboardPlan(volumeNo, platform, maxEpisodes) {
|
|
169
|
-
return postJson(NOVEL_API.storyboardPlan, {
|
|
170
|
-
volumeNo,
|
|
171
|
-
platform,
|
|
172
|
-
maxEpisodes
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
159
|
async plan(outline, chapterCount, volume) {
|
|
176
160
|
return postJson(NOVEL_API.plan, {
|
|
177
161
|
outline,
|
|
@@ -286,6 +270,14 @@ window.__ModuleLoader__.load({
|
|
|
286
270
|
async roles(req) {
|
|
287
271
|
return postJson(NOVEL_API.roles, req);
|
|
288
272
|
}
|
|
273
|
+
/** 场景库:AI 提炼 / 采纳 / 更新 / 删除 / 图集。 */
|
|
274
|
+
async scenes(req) {
|
|
275
|
+
return postJson(NOVEL_API.scenes, req);
|
|
276
|
+
}
|
|
277
|
+
/** 视觉世界观规则:提炼 / 保存。 */
|
|
278
|
+
async visualRules(req) {
|
|
279
|
+
return postJson(NOVEL_API.visualRules, req);
|
|
280
|
+
}
|
|
289
281
|
/** 小说简介:AI 生成/补全(partial 留空 = 全量),或手动保存。 */
|
|
290
282
|
async blurb(action, text, partial) {
|
|
291
283
|
return postJson(NOVEL_API.blurb, {
|
|
@@ -918,272 +910,272 @@ window.__ModuleLoader__.load({
|
|
|
918
910
|
document.head.appendChild(tag);
|
|
919
911
|
}
|
|
920
912
|
var panel_module_css_default = {
|
|
921
|
-
"
|
|
922
|
-
"
|
|
923
|
-
"
|
|
924
|
-
"
|
|
925
|
-
"
|
|
926
|
-
"
|
|
927
|
-
"
|
|
928
|
-
"
|
|
929
|
-
"
|
|
930
|
-
"
|
|
931
|
-
"createBookTop": "zE6uZW_createBookTop",
|
|
932
|
-
"createBookCard": "zE6uZW_createBookCard",
|
|
933
|
-
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
934
|
-
"navTabBadgeLive": "zE6uZW_navTabBadgeLive",
|
|
935
|
-
"navTabIcon": "zE6uZW_navTabIcon",
|
|
936
|
-
"statRowD": "zE6uZW_statRowD",
|
|
937
|
-
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
938
|
-
"readerGroupArrow": "zE6uZW_readerGroupArrow",
|
|
939
|
-
"progressBar": "zE6uZW_progressBar",
|
|
940
|
-
"bookCreateForm": "zE6uZW_bookCreateForm",
|
|
941
|
-
"panelContent": "zE6uZW_panelContent",
|
|
942
|
-
"bookshelfLabel": "zE6uZW_bookshelfLabel",
|
|
943
|
-
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
913
|
+
"workflowRow": "zE6uZW_workflowRow",
|
|
914
|
+
"genreDesc": "zE6uZW_genreDesc",
|
|
915
|
+
"readerTitle": "zE6uZW_readerTitle",
|
|
916
|
+
"diffTagOld": "zE6uZW_diffTagOld",
|
|
917
|
+
"dashFacts": "zE6uZW_dashFacts",
|
|
918
|
+
"toolStepStatus": "zE6uZW_toolStepStatus",
|
|
919
|
+
"readerLoading": "zE6uZW_readerLoading",
|
|
920
|
+
"volumeGroup": "zE6uZW_volumeGroup",
|
|
921
|
+
"fileList": "zE6uZW_fileList",
|
|
922
|
+
"chatScroll": "zE6uZW_chatScroll",
|
|
944
923
|
"progressLineLive": "zE6uZW_progressLineLive",
|
|
945
|
-
"
|
|
946
|
-
"
|
|
924
|
+
"workflowDotDone": "zE6uZW_workflowDotDone",
|
|
925
|
+
"dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
|
|
926
|
+
"bookCardMetaRow": "zE6uZW_bookCardMetaRow",
|
|
927
|
+
"navGroupLabel": "zE6uZW_navGroupLabel",
|
|
928
|
+
"navTabBadgeDone": "zE6uZW_navTabBadgeDone",
|
|
929
|
+
"toolSteps": "zE6uZW_toolSteps",
|
|
930
|
+
"shelfTitleRow": "zE6uZW_shelfTitleRow",
|
|
947
931
|
"buttonSmall": "zE6uZW_buttonSmall",
|
|
948
|
-
"
|
|
949
|
-
"
|
|
932
|
+
"bookChipMeta": "zE6uZW_bookChipMeta",
|
|
933
|
+
"row": "zE6uZW_row",
|
|
934
|
+
"readerItemBadge": "zE6uZW_readerItemBadge",
|
|
950
935
|
"shelfEmpty": "zE6uZW_shelfEmpty",
|
|
951
|
-
"
|
|
952
|
-
"
|
|
953
|
-
"
|
|
954
|
-
"
|
|
955
|
-
"
|
|
936
|
+
"readerSeg": "zE6uZW_readerSeg",
|
|
937
|
+
"fieldLabel": "zE6uZW_fieldLabel",
|
|
938
|
+
"tlSegTrack": "zE6uZW_tlSegTrack",
|
|
939
|
+
"spaceBetween": "zE6uZW_spaceBetween",
|
|
940
|
+
"chapterTitle": "zE6uZW_chapterTitle",
|
|
941
|
+
"bookCardBlurb": "zE6uZW_bookCardBlurb",
|
|
942
|
+
"ideaCard": "zE6uZW_ideaCard",
|
|
943
|
+
"bookAdd": "zE6uZW_bookAdd",
|
|
956
944
|
"dropzoneIcon": "zE6uZW_dropzoneIcon",
|
|
945
|
+
"bookCardActions": "zE6uZW_bookCardActions",
|
|
946
|
+
"bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
|
|
947
|
+
"createBookTitle": "zE6uZW_createBookTitle",
|
|
948
|
+
"bookCardActive": "zE6uZW_bookCardActive",
|
|
949
|
+
"bookshelfList": "zE6uZW_bookshelfList",
|
|
950
|
+
"tlSegLabel": "zE6uZW_tlSegLabel",
|
|
951
|
+
"bookSwitch": "zE6uZW_bookSwitch",
|
|
952
|
+
"chapterMain": "zE6uZW_chapterMain",
|
|
953
|
+
"assetStatDetail": "zE6uZW_assetStatDetail",
|
|
954
|
+
"progressLineError": "zE6uZW_progressLineError",
|
|
957
955
|
"iconButton": "zE6uZW_iconButton",
|
|
958
|
-
"
|
|
959
|
-
"view": "zE6uZW_view",
|
|
960
|
-
"volumeGroupToggle": "zE6uZW_volumeGroupToggle",
|
|
961
|
-
"bookCardProgressFill": "zE6uZW_bookCardProgressFill",
|
|
962
|
-
"volumeGroupHeader": "zE6uZW_volumeGroupHeader",
|
|
963
|
-
"badgeWritten": "zE6uZW_badgeWritten",
|
|
964
|
-
"chatRole": "zE6uZW_chatRole",
|
|
965
|
-
"bigProgressBarFill": "zE6uZW_bigProgressBarFill",
|
|
966
|
-
"toolLive": "zE6uZW_toolLive",
|
|
967
|
-
"statCardDLabel": "zE6uZW_statCardDLabel",
|
|
968
|
-
"readerGroupTitle": "zE6uZW_readerGroupTitle",
|
|
969
|
-
"readerSegBtn": "zE6uZW_readerSegBtn",
|
|
970
|
-
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
971
|
-
"toolStepIcon": "zE6uZW_toolStepIcon",
|
|
972
|
-
"dropzone": "zE6uZW_dropzone",
|
|
973
|
-
"navSpacer": "zE6uZW_navSpacer",
|
|
974
|
-
"dashHero": "zE6uZW_dashHero",
|
|
975
|
-
"bookChipMeta": "zE6uZW_bookChipMeta",
|
|
976
|
-
"bookshelf": "zE6uZW_bookshelf",
|
|
977
|
-
"chapterPreview": "zE6uZW_chapterPreview",
|
|
978
|
-
"chapterActions": "zE6uZW_chapterActions",
|
|
979
|
-
"readerError": "zE6uZW_readerError",
|
|
980
|
-
"diffTagOld": "zE6uZW_diffTagOld",
|
|
981
|
-
"statCardDDown": "zE6uZW_statCardDDown",
|
|
982
|
-
"workflowDot": "zE6uZW_workflowDot",
|
|
956
|
+
"dashJourneyStages": "zE6uZW_dashJourneyStages",
|
|
983
957
|
"readerItem": "zE6uZW_readerItem",
|
|
984
|
-
"
|
|
985
|
-
"
|
|
986
|
-
"
|
|
987
|
-
"
|
|
988
|
-
"
|
|
989
|
-
"
|
|
990
|
-
"
|
|
991
|
-
"
|
|
992
|
-
"
|
|
993
|
-
"
|
|
994
|
-
"
|
|
995
|
-
"cardTitle": "zE6uZW_cardTitle",
|
|
996
|
-
"wsEditor": "zE6uZW_wsEditor",
|
|
997
|
-
"ideaCard": "zE6uZW_ideaCard",
|
|
998
|
-
"wsPreviewText": "zE6uZW_wsPreviewText",
|
|
999
|
-
"bookAddIcon": "zE6uZW_bookAddIcon",
|
|
1000
|
-
"shelfGrid": "zE6uZW_shelfGrid",
|
|
1001
|
-
"row": "zE6uZW_row",
|
|
1002
|
-
"busyRow": "zE6uZW_busyRow",
|
|
1003
|
-
"assistantStatus": "zE6uZW_assistantStatus",
|
|
1004
|
-
"statCardD": "zE6uZW_statCardD",
|
|
1005
|
-
"bookChipName": "zE6uZW_bookChipName",
|
|
1006
|
-
"fadeIn": "zE6uZW_fadeIn",
|
|
1007
|
-
"chapter": "zE6uZW_chapter",
|
|
1008
|
-
"readerChapterTitle": "zE6uZW_readerChapterTitle",
|
|
1009
|
-
"readerGroup": "zE6uZW_readerGroup",
|
|
1010
|
-
"readerItemNo": "zE6uZW_readerItemNo",
|
|
958
|
+
"buttonPrimary": "zE6uZW_buttonPrimary",
|
|
959
|
+
"panelTitle": "zE6uZW_panelTitle",
|
|
960
|
+
"todoInfo": "zE6uZW_todoInfo",
|
|
961
|
+
"toolStepActive": "zE6uZW_toolStepActive",
|
|
962
|
+
"wsPreview": "zE6uZW_wsPreview",
|
|
963
|
+
"dashStageDone": "zE6uZW_dashStageDone",
|
|
964
|
+
"progress": "zE6uZW_progress",
|
|
965
|
+
"workflowLabel": "zE6uZW_workflowLabel",
|
|
966
|
+
"panel": "zE6uZW_panel",
|
|
967
|
+
"bookCard": "zE6uZW_bookCard",
|
|
968
|
+
"readerSegActive": "zE6uZW_readerSegActive",
|
|
1011
969
|
"toolStepName": "zE6uZW_toolStepName",
|
|
1012
|
-
"
|
|
1013
|
-
"
|
|
970
|
+
"panelNav": "zE6uZW_panelNav",
|
|
971
|
+
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
972
|
+
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
973
|
+
"field": "zE6uZW_field",
|
|
974
|
+
"readerGroupArrow": "zE6uZW_readerGroupArrow",
|
|
975
|
+
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
976
|
+
"meta": "zE6uZW_meta",
|
|
977
|
+
"bookshelfLabel": "zE6uZW_bookshelfLabel",
|
|
1014
978
|
"button": "zE6uZW_button",
|
|
1015
|
-
"
|
|
1016
|
-
"
|
|
1017
|
-
"assetStatValue": "zE6uZW_assetStatValue",
|
|
1018
|
-
"shelfTitleRow": "zE6uZW_shelfTitleRow",
|
|
1019
|
-
"tlSegLabel": "zE6uZW_tlSegLabel",
|
|
1020
|
-
"dashJourneyStages": "zE6uZW_dashJourneyStages",
|
|
1021
|
-
"ideaCandidate": "zE6uZW_ideaCandidate",
|
|
1022
|
-
"workflowList": "zE6uZW_workflowList",
|
|
1023
|
-
"readerBody": "zE6uZW_readerBody",
|
|
1024
|
-
"workflowBody": "zE6uZW_workflowBody",
|
|
1025
|
-
"ideaToggle": "zE6uZW_ideaToggle",
|
|
1026
|
-
"wsPage": "zE6uZW_wsPage",
|
|
1027
|
-
"todoText": "zE6uZW_todoText",
|
|
1028
|
-
"bookAdd": "zE6uZW_bookAdd",
|
|
1029
|
-
"chapterList": "zE6uZW_chapterList",
|
|
1030
|
-
"bookSwitchMeta": "zE6uZW_bookSwitchMeta",
|
|
1031
|
-
"reviewBox": "zE6uZW_reviewBox",
|
|
1032
|
-
"assetGrid": "zE6uZW_assetGrid",
|
|
1033
|
-
"entryIcon": "zE6uZW_entryIcon",
|
|
1034
|
-
"readerItemTitle": "zE6uZW_readerItemTitle",
|
|
1035
|
-
"panelNavCollapsed": "zE6uZW_panelNavCollapsed",
|
|
1036
|
-
"navGroupLabel": "zE6uZW_navGroupLabel",
|
|
979
|
+
"badgeError": "zE6uZW_badgeError",
|
|
980
|
+
"assistantFloatHeader": "zE6uZW_assistantFloatHeader",
|
|
1037
981
|
"wsSelectedText": "zE6uZW_wsSelectedText",
|
|
982
|
+
"bookCardTitleRow": "zE6uZW_bookCardTitleRow",
|
|
983
|
+
"createBookCard": "zE6uZW_createBookCard",
|
|
984
|
+
"onlyChanges": "zE6uZW_onlyChanges",
|
|
985
|
+
"panelBody": "zE6uZW_panelBody",
|
|
1038
986
|
"navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
|
|
1039
|
-
"
|
|
1040
|
-
"
|
|
1041
|
-
"
|
|
1042
|
-
"
|
|
1043
|
-
"
|
|
1044
|
-
"
|
|
1045
|
-
"
|
|
1046
|
-
"
|
|
1047
|
-
"
|
|
1048
|
-
"diffTagNew": "zE6uZW_diffTagNew",
|
|
1049
|
-
"pulse": "zE6uZW_pulse",
|
|
1050
|
-
"assistantFloat": "zE6uZW_assistantFloat",
|
|
987
|
+
"tlSegFill": "zE6uZW_tlSegFill",
|
|
988
|
+
"workflowDot": "zE6uZW_workflowDot",
|
|
989
|
+
"progressBarFill": "zE6uZW_progressBarFill",
|
|
990
|
+
"readerGroup": "zE6uZW_readerGroup",
|
|
991
|
+
"statCardDValue": "zE6uZW_statCardDValue",
|
|
992
|
+
"diffOld": "zE6uZW_diffOld",
|
|
993
|
+
"bookChipRemove": "zE6uZW_bookChipRemove",
|
|
994
|
+
"navTabBadgeLive": "zE6uZW_navTabBadgeLive",
|
|
995
|
+
"bookSwitchArrow": "zE6uZW_bookSwitchArrow",
|
|
1051
996
|
"tlSegCurrent": "zE6uZW_tlSegCurrent",
|
|
1052
|
-
"
|
|
1053
|
-
"
|
|
1054
|
-
"
|
|
997
|
+
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
998
|
+
"chapterFocus": "zE6uZW_chapterFocus",
|
|
999
|
+
"chatRole": "zE6uZW_chatRole",
|
|
1000
|
+
"toolStepIcon": "zE6uZW_toolStepIcon",
|
|
1001
|
+
"readerItemTitle": "zE6uZW_readerItemTitle",
|
|
1002
|
+
"chapterNum": "zE6uZW_chapterNum",
|
|
1003
|
+
"statCardDIcon": "zE6uZW_statCardDIcon",
|
|
1004
|
+
"assistantResize": "zE6uZW_assistantResize",
|
|
1005
|
+
"assistantStatusBusy": "zE6uZW_assistantStatusBusy",
|
|
1055
1006
|
"shelfView": "zE6uZW_shelfView",
|
|
1056
|
-
"
|
|
1057
|
-
"
|
|
1007
|
+
"progressBar": "zE6uZW_progressBar",
|
|
1008
|
+
"assistantFloat": "zE6uZW_assistantFloat",
|
|
1058
1009
|
"dashGrid": "zE6uZW_dashGrid",
|
|
1059
|
-
"
|
|
1060
|
-
"
|
|
1061
|
-
"
|
|
1062
|
-
"
|
|
1010
|
+
"navTitleName": "zE6uZW_navTitleName",
|
|
1011
|
+
"assistantStatus": "zE6uZW_assistantStatus",
|
|
1012
|
+
"navTitle": "zE6uZW_navTitle",
|
|
1013
|
+
"assetStat": "zE6uZW_assetStat",
|
|
1014
|
+
"assistantFloatBody": "zE6uZW_assistantFloatBody",
|
|
1015
|
+
"busyRow": "zE6uZW_busyRow",
|
|
1016
|
+
"badgeDone": "zE6uZW_badgeDone",
|
|
1017
|
+
"legendOld": "zE6uZW_legendOld",
|
|
1018
|
+
"tab": "zE6uZW_tab",
|
|
1019
|
+
"reviewBox": "zE6uZW_reviewBox",
|
|
1020
|
+
"bookAddIcon": "zE6uZW_bookAddIcon",
|
|
1021
|
+
"dashFact": "zE6uZW_dashFact",
|
|
1022
|
+
"badgeRejected": "zE6uZW_badgeRejected",
|
|
1023
|
+
"chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
|
|
1024
|
+
"navGroup": "zE6uZW_navGroup",
|
|
1063
1025
|
"navTitleBook": "zE6uZW_navTitleBook",
|
|
1064
|
-
"
|
|
1065
|
-
"
|
|
1066
|
-
"
|
|
1067
|
-
"readerItemBadge": "zE6uZW_readerItemBadge",
|
|
1068
|
-
"panelBody": "zE6uZW_panelBody",
|
|
1069
|
-
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
1070
|
-
"shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
|
|
1071
|
-
"bigProgressBar": "zE6uZW_bigProgressBar",
|
|
1072
|
-
"dashJourneyBar": "zE6uZW_dashJourneyBar",
|
|
1073
|
-
"diffColumn": "zE6uZW_diffColumn",
|
|
1074
|
-
"diffAdd": "zE6uZW_diffAdd",
|
|
1075
|
-
"tlSegTrack": "zE6uZW_tlSegTrack",
|
|
1076
|
-
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
1077
|
-
"readerFoot": "zE6uZW_readerFoot",
|
|
1078
|
-
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
1079
|
-
"textarea": "zE6uZW_textarea",
|
|
1080
|
-
"dashStageDone": "zE6uZW_dashStageDone",
|
|
1081
|
-
"liveText": "zE6uZW_liveText",
|
|
1026
|
+
"diffDel": "zE6uZW_diffDel",
|
|
1027
|
+
"bookCardCover": "zE6uZW_bookCardCover",
|
|
1028
|
+
"todoText": "zE6uZW_todoText",
|
|
1082
1029
|
"bookSwitchName": "zE6uZW_bookSwitchName",
|
|
1083
|
-
"
|
|
1084
|
-
"
|
|
1085
|
-
"
|
|
1086
|
-
"
|
|
1087
|
-
"
|
|
1088
|
-
"
|
|
1089
|
-
"
|
|
1030
|
+
"bookCardName": "zE6uZW_bookCardName",
|
|
1031
|
+
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
1032
|
+
"navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
|
|
1033
|
+
"tlBar": "zE6uZW_tlBar",
|
|
1034
|
+
"workflowHint": "zE6uZW_workflowHint",
|
|
1035
|
+
"bookCreateForm": "zE6uZW_bookCreateForm",
|
|
1036
|
+
"readerItemActive": "zE6uZW_readerItemActive",
|
|
1037
|
+
"fadeIn": "zE6uZW_fadeIn",
|
|
1038
|
+
"bookshelf": "zE6uZW_bookshelf",
|
|
1039
|
+
"pulse": "zE6uZW_pulse",
|
|
1040
|
+
"assetGrid": "zE6uZW_assetGrid",
|
|
1041
|
+
"statCardDDown": "zE6uZW_statCardDDown",
|
|
1090
1042
|
"input": "zE6uZW_input",
|
|
1091
|
-
"
|
|
1092
|
-
"
|
|
1093
|
-
"
|
|
1043
|
+
"dashJourneyFill": "zE6uZW_dashJourneyFill",
|
|
1044
|
+
"readerPara": "zE6uZW_readerPara",
|
|
1045
|
+
"badgeWritten": "zE6uZW_badgeWritten",
|
|
1046
|
+
"badgeGenerating": "zE6uZW_badgeGenerating",
|
|
1047
|
+
"volumeGroupHeader": "zE6uZW_volumeGroupHeader",
|
|
1048
|
+
"view": "zE6uZW_view",
|
|
1049
|
+
"diffText": "zE6uZW_diffText",
|
|
1050
|
+
"navBadgePulse": "zE6uZW_navBadgePulse",
|
|
1051
|
+
"cardTitle": "zE6uZW_cardTitle",
|
|
1052
|
+
"dashHeroAction": "zE6uZW_dashHeroAction",
|
|
1053
|
+
"toolStepError": "zE6uZW_toolStepError",
|
|
1054
|
+
"badge": "zE6uZW_badge",
|
|
1055
|
+
"diffSameBody": "zE6uZW_diffSameBody",
|
|
1056
|
+
"readerError": "zE6uZW_readerError",
|
|
1057
|
+
"ideaToggle": "zE6uZW_ideaToggle",
|
|
1058
|
+
"entryIcon": "zE6uZW_entryIcon",
|
|
1059
|
+
"workflowList": "zE6uZW_workflowList",
|
|
1060
|
+
"panelContent": "zE6uZW_panelContent",
|
|
1094
1061
|
"shelfSearch": "zE6uZW_shelfSearch",
|
|
1062
|
+
"shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
|
|
1063
|
+
"chapterPreview": "zE6uZW_chapterPreview",
|
|
1095
1064
|
"wsColumns": "zE6uZW_wsColumns",
|
|
1096
|
-
"
|
|
1097
|
-
"
|
|
1098
|
-
"
|
|
1099
|
-
"
|
|
1100
|
-
"
|
|
1101
|
-
"
|
|
1102
|
-
"
|
|
1103
|
-
"
|
|
1104
|
-
"
|
|
1105
|
-
"
|
|
1106
|
-
"shelfHeader": "zE6uZW_shelfHeader",
|
|
1107
|
-
"tlSegFill": "zE6uZW_tlSegFill",
|
|
1108
|
-
"createBookTitle": "zE6uZW_createBookTitle",
|
|
1109
|
-
"bookSwitchArrow": "zE6uZW_bookSwitchArrow",
|
|
1110
|
-
"bookSwitchCover": "zE6uZW_bookSwitchCover",
|
|
1111
|
-
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
1112
|
-
"progressLine": "zE6uZW_progressLine",
|
|
1113
|
-
"tlBar": "zE6uZW_tlBar",
|
|
1065
|
+
"tlSegDone": "zE6uZW_tlSegDone",
|
|
1066
|
+
"dashHeroArrow": "zE6uZW_dashHeroArrow",
|
|
1067
|
+
"ideaCandidate": "zE6uZW_ideaCandidate",
|
|
1068
|
+
"readerChapterTitle": "zE6uZW_readerChapterTitle",
|
|
1069
|
+
"progressLineDone": "zE6uZW_progressLineDone",
|
|
1070
|
+
"wsPage": "zE6uZW_wsPage",
|
|
1071
|
+
"badgePending": "zE6uZW_badgePending",
|
|
1072
|
+
"dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
|
|
1073
|
+
"readerSegBtn": "zE6uZW_readerSegBtn",
|
|
1074
|
+
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
1114
1075
|
"dashStageDot": "zE6uZW_dashStageDot",
|
|
1115
|
-
"
|
|
1116
|
-
"
|
|
1076
|
+
"toolStep": "zE6uZW_toolStep",
|
|
1077
|
+
"progressLine": "zE6uZW_progressLine",
|
|
1117
1078
|
"diffList": "zE6uZW_diffList",
|
|
1118
|
-
"
|
|
1119
|
-
"
|
|
1120
|
-
"
|
|
1121
|
-
"
|
|
1122
|
-
"
|
|
1123
|
-
"
|
|
1124
|
-
"
|
|
1125
|
-
"
|
|
1126
|
-
"
|
|
1127
|
-
"badgeDone": "zE6uZW_badgeDone",
|
|
1128
|
-
"diffSameBody": "zE6uZW_diffSameBody",
|
|
1129
|
-
"meta": "zE6uZW_meta",
|
|
1130
|
-
"navTabLabel": "zE6uZW_navTabLabel",
|
|
1131
|
-
"bookCardName": "zE6uZW_bookCardName",
|
|
1079
|
+
"buttonDanger": "zE6uZW_buttonDanger",
|
|
1080
|
+
"diffColumn": "zE6uZW_diffColumn",
|
|
1081
|
+
"dashJourney": "zE6uZW_dashJourney",
|
|
1082
|
+
"bookCreateOutline": "zE6uZW_bookCreateOutline",
|
|
1083
|
+
"readerSidebar": "zE6uZW_readerSidebar",
|
|
1084
|
+
"readerItemNo": "zE6uZW_readerItemNo",
|
|
1085
|
+
"createBookTop": "zE6uZW_createBookTop",
|
|
1086
|
+
"bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
|
|
1087
|
+
"createBookIcon": "zE6uZW_createBookIcon",
|
|
1132
1088
|
"diffChange": "zE6uZW_diffChange",
|
|
1133
|
-
"wsPreview": "zE6uZW_wsPreview",
|
|
1134
|
-
"navTitle": "zE6uZW_navTitle",
|
|
1135
|
-
"statCardDValue": "zE6uZW_statCardDValue",
|
|
1136
|
-
"chapterNum": "zE6uZW_chapterNum",
|
|
1137
|
-
"bookshelfList": "zE6uZW_bookshelfList",
|
|
1138
|
-
"readerChapterMeta": "zE6uZW_readerChapterMeta",
|
|
1139
|
-
"dashStage": "zE6uZW_dashStage",
|
|
1140
|
-
"bookChipActive": "zE6uZW_bookChipActive",
|
|
1141
|
-
"buttonPrimary": "zE6uZW_buttonPrimary",
|
|
1142
|
-
"chapterTitle": "zE6uZW_chapterTitle",
|
|
1143
|
-
"navAboutRow": "zE6uZW_navAboutRow",
|
|
1144
|
-
"wsAppliedBanner": "zE6uZW_wsAppliedBanner",
|
|
1145
|
-
"bookCardActive": "zE6uZW_bookCardActive",
|
|
1146
1089
|
"statCardDDetail": "zE6uZW_statCardDDetail",
|
|
1147
|
-
"
|
|
1148
|
-
"
|
|
1149
|
-
"
|
|
1150
|
-
"
|
|
1151
|
-
"
|
|
1152
|
-
"
|
|
1090
|
+
"tlSeg": "zE6uZW_tlSeg",
|
|
1091
|
+
"navActions": "zE6uZW_navActions",
|
|
1092
|
+
"shelfToolbar": "zE6uZW_shelfToolbar",
|
|
1093
|
+
"readerGroupCount": "zE6uZW_readerGroupCount",
|
|
1094
|
+
"shelfFilters": "zE6uZW_shelfFilters",
|
|
1095
|
+
"statRowD": "zE6uZW_statRowD",
|
|
1096
|
+
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
1097
|
+
"bigProgressBarFill": "zE6uZW_bigProgressBarFill",
|
|
1153
1098
|
"legendNew": "zE6uZW_legendNew",
|
|
1154
|
-
"
|
|
1155
|
-
"
|
|
1156
|
-
"
|
|
1099
|
+
"todoDanger": "zE6uZW_todoDanger",
|
|
1100
|
+
"panelNavCollapsed": "zE6uZW_panelNavCollapsed",
|
|
1101
|
+
"navSpacer": "zE6uZW_navSpacer",
|
|
1102
|
+
"bigProgressBar": "zE6uZW_bigProgressBar",
|
|
1103
|
+
"shelfHeader": "zE6uZW_shelfHeader",
|
|
1157
1104
|
"wsPageHeader": "zE6uZW_wsPageHeader",
|
|
1158
|
-
"
|
|
1159
|
-
"
|
|
1160
|
-
"readerGroupCount": "zE6uZW_readerGroupCount",
|
|
1161
|
-
"diffNew": "zE6uZW_diffNew",
|
|
1162
|
-
"bookSwitch": "zE6uZW_bookSwitch",
|
|
1163
|
-
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
1164
|
-
"tlSegDone": "zE6uZW_tlSegDone",
|
|
1165
|
-
"chapterFocusPulse": "zE6uZW_chapterFocusPulse",
|
|
1166
|
-
"dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
|
|
1167
|
-
"chapterFocus": "zE6uZW_chapterFocus",
|
|
1168
|
-
"chatScroll": "zE6uZW_chatScroll",
|
|
1169
|
-
"badgeError": "zE6uZW_badgeError",
|
|
1170
|
-
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
1105
|
+
"dashJourneyBar": "zE6uZW_dashJourneyBar",
|
|
1106
|
+
"liveText": "zE6uZW_liveText",
|
|
1171
1107
|
"readerView": "zE6uZW_readerView",
|
|
1172
|
-
"
|
|
1108
|
+
"navAbout": "zE6uZW_navAbout",
|
|
1109
|
+
"chapterFocusPulse": "zE6uZW_chapterFocusPulse",
|
|
1110
|
+
"bookSwitchCover": "zE6uZW_bookSwitchCover",
|
|
1111
|
+
"readerBody": "zE6uZW_readerBody",
|
|
1112
|
+
"coverPreview": "zE6uZW_coverPreview",
|
|
1113
|
+
"readerMain": "zE6uZW_readerMain",
|
|
1114
|
+
"wsEditor": "zE6uZW_wsEditor",
|
|
1115
|
+
"bookCardBody": "zE6uZW_bookCardBody",
|
|
1116
|
+
"bookCreateCard": "zE6uZW_bookCreateCard",
|
|
1117
|
+
"dashHeroActionBody": "zE6uZW_dashHeroActionBody",
|
|
1118
|
+
"readerArticle": "zE6uZW_readerArticle",
|
|
1119
|
+
"dashStage": "zE6uZW_dashStage",
|
|
1120
|
+
"wsSelected": "zE6uZW_wsSelected",
|
|
1121
|
+
"todoItem": "zE6uZW_todoItem",
|
|
1122
|
+
"navTabIcon": "zE6uZW_navTabIcon",
|
|
1123
|
+
"textarea": "zE6uZW_textarea",
|
|
1124
|
+
"bookSwitchMeta": "zE6uZW_bookSwitchMeta",
|
|
1125
|
+
"tabBar": "zE6uZW_tabBar",
|
|
1126
|
+
"statCardDIconRed": "zE6uZW_statCardDIconRed",
|
|
1127
|
+
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
1128
|
+
"dashHeroSparkle": "zE6uZW_dashHeroSparkle",
|
|
1129
|
+
"toolLive": "zE6uZW_toolLive",
|
|
1130
|
+
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
1131
|
+
"diffTagNew": "zE6uZW_diffTagNew",
|
|
1132
|
+
"wsColumn": "zE6uZW_wsColumn",
|
|
1173
1133
|
"dashHeroTitle": "zE6uZW_dashHeroTitle",
|
|
1174
|
-
"
|
|
1175
|
-
"
|
|
1176
|
-
"
|
|
1134
|
+
"createBookView": "zE6uZW_createBookView",
|
|
1135
|
+
"bookAddCard": "zE6uZW_bookAddCard",
|
|
1136
|
+
"diffLegend": "zE6uZW_diffLegend",
|
|
1137
|
+
"wsPreviewText": "zE6uZW_wsPreviewText",
|
|
1138
|
+
"navAboutRow": "zE6uZW_navAboutRow",
|
|
1139
|
+
"chapterBeats": "zE6uZW_chapterBeats",
|
|
1140
|
+
"bookChip": "zE6uZW_bookChip",
|
|
1141
|
+
"diffAdd": "zE6uZW_diffAdd",
|
|
1142
|
+
"card": "zE6uZW_card",
|
|
1143
|
+
"readerText": "zE6uZW_readerText",
|
|
1144
|
+
"readerFoot": "zE6uZW_readerFoot",
|
|
1177
1145
|
"entry": "zE6uZW_entry",
|
|
1146
|
+
"navTab": "zE6uZW_navTab",
|
|
1147
|
+
"chapterList": "zE6uZW_chapterList",
|
|
1148
|
+
"navGroupSep": "zE6uZW_navGroupSep",
|
|
1149
|
+
"readerChapterMeta": "zE6uZW_readerChapterMeta",
|
|
1150
|
+
"readerHeader": "zE6uZW_readerHeader",
|
|
1151
|
+
"outlineReadonly": "zE6uZW_outlineReadonly",
|
|
1152
|
+
"navTitleLogo": "zE6uZW_navTitleLogo",
|
|
1153
|
+
"diffNew": "zE6uZW_diffNew",
|
|
1154
|
+
"shelfGrid": "zE6uZW_shelfGrid",
|
|
1155
|
+
"workflowDotActive": "zE6uZW_workflowDotActive",
|
|
1156
|
+
"dashStageCurrent": "zE6uZW_dashStageCurrent",
|
|
1157
|
+
"statCardDUnit": "zE6uZW_statCardDUnit",
|
|
1158
|
+
"workflowBody": "zE6uZW_workflowBody",
|
|
1159
|
+
"navActionBtn": "zE6uZW_navActionBtn",
|
|
1160
|
+
"chapterActions": "zE6uZW_chapterActions",
|
|
1161
|
+
"dashHero": "zE6uZW_dashHero",
|
|
1162
|
+
"navTabLabel": "zE6uZW_navTabLabel",
|
|
1163
|
+
"bookChipName": "zE6uZW_bookChipName",
|
|
1164
|
+
"entryLabel": "zE6uZW_entryLabel",
|
|
1165
|
+
"wsAppliedBanner": "zE6uZW_wsAppliedBanner",
|
|
1166
|
+
"todoWarning": "zE6uZW_todoWarning",
|
|
1167
|
+
"assetStatValue": "zE6uZW_assetStatValue",
|
|
1168
|
+
"readerGroupTitle": "zE6uZW_readerGroupTitle",
|
|
1169
|
+
"statCardDLabel": "zE6uZW_statCardDLabel",
|
|
1170
|
+
"bookCardProgressFill": "zE6uZW_bookCardProgressFill",
|
|
1171
|
+
"navTabBadge": "zE6uZW_navTabBadge",
|
|
1172
|
+
"statCardD": "zE6uZW_statCardD",
|
|
1178
1173
|
"diffSame": "zE6uZW_diffSame",
|
|
1179
|
-
"
|
|
1180
|
-
"
|
|
1181
|
-
"
|
|
1182
|
-
"
|
|
1183
|
-
"
|
|
1184
|
-
"panel": "zE6uZW_panel",
|
|
1185
|
-
"progressBarFill": "zE6uZW_progressBarFill",
|
|
1186
|
-
"createBookIcon": "zE6uZW_createBookIcon"
|
|
1174
|
+
"chapter": "zE6uZW_chapter",
|
|
1175
|
+
"dropzone": "zE6uZW_dropzone",
|
|
1176
|
+
"bookChipActive": "zE6uZW_bookChipActive",
|
|
1177
|
+
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
1178
|
+
"volumeGroupToggle": "zE6uZW_volumeGroupToggle"
|
|
1187
1179
|
};
|
|
1188
1180
|
//#endregion
|
|
1189
1181
|
//#region src/client/panel/AssistantTab.tsx
|
|
@@ -5567,9 +5559,14 @@ window.__ModuleLoader__.load({
|
|
|
5567
5559
|
icon: "🔍"
|
|
5568
5560
|
},
|
|
5569
5561
|
{
|
|
5570
|
-
id: "
|
|
5571
|
-
label: "
|
|
5572
|
-
icon: "
|
|
5562
|
+
id: "roleImage",
|
|
5563
|
+
label: "角色形象",
|
|
5564
|
+
icon: "🖼️"
|
|
5565
|
+
},
|
|
5566
|
+
{
|
|
5567
|
+
id: "scenes",
|
|
5568
|
+
label: "场景库",
|
|
5569
|
+
icon: "🏞️"
|
|
5573
5570
|
},
|
|
5574
5571
|
{
|
|
5575
5572
|
id: "run",
|
|
@@ -5607,7 +5604,7 @@ window.__ModuleLoader__.load({
|
|
|
5607
5604
|
"high",
|
|
5608
5605
|
"max"
|
|
5609
5606
|
];
|
|
5610
|
-
const PLUGIN_VERSION = "1.
|
|
5607
|
+
const PLUGIN_VERSION = "1.3.0";
|
|
5611
5608
|
/** GitHub 仓库地址(关于区块点击跳转)。 */
|
|
5612
5609
|
const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
|
|
5613
5610
|
/** Whether any chapter is being generated right now. */
|
|
@@ -6036,16 +6033,23 @@ window.__ModuleLoader__.load({
|
|
|
6036
6033
|
const [breakdownResult, setBreakdownResult] = (0, react.useState)(null);
|
|
6037
6034
|
const [breakdownScope, setBreakdownScope] = (0, react.useState)("recent");
|
|
6038
6035
|
const [breakdownPreset, setBreakdownPreset] = (0, react.useState)("quick");
|
|
6039
|
-
/**
|
|
6040
|
-
const [
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
const [
|
|
6047
|
-
/**
|
|
6048
|
-
const [
|
|
6036
|
+
/** 角色图集上传:当前等待上传的角色名。 */
|
|
6037
|
+
const [roleImageTarget, setRoleImageTarget] = (0, react.useState)(null);
|
|
6038
|
+
/** 角色图集上传:当前用途标签(立绘/四视图/表情-x/场景/细节)。 */
|
|
6039
|
+
const [roleImageLabel, setRoleImageLabel] = (0, react.useState)("立绘");
|
|
6040
|
+
/** 角色形象详情:当前打开的角色名(null = 关闭)。 */
|
|
6041
|
+
const [detailRoleName, setDetailRoleName] = (0, react.useState)(null);
|
|
6042
|
+
/** 详情面板:上传标签输入。 */
|
|
6043
|
+
const [detailUploadLabel, setDetailUploadLabel] = (0, react.useState)("立绘");
|
|
6044
|
+
/** 场景库:AI 提炼候选(null = 未运行)。 */
|
|
6045
|
+
const [sceneCandidates, setSceneCandidates] = (0, react.useState)(null);
|
|
6046
|
+
/** 场景库:当前打开的场景名。 */
|
|
6047
|
+
const [sceneDetailName, setSceneDetailName] = (0, react.useState)(null);
|
|
6048
|
+
/** 场景库:上传标签输入。 */
|
|
6049
|
+
const [sceneUploadLabel, setSceneUploadLabel] = (0, react.useState)("全景");
|
|
6050
|
+
/** 场景库:编辑草稿(null = 不在编辑)。 */
|
|
6051
|
+
const [sceneDraft, setSceneDraft] = (0, react.useState)(null);
|
|
6052
|
+
const roleImageInputRef = (0, react.useRef)(null);
|
|
6049
6053
|
/** AI 建议的剧情线候选(null = 未运行)。 */
|
|
6050
6054
|
const [plotlineSuggestions, setPlotlineSuggestions] = (0, react.useState)(null);
|
|
6051
6055
|
/** 剧情健康检查报告(null = 未运行)。 */
|
|
@@ -6712,77 +6716,136 @@ window.__ModuleLoader__.load({
|
|
|
6712
6716
|
setBusyLabel("");
|
|
6713
6717
|
}
|
|
6714
6718
|
};
|
|
6715
|
-
/**
|
|
6716
|
-
const
|
|
6719
|
+
/** 生成单个角色的形象锚点(复用角色库 visual 能力)。 */
|
|
6720
|
+
const handleRoleVisual = async (name) => {
|
|
6717
6721
|
setBusy(true);
|
|
6718
|
-
setBusyLabel(
|
|
6722
|
+
setBusyLabel(`生成「${name}」形象锚点…`);
|
|
6719
6723
|
setError("");
|
|
6720
6724
|
try {
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6725
|
+
await api.roles({
|
|
6726
|
+
op: "visual",
|
|
6727
|
+
name
|
|
6728
|
+
});
|
|
6729
|
+
await refresh(false);
|
|
6730
|
+
pushProgress(`已生成「${name}」形象锚点`, "done");
|
|
6724
6731
|
} catch (err) {
|
|
6725
6732
|
setError(err.message);
|
|
6726
|
-
pushProgress(
|
|
6733
|
+
pushProgress(`生成「${name}」形象锚点失败:${err.message}`, "error");
|
|
6727
6734
|
} finally {
|
|
6728
6735
|
setBusy(false);
|
|
6729
6736
|
setBusyLabel("");
|
|
6730
6737
|
}
|
|
6731
6738
|
};
|
|
6732
|
-
/**
|
|
6733
|
-
const
|
|
6739
|
+
/** 上传角色图:读取本地图片为 dataURL 并写入角色卡(带用途标签 → 图集)。 */
|
|
6740
|
+
const handleRoleImageUpload = async (name, file, label = "立绘") => {
|
|
6741
|
+
const dataUrl = await new Promise((resolve, reject) => {
|
|
6742
|
+
const reader = new FileReader();
|
|
6743
|
+
reader.onload = () => resolve(String(reader.result));
|
|
6744
|
+
reader.onerror = () => reject(reader.error ?? /* @__PURE__ */ new Error("读取图片失败"));
|
|
6745
|
+
reader.readAsDataURL(file);
|
|
6746
|
+
});
|
|
6734
6747
|
setBusy(true);
|
|
6735
|
-
setBusyLabel(
|
|
6748
|
+
setBusyLabel(`上传「${name}」${label}…`);
|
|
6736
6749
|
setError("");
|
|
6737
6750
|
try {
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6751
|
+
await api.roles({
|
|
6752
|
+
op: "image",
|
|
6753
|
+
name,
|
|
6754
|
+
dataUrl,
|
|
6755
|
+
label
|
|
6756
|
+
});
|
|
6757
|
+
await refresh(false);
|
|
6758
|
+
pushProgress(`已上传「${name}」${label}`, "done");
|
|
6741
6759
|
} catch (err) {
|
|
6742
6760
|
setError(err.message);
|
|
6743
|
-
pushProgress(
|
|
6761
|
+
pushProgress(`上传「${name}」${label}失败:${err.message}`, "error");
|
|
6744
6762
|
} finally {
|
|
6745
6763
|
setBusy(false);
|
|
6746
6764
|
setBusyLabel("");
|
|
6765
|
+
setRoleImageTarget(null);
|
|
6766
|
+
if (roleImageInputRef.current !== null) roleImageInputRef.current.value = "";
|
|
6747
6767
|
}
|
|
6748
6768
|
};
|
|
6749
|
-
/**
|
|
6750
|
-
const
|
|
6751
|
-
const missing = chapters.filter((c) => c.status !== "pending" && c.status !== "generating" && c.status !== "error" && c.authorReview === void 0).length;
|
|
6769
|
+
/** 用豆包/Seedream 为角色生成参考图。 */
|
|
6770
|
+
const handleRoleImageGenerate = async (name) => {
|
|
6752
6771
|
setBusy(true);
|
|
6753
|
-
setBusyLabel(
|
|
6772
|
+
setBusyLabel(`用豆包生成「${name}」参考图…`);
|
|
6754
6773
|
setError("");
|
|
6755
6774
|
try {
|
|
6756
|
-
await api.
|
|
6757
|
-
|
|
6775
|
+
await api.roles({
|
|
6776
|
+
op: "imageGenerate",
|
|
6777
|
+
name
|
|
6758
6778
|
});
|
|
6779
|
+
await refresh(false);
|
|
6780
|
+
pushProgress(`已生成「${name}」参考图`, "done");
|
|
6759
6781
|
} catch (err) {
|
|
6760
6782
|
setError(err.message);
|
|
6761
|
-
pushProgress(
|
|
6783
|
+
pushProgress(`生成「${name}」参考图失败:${err.message}`, "error");
|
|
6762
6784
|
} finally {
|
|
6763
6785
|
setBusy(false);
|
|
6764
6786
|
setBusyLabel("");
|
|
6765
6787
|
}
|
|
6766
6788
|
};
|
|
6767
|
-
/**
|
|
6768
|
-
const
|
|
6789
|
+
/** 更新角色漫画重要性(main/support/extra)。 */
|
|
6790
|
+
const handleRoleImportance = async (role, importance) => {
|
|
6769
6791
|
setBusy(true);
|
|
6770
|
-
setBusyLabel(
|
|
6792
|
+
setBusyLabel(`更新「${role.name}」重要性…`);
|
|
6771
6793
|
setError("");
|
|
6772
6794
|
try {
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
} : c)
|
|
6795
|
+
await api.roles({
|
|
6796
|
+
op: "update",
|
|
6797
|
+
role: {
|
|
6798
|
+
...role,
|
|
6799
|
+
importance
|
|
6800
|
+
}
|
|
6780
6801
|
});
|
|
6781
|
-
|
|
6782
|
-
pushProgress(
|
|
6802
|
+
await refresh(false);
|
|
6803
|
+
pushProgress(`已更新「${role.name}」重要性`, "done");
|
|
6783
6804
|
} catch (err) {
|
|
6784
6805
|
setError(err.message);
|
|
6785
|
-
pushProgress(
|
|
6806
|
+
pushProgress(`更新「${role.name}」重要性失败:${err.message}`, "error");
|
|
6807
|
+
} finally {
|
|
6808
|
+
setBusy(false);
|
|
6809
|
+
setBusyLabel("");
|
|
6810
|
+
}
|
|
6811
|
+
};
|
|
6812
|
+
/** 作者复盘补跑:全书缺失章节(流式)。 */
|
|
6813
|
+
const handleAuthorBackfillAll = async () => {
|
|
6814
|
+
const missing = chapters.filter((c) => c.status !== "pending" && c.status !== "generating" && c.status !== "error" && c.authorReview === void 0).length;
|
|
6815
|
+
setBusy(true);
|
|
6816
|
+
setBusyLabel(`补齐历史章节作者复盘(${missing} 章)…`);
|
|
6817
|
+
setError("");
|
|
6818
|
+
try {
|
|
6819
|
+
await api.reviewBackfillAll((frame) => {
|
|
6820
|
+
applyJobFrame(frame, () => "");
|
|
6821
|
+
});
|
|
6822
|
+
} catch (err) {
|
|
6823
|
+
setError(err.message);
|
|
6824
|
+
pushProgress(`补齐作者复盘失败:${err.message}`, "error");
|
|
6825
|
+
} finally {
|
|
6826
|
+
setBusy(false);
|
|
6827
|
+
setBusyLabel("");
|
|
6828
|
+
}
|
|
6829
|
+
};
|
|
6830
|
+
/** 作者复盘补跑:单章。 */
|
|
6831
|
+
const handleAuthorBackfillChapter = async (no) => {
|
|
6832
|
+
setBusy(true);
|
|
6833
|
+
setBusyLabel(`生成第 ${no} 章作者复盘…`);
|
|
6834
|
+
setError("");
|
|
6835
|
+
try {
|
|
6836
|
+
const result = await api.reviewBackfillChapter(no);
|
|
6837
|
+
setProject((prev) => prev === null ? prev : {
|
|
6838
|
+
...prev,
|
|
6839
|
+
chapters: prev.chapters.map((c) => c.no === result.no ? {
|
|
6840
|
+
...c,
|
|
6841
|
+
authorReview: result.review
|
|
6842
|
+
} : c)
|
|
6843
|
+
});
|
|
6844
|
+
const r = result.review;
|
|
6845
|
+
pushProgress(`📋 第${no}章作者复盘:钩子${r.hookHonored ? "已兑现 ✓" : "未兑现 ✗"} · 结尾钩子 ${r.endingHook}/10`, r.hookHonored && r.endingHook >= 6 ? "done" : "error");
|
|
6846
|
+
} catch (err) {
|
|
6847
|
+
setError(err.message);
|
|
6848
|
+
pushProgress(`生成第 ${no} 章作者复盘失败:${err.message}`, "error");
|
|
6786
6849
|
} finally {
|
|
6787
6850
|
setBusy(false);
|
|
6788
6851
|
setBusyLabel("");
|
|
@@ -7631,7 +7694,10 @@ window.__ModuleLoader__.load({
|
|
|
7631
7694
|
reviewPassScore: configDraft.reviewPassScore,
|
|
7632
7695
|
autoReview: configDraft.autoReview,
|
|
7633
7696
|
autoAuthorReview: configDraft.autoAuthorReview,
|
|
7634
|
-
autoReviewAfterRevise: configDraft.autoReviewAfterRevise
|
|
7697
|
+
autoReviewAfterRevise: configDraft.autoReviewAfterRevise,
|
|
7698
|
+
imageApiKey: configDraft.imageApiKey,
|
|
7699
|
+
imageApiModel: configDraft.imageApiModel,
|
|
7700
|
+
imageApiEnabled: configDraft.imageApiEnabled ?? false
|
|
7635
7701
|
});
|
|
7636
7702
|
setConfig(result.config);
|
|
7637
7703
|
setConfigDraft(result.config);
|
|
@@ -10697,6 +10763,79 @@ window.__ModuleLoader__.load({
|
|
|
10697
10763
|
})
|
|
10698
10764
|
]
|
|
10699
10765
|
}),
|
|
10766
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10767
|
+
className: panel_module_css_default.row,
|
|
10768
|
+
children: [
|
|
10769
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10770
|
+
className: panel_module_css_default.field,
|
|
10771
|
+
style: { flex: 1 },
|
|
10772
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
10773
|
+
className: panel_module_css_default.fieldLabel,
|
|
10774
|
+
children: "豆包 API Key(生图)"
|
|
10775
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
10776
|
+
className: panel_module_css_default.input,
|
|
10777
|
+
type: "password",
|
|
10778
|
+
placeholder: "ark-...",
|
|
10779
|
+
value: configDraft.imageApiKey ?? "",
|
|
10780
|
+
onChange: (e) => {
|
|
10781
|
+
setConfigDraft({
|
|
10782
|
+
...configDraft,
|
|
10783
|
+
imageApiKey: e.target.value
|
|
10784
|
+
});
|
|
10785
|
+
}
|
|
10786
|
+
})]
|
|
10787
|
+
}),
|
|
10788
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10789
|
+
className: panel_module_css_default.field,
|
|
10790
|
+
style: { flex: 1 },
|
|
10791
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
10792
|
+
className: panel_module_css_default.fieldLabel,
|
|
10793
|
+
children: "豆包生图模型"
|
|
10794
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
10795
|
+
className: panel_module_css_default.input,
|
|
10796
|
+
placeholder: "doubao-seedream-5-0-pro-260628",
|
|
10797
|
+
value: configDraft.imageApiModel ?? "",
|
|
10798
|
+
onChange: (e) => {
|
|
10799
|
+
setConfigDraft({
|
|
10800
|
+
...configDraft,
|
|
10801
|
+
imageApiModel: e.target.value
|
|
10802
|
+
});
|
|
10803
|
+
}
|
|
10804
|
+
})]
|
|
10805
|
+
}),
|
|
10806
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10807
|
+
className: panel_module_css_default.field,
|
|
10808
|
+
style: { flex: 1 },
|
|
10809
|
+
children: [
|
|
10810
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
10811
|
+
className: panel_module_css_default.fieldLabel,
|
|
10812
|
+
children: "启用豆包生图"
|
|
10813
|
+
}),
|
|
10814
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
10815
|
+
className: panel_module_css_default.input,
|
|
10816
|
+
value: configDraft.imageApiEnabled ? "1" : "0",
|
|
10817
|
+
onChange: (e) => {
|
|
10818
|
+
setConfigDraft({
|
|
10819
|
+
...configDraft,
|
|
10820
|
+
imageApiEnabled: e.target.value === "1"
|
|
10821
|
+
});
|
|
10822
|
+
},
|
|
10823
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
10824
|
+
value: "0",
|
|
10825
|
+
children: "关(默认)"
|
|
10826
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
10827
|
+
value: "1",
|
|
10828
|
+
children: "开"
|
|
10829
|
+
})]
|
|
10830
|
+
}),
|
|
10831
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10832
|
+
className: panel_module_css_default.meta,
|
|
10833
|
+
children: "开启后漫画工坊才显示「豆包生成」按钮"
|
|
10834
|
+
})
|
|
10835
|
+
]
|
|
10836
|
+
})
|
|
10837
|
+
]
|
|
10838
|
+
}),
|
|
10700
10839
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10701
10840
|
className: panel_module_css_default.row,
|
|
10702
10841
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -11976,432 +12115,1742 @@ window.__ModuleLoader__.load({
|
|
|
11976
12115
|
})
|
|
11977
12116
|
]
|
|
11978
12117
|
}),
|
|
11979
|
-
activeTab === "
|
|
12118
|
+
activeTab === "roleImage" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11980
12119
|
className: panel_module_css_default.card,
|
|
12120
|
+
style: {
|
|
12121
|
+
flex: 1,
|
|
12122
|
+
minHeight: 0
|
|
12123
|
+
},
|
|
11981
12124
|
children: [
|
|
11982
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
12125
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11983
12126
|
className: panel_module_css_default.row,
|
|
11984
12127
|
style: {
|
|
11985
12128
|
justifyContent: "space-between",
|
|
11986
12129
|
flexWrap: "wrap"
|
|
11987
12130
|
},
|
|
11988
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12131
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11989
12132
|
className: panel_module_css_default.cardTitle,
|
|
11990
12133
|
style: {
|
|
11991
12134
|
fontSize: 17,
|
|
11992
12135
|
fontWeight: 700
|
|
11993
12136
|
},
|
|
11994
|
-
children: "
|
|
11995
|
-
})
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
className: panel_module_css_default.row,
|
|
11999
|
-
style: {
|
|
12000
|
-
flexWrap: "wrap",
|
|
12001
|
-
gap: 6
|
|
12002
|
-
},
|
|
12003
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12004
|
-
type: "button",
|
|
12005
|
-
className: `${panel_module_css_default.button} ${storyboardView === "single" ? panel_module_css_default.buttonPrimary : ""}`,
|
|
12006
|
-
style: {
|
|
12007
|
-
fontSize: 14,
|
|
12008
|
-
flex: 1
|
|
12009
|
-
},
|
|
12010
|
-
onClick: () => {
|
|
12011
|
-
setStoryboardView("single");
|
|
12012
|
-
},
|
|
12013
|
-
children: "🎞️ 单集分镜"
|
|
12014
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12015
|
-
type: "button",
|
|
12016
|
-
className: `${panel_module_css_default.button} ${storyboardView === "plan" ? panel_module_css_default.buttonPrimary : ""}`,
|
|
12017
|
-
style: {
|
|
12018
|
-
fontSize: 14,
|
|
12019
|
-
flex: 1
|
|
12020
|
-
},
|
|
12021
|
-
onClick: () => {
|
|
12022
|
-
setStoryboardView("plan");
|
|
12023
|
-
},
|
|
12024
|
-
children: "📺 按卷规划"
|
|
12137
|
+
children: "🖼️ 角色形象"
|
|
12138
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12139
|
+
className: panel_module_css_default.meta,
|
|
12140
|
+
children: "角色形象锚点 / 参考图(漫画功能已移除,形象保留用于立绘与一致性)"
|
|
12025
12141
|
})]
|
|
12026
12142
|
}),
|
|
12027
|
-
|
|
12143
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
12144
|
+
ref: roleImageInputRef,
|
|
12145
|
+
type: "file",
|
|
12146
|
+
accept: "image/*",
|
|
12147
|
+
style: { display: "none" },
|
|
12148
|
+
onChange: (e) => {
|
|
12149
|
+
const file = e.target.files?.[0];
|
|
12150
|
+
const target = roleImageTarget;
|
|
12151
|
+
if (file === void 0 || target === null) return;
|
|
12152
|
+
const readDataUrl = () => new Promise((resolve, reject) => {
|
|
12153
|
+
const reader = new FileReader();
|
|
12154
|
+
reader.onload = () => resolve(String(reader.result));
|
|
12155
|
+
reader.onerror = () => reject(reader.error ?? /* @__PURE__ */ new Error("读取图片失败"));
|
|
12156
|
+
reader.readAsDataURL(file);
|
|
12157
|
+
});
|
|
12158
|
+
(async () => {
|
|
12159
|
+
const dataUrl = await readDataUrl();
|
|
12160
|
+
if (target.endsWith("||scene")) {
|
|
12161
|
+
const sceneName = target.slice(0, -7);
|
|
12162
|
+
setBusy(true);
|
|
12163
|
+
setBusyLabel(`上传场景图「${sceneName}」${roleImageLabel}…`);
|
|
12164
|
+
setError("");
|
|
12165
|
+
try {
|
|
12166
|
+
await api.scenes({
|
|
12167
|
+
op: "image",
|
|
12168
|
+
name: sceneName,
|
|
12169
|
+
dataUrl,
|
|
12170
|
+
label: roleImageLabel
|
|
12171
|
+
});
|
|
12172
|
+
await refresh(false);
|
|
12173
|
+
pushProgress(`已上传场景「${sceneName}」${roleImageLabel}`, "done");
|
|
12174
|
+
} catch (err) {
|
|
12175
|
+
setError(err.message);
|
|
12176
|
+
pushProgress(`场景图上传失败:${err.message}`, "error");
|
|
12177
|
+
} finally {
|
|
12178
|
+
setBusy(false);
|
|
12179
|
+
setBusyLabel("");
|
|
12180
|
+
setRoleImageTarget(null);
|
|
12181
|
+
if (roleImageInputRef.current !== null) roleImageInputRef.current.value = "";
|
|
12182
|
+
}
|
|
12183
|
+
} else await handleRoleImageUpload(target, file, roleImageLabel);
|
|
12184
|
+
})();
|
|
12185
|
+
}
|
|
12186
|
+
}),
|
|
12187
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12028
12188
|
style: {
|
|
12029
12189
|
display: "flex",
|
|
12030
12190
|
flexDirection: "column",
|
|
12031
|
-
gap: 10
|
|
12191
|
+
gap: 10,
|
|
12192
|
+
flex: 1,
|
|
12193
|
+
minHeight: 0,
|
|
12194
|
+
overflowY: "auto"
|
|
12032
12195
|
},
|
|
12033
12196
|
children: [
|
|
12034
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
12197
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12035
12198
|
className: panel_module_css_default.row,
|
|
12036
12199
|
style: {
|
|
12037
12200
|
flexWrap: "wrap",
|
|
12038
|
-
gap: 6
|
|
12201
|
+
gap: 6,
|
|
12202
|
+
justifyContent: "space-between"
|
|
12039
12203
|
},
|
|
12040
|
-
children:
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
value: storyboardPlanVolume,
|
|
12045
|
-
onChange: (e) => {
|
|
12046
|
-
setStoryboardPlanVolume(Number(e.target.value));
|
|
12047
|
-
},
|
|
12048
|
-
title: "选择要规划的卷",
|
|
12049
|
-
children: volumes !== void 0 && volumes.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
12050
|
-
value: v.no,
|
|
12051
|
-
children: [
|
|
12052
|
-
"第",
|
|
12053
|
-
v.no,
|
|
12054
|
-
"卷《",
|
|
12055
|
-
v.title,
|
|
12056
|
-
"》"
|
|
12057
|
-
]
|
|
12058
|
-
}, v.no))
|
|
12059
|
-
}),
|
|
12060
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12204
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12205
|
+
className: panel_module_css_default.row,
|
|
12206
|
+
style: { gap: 6 },
|
|
12207
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12061
12208
|
type: "button",
|
|
12062
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.
|
|
12209
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12063
12210
|
disabled: busy,
|
|
12064
12211
|
onClick: () => {
|
|
12065
|
-
|
|
12212
|
+
(async () => {
|
|
12213
|
+
setBusy(true);
|
|
12214
|
+
setBusyLabel("⚠️ 提炼本书视觉规则…");
|
|
12215
|
+
setError("");
|
|
12216
|
+
try {
|
|
12217
|
+
const result = await api.visualRules({ op: "extract" });
|
|
12218
|
+
await refresh(false);
|
|
12219
|
+
pushProgress(`已提炼 ${result.rules.length} 条视觉规则(已注入所有提示词)`, "done");
|
|
12220
|
+
} catch (err) {
|
|
12221
|
+
setError(err.message);
|
|
12222
|
+
pushProgress(`视觉规则提炼失败:${err.message}`, "error");
|
|
12223
|
+
} finally {
|
|
12224
|
+
setBusy(false);
|
|
12225
|
+
setBusyLabel("");
|
|
12226
|
+
}
|
|
12227
|
+
})();
|
|
12066
12228
|
},
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
children: "分集原则:高潮章单独成集或两章一集;过渡章 2-3 章合并;断点选在钩子最强处;每集 60-120 秒。生成后逐集确认,满意再用「单集分镜」为某集生成分镜。"
|
|
12229
|
+
children: "⚠️ 提炼视觉规则"
|
|
12230
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12231
|
+
type: "button",
|
|
12232
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12233
|
+
onClick: () => {
|
|
12234
|
+
refresh(false);
|
|
12235
|
+
pushProgress("角色库已刷新", "done");
|
|
12236
|
+
},
|
|
12237
|
+
children: "🔄 刷新角色库"
|
|
12238
|
+
})]
|
|
12239
|
+
})
|
|
12079
12240
|
}),
|
|
12080
|
-
|
|
12081
|
-
className: panel_module_css_default.shelfEmpty,
|
|
12082
|
-
style: { minHeight: 140 },
|
|
12083
|
-
children: [
|
|
12084
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12085
|
-
className: panel_module_css_default.shelfEmptyIcon,
|
|
12086
|
-
children: "📺"
|
|
12087
|
-
}),
|
|
12088
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12089
|
-
className: panel_module_css_default.shelfEmptyTitle,
|
|
12090
|
-
children: "尚未生成分集计划"
|
|
12091
|
-
}),
|
|
12092
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12093
|
-
className: panel_module_css_default.meta,
|
|
12094
|
-
children: "选卷后点「生成分集计划」,AI 把整卷按故事弧线分成漫剧集"
|
|
12095
|
-
})
|
|
12096
|
-
]
|
|
12097
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12241
|
+
(project?.visualRules ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12098
12242
|
style: {
|
|
12099
12243
|
display: "flex",
|
|
12100
|
-
|
|
12101
|
-
gap:
|
|
12244
|
+
flexWrap: "wrap",
|
|
12245
|
+
gap: 4,
|
|
12246
|
+
alignItems: "center",
|
|
12247
|
+
marginTop: 6
|
|
12102
12248
|
},
|
|
12103
|
-
children: [
|
|
12104
|
-
|
|
12105
|
-
|
|
12106
|
-
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12249
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12250
|
+
className: panel_module_css_default.meta,
|
|
12251
|
+
style: { fontSize: 11 },
|
|
12252
|
+
children: "⚠️ 本书视觉规则:"
|
|
12253
|
+
}), (project?.visualRules ?? []).map((r, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12254
|
+
style: {
|
|
12255
|
+
border: "1px solid var(--nf-warn, #b8860b)",
|
|
12256
|
+
borderRadius: 999,
|
|
12257
|
+
padding: "1px 8px",
|
|
12258
|
+
fontSize: 10,
|
|
12259
|
+
color: "var(--nf-warn, #b8860b)"
|
|
12260
|
+
},
|
|
12261
|
+
children: r
|
|
12262
|
+
}, i))]
|
|
12263
|
+
}),
|
|
12264
|
+
(() => {
|
|
12265
|
+
const roles = project?.roles ?? [];
|
|
12266
|
+
if (roles.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12267
|
+
className: panel_module_css_default.shelfEmpty,
|
|
12268
|
+
style: {
|
|
12269
|
+
minHeight: 140,
|
|
12270
|
+
flex: 1
|
|
12271
|
+
},
|
|
12272
|
+
children: [
|
|
12273
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12274
|
+
className: panel_module_css_default.shelfEmptyIcon,
|
|
12275
|
+
children: "🎭"
|
|
12276
|
+
}),
|
|
12277
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12278
|
+
className: panel_module_css_default.shelfEmptyTitle,
|
|
12279
|
+
children: "角色库为空"
|
|
12280
|
+
}),
|
|
12281
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12282
|
+
className: panel_module_css_default.meta,
|
|
12283
|
+
children: "请先到「角色库」提炼角色并生成形象锚点"
|
|
12284
|
+
}),
|
|
12285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12286
|
+
type: "button",
|
|
12287
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12288
|
+
onClick: () => {
|
|
12289
|
+
setActiveTab("roles");
|
|
12290
|
+
},
|
|
12291
|
+
children: "去角色库"
|
|
12292
|
+
})
|
|
12293
|
+
]
|
|
12294
|
+
});
|
|
12295
|
+
const detailRole = detailRoleName !== null ? roles.find((r) => r.name === detailRoleName) : void 0;
|
|
12296
|
+
const group = (role) => {
|
|
12297
|
+
const g = role.gallery ?? [];
|
|
12298
|
+
const byLabel = (key) => g.filter((x) => x.label === key);
|
|
12299
|
+
const byPrefix = (pre) => g.filter((x) => x.label.startsWith(pre));
|
|
12300
|
+
return {
|
|
12301
|
+
portrait: byLabel("立绘")[0],
|
|
12302
|
+
sheet: byLabel("四视图")[0],
|
|
12303
|
+
expressions: byPrefix("表情-"),
|
|
12304
|
+
others: g.filter((x) => x.label !== "立绘" && x.label !== "四视图" && !x.label.startsWith("表情-"))
|
|
12305
|
+
};
|
|
12306
|
+
};
|
|
12307
|
+
const uploadInDetail = (role) => {
|
|
12308
|
+
setRoleImageLabel(detailUploadLabel.trim() !== "" ? detailUploadLabel.trim() : "立绘");
|
|
12309
|
+
setRoleImageTarget(role.name);
|
|
12310
|
+
roleImageInputRef.current?.click();
|
|
12311
|
+
};
|
|
12312
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12313
|
+
style: {
|
|
12314
|
+
display: "grid",
|
|
12315
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(130px, 1fr))",
|
|
12316
|
+
gap: 10
|
|
12317
|
+
},
|
|
12318
|
+
children: roles.map((r) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12319
|
+
onClick: () => {
|
|
12320
|
+
setDetailRoleName(r.name);
|
|
12321
|
+
setDetailUploadLabel("立绘");
|
|
12322
|
+
},
|
|
12119
12323
|
style: {
|
|
12324
|
+
cursor: "pointer",
|
|
12325
|
+
border: "1px solid var(--nf-border)",
|
|
12326
|
+
borderRadius: 12,
|
|
12327
|
+
overflow: "hidden",
|
|
12328
|
+
background: "var(--nf-bg-inset)",
|
|
12120
12329
|
display: "flex",
|
|
12121
|
-
flexDirection: "column"
|
|
12122
|
-
gap: 4,
|
|
12123
|
-
maxHeight: 380,
|
|
12124
|
-
overflowY: "auto"
|
|
12330
|
+
flexDirection: "column"
|
|
12125
12331
|
},
|
|
12126
|
-
children:
|
|
12332
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12127
12333
|
style: {
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12334
|
+
aspectRatio: "3/4",
|
|
12335
|
+
display: "flex",
|
|
12336
|
+
alignItems: "center",
|
|
12337
|
+
justifyContent: "center",
|
|
12338
|
+
background: "var(--nf-bg-inset)",
|
|
12339
|
+
borderBottom: "1px solid var(--nf-border)",
|
|
12340
|
+
position: "relative",
|
|
12341
|
+
overflow: "hidden"
|
|
12132
12342
|
},
|
|
12133
|
-
children: [
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12343
|
+
children: [r.imageUrl !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
12344
|
+
src: r.imageUrl,
|
|
12345
|
+
alt: r.name,
|
|
12346
|
+
style: {
|
|
12347
|
+
width: "100%",
|
|
12348
|
+
height: "100%",
|
|
12349
|
+
objectFit: "cover",
|
|
12350
|
+
objectPosition: "center 20%"
|
|
12351
|
+
}
|
|
12352
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12353
|
+
className: panel_module_css_default.meta,
|
|
12354
|
+
children: "暂无形象"
|
|
12355
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12356
|
+
style: {
|
|
12357
|
+
position: "absolute",
|
|
12358
|
+
bottom: 4,
|
|
12359
|
+
right: 4,
|
|
12360
|
+
background: "rgba(0,0,0,0.6)",
|
|
12361
|
+
color: "#fff",
|
|
12362
|
+
fontSize: 10,
|
|
12363
|
+
borderRadius: 6,
|
|
12364
|
+
padding: "1px 6px"
|
|
12365
|
+
},
|
|
12366
|
+
children: ["🖼 ", (r.gallery ?? []).length]
|
|
12367
|
+
})]
|
|
12368
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12369
|
+
style: {
|
|
12370
|
+
padding: 6,
|
|
12371
|
+
display: "flex",
|
|
12372
|
+
flexDirection: "column",
|
|
12373
|
+
gap: 2
|
|
12374
|
+
},
|
|
12375
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12376
|
+
style: {
|
|
12377
|
+
display: "flex",
|
|
12378
|
+
justifyContent: "space-between",
|
|
12379
|
+
alignItems: "center"
|
|
12380
|
+
},
|
|
12381
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12382
|
+
style: { fontSize: 13 },
|
|
12383
|
+
children: r.name
|
|
12384
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12385
|
+
className: panel_module_css_default.meta,
|
|
12386
|
+
style: { fontSize: 10 },
|
|
12387
|
+
children: r.roleLabel
|
|
12388
|
+
})]
|
|
12389
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12390
|
+
className: panel_module_css_default.meta,
|
|
12391
|
+
style: {
|
|
12392
|
+
fontSize: 10,
|
|
12393
|
+
whiteSpace: "nowrap",
|
|
12394
|
+
overflow: "hidden",
|
|
12395
|
+
textOverflow: "ellipsis"
|
|
12396
|
+
},
|
|
12397
|
+
children: [
|
|
12398
|
+
r.imagePrompt !== void 0 ? "✓ 锚点" : "⚠ 无锚点",
|
|
12399
|
+
" · ",
|
|
12400
|
+
(r.identity ?? "").slice(0, 16)
|
|
12401
|
+
]
|
|
12402
|
+
})]
|
|
12403
|
+
})]
|
|
12404
|
+
}, r.name))
|
|
12405
|
+
}), detailRole !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12406
|
+
style: {
|
|
12407
|
+
position: "fixed",
|
|
12408
|
+
inset: 0,
|
|
12409
|
+
background: "rgba(0,0,0,0.55)",
|
|
12410
|
+
zIndex: 1e3,
|
|
12411
|
+
display: "flex",
|
|
12412
|
+
alignItems: "center",
|
|
12413
|
+
justifyContent: "center",
|
|
12414
|
+
padding: 24
|
|
12415
|
+
},
|
|
12416
|
+
onClick: () => {
|
|
12417
|
+
setDetailRoleName(null);
|
|
12418
|
+
},
|
|
12419
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12420
|
+
style: {
|
|
12421
|
+
background: "var(--nf-bg)",
|
|
12422
|
+
border: "1px solid var(--nf-border)",
|
|
12423
|
+
borderRadius: 16,
|
|
12424
|
+
width: "min(960px, 100%)",
|
|
12425
|
+
maxHeight: "92vh",
|
|
12426
|
+
overflowY: "auto",
|
|
12427
|
+
padding: 20,
|
|
12428
|
+
position: "relative"
|
|
12429
|
+
},
|
|
12430
|
+
onClick: (e) => e.stopPropagation(),
|
|
12431
|
+
children: [
|
|
12432
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12433
|
+
type: "button",
|
|
12434
|
+
className: panel_module_css_default.iconButton,
|
|
12435
|
+
style: {
|
|
12436
|
+
position: "absolute",
|
|
12437
|
+
top: 12,
|
|
12438
|
+
right: 12,
|
|
12439
|
+
fontSize: 18
|
|
12440
|
+
},
|
|
12441
|
+
title: "关闭",
|
|
12442
|
+
"aria-label": "关闭",
|
|
12443
|
+
onClick: () => {
|
|
12444
|
+
setDetailRoleName(null);
|
|
12445
|
+
},
|
|
12446
|
+
children: "✕"
|
|
12447
|
+
}),
|
|
12448
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12449
|
+
style: { marginBottom: 12 },
|
|
12450
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12451
|
+
style: {
|
|
12452
|
+
display: "flex",
|
|
12453
|
+
alignItems: "baseline",
|
|
12454
|
+
gap: 10,
|
|
12455
|
+
flexWrap: "wrap"
|
|
12456
|
+
},
|
|
12457
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12458
|
+
style: { fontSize: 22 },
|
|
12459
|
+
children: detailRole.name
|
|
12460
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12461
|
+
className: panel_module_css_default.badge,
|
|
12462
|
+
style: {
|
|
12463
|
+
borderColor: "var(--nf-accent)",
|
|
12464
|
+
color: "var(--nf-accent)"
|
|
12465
|
+
},
|
|
12466
|
+
children: detailRole.roleLabel
|
|
12467
|
+
})]
|
|
12468
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12469
|
+
className: panel_module_css_default.meta,
|
|
12470
|
+
style: { marginTop: 4 },
|
|
12471
|
+
children: detailRole.identity
|
|
12472
|
+
})]
|
|
12473
|
+
}),
|
|
12474
|
+
(project?.visualRules ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12475
|
+
style: {
|
|
12476
|
+
border: "1px solid var(--nf-warn, #b8860b)",
|
|
12477
|
+
borderRadius: 10,
|
|
12478
|
+
padding: "6px 10px",
|
|
12479
|
+
marginBottom: 10,
|
|
12480
|
+
fontSize: 11
|
|
12481
|
+
},
|
|
12482
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "⚠️ 本书视觉规则(已内嵌到下方所有提示词)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12483
|
+
style: {
|
|
12484
|
+
display: "flex",
|
|
12485
|
+
flexWrap: "wrap",
|
|
12486
|
+
gap: 4,
|
|
12487
|
+
marginTop: 4
|
|
12488
|
+
},
|
|
12489
|
+
children: (project?.visualRules ?? []).map((r, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12490
|
+
style: {
|
|
12491
|
+
border: "1px solid var(--nf-border)",
|
|
12492
|
+
borderRadius: 999,
|
|
12493
|
+
padding: "1px 8px",
|
|
12494
|
+
fontSize: 10
|
|
12495
|
+
},
|
|
12496
|
+
children: r
|
|
12497
|
+
}, i))
|
|
12498
|
+
})]
|
|
12499
|
+
}),
|
|
12500
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
12501
|
+
style: {
|
|
12502
|
+
marginBottom: 10,
|
|
12503
|
+
fontSize: 12
|
|
12504
|
+
},
|
|
12505
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
|
|
12506
|
+
style: {
|
|
12507
|
+
cursor: "pointer",
|
|
12508
|
+
color: "var(--nf-text-2)"
|
|
12509
|
+
},
|
|
12510
|
+
children: [
|
|
12511
|
+
"🖼 图集(",
|
|
12512
|
+
(detailRole.gallery ?? []).length,
|
|
12513
|
+
" 张 · 点击展开/收起)"
|
|
12514
|
+
]
|
|
12515
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12516
|
+
style: { marginTop: 8 },
|
|
12517
|
+
children: (() => {
|
|
12518
|
+
const g = group(detailRole);
|
|
12519
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
12520
|
+
(g.portrait !== void 0 || g.sheet !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12521
|
+
style: {
|
|
12522
|
+
display: "grid",
|
|
12523
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
|
|
12524
|
+
gap: 10,
|
|
12525
|
+
marginBottom: 12
|
|
12526
|
+
},
|
|
12527
|
+
children: [g.portrait !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12528
|
+
style: {
|
|
12529
|
+
border: "1px solid var(--nf-border)",
|
|
12530
|
+
borderRadius: 12,
|
|
12531
|
+
overflow: "hidden"
|
|
12532
|
+
},
|
|
12533
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
12534
|
+
src: g.portrait.dataUrl,
|
|
12535
|
+
alt: "立绘",
|
|
12536
|
+
style: {
|
|
12537
|
+
width: "100%",
|
|
12538
|
+
maxHeight: 380,
|
|
12539
|
+
objectFit: "contain",
|
|
12540
|
+
display: "block",
|
|
12541
|
+
background: "#111"
|
|
12542
|
+
}
|
|
12543
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12544
|
+
className: panel_module_css_default.meta,
|
|
12545
|
+
style: {
|
|
12546
|
+
padding: "2px 8px",
|
|
12547
|
+
fontSize: 11
|
|
12548
|
+
},
|
|
12549
|
+
children: "立绘"
|
|
12550
|
+
})]
|
|
12551
|
+
}), g.sheet !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12552
|
+
style: {
|
|
12553
|
+
border: "1px solid var(--nf-border)",
|
|
12554
|
+
borderRadius: 12,
|
|
12555
|
+
overflow: "hidden"
|
|
12556
|
+
},
|
|
12557
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
12558
|
+
src: g.sheet.dataUrl,
|
|
12559
|
+
alt: "四视图",
|
|
12560
|
+
style: {
|
|
12561
|
+
width: "100%",
|
|
12562
|
+
maxHeight: 380,
|
|
12563
|
+
objectFit: "contain",
|
|
12564
|
+
display: "block",
|
|
12565
|
+
background: "#111"
|
|
12566
|
+
}
|
|
12567
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12568
|
+
className: panel_module_css_default.meta,
|
|
12569
|
+
style: {
|
|
12570
|
+
padding: "2px 8px",
|
|
12571
|
+
fontSize: 11
|
|
12572
|
+
},
|
|
12573
|
+
children: "四视图"
|
|
12574
|
+
})]
|
|
12575
|
+
})]
|
|
12576
|
+
}),
|
|
12577
|
+
g.expressions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12578
|
+
style: { marginBottom: 12 },
|
|
12579
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12580
|
+
style: { fontSize: 13 },
|
|
12581
|
+
children: "表情设定"
|
|
12582
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12583
|
+
style: {
|
|
12584
|
+
display: "grid",
|
|
12585
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(110px, 1fr))",
|
|
12586
|
+
gap: 8,
|
|
12587
|
+
marginTop: 6
|
|
12588
|
+
},
|
|
12589
|
+
children: g.expressions.map((img) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12590
|
+
style: {
|
|
12591
|
+
border: "1px solid var(--nf-border)",
|
|
12592
|
+
borderRadius: 10,
|
|
12593
|
+
overflow: "hidden",
|
|
12594
|
+
position: "relative"
|
|
12595
|
+
},
|
|
12596
|
+
children: [
|
|
12597
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
12598
|
+
src: img.dataUrl,
|
|
12599
|
+
alt: img.label,
|
|
12600
|
+
style: {
|
|
12601
|
+
width: "100%",
|
|
12602
|
+
height: 110,
|
|
12603
|
+
objectFit: "cover",
|
|
12604
|
+
display: "block"
|
|
12605
|
+
}
|
|
12606
|
+
}),
|
|
12607
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12608
|
+
style: {
|
|
12609
|
+
background: "rgba(0,0,0,0.55)",
|
|
12610
|
+
color: "#fff",
|
|
12611
|
+
fontSize: 10,
|
|
12612
|
+
padding: "1px 6px",
|
|
12613
|
+
textAlign: "center"
|
|
12614
|
+
},
|
|
12615
|
+
children: img.label.replace("表情-", "")
|
|
12616
|
+
}),
|
|
12617
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12618
|
+
type: "button",
|
|
12619
|
+
className: panel_module_css_default.iconButton,
|
|
12620
|
+
style: {
|
|
12621
|
+
position: "absolute",
|
|
12622
|
+
top: 2,
|
|
12623
|
+
right: 2,
|
|
12624
|
+
fontSize: 11
|
|
12625
|
+
},
|
|
12626
|
+
title: "删除",
|
|
12627
|
+
"aria-label": "删除",
|
|
12628
|
+
onClick: () => {
|
|
12629
|
+
(async () => {
|
|
12630
|
+
try {
|
|
12631
|
+
await api.roles({
|
|
12632
|
+
op: "removeImage",
|
|
12633
|
+
name: detailRole.name,
|
|
12634
|
+
label: img.label
|
|
12635
|
+
});
|
|
12636
|
+
await refresh(false);
|
|
12637
|
+
pushProgress(`已删除「${detailRole.name}」${img.label}`, "done");
|
|
12638
|
+
} catch (err) {
|
|
12639
|
+
setError(err.message);
|
|
12640
|
+
}
|
|
12641
|
+
})();
|
|
12642
|
+
},
|
|
12643
|
+
children: "×"
|
|
12644
|
+
})
|
|
12645
|
+
]
|
|
12646
|
+
}, img.label))
|
|
12647
|
+
})]
|
|
12648
|
+
}),
|
|
12649
|
+
g.others.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12650
|
+
style: { marginBottom: 12 },
|
|
12651
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12652
|
+
style: { fontSize: 13 },
|
|
12653
|
+
children: "场景 / 细节"
|
|
12654
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12655
|
+
style: {
|
|
12656
|
+
display: "grid",
|
|
12657
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))",
|
|
12658
|
+
gap: 8,
|
|
12659
|
+
marginTop: 6
|
|
12660
|
+
},
|
|
12661
|
+
children: g.others.map((img) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12662
|
+
style: {
|
|
12663
|
+
border: "1px solid var(--nf-border)",
|
|
12664
|
+
borderRadius: 10,
|
|
12665
|
+
overflow: "hidden",
|
|
12666
|
+
position: "relative"
|
|
12667
|
+
},
|
|
12668
|
+
children: [
|
|
12669
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
12670
|
+
src: img.dataUrl,
|
|
12671
|
+
alt: img.label,
|
|
12672
|
+
style: {
|
|
12673
|
+
width: "100%",
|
|
12674
|
+
height: 90,
|
|
12675
|
+
objectFit: "cover",
|
|
12676
|
+
display: "block"
|
|
12677
|
+
}
|
|
12678
|
+
}),
|
|
12679
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12680
|
+
style: {
|
|
12681
|
+
background: "rgba(0,0,0,0.55)",
|
|
12682
|
+
color: "#fff",
|
|
12683
|
+
fontSize: 10,
|
|
12684
|
+
padding: "1px 6px",
|
|
12685
|
+
textAlign: "center"
|
|
12686
|
+
},
|
|
12687
|
+
children: img.label
|
|
12688
|
+
}),
|
|
12689
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12690
|
+
type: "button",
|
|
12691
|
+
className: panel_module_css_default.iconButton,
|
|
12692
|
+
style: {
|
|
12693
|
+
position: "absolute",
|
|
12694
|
+
top: 2,
|
|
12695
|
+
right: 2,
|
|
12696
|
+
fontSize: 11
|
|
12697
|
+
},
|
|
12698
|
+
title: "删除",
|
|
12699
|
+
"aria-label": "删除",
|
|
12700
|
+
onClick: () => {
|
|
12701
|
+
(async () => {
|
|
12702
|
+
try {
|
|
12703
|
+
await api.roles({
|
|
12704
|
+
op: "removeImage",
|
|
12705
|
+
name: detailRole.name,
|
|
12706
|
+
label: img.label
|
|
12707
|
+
});
|
|
12708
|
+
await refresh(false);
|
|
12709
|
+
pushProgress(`已删除「${detailRole.name}」${img.label}`, "done");
|
|
12710
|
+
} catch (err) {
|
|
12711
|
+
setError(err.message);
|
|
12712
|
+
}
|
|
12713
|
+
})();
|
|
12714
|
+
},
|
|
12715
|
+
children: "×"
|
|
12716
|
+
})
|
|
12717
|
+
]
|
|
12718
|
+
}, img.label))
|
|
12719
|
+
})]
|
|
12720
|
+
})
|
|
12721
|
+
] });
|
|
12722
|
+
})()
|
|
12723
|
+
})]
|
|
12724
|
+
}),
|
|
12725
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12726
|
+
style: {
|
|
12727
|
+
display: "grid",
|
|
12728
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
|
|
12729
|
+
gap: 14,
|
|
12730
|
+
marginBottom: 12
|
|
12731
|
+
},
|
|
12732
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12733
|
+
style: { fontSize: 13 },
|
|
12734
|
+
children: "基本信息"
|
|
12735
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12736
|
+
style: {
|
|
12737
|
+
fontSize: 12,
|
|
12738
|
+
lineHeight: 1.8,
|
|
12739
|
+
marginTop: 4
|
|
12740
|
+
},
|
|
12741
|
+
children: [
|
|
12742
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12743
|
+
className: panel_module_css_default.meta,
|
|
12744
|
+
children: "性格:"
|
|
12745
|
+
}), (detailRole.traits ?? []).join("、") || "—"] }),
|
|
12746
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12747
|
+
className: panel_module_css_default.meta,
|
|
12748
|
+
children: "目标:"
|
|
12749
|
+
}), detailRole.goals || "—"] }),
|
|
12750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12751
|
+
className: panel_module_css_default.meta,
|
|
12752
|
+
children: "关系:"
|
|
12753
|
+
}), (detailRole.relations ?? []).join(";") || "—"] }),
|
|
12754
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12755
|
+
className: panel_module_css_default.meta,
|
|
12756
|
+
children: "成长线:"
|
|
12757
|
+
}), (detailRole.arc ?? []).join(";") || "—"] })
|
|
12758
|
+
]
|
|
12759
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
12760
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12761
|
+
className: panel_module_css_default.row,
|
|
12762
|
+
style: {
|
|
12763
|
+
justifyContent: "space-between",
|
|
12764
|
+
flexWrap: "wrap"
|
|
12765
|
+
},
|
|
12766
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12767
|
+
style: { fontSize: 13 },
|
|
12768
|
+
children: "📄 提示词包"
|
|
12769
|
+
}), detailRole.imagePrompt !== void 0 && detailRole.promptKit === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12770
|
+
type: "button",
|
|
12771
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12772
|
+
disabled: busy,
|
|
12773
|
+
onClick: () => {
|
|
12774
|
+
(async () => {
|
|
12775
|
+
setBusy(true);
|
|
12776
|
+
setBusyLabel(`精修「${detailRole.name}」提示词…`);
|
|
12777
|
+
setError("");
|
|
12778
|
+
try {
|
|
12779
|
+
await api.roles({
|
|
12780
|
+
op: "promptKit",
|
|
12781
|
+
name: detailRole.name
|
|
12782
|
+
});
|
|
12783
|
+
await refresh(false);
|
|
12784
|
+
pushProgress(`已生成「${detailRole.name}」四类精修提示词`, "done");
|
|
12785
|
+
} catch (err) {
|
|
12786
|
+
setError(err.message);
|
|
12787
|
+
pushProgress(`提示词精修失败:${err.message}`, "error");
|
|
12788
|
+
} finally {
|
|
12789
|
+
setBusy(false);
|
|
12790
|
+
setBusyLabel("");
|
|
12791
|
+
}
|
|
12792
|
+
})();
|
|
12793
|
+
},
|
|
12794
|
+
children: "✨ 生成精修版"
|
|
12795
|
+
})]
|
|
12796
|
+
}),
|
|
12797
|
+
detailRole.imagePrompt === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12798
|
+
className: panel_module_css_default.meta,
|
|
12799
|
+
children: "未生成锚点,先点「✨ 生成锚点」"
|
|
12800
|
+
}),
|
|
12801
|
+
(() => {
|
|
12802
|
+
const anchor = detailRole.imagePrompt;
|
|
12803
|
+
if (anchor === void 0) return null;
|
|
12804
|
+
const rules = project?.visualRules ?? [];
|
|
12805
|
+
const rulesZh = rules.length > 0 ? "\n【本书视觉规则】" + rules.join(";") : "";
|
|
12806
|
+
const expressions = detailRole.expressions ?? ["平静"];
|
|
12807
|
+
const expName = (n) => n.replace(/^表情-/, "");
|
|
12808
|
+
const kit = detailRole.promptKit;
|
|
12809
|
+
const blocks = [];
|
|
12810
|
+
if (kit !== void 0) {
|
|
12811
|
+
blocks.push({
|
|
12812
|
+
key: "portrait",
|
|
12813
|
+
title: "立绘",
|
|
12814
|
+
zh: kit.portrait.zh,
|
|
12815
|
+
en: kit.portrait.en
|
|
12816
|
+
});
|
|
12817
|
+
blocks.push({
|
|
12818
|
+
key: "sheet",
|
|
12819
|
+
title: "四视图",
|
|
12820
|
+
zh: kit.sheet.zh,
|
|
12821
|
+
en: kit.sheet.en
|
|
12822
|
+
});
|
|
12823
|
+
for (const e of kit.expressions) blocks.push({
|
|
12824
|
+
key: "exp-" + e.name,
|
|
12825
|
+
title: `表情·${e.name}`,
|
|
12826
|
+
zh: e.zh,
|
|
12827
|
+
en: e.en
|
|
12828
|
+
});
|
|
12829
|
+
blocks.push({
|
|
12830
|
+
key: "details",
|
|
12831
|
+
title: "细节",
|
|
12832
|
+
zh: kit.details.zh,
|
|
12833
|
+
en: kit.details.en
|
|
12834
|
+
});
|
|
12835
|
+
} else {
|
|
12836
|
+
blocks.push({
|
|
12837
|
+
key: "portrait",
|
|
12838
|
+
title: "立绘",
|
|
12839
|
+
zh: anchor.zh + "。全身/半身正视图,写实电影感。" + rulesZh,
|
|
12840
|
+
en: anchor.en + ", full body, front view, plain background"
|
|
12841
|
+
});
|
|
12842
|
+
blocks.push({
|
|
12843
|
+
key: "sheet",
|
|
12844
|
+
title: "四视图",
|
|
12845
|
+
zh: anchor.zh + "。同一角色的正面/左侧面/右侧面/背面四视图设定表,纯白背景,四个视角分别描述。" + rulesZh,
|
|
12846
|
+
en: anchor.en + ", character sheet, front view, left side view, right side view, back view, full body, plain white background"
|
|
12847
|
+
});
|
|
12848
|
+
for (const n of expressions) blocks.push({
|
|
12849
|
+
key: "exp-" + n,
|
|
12850
|
+
title: `表情·${expName(n)}`,
|
|
12851
|
+
zh: anchor.zh + `。表情:${expName(n)},脸部特写(头部到锁骨),纯白背景,五官与角色定稿完全一致,皮肤纹理细节完整,无多余杂物。` + rulesZh,
|
|
12852
|
+
en: anchor.en + `, facial close-up, head to collarbone, expression: ${expName(n)}, plain white background, consistent with character design, detailed skin texture, no extra objects`
|
|
12853
|
+
});
|
|
12854
|
+
blocks.push({
|
|
12855
|
+
key: "details",
|
|
12856
|
+
title: "细节",
|
|
12857
|
+
zh: `多组局部细节集合参考图,纯白背景:${anchor.tags.map((t) => t + "特写").join(";")}。细节清晰锐利,角色细节参考稿,无多余杂物。` + rulesZh,
|
|
12858
|
+
en: anchor.tags.join(", ") + ", multi-panel detail reference sheet, plain white background, macro close-up, sharp details, character detail sheet, no extra objects"
|
|
12859
|
+
});
|
|
12860
|
+
}
|
|
12861
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12862
|
+
style: {
|
|
12863
|
+
display: "flex",
|
|
12864
|
+
flexDirection: "column",
|
|
12865
|
+
gap: 8,
|
|
12866
|
+
marginTop: 8
|
|
12867
|
+
},
|
|
12868
|
+
children: [blocks.map((b) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12869
|
+
style: {
|
|
12870
|
+
border: "1px solid var(--nf-border)",
|
|
12871
|
+
borderRadius: 8,
|
|
12872
|
+
padding: "6px 8px"
|
|
12873
|
+
},
|
|
12874
|
+
children: [
|
|
12875
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12876
|
+
className: panel_module_css_default.row,
|
|
12877
|
+
style: { justifyContent: "space-between" },
|
|
12878
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
12879
|
+
style: { fontSize: 11 },
|
|
12880
|
+
children: b.title
|
|
12881
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12882
|
+
className: panel_module_css_default.row,
|
|
12883
|
+
style: { gap: 4 },
|
|
12884
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12885
|
+
type: "button",
|
|
12886
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12887
|
+
style: { fontSize: 10 },
|
|
12888
|
+
onClick: () => {
|
|
12889
|
+
navigator.clipboard?.writeText(b.zh).then(() => {
|
|
12890
|
+
pushProgress(`已复制「${detailRole.name}」${b.title}中文提示词`, "done");
|
|
12891
|
+
}).catch(() => {});
|
|
12892
|
+
},
|
|
12893
|
+
children: "复制"
|
|
12894
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12895
|
+
type: "button",
|
|
12896
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12897
|
+
style: { fontSize: 10 },
|
|
12898
|
+
onClick: () => {
|
|
12899
|
+
navigator.clipboard?.writeText(b.en).then(() => {
|
|
12900
|
+
pushProgress(`已复制「${detailRole.name}」${b.title}英文标签`, "done");
|
|
12901
|
+
}).catch(() => {});
|
|
12902
|
+
},
|
|
12903
|
+
children: "EN"
|
|
12904
|
+
})]
|
|
12905
|
+
})]
|
|
12906
|
+
}),
|
|
12907
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12908
|
+
className: panel_module_css_default.meta,
|
|
12909
|
+
style: {
|
|
12910
|
+
fontSize: 11,
|
|
12911
|
+
lineHeight: 1.5,
|
|
12912
|
+
marginTop: 3
|
|
12913
|
+
},
|
|
12914
|
+
children: b.zh
|
|
12915
|
+
}),
|
|
12916
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
12917
|
+
style: { marginTop: 3 },
|
|
12918
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
|
|
12919
|
+
style: {
|
|
12920
|
+
cursor: "pointer",
|
|
12921
|
+
fontSize: 10,
|
|
12922
|
+
color: "var(--nf-text-2)"
|
|
12923
|
+
},
|
|
12924
|
+
children: "🌐 英文标签(点击展开)"
|
|
12925
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12926
|
+
className: panel_module_css_default.meta,
|
|
12927
|
+
style: {
|
|
12928
|
+
fontSize: 9,
|
|
12929
|
+
fontFamily: "monospace",
|
|
12930
|
+
marginTop: 2,
|
|
12931
|
+
wordBreak: "break-all",
|
|
12932
|
+
color: "var(--nf-text-2)"
|
|
12933
|
+
},
|
|
12934
|
+
children: b.en
|
|
12935
|
+
})]
|
|
12936
|
+
})
|
|
12937
|
+
]
|
|
12938
|
+
}, b.key)), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12939
|
+
className: panel_module_css_default.meta,
|
|
12940
|
+
style: { fontSize: 10 },
|
|
12941
|
+
children: ["关键词:", (anchor.tags ?? []).join("、")]
|
|
12942
|
+
})]
|
|
12943
|
+
});
|
|
12944
|
+
})()
|
|
12945
|
+
] })]
|
|
12946
|
+
}),
|
|
12947
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12948
|
+
style: {
|
|
12949
|
+
borderTop: "1px solid var(--nf-border)",
|
|
12950
|
+
paddingTop: 10,
|
|
12951
|
+
display: "flex",
|
|
12952
|
+
flexWrap: "wrap",
|
|
12953
|
+
gap: 6,
|
|
12954
|
+
alignItems: "center"
|
|
12955
|
+
},
|
|
12956
|
+
children: [
|
|
12957
|
+
detailRole.imagePrompt === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12958
|
+
type: "button",
|
|
12959
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12960
|
+
disabled: busy,
|
|
12961
|
+
onClick: () => {
|
|
12962
|
+
handleRoleVisual(detailRole.name);
|
|
12963
|
+
},
|
|
12964
|
+
children: "✨ 生成锚点"
|
|
12965
|
+
}),
|
|
12966
|
+
detailRole.imagePrompt !== void 0 && config?.imageApiEnabled === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12967
|
+
type: "button",
|
|
12968
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12969
|
+
disabled: busy,
|
|
12970
|
+
onClick: () => {
|
|
12971
|
+
handleRoleImageGenerate(detailRole.name);
|
|
12972
|
+
},
|
|
12973
|
+
children: "豆包生成"
|
|
12974
|
+
}),
|
|
12975
|
+
detailRole.imagePrompt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12976
|
+
type: "button",
|
|
12977
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12978
|
+
onClick: () => {
|
|
12979
|
+
const text = [detailRole.imagePrompt.en, detailRole.imagePrompt.tags.join(", ")].filter(Boolean).join("\n");
|
|
12980
|
+
navigator.clipboard?.writeText(text).then(() => {
|
|
12981
|
+
pushProgress(`已复制「${detailRole.name}」英文生图提示词`, "done");
|
|
12982
|
+
}).catch(() => {});
|
|
12983
|
+
},
|
|
12984
|
+
children: "复制提示词"
|
|
12985
|
+
}),
|
|
12986
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
12987
|
+
className: panel_module_css_default.input,
|
|
12988
|
+
style: {
|
|
12989
|
+
width: 140,
|
|
12990
|
+
fontSize: 12,
|
|
12991
|
+
padding: "3px 6px"
|
|
12992
|
+
},
|
|
12993
|
+
placeholder: "图集标签",
|
|
12994
|
+
value: detailUploadLabel,
|
|
12995
|
+
onChange: (e) => {
|
|
12996
|
+
setDetailUploadLabel(e.target.value);
|
|
12997
|
+
}
|
|
12998
|
+
}),
|
|
12999
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13000
|
+
type: "button",
|
|
13001
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13002
|
+
disabled: busy,
|
|
13003
|
+
onClick: () => {
|
|
13004
|
+
uploadInDetail(detailRole);
|
|
13005
|
+
},
|
|
13006
|
+
children: "📤 上传图"
|
|
13007
|
+
}),
|
|
13008
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
13009
|
+
className: panel_module_css_default.input,
|
|
13010
|
+
style: {
|
|
13011
|
+
fontSize: 12,
|
|
13012
|
+
padding: "3px 4px",
|
|
13013
|
+
width: 90
|
|
13014
|
+
},
|
|
13015
|
+
value: detailRole.importance ?? "support",
|
|
13016
|
+
onChange: (e) => {
|
|
13017
|
+
handleRoleImportance(detailRole, e.target.value);
|
|
13018
|
+
},
|
|
13019
|
+
title: "漫剧重要性",
|
|
13020
|
+
children: [
|
|
13021
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
13022
|
+
value: "main",
|
|
13023
|
+
children: "重要"
|
|
13024
|
+
}),
|
|
13025
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
13026
|
+
value: "support",
|
|
13027
|
+
children: "配角"
|
|
13028
|
+
}),
|
|
13029
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
13030
|
+
value: "extra",
|
|
13031
|
+
children: "路人"
|
|
13032
|
+
})
|
|
13033
|
+
]
|
|
13034
|
+
})
|
|
13035
|
+
]
|
|
13036
|
+
})
|
|
13037
|
+
]
|
|
13038
|
+
})
|
|
13039
|
+
})] });
|
|
13040
|
+
})()
|
|
12188
13041
|
]
|
|
12189
|
-
})
|
|
12190
|
-
|
|
13042
|
+
})
|
|
13043
|
+
]
|
|
13044
|
+
}),
|
|
13045
|
+
activeTab === "scenes" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13046
|
+
className: panel_module_css_default.card,
|
|
13047
|
+
style: {
|
|
13048
|
+
flex: 1,
|
|
13049
|
+
minHeight: 0
|
|
13050
|
+
},
|
|
13051
|
+
children: [
|
|
13052
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12191
13053
|
className: panel_module_css_default.row,
|
|
12192
13054
|
style: {
|
|
12193
13055
|
justifyContent: "space-between",
|
|
12194
13056
|
flexWrap: "wrap"
|
|
12195
13057
|
},
|
|
12196
13058
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13059
|
+
className: panel_module_css_default.cardTitle,
|
|
13060
|
+
style: {
|
|
13061
|
+
fontSize: 17,
|
|
13062
|
+
fontWeight: 700
|
|
13063
|
+
},
|
|
13064
|
+
children: "🏞️ 场景库"
|
|
13065
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12197
13066
|
className: panel_module_css_default.meta,
|
|
12198
|
-
children: "
|
|
12199
|
-
})
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12203
|
-
|
|
13067
|
+
children: "场景视觉锚点:提炼自正文,供漫剧分镜/生图锁定\"在哪、什么氛围\""
|
|
13068
|
+
})]
|
|
13069
|
+
}),
|
|
13070
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13071
|
+
className: panel_module_css_default.row,
|
|
13072
|
+
style: {
|
|
13073
|
+
flexWrap: "wrap",
|
|
13074
|
+
gap: 6,
|
|
13075
|
+
margin: "8px 0"
|
|
13076
|
+
},
|
|
13077
|
+
children: [
|
|
13078
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13079
|
+
type: "button",
|
|
13080
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
|
|
13081
|
+
disabled: busy,
|
|
13082
|
+
onClick: () => {
|
|
13083
|
+
(async () => {
|
|
13084
|
+
setBusy(true);
|
|
13085
|
+
setBusyLabel("✨ 从全书提炼场景…");
|
|
13086
|
+
setError("");
|
|
13087
|
+
try {
|
|
13088
|
+
const result = await api.scenes({ op: "extract" });
|
|
13089
|
+
setSceneCandidates(result.candidates ?? []);
|
|
13090
|
+
pushProgress(`提炼出 ${(result.candidates ?? []).length} 个候选场景,可采纳或修改后采纳`, "done");
|
|
13091
|
+
} catch (err) {
|
|
13092
|
+
setError(err.message);
|
|
13093
|
+
pushProgress(`场景提炼失败:${err.message}`, "error");
|
|
13094
|
+
} finally {
|
|
13095
|
+
setBusy(false);
|
|
13096
|
+
setBusyLabel("");
|
|
13097
|
+
}
|
|
13098
|
+
})();
|
|
13099
|
+
},
|
|
13100
|
+
children: busy ? "⏳ 提炼中…" : "✨ 从全书提炼场景"
|
|
13101
|
+
}),
|
|
13102
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13103
|
+
type: "button",
|
|
13104
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13105
|
+
onClick: () => {
|
|
13106
|
+
refresh(false);
|
|
13107
|
+
pushProgress("场景库已刷新", "done");
|
|
13108
|
+
},
|
|
13109
|
+
children: "🔄 刷新"
|
|
13110
|
+
}),
|
|
13111
|
+
sceneCandidates !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13112
|
+
type: "button",
|
|
13113
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13114
|
+
onClick: () => {
|
|
13115
|
+
setSceneCandidates(null);
|
|
13116
|
+
},
|
|
13117
|
+
children: "收起候选"
|
|
13118
|
+
})
|
|
13119
|
+
]
|
|
13120
|
+
}),
|
|
13121
|
+
sceneDraft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13122
|
+
style: {
|
|
13123
|
+
border: "1px solid var(--nf-accent)",
|
|
13124
|
+
borderRadius: 10,
|
|
13125
|
+
padding: 10,
|
|
13126
|
+
marginBottom: 10,
|
|
13127
|
+
display: "flex",
|
|
13128
|
+
flexDirection: "column",
|
|
13129
|
+
gap: 6
|
|
13130
|
+
},
|
|
13131
|
+
children: [
|
|
13132
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13133
|
+
style: { fontSize: 13 },
|
|
13134
|
+
children: "编辑场景"
|
|
13135
|
+
}),
|
|
13136
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13137
|
+
className: panel_module_css_default.input,
|
|
13138
|
+
style: {
|
|
13139
|
+
fontSize: 12,
|
|
13140
|
+
padding: "4px 8px"
|
|
13141
|
+
},
|
|
13142
|
+
placeholder: "场景名",
|
|
13143
|
+
value: sceneDraft.name,
|
|
13144
|
+
onChange: (e) => {
|
|
13145
|
+
setSceneDraft({
|
|
13146
|
+
...sceneDraft,
|
|
13147
|
+
name: e.target.value
|
|
13148
|
+
});
|
|
13149
|
+
}
|
|
13150
|
+
}),
|
|
13151
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13152
|
+
className: panel_module_css_default.input,
|
|
13153
|
+
style: {
|
|
13154
|
+
fontSize: 12,
|
|
13155
|
+
padding: "4px 8px"
|
|
13156
|
+
},
|
|
13157
|
+
placeholder: "一句话定位",
|
|
13158
|
+
value: sceneDraft.summary,
|
|
13159
|
+
onChange: (e) => {
|
|
13160
|
+
setSceneDraft({
|
|
13161
|
+
...sceneDraft,
|
|
13162
|
+
summary: e.target.value
|
|
13163
|
+
});
|
|
13164
|
+
}
|
|
13165
|
+
}),
|
|
13166
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13167
|
+
className: panel_module_css_default.row,
|
|
13168
|
+
style: { gap: 6 },
|
|
13169
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
12204
13170
|
className: panel_module_css_default.input,
|
|
12205
|
-
style: {
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
13171
|
+
style: {
|
|
13172
|
+
fontSize: 12,
|
|
13173
|
+
padding: "4px 8px",
|
|
13174
|
+
flex: 1
|
|
12209
13175
|
},
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
value: c.no,
|
|
12213
|
-
children: [
|
|
12214
|
-
"第",
|
|
12215
|
-
c.no,
|
|
12216
|
-
"章 ",
|
|
12217
|
-
c.title
|
|
12218
|
-
]
|
|
12219
|
-
}, c.no))
|
|
12220
|
-
}),
|
|
12221
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
12222
|
-
className: panel_module_css_default.input,
|
|
12223
|
-
style: { width: 100 },
|
|
12224
|
-
value: storyboardTool,
|
|
13176
|
+
placeholder: "幕归属(第一幕后场…)",
|
|
13177
|
+
value: sceneDraft.act ?? "",
|
|
12225
13178
|
onChange: (e) => {
|
|
12226
|
-
|
|
13179
|
+
setSceneDraft({
|
|
13180
|
+
...sceneDraft,
|
|
13181
|
+
act: e.target.value
|
|
13182
|
+
});
|
|
13183
|
+
}
|
|
13184
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13185
|
+
className: panel_module_css_default.input,
|
|
13186
|
+
style: {
|
|
13187
|
+
fontSize: 12,
|
|
13188
|
+
padding: "4px 8px",
|
|
13189
|
+
flex: 1
|
|
12227
13190
|
},
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
13191
|
+
placeholder: "时间光态(雨夜/闭店后…)",
|
|
13192
|
+
value: sceneDraft.moment ?? "",
|
|
13193
|
+
onChange: (e) => {
|
|
13194
|
+
setSceneDraft({
|
|
13195
|
+
...sceneDraft,
|
|
13196
|
+
moment: e.target.value
|
|
13197
|
+
});
|
|
13198
|
+
}
|
|
13199
|
+
})]
|
|
13200
|
+
}),
|
|
13201
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
13202
|
+
className: panel_module_css_default.input,
|
|
13203
|
+
style: {
|
|
13204
|
+
fontSize: 12,
|
|
13205
|
+
padding: "4px 8px",
|
|
13206
|
+
minHeight: 48
|
|
13207
|
+
},
|
|
13208
|
+
placeholder: "关键镜头(每行一条:人物动作+情绪+镜头)",
|
|
13209
|
+
value: (sceneDraft.beats ?? []).join("\n"),
|
|
13210
|
+
onChange: (e) => {
|
|
13211
|
+
setSceneDraft({
|
|
13212
|
+
...sceneDraft,
|
|
13213
|
+
beats: e.target.value.split(/\n+/).map((x) => x.trim()).filter(Boolean)
|
|
13214
|
+
});
|
|
13215
|
+
}
|
|
13216
|
+
}),
|
|
13217
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13218
|
+
className: panel_module_css_default.input,
|
|
13219
|
+
style: {
|
|
13220
|
+
fontSize: 12,
|
|
13221
|
+
padding: "4px 8px"
|
|
13222
|
+
},
|
|
13223
|
+
placeholder: "人物在场状态(含标志物细节)",
|
|
13224
|
+
value: sceneDraft.characterState ?? "",
|
|
13225
|
+
onChange: (e) => {
|
|
13226
|
+
setSceneDraft({
|
|
13227
|
+
...sceneDraft,
|
|
13228
|
+
characterState: e.target.value
|
|
13229
|
+
});
|
|
13230
|
+
}
|
|
13231
|
+
}),
|
|
13232
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
13233
|
+
className: panel_module_css_default.input,
|
|
13234
|
+
style: {
|
|
13235
|
+
fontSize: 12,
|
|
13236
|
+
padding: "4px 8px",
|
|
13237
|
+
minHeight: 60
|
|
13238
|
+
},
|
|
13239
|
+
placeholder: "环境构成(每行一项)",
|
|
13240
|
+
value: (sceneDraft.elements ?? []).join("\n"),
|
|
13241
|
+
onChange: (e) => {
|
|
13242
|
+
setSceneDraft({
|
|
13243
|
+
...sceneDraft,
|
|
13244
|
+
elements: e.target.value.split(/\n+/).map((x) => x.trim()).filter(Boolean)
|
|
13245
|
+
});
|
|
13246
|
+
}
|
|
13247
|
+
}),
|
|
13248
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
13249
|
+
className: panel_module_css_default.input,
|
|
13250
|
+
style: {
|
|
13251
|
+
fontSize: 12,
|
|
13252
|
+
padding: "4px 8px",
|
|
13253
|
+
minHeight: 60
|
|
13254
|
+
},
|
|
13255
|
+
placeholder: "中文生图提示词",
|
|
13256
|
+
value: sceneDraft.zh,
|
|
13257
|
+
onChange: (e) => {
|
|
13258
|
+
setSceneDraft({
|
|
13259
|
+
...sceneDraft,
|
|
13260
|
+
zh: e.target.value
|
|
13261
|
+
});
|
|
13262
|
+
}
|
|
13263
|
+
}),
|
|
13264
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
13265
|
+
className: panel_module_css_default.input,
|
|
13266
|
+
style: {
|
|
13267
|
+
fontSize: 12,
|
|
13268
|
+
padding: "4px 8px",
|
|
13269
|
+
minHeight: 60
|
|
13270
|
+
},
|
|
13271
|
+
placeholder: "英文生图提示词",
|
|
13272
|
+
value: sceneDraft.en,
|
|
13273
|
+
onChange: (e) => {
|
|
13274
|
+
setSceneDraft({
|
|
13275
|
+
...sceneDraft,
|
|
13276
|
+
en: e.target.value
|
|
13277
|
+
});
|
|
13278
|
+
}
|
|
13279
|
+
}),
|
|
13280
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13281
|
+
className: panel_module_css_default.row,
|
|
13282
|
+
style: { gap: 6 },
|
|
13283
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12249
13284
|
type: "button",
|
|
12250
13285
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
|
|
12251
|
-
disabled: busy,
|
|
13286
|
+
disabled: busy || sceneDraft.name.trim() === "",
|
|
13287
|
+
onClick: () => {
|
|
13288
|
+
(async () => {
|
|
13289
|
+
setBusy(true);
|
|
13290
|
+
try {
|
|
13291
|
+
await api.scenes({
|
|
13292
|
+
op: "update",
|
|
13293
|
+
scene: {
|
|
13294
|
+
...sceneDraft,
|
|
13295
|
+
name: sceneDraft.name.trim()
|
|
13296
|
+
}
|
|
13297
|
+
});
|
|
13298
|
+
await refresh(false);
|
|
13299
|
+
setSceneDraft(null);
|
|
13300
|
+
pushProgress(`已保存场景「${sceneDraft.name.trim()}」`, "done");
|
|
13301
|
+
} catch (err) {
|
|
13302
|
+
setError(err.message);
|
|
13303
|
+
} finally {
|
|
13304
|
+
setBusy(false);
|
|
13305
|
+
}
|
|
13306
|
+
})();
|
|
13307
|
+
},
|
|
13308
|
+
children: "保存"
|
|
13309
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13310
|
+
type: "button",
|
|
13311
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
12252
13312
|
onClick: () => {
|
|
12253
|
-
|
|
13313
|
+
setSceneDraft(null);
|
|
12254
13314
|
},
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
})
|
|
12258
|
-
]
|
|
12259
|
-
})]
|
|
12260
|
-
}), storyboardResult === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12261
|
-
className: panel_module_css_default.shelfEmpty,
|
|
12262
|
-
style: { minHeight: 140 },
|
|
12263
|
-
children: [
|
|
12264
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12265
|
-
className: panel_module_css_default.shelfEmptyIcon,
|
|
12266
|
-
children: "🎬"
|
|
12267
|
-
}),
|
|
12268
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12269
|
-
className: panel_module_css_default.shelfEmptyTitle,
|
|
12270
|
-
children: "尚未生成分镜"
|
|
12271
|
-
}),
|
|
12272
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12273
|
-
className: panel_module_css_default.meta,
|
|
12274
|
-
children: "选择章节与 AI 工具,点「生成分镜」开始"
|
|
13315
|
+
children: "取消"
|
|
13316
|
+
})]
|
|
12275
13317
|
})
|
|
12276
13318
|
]
|
|
12277
|
-
})
|
|
13319
|
+
}),
|
|
13320
|
+
sceneCandidates !== null && sceneCandidates.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12278
13321
|
style: {
|
|
12279
13322
|
display: "flex",
|
|
12280
13323
|
flexDirection: "column",
|
|
12281
|
-
gap:
|
|
13324
|
+
gap: 6,
|
|
13325
|
+
marginBottom: 10
|
|
12282
13326
|
},
|
|
12283
|
-
children:
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
className: panel_module_css_default.meta,
|
|
12294
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "本集钩子:" }), storyboardResult.hook]
|
|
12295
|
-
}),
|
|
12296
|
-
storyboardResult.characters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12297
|
-
style: {
|
|
12298
|
-
display: "flex",
|
|
12299
|
-
flexDirection: "column",
|
|
12300
|
-
gap: 6
|
|
12301
|
-
},
|
|
12302
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "角色视觉锚点(全分镜强制复用)" }), storyboardResult.characters.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13327
|
+
children: sceneCandidates.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13328
|
+
style: {
|
|
13329
|
+
border: "1px solid var(--nf-accent)",
|
|
13330
|
+
borderRadius: 10,
|
|
13331
|
+
padding: "8px 10px",
|
|
13332
|
+
fontSize: 12
|
|
13333
|
+
},
|
|
13334
|
+
children: [
|
|
13335
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13336
|
+
className: panel_module_css_default.row,
|
|
12303
13337
|
style: {
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
fontSize: 12
|
|
13338
|
+
flexWrap: "wrap",
|
|
13339
|
+
gap: 6,
|
|
13340
|
+
justifyContent: "space-between"
|
|
12308
13341
|
},
|
|
12309
|
-
children: [
|
|
12310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
12311
|
-
|
|
13342
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
13343
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: s.name }),
|
|
13344
|
+
" ",
|
|
13345
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12312
13346
|
className: panel_module_css_default.meta,
|
|
12313
|
-
children:
|
|
12314
|
-
})
|
|
12315
|
-
|
|
13347
|
+
children: ["· ", (s.moods ?? []).join("、")]
|
|
13348
|
+
})
|
|
13349
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13350
|
+
className: panel_module_css_default.row,
|
|
13351
|
+
style: { gap: 4 },
|
|
13352
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13353
|
+
type: "button",
|
|
13354
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13355
|
+
onClick: () => {
|
|
13356
|
+
(async () => {
|
|
13357
|
+
try {
|
|
13358
|
+
await api.scenes({
|
|
13359
|
+
op: "adopt",
|
|
13360
|
+
scene: s
|
|
13361
|
+
});
|
|
13362
|
+
setSceneCandidates((sceneCandidates ?? []).filter((x) => x.name !== s.name));
|
|
13363
|
+
await refresh(false);
|
|
13364
|
+
pushProgress(`已采纳场景「${s.name}」`, "done");
|
|
13365
|
+
} catch (err) {
|
|
13366
|
+
setError(err.message);
|
|
13367
|
+
}
|
|
13368
|
+
})();
|
|
13369
|
+
},
|
|
13370
|
+
children: "采纳"
|
|
13371
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13372
|
+
type: "button",
|
|
13373
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13374
|
+
onClick: () => {
|
|
13375
|
+
setSceneDraft(s);
|
|
13376
|
+
setSceneCandidates(null);
|
|
13377
|
+
},
|
|
13378
|
+
children: "修改后采纳"
|
|
13379
|
+
})]
|
|
13380
|
+
})]
|
|
13381
|
+
}),
|
|
13382
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13383
|
+
className: panel_module_css_default.meta,
|
|
13384
|
+
style: { marginTop: 2 },
|
|
13385
|
+
children: s.summary
|
|
13386
|
+
}),
|
|
13387
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13388
|
+
className: panel_module_css_default.meta,
|
|
13389
|
+
style: {
|
|
13390
|
+
marginTop: 2,
|
|
13391
|
+
fontSize: 11
|
|
13392
|
+
},
|
|
13393
|
+
children: ["要素:", (s.elements ?? []).join(";")]
|
|
13394
|
+
})
|
|
13395
|
+
]
|
|
13396
|
+
}, s.name))
|
|
13397
|
+
}),
|
|
13398
|
+
(() => {
|
|
13399
|
+
const scenes = project?.scenes ?? [];
|
|
13400
|
+
const detail = sceneDetailName !== null ? scenes.find((s) => s.name === sceneDetailName) : void 0;
|
|
13401
|
+
if (scenes.length === 0 && sceneCandidates === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13402
|
+
className: panel_module_css_default.shelfEmpty,
|
|
13403
|
+
style: {
|
|
13404
|
+
minHeight: 140,
|
|
13405
|
+
flex: 1
|
|
13406
|
+
},
|
|
13407
|
+
children: [
|
|
13408
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13409
|
+
className: panel_module_css_default.shelfEmptyIcon,
|
|
13410
|
+
children: "🏞️"
|
|
13411
|
+
}),
|
|
13412
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13413
|
+
className: panel_module_css_default.shelfEmptyTitle,
|
|
13414
|
+
children: "场景库为空"
|
|
13415
|
+
}),
|
|
13416
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13417
|
+
className: panel_module_css_default.meta,
|
|
13418
|
+
children: "点「✨ 从全书提炼场景」自动建立,或手动新增"
|
|
13419
|
+
})
|
|
13420
|
+
]
|
|
13421
|
+
});
|
|
13422
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13423
|
+
style: {
|
|
13424
|
+
display: "grid",
|
|
13425
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
|
13426
|
+
gap: 10
|
|
13427
|
+
},
|
|
13428
|
+
children: scenes.map((s) => {
|
|
13429
|
+
const cover = (s.gallery ?? [])[0];
|
|
13430
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13431
|
+
onClick: () => {
|
|
13432
|
+
setSceneDetailName(s.name);
|
|
13433
|
+
setSceneUploadLabel("全景");
|
|
13434
|
+
},
|
|
13435
|
+
style: {
|
|
13436
|
+
cursor: "pointer",
|
|
13437
|
+
border: "1px solid var(--nf-border)",
|
|
13438
|
+
borderRadius: 12,
|
|
13439
|
+
overflow: "hidden",
|
|
13440
|
+
background: "var(--nf-bg-inset)",
|
|
13441
|
+
display: "flex",
|
|
13442
|
+
flexDirection: "column"
|
|
13443
|
+
},
|
|
13444
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13445
|
+
style: {
|
|
13446
|
+
height: 100,
|
|
13447
|
+
display: "flex",
|
|
13448
|
+
alignItems: "center",
|
|
13449
|
+
justifyContent: "center",
|
|
13450
|
+
background: "var(--nf-bg-inset)",
|
|
13451
|
+
borderBottom: "1px solid var(--nf-border)",
|
|
13452
|
+
position: "relative"
|
|
13453
|
+
},
|
|
13454
|
+
children: [cover !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
13455
|
+
src: cover.dataUrl,
|
|
13456
|
+
alt: s.name,
|
|
13457
|
+
style: {
|
|
13458
|
+
width: "100%",
|
|
13459
|
+
height: "100%",
|
|
13460
|
+
objectFit: "cover"
|
|
13461
|
+
}
|
|
13462
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12316
13463
|
className: panel_module_css_default.meta,
|
|
13464
|
+
children: "暂无场景图"
|
|
13465
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12317
13466
|
style: {
|
|
12318
|
-
|
|
12319
|
-
|
|
13467
|
+
position: "absolute",
|
|
13468
|
+
bottom: 4,
|
|
13469
|
+
right: 4,
|
|
13470
|
+
background: "rgba(0,0,0,0.6)",
|
|
13471
|
+
color: "#fff",
|
|
13472
|
+
fontSize: 10,
|
|
13473
|
+
borderRadius: 6,
|
|
13474
|
+
padding: "1px 6px"
|
|
12320
13475
|
},
|
|
12321
|
-
children:
|
|
12322
|
-
})
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
13476
|
+
children: ["🖼 ", (s.gallery ?? []).length]
|
|
13477
|
+
})]
|
|
13478
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13479
|
+
style: {
|
|
13480
|
+
padding: 6,
|
|
13481
|
+
display: "flex",
|
|
13482
|
+
flexDirection: "column",
|
|
13483
|
+
gap: 2
|
|
13484
|
+
},
|
|
13485
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13486
|
+
style: { fontSize: 13 },
|
|
13487
|
+
children: s.name
|
|
13488
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13489
|
+
className: panel_module_css_default.meta,
|
|
13490
|
+
style: { fontSize: 10 },
|
|
13491
|
+
children: (s.moods ?? []).join("、") || s.summary.slice(0, 16)
|
|
13492
|
+
})]
|
|
13493
|
+
})]
|
|
13494
|
+
}, s.name);
|
|
13495
|
+
})
|
|
13496
|
+
}), detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13497
|
+
style: {
|
|
13498
|
+
position: "fixed",
|
|
13499
|
+
inset: 0,
|
|
13500
|
+
background: "rgba(0,0,0,0.55)",
|
|
13501
|
+
zIndex: 1e3,
|
|
13502
|
+
display: "flex",
|
|
13503
|
+
alignItems: "center",
|
|
13504
|
+
justifyContent: "center",
|
|
13505
|
+
padding: 24
|
|
13506
|
+
},
|
|
13507
|
+
onClick: () => {
|
|
13508
|
+
setSceneDetailName(null);
|
|
13509
|
+
},
|
|
13510
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12327
13511
|
style: {
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
13512
|
+
background: "var(--nf-bg)",
|
|
13513
|
+
border: "1px solid var(--nf-border)",
|
|
13514
|
+
borderRadius: 16,
|
|
13515
|
+
width: "min(860px, 100%)",
|
|
13516
|
+
maxHeight: "92vh",
|
|
13517
|
+
overflowY: "auto",
|
|
13518
|
+
padding: 20,
|
|
13519
|
+
position: "relative"
|
|
12331
13520
|
},
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
12336
|
-
"分镜表(",
|
|
12337
|
-
storyboardResult.panels.length,
|
|
12338
|
-
" 格)"
|
|
12339
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13521
|
+
onClick: (e) => e.stopPropagation(),
|
|
13522
|
+
children: [
|
|
13523
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12340
13524
|
type: "button",
|
|
12341
|
-
className:
|
|
13525
|
+
className: panel_module_css_default.iconButton,
|
|
13526
|
+
style: {
|
|
13527
|
+
position: "absolute",
|
|
13528
|
+
top: 12,
|
|
13529
|
+
right: 12,
|
|
13530
|
+
fontSize: 18
|
|
13531
|
+
},
|
|
13532
|
+
title: "关闭",
|
|
13533
|
+
"aria-label": "关闭",
|
|
12342
13534
|
onClick: () => {
|
|
12343
|
-
|
|
12344
|
-
navigator.clipboard?.writeText(text).then(() => {
|
|
12345
|
-
pushProgress("分镜表已复制到剪贴板", "done");
|
|
12346
|
-
}).catch(() => {});
|
|
13535
|
+
setSceneDetailName(null);
|
|
12347
13536
|
},
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
13537
|
+
children: "✕"
|
|
13538
|
+
}),
|
|
13539
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13540
|
+
style: { marginBottom: 12 },
|
|
13541
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13542
|
+
style: { fontSize: 20 },
|
|
13543
|
+
children: detail.name
|
|
13544
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13545
|
+
className: panel_module_css_default.meta,
|
|
13546
|
+
style: { marginTop: 4 },
|
|
13547
|
+
children: detail.summary
|
|
13548
|
+
})]
|
|
13549
|
+
}),
|
|
13550
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13551
|
+
style: {
|
|
13552
|
+
display: "grid",
|
|
13553
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(160px, 1fr))",
|
|
13554
|
+
gap: 8,
|
|
13555
|
+
marginBottom: 12
|
|
13556
|
+
},
|
|
13557
|
+
children: [(detail.gallery ?? []).map((img) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12361
13558
|
style: {
|
|
12362
|
-
|
|
12363
|
-
|
|
13559
|
+
border: "1px solid var(--nf-border)",
|
|
13560
|
+
borderRadius: 10,
|
|
13561
|
+
overflow: "hidden",
|
|
13562
|
+
position: "relative"
|
|
12364
13563
|
},
|
|
12365
13564
|
children: [
|
|
12366
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
12367
|
-
|
|
13565
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
13566
|
+
src: img.dataUrl,
|
|
13567
|
+
alt: img.label,
|
|
13568
|
+
style: {
|
|
13569
|
+
width: "100%",
|
|
13570
|
+
height: 100,
|
|
13571
|
+
objectFit: "cover",
|
|
13572
|
+
display: "block"
|
|
13573
|
+
}
|
|
13574
|
+
}),
|
|
13575
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12368
13576
|
style: {
|
|
12369
|
-
|
|
12370
|
-
color: "
|
|
12371
|
-
|
|
13577
|
+
background: "rgba(0,0,0,0.55)",
|
|
13578
|
+
color: "#fff",
|
|
13579
|
+
fontSize: 10,
|
|
13580
|
+
padding: "1px 6px",
|
|
13581
|
+
textAlign: "center"
|
|
12372
13582
|
},
|
|
12373
|
-
children:
|
|
13583
|
+
children: img.label
|
|
12374
13584
|
}),
|
|
12375
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
12376
|
-
|
|
12377
|
-
className: panel_module_css_default.
|
|
12378
|
-
|
|
13585
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13586
|
+
type: "button",
|
|
13587
|
+
className: panel_module_css_default.iconButton,
|
|
13588
|
+
style: {
|
|
13589
|
+
position: "absolute",
|
|
13590
|
+
top: 2,
|
|
13591
|
+
right: 2,
|
|
13592
|
+
fontSize: 11
|
|
13593
|
+
},
|
|
13594
|
+
title: "删除",
|
|
13595
|
+
"aria-label": "删除",
|
|
13596
|
+
onClick: () => {
|
|
13597
|
+
(async () => {
|
|
13598
|
+
try {
|
|
13599
|
+
await api.scenes({
|
|
13600
|
+
op: "removeImage",
|
|
13601
|
+
name: detail.name,
|
|
13602
|
+
label: img.label
|
|
13603
|
+
});
|
|
13604
|
+
await refresh(false);
|
|
13605
|
+
pushProgress(`已删除「${detail.name}」${img.label}`, "done");
|
|
13606
|
+
} catch (err) {
|
|
13607
|
+
setError(err.message);
|
|
13608
|
+
}
|
|
13609
|
+
})();
|
|
13610
|
+
},
|
|
13611
|
+
children: "×"
|
|
12379
13612
|
})
|
|
12380
13613
|
]
|
|
12381
|
-
}),
|
|
12382
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12383
|
-
className: panel_module_css_default.meta,
|
|
12384
|
-
children: p.visual
|
|
12385
|
-
}),
|
|
12386
|
-
p.dialogue !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12387
|
-
className: panel_module_css_default.meta,
|
|
12388
|
-
style: { color: "var(--nf-info)" },
|
|
12389
|
-
children: ["💬 ", p.dialogue]
|
|
12390
|
-
}),
|
|
12391
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13614
|
+
}, img.label)), (detail.gallery ?? []).length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12392
13615
|
className: panel_module_css_default.meta,
|
|
13616
|
+
children: "暂无场景图"
|
|
13617
|
+
})]
|
|
13618
|
+
}),
|
|
13619
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13620
|
+
style: {
|
|
13621
|
+
display: "grid",
|
|
13622
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
|
|
13623
|
+
gap: 14,
|
|
13624
|
+
marginBottom: 12
|
|
13625
|
+
},
|
|
13626
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12393
13627
|
style: {
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
color: "var(--nf-text-2)"
|
|
13628
|
+
fontSize: 12,
|
|
13629
|
+
lineHeight: 1.8
|
|
12397
13630
|
},
|
|
12398
|
-
children:
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
13631
|
+
children: [
|
|
13632
|
+
(detail.act !== void 0 || detail.moment !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13633
|
+
style: { marginBottom: 6 },
|
|
13634
|
+
children: [detail.act !== void 0 && detail.act !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13635
|
+
className: panel_module_css_default.badge,
|
|
13636
|
+
style: {
|
|
13637
|
+
borderColor: "var(--nf-accent)",
|
|
13638
|
+
color: "var(--nf-accent)",
|
|
13639
|
+
marginRight: 6
|
|
13640
|
+
},
|
|
13641
|
+
children: detail.act
|
|
13642
|
+
}), detail.moment !== void 0 && detail.moment !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13643
|
+
className: panel_module_css_default.meta,
|
|
13644
|
+
children: detail.moment
|
|
13645
|
+
})]
|
|
13646
|
+
}),
|
|
13647
|
+
(detail.beats ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13648
|
+
style: { marginBottom: 8 },
|
|
13649
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13650
|
+
style: { fontSize: 13 },
|
|
13651
|
+
children: "关键镜头"
|
|
13652
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13653
|
+
style: { marginTop: 4 },
|
|
13654
|
+
children: (detail.beats ?? []).map((b, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13655
|
+
style: {
|
|
13656
|
+
fontSize: 11,
|
|
13657
|
+
color: "var(--nf-text-2)",
|
|
13658
|
+
marginTop: 2
|
|
13659
|
+
},
|
|
13660
|
+
children: ["🎬 ", b]
|
|
13661
|
+
}, i))
|
|
13662
|
+
})]
|
|
13663
|
+
}),
|
|
13664
|
+
detail.characterState !== void 0 && detail.characterState !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13665
|
+
style: { marginBottom: 8 },
|
|
13666
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13667
|
+
style: { fontSize: 13 },
|
|
13668
|
+
children: "人物状态"
|
|
13669
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13670
|
+
className: panel_module_css_default.meta,
|
|
13671
|
+
style: { marginTop: 2 },
|
|
13672
|
+
children: detail.characterState
|
|
13673
|
+
})]
|
|
13674
|
+
}),
|
|
13675
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13676
|
+
style: { fontSize: 13 },
|
|
13677
|
+
children: "环境构成"
|
|
13678
|
+
}),
|
|
13679
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13680
|
+
style: { marginTop: 4 },
|
|
13681
|
+
children: (detail.elements ?? []).map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13682
|
+
style: {
|
|
13683
|
+
border: "1px solid var(--nf-border)",
|
|
13684
|
+
borderRadius: 999,
|
|
13685
|
+
padding: "1px 8px",
|
|
13686
|
+
fontSize: 11,
|
|
13687
|
+
margin: "0 4px 4px 0",
|
|
13688
|
+
display: "inline-block"
|
|
13689
|
+
},
|
|
13690
|
+
children: e
|
|
13691
|
+
}, e))
|
|
13692
|
+
}),
|
|
13693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13694
|
+
style: { marginTop: 8 },
|
|
13695
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13696
|
+
style: { fontSize: 13 },
|
|
13697
|
+
children: "色调光影"
|
|
13698
|
+
})
|
|
13699
|
+
}),
|
|
13700
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13701
|
+
style: { marginTop: 4 },
|
|
13702
|
+
children: (detail.palette ?? []).join(";") || "—"
|
|
13703
|
+
}),
|
|
13704
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13705
|
+
style: { marginTop: 8 },
|
|
13706
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13707
|
+
style: { fontSize: 13 },
|
|
13708
|
+
children: "氛围"
|
|
13709
|
+
})
|
|
13710
|
+
}),
|
|
13711
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13712
|
+
style: { marginTop: 4 },
|
|
13713
|
+
children: (detail.moods ?? []).join("、") || "—"
|
|
13714
|
+
}),
|
|
13715
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13716
|
+
style: { marginTop: 8 },
|
|
13717
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13718
|
+
style: { fontSize: 13 },
|
|
13719
|
+
children: "依据"
|
|
13720
|
+
})
|
|
13721
|
+
}),
|
|
13722
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13723
|
+
className: panel_module_css_default.meta,
|
|
13724
|
+
style: { marginTop: 4 },
|
|
13725
|
+
children: detail.source || "—"
|
|
13726
|
+
})
|
|
13727
|
+
]
|
|
13728
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
13729
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
13730
|
+
style: { fontSize: 13 },
|
|
13731
|
+
children: "生图提示词"
|
|
13732
|
+
}),
|
|
13733
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13734
|
+
className: panel_module_css_default.meta,
|
|
13735
|
+
style: {
|
|
13736
|
+
fontSize: 11,
|
|
13737
|
+
lineHeight: 1.6,
|
|
13738
|
+
marginTop: 4
|
|
13739
|
+
},
|
|
13740
|
+
children: detail.zh
|
|
13741
|
+
}),
|
|
13742
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13743
|
+
className: panel_module_css_default.meta,
|
|
13744
|
+
style: {
|
|
13745
|
+
fontSize: 10,
|
|
13746
|
+
fontFamily: "monospace",
|
|
13747
|
+
marginTop: 4,
|
|
13748
|
+
wordBreak: "break-all"
|
|
13749
|
+
},
|
|
13750
|
+
children: detail.en
|
|
13751
|
+
}),
|
|
13752
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13753
|
+
style: {
|
|
13754
|
+
display: "flex",
|
|
13755
|
+
flexWrap: "wrap",
|
|
13756
|
+
gap: 4,
|
|
13757
|
+
marginTop: 8
|
|
13758
|
+
},
|
|
13759
|
+
children: (detail.tags ?? []).map((t) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13760
|
+
style: {
|
|
13761
|
+
border: "1px solid var(--nf-border)",
|
|
13762
|
+
borderRadius: 999,
|
|
13763
|
+
padding: "2px 8px",
|
|
13764
|
+
fontSize: 11
|
|
13765
|
+
},
|
|
13766
|
+
children: t
|
|
13767
|
+
}, t))
|
|
13768
|
+
})
|
|
13769
|
+
] })]
|
|
13770
|
+
}),
|
|
13771
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13772
|
+
style: {
|
|
13773
|
+
borderTop: "1px solid var(--nf-border)",
|
|
13774
|
+
paddingTop: 10,
|
|
13775
|
+
display: "flex",
|
|
13776
|
+
flexWrap: "wrap",
|
|
13777
|
+
gap: 6,
|
|
13778
|
+
alignItems: "center"
|
|
13779
|
+
},
|
|
13780
|
+
children: [
|
|
13781
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13782
|
+
type: "button",
|
|
13783
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13784
|
+
onClick: () => {
|
|
13785
|
+
const text = [detail.en, detail.tags.join(", ")].filter(Boolean).join("\n");
|
|
13786
|
+
navigator.clipboard?.writeText(text).then(() => {
|
|
13787
|
+
pushProgress(`已复制「${detail.name}」英文生图提示词`, "done");
|
|
13788
|
+
}).catch(() => {});
|
|
13789
|
+
},
|
|
13790
|
+
children: "复制提示词"
|
|
13791
|
+
}),
|
|
13792
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13793
|
+
className: panel_module_css_default.input,
|
|
13794
|
+
style: {
|
|
13795
|
+
width: 130,
|
|
13796
|
+
fontSize: 12,
|
|
13797
|
+
padding: "3px 6px"
|
|
13798
|
+
},
|
|
13799
|
+
placeholder: "图集标签",
|
|
13800
|
+
value: sceneUploadLabel,
|
|
13801
|
+
onChange: (e) => {
|
|
13802
|
+
setSceneUploadLabel(e.target.value);
|
|
13803
|
+
}
|
|
13804
|
+
}),
|
|
13805
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13806
|
+
type: "button",
|
|
13807
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13808
|
+
disabled: busy,
|
|
13809
|
+
onClick: () => {
|
|
13810
|
+
setRoleImageLabel(sceneUploadLabel.trim() !== "" ? sceneUploadLabel.trim() : "全景");
|
|
13811
|
+
setSceneUploadLabel(sceneUploadLabel.trim() !== "" ? sceneUploadLabel.trim() : "全景");
|
|
13812
|
+
setRoleImageTarget(detail.name + "||scene");
|
|
13813
|
+
roleImageInputRef.current?.click();
|
|
13814
|
+
},
|
|
13815
|
+
children: "📤 上传场景图"
|
|
13816
|
+
}),
|
|
13817
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13818
|
+
type: "button",
|
|
13819
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13820
|
+
onClick: () => {
|
|
13821
|
+
setSceneDraft(detail);
|
|
13822
|
+
setSceneDetailName(null);
|
|
13823
|
+
},
|
|
13824
|
+
children: "✏️ 编辑"
|
|
13825
|
+
}),
|
|
13826
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13827
|
+
type: "button",
|
|
13828
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
13829
|
+
style: { color: "var(--nf-danger, #e05)" },
|
|
13830
|
+
onClick: () => {
|
|
13831
|
+
(async () => {
|
|
13832
|
+
if (!window.confirm(`确定删除场景「${detail.name}」?`)) return;
|
|
13833
|
+
try {
|
|
13834
|
+
await api.scenes({
|
|
13835
|
+
op: "remove",
|
|
13836
|
+
name: detail.name
|
|
13837
|
+
});
|
|
13838
|
+
await refresh(false);
|
|
13839
|
+
setSceneDetailName(null);
|
|
13840
|
+
pushProgress(`已删除场景「${detail.name}」`, "done");
|
|
13841
|
+
} catch (err) {
|
|
13842
|
+
setError(err.message);
|
|
13843
|
+
}
|
|
13844
|
+
})();
|
|
13845
|
+
},
|
|
13846
|
+
children: "🗑 删除"
|
|
13847
|
+
})
|
|
13848
|
+
]
|
|
13849
|
+
})
|
|
13850
|
+
]
|
|
12402
13851
|
})
|
|
12403
|
-
]
|
|
12404
|
-
})
|
|
13852
|
+
})] });
|
|
13853
|
+
})()
|
|
12405
13854
|
]
|
|
12406
13855
|
})
|
|
12407
13856
|
] })
|