@waterwx/dsh-novel-forge 1.1.4 → 1.1.5
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 +2 -0
- package/lib/client.js +815 -287
- package/lib/client.js.map +1 -1
- package/lib/index.js +740 -521
- package/lib/index.js.map +1 -1
- package/lib/types/client/api.d.ts +7 -0
- package/lib/types/client/panel/NovelPanel.d.ts +1 -1
- package/lib/types/engine.d.ts +3 -1
- package/lib/types/protocol.d.ts +45 -0
- package/package.json +1 -1
- package/src/assistant.ts +27 -4
- package/src/client/api.ts +10 -0
- package/src/client/panel/NovelPanel.tsx +279 -41
- package/src/engine.ts +77 -0
- package/src/protocol.ts +48 -0
- package/src/routes.ts +90 -0
package/lib/client.js
CHANGED
|
@@ -65,8 +65,12 @@ window.__ModuleLoader__.load({
|
|
|
65
65
|
cover: "/api/dsh-novel-forge/blurb/cover",
|
|
66
66
|
/** 剧情线管理:增删改 + 关联章节。 */
|
|
67
67
|
plotlines: "/api/dsh-novel-forge/plotlines",
|
|
68
|
+
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
69
|
+
roles: "/api/dsh-novel-forge/roles",
|
|
68
70
|
/** 作者复盘补跑:对已写章节补齐 authorReview(全书流式 / 单章 JSON)。 */
|
|
69
71
|
reviewBackfill: "/api/dsh-novel-forge/review/backfill",
|
|
72
|
+
/** 章节复位:generating 卡死 → pending(可重新生成)。 */
|
|
73
|
+
chapterReset: "/api/dsh-novel-forge/chapter/reset",
|
|
70
74
|
/** 敏感词检查:全书已写章节或指定文本。 */
|
|
71
75
|
sensitiveCheck: "/api/dsh-novel-forge/sensitive-check",
|
|
72
76
|
config: "/api/dsh-novel-forge/config",
|
|
@@ -220,6 +224,14 @@ window.__ModuleLoader__.load({
|
|
|
220
224
|
async reviewBackfillAll(onFrame) {
|
|
221
225
|
await this.streamJob(NOVEL_API.reviewBackfill, {}, onFrame);
|
|
222
226
|
}
|
|
227
|
+
/** 章节复位:generating 卡死 → pending。 */
|
|
228
|
+
async chapterReset(no) {
|
|
229
|
+
return postJson(NOVEL_API.chapterReset, { chapterNo: no });
|
|
230
|
+
}
|
|
231
|
+
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
232
|
+
async roles(req) {
|
|
233
|
+
return postJson(NOVEL_API.roles, req);
|
|
234
|
+
}
|
|
223
235
|
/** 小说简介:AI 生成/补全(partial 留空 = 全量),或手动保存。 */
|
|
224
236
|
async blurb(action, text, partial) {
|
|
225
237
|
return postJson(NOVEL_API.blurb, {
|
|
@@ -765,205 +777,205 @@ window.__ModuleLoader__.load({
|
|
|
765
777
|
document.head.appendChild(tag);
|
|
766
778
|
}
|
|
767
779
|
var panel_module_css_default = {
|
|
768
|
-
"
|
|
769
|
-
"
|
|
770
|
-
"
|
|
771
|
-
"
|
|
772
|
-
"
|
|
773
|
-
"
|
|
774
|
-
"
|
|
775
|
-
"
|
|
776
|
-
"
|
|
780
|
+
"headerProgress": "CUIYUW_headerProgress",
|
|
781
|
+
"assetGrid": "CUIYUW_assetGrid",
|
|
782
|
+
"textarea": "CUIYUW_textarea",
|
|
783
|
+
"entryIcon": "CUIYUW_entryIcon",
|
|
784
|
+
"assistantStatus": "CUIYUW_assistantStatus",
|
|
785
|
+
"assistantResize": "CUIYUW_assistantResize",
|
|
786
|
+
"navTabIcon": "CUIYUW_navTabIcon",
|
|
787
|
+
"workflowHint": "CUIYUW_workflowHint",
|
|
788
|
+
"chapter": "CUIYUW_chapter",
|
|
789
|
+
"bookCardBody": "CUIYUW_bookCardBody",
|
|
790
|
+
"navGroupLabel": "CUIYUW_navGroupLabel",
|
|
791
|
+
"bookshelf": "CUIYUW_bookshelf",
|
|
792
|
+
"navAbout": "CUIYUW_navAbout",
|
|
793
|
+
"dashHeroSparkle": "CUIYUW_dashHeroSparkle",
|
|
794
|
+
"dashJourneyStages": "CUIYUW_dashJourneyStages",
|
|
795
|
+
"panelNavCollapsed": "CUIYUW_panelNavCollapsed",
|
|
796
|
+
"fieldLabel": "CUIYUW_fieldLabel",
|
|
797
|
+
"dashHeroActionBody": "CUIYUW_dashHeroActionBody",
|
|
798
|
+
"todoItem": "CUIYUW_todoItem",
|
|
799
|
+
"toolLive": "CUIYUW_toolLive",
|
|
800
|
+
"assistantFloatHeader": "CUIYUW_assistantFloatHeader",
|
|
801
|
+
"createBookView": "CUIYUW_createBookView",
|
|
802
|
+
"row": "CUIYUW_row",
|
|
803
|
+
"wsColumns": "CUIYUW_wsColumns",
|
|
804
|
+
"workflowRow": "CUIYUW_workflowRow",
|
|
805
|
+
"fadeIn": "CUIYUW_fadeIn",
|
|
806
|
+
"bookChipMeta": "CUIYUW_bookChipMeta",
|
|
807
|
+
"assetStatValue": "CUIYUW_assetStatValue",
|
|
808
|
+
"progressLineError": "CUIYUW_progressLineError",
|
|
809
|
+
"bookChipName": "CUIYUW_bookChipName",
|
|
777
810
|
"toolSteps": "CUIYUW_toolSteps",
|
|
778
|
-
"
|
|
779
|
-
"
|
|
780
|
-
"
|
|
781
|
-
"
|
|
782
|
-
"
|
|
783
|
-
"
|
|
811
|
+
"dashHeroEyebrow": "CUIYUW_dashHeroEyebrow",
|
|
812
|
+
"todoText": "CUIYUW_todoText",
|
|
813
|
+
"createBookIcon": "CUIYUW_createBookIcon",
|
|
814
|
+
"dropzoneActive": "CUIYUW_dropzoneActive",
|
|
815
|
+
"iconButton": "CUIYUW_iconButton",
|
|
816
|
+
"fileList": "CUIYUW_fileList",
|
|
817
|
+
"badge": "CUIYUW_badge",
|
|
818
|
+
"chatScroll": "CUIYUW_chatScroll",
|
|
819
|
+
"workflowList": "CUIYUW_workflowList",
|
|
820
|
+
"wsPage": "CUIYUW_wsPage",
|
|
821
|
+
"assetStatDetail": "CUIYUW_assetStatDetail",
|
|
822
|
+
"diffAdd": "CUIYUW_diffAdd",
|
|
823
|
+
"dashStageDot": "CUIYUW_dashStageDot",
|
|
784
824
|
"chatRole": "CUIYUW_chatRole",
|
|
785
|
-
"
|
|
825
|
+
"todoDanger": "CUIYUW_todoDanger",
|
|
826
|
+
"navTabBadgeDanger": "CUIYUW_navTabBadgeDanger",
|
|
827
|
+
"bookCreateOutline": "CUIYUW_bookCreateOutline",
|
|
828
|
+
"dashHeroAction": "CUIYUW_dashHeroAction",
|
|
829
|
+
"diffOld": "CUIYUW_diffOld",
|
|
786
830
|
"badgeError": "CUIYUW_badgeError",
|
|
787
|
-
"
|
|
788
|
-
"
|
|
789
|
-
"navGroupSep": "CUIYUW_navGroupSep",
|
|
790
|
-
"navGroupLabel": "CUIYUW_navGroupLabel",
|
|
791
|
-
"diffAdd": "CUIYUW_diffAdd",
|
|
831
|
+
"progress": "CUIYUW_progress",
|
|
832
|
+
"dashJourneyBar": "CUIYUW_dashJourneyBar",
|
|
792
833
|
"wsSelected": "CUIYUW_wsSelected",
|
|
793
|
-
"
|
|
794
|
-
"
|
|
795
|
-
"
|
|
796
|
-
"
|
|
797
|
-
"
|
|
798
|
-
"
|
|
799
|
-
"
|
|
800
|
-
"dashFact": "CUIYUW_dashFact",
|
|
834
|
+
"badgeDone": "CUIYUW_badgeDone",
|
|
835
|
+
"headerProgressDot": "CUIYUW_headerProgressDot",
|
|
836
|
+
"reviewBox": "CUIYUW_reviewBox",
|
|
837
|
+
"toolStepActive": "CUIYUW_toolStepActive",
|
|
838
|
+
"button": "CUIYUW_button",
|
|
839
|
+
"volumeGroup": "CUIYUW_volumeGroup",
|
|
840
|
+
"assetStatLabel": "CUIYUW_assetStatLabel",
|
|
801
841
|
"bookCreateCard": "CUIYUW_bookCreateCard",
|
|
802
|
-
"
|
|
803
|
-
"
|
|
804
|
-
"
|
|
805
|
-
"bookshelfLabel": "CUIYUW_bookshelfLabel",
|
|
842
|
+
"createBookTop": "CUIYUW_createBookTop",
|
|
843
|
+
"dashStageDone": "CUIYUW_dashStageDone",
|
|
844
|
+
"genreDesc": "CUIYUW_genreDesc",
|
|
806
845
|
"dashJourneyFill": "CUIYUW_dashJourneyFill",
|
|
807
|
-
"
|
|
808
|
-
"
|
|
809
|
-
"
|
|
846
|
+
"wsPreview": "CUIYUW_wsPreview",
|
|
847
|
+
"onlyChanges": "CUIYUW_onlyChanges",
|
|
848
|
+
"toolStepError": "CUIYUW_toolStepError",
|
|
849
|
+
"wsPageHeader": "CUIYUW_wsPageHeader",
|
|
850
|
+
"view": "CUIYUW_view",
|
|
851
|
+
"todoWarning": "CUIYUW_todoWarning",
|
|
810
852
|
"diffTagNew": "CUIYUW_diffTagNew",
|
|
811
|
-
"
|
|
812
|
-
"
|
|
813
|
-
"dashStageDone": "CUIYUW_dashStageDone",
|
|
814
|
-
"navTabIcon": "CUIYUW_navTabIcon",
|
|
815
|
-
"bookChipName": "CUIYUW_bookChipName",
|
|
816
|
-
"badge": "CUIYUW_badge",
|
|
817
|
-
"navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
|
|
853
|
+
"dashFacts": "CUIYUW_dashFacts",
|
|
854
|
+
"input": "CUIYUW_input",
|
|
818
855
|
"tab": "CUIYUW_tab",
|
|
819
|
-
"
|
|
820
|
-
"
|
|
821
|
-
"
|
|
822
|
-
"
|
|
856
|
+
"pulse": "CUIYUW_pulse",
|
|
857
|
+
"progressLineLive": "CUIYUW_progressLineLive",
|
|
858
|
+
"assistantFloat": "CUIYUW_assistantFloat",
|
|
859
|
+
"bookCardTitleRow": "CUIYUW_bookCardTitleRow",
|
|
823
860
|
"dashHeroBook": "CUIYUW_dashHeroBook",
|
|
824
|
-
"
|
|
825
|
-
"
|
|
826
|
-
"
|
|
827
|
-
"
|
|
828
|
-
"
|
|
829
|
-
"
|
|
830
|
-
"
|
|
831
|
-
"
|
|
832
|
-
"
|
|
833
|
-
"
|
|
834
|
-
"
|
|
835
|
-
"
|
|
836
|
-
"
|
|
837
|
-
"
|
|
838
|
-
"
|
|
839
|
-
"
|
|
840
|
-
"bookChipActive": "CUIYUW_bookChipActive",
|
|
841
|
-
"entry": "CUIYUW_entry",
|
|
842
|
-
"badgeDone": "CUIYUW_badgeDone",
|
|
843
|
-
"diffSameBody": "CUIYUW_diffSameBody",
|
|
861
|
+
"bookCardProgressBar": "CUIYUW_bookCardProgressBar",
|
|
862
|
+
"diffLegend": "CUIYUW_diffLegend",
|
|
863
|
+
"buttonDanger": "CUIYUW_buttonDanger",
|
|
864
|
+
"bookCardProgressFill": "CUIYUW_bookCardProgressFill",
|
|
865
|
+
"bigProgressBar": "CUIYUW_bigProgressBar",
|
|
866
|
+
"shelfHeader": "CUIYUW_shelfHeader",
|
|
867
|
+
"workflowDotDone": "CUIYUW_workflowDotDone",
|
|
868
|
+
"bigProgressBarFill": "CUIYUW_bigProgressBarFill",
|
|
869
|
+
"bookCreateForm": "CUIYUW_bookCreateForm",
|
|
870
|
+
"diffList": "CUIYUW_diffList",
|
|
871
|
+
"chapterMain": "CUIYUW_chapterMain",
|
|
872
|
+
"badgeRejected": "CUIYUW_badgeRejected",
|
|
873
|
+
"legendNew": "CUIYUW_legendNew",
|
|
874
|
+
"diffText": "CUIYUW_diffText",
|
|
875
|
+
"diffTagOld": "CUIYUW_diffTagOld",
|
|
876
|
+
"panelBody": "CUIYUW_panelBody",
|
|
844
877
|
"shelfView": "CUIYUW_shelfView",
|
|
845
|
-
"
|
|
878
|
+
"bookCard": "CUIYUW_bookCard",
|
|
879
|
+
"panelSubtitle": "CUIYUW_panelSubtitle",
|
|
880
|
+
"dashStageCurrent": "CUIYUW_dashStageCurrent",
|
|
881
|
+
"panelContent": "CUIYUW_panelContent",
|
|
846
882
|
"buttonSmall": "CUIYUW_buttonSmall",
|
|
847
|
-
"
|
|
848
|
-
"
|
|
849
|
-
"
|
|
850
|
-
"bookCardCover": "CUIYUW_bookCardCover",
|
|
851
|
-
"progressLine": "CUIYUW_progressLine",
|
|
852
|
-
"chapterActions": "CUIYUW_chapterActions",
|
|
853
|
-
"progressBarFill": "CUIYUW_progressBarFill",
|
|
854
|
-
"bookshelf": "CUIYUW_bookshelf",
|
|
855
|
-
"assetGrid": "CUIYUW_assetGrid",
|
|
856
|
-
"navAbout": "CUIYUW_navAbout",
|
|
857
|
-
"badgeRejected": "CUIYUW_badgeRejected",
|
|
858
|
-
"assetStatValue": "CUIYUW_assetStatValue",
|
|
859
|
-
"bookCardBody": "CUIYUW_bookCardBody",
|
|
860
|
-
"bookChip": "CUIYUW_bookChip",
|
|
861
|
-
"bookCardProgressBar": "CUIYUW_bookCardProgressBar",
|
|
862
|
-
"badgePending": "CUIYUW_badgePending",
|
|
863
|
-
"dashHeroActionBody": "CUIYUW_dashHeroActionBody",
|
|
864
|
-
"assistantFloat": "CUIYUW_assistantFloat",
|
|
865
|
-
"shelfGrid": "CUIYUW_shelfGrid",
|
|
883
|
+
"badgeGenerating": "CUIYUW_badgeGenerating",
|
|
884
|
+
"wsPreviewText": "CUIYUW_wsPreviewText",
|
|
885
|
+
"dashGrid": "CUIYUW_dashGrid",
|
|
866
886
|
"entryLabel": "CUIYUW_entryLabel",
|
|
867
|
-
"bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
|
|
868
|
-
"textarea": "CUIYUW_textarea",
|
|
869
|
-
"diffOld": "CUIYUW_diffOld",
|
|
870
|
-
"headerProgress": "CUIYUW_headerProgress",
|
|
871
887
|
"assistantFloatBody": "CUIYUW_assistantFloatBody",
|
|
872
|
-
"
|
|
873
|
-
"
|
|
874
|
-
"
|
|
875
|
-
"
|
|
876
|
-
"
|
|
877
|
-
"
|
|
878
|
-
"
|
|
879
|
-
"
|
|
880
|
-
"
|
|
881
|
-
"
|
|
882
|
-
"
|
|
883
|
-
"
|
|
888
|
+
"chapterPreview": "CUIYUW_chapterPreview",
|
|
889
|
+
"navGroup": "CUIYUW_navGroup",
|
|
890
|
+
"createBookTitle": "CUIYUW_createBookTitle",
|
|
891
|
+
"bookChip": "CUIYUW_bookChip",
|
|
892
|
+
"panelHeader": "CUIYUW_panelHeader",
|
|
893
|
+
"progressBar": "CUIYUW_progressBar",
|
|
894
|
+
"toolStep": "CUIYUW_toolStep",
|
|
895
|
+
"buttonPrimary": "CUIYUW_buttonPrimary",
|
|
896
|
+
"busyRow": "CUIYUW_busyRow",
|
|
897
|
+
"bookCardActive": "CUIYUW_bookCardActive",
|
|
898
|
+
"tabBar": "CUIYUW_tabBar",
|
|
899
|
+
"field": "CUIYUW_field",
|
|
900
|
+
"card": "CUIYUW_card",
|
|
901
|
+
"badgePending": "CUIYUW_badgePending",
|
|
902
|
+
"volumeGroupToggle": "CUIYUW_volumeGroupToggle",
|
|
903
|
+
"chapterActions": "CUIYUW_chapterActions",
|
|
904
|
+
"dashFact": "CUIYUW_dashFact",
|
|
905
|
+
"diffSame": "CUIYUW_diffSame",
|
|
884
906
|
"bookAddIcon": "CUIYUW_bookAddIcon",
|
|
885
|
-
"
|
|
907
|
+
"diffNew": "CUIYUW_diffNew",
|
|
908
|
+
"navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
|
|
909
|
+
"navTabLabel": "CUIYUW_navTabLabel",
|
|
910
|
+
"chapterList": "CUIYUW_chapterList",
|
|
911
|
+
"progressLine": "CUIYUW_progressLine",
|
|
912
|
+
"bookCardBlurb": "CUIYUW_bookCardBlurb",
|
|
913
|
+
"spaceBetween": "CUIYUW_spaceBetween",
|
|
914
|
+
"coverPlaceholder": "CUIYUW_coverPlaceholder",
|
|
915
|
+
"bookCardCover": "CUIYUW_bookCardCover",
|
|
916
|
+
"badgeWritten": "CUIYUW_badgeWritten",
|
|
917
|
+
"toolStepIcon": "CUIYUW_toolStepIcon",
|
|
918
|
+
"dropzoneIcon": "CUIYUW_dropzoneIcon",
|
|
919
|
+
"outlineReadonly": "CUIYUW_outlineReadonly",
|
|
920
|
+
"coverPreview": "CUIYUW_coverPreview",
|
|
886
921
|
"chatBubbleUser": "CUIYUW_chatBubbleUser",
|
|
887
|
-
"
|
|
922
|
+
"panel": "CUIYUW_panel",
|
|
923
|
+
"cardTitle": "CUIYUW_cardTitle",
|
|
924
|
+
"chatBubbleAssistant": "CUIYUW_chatBubbleAssistant",
|
|
925
|
+
"navTab": "CUIYUW_navTab",
|
|
926
|
+
"dashHeroArrow": "CUIYUW_dashHeroArrow",
|
|
888
927
|
"dashHeroActionTitle": "CUIYUW_dashHeroActionTitle",
|
|
889
|
-
"
|
|
928
|
+
"bookChipActive": "CUIYUW_bookChipActive",
|
|
929
|
+
"panelNav": "CUIYUW_panelNav",
|
|
890
930
|
"diffDel": "CUIYUW_diffDel",
|
|
891
|
-
"
|
|
892
|
-
"
|
|
893
|
-
"
|
|
894
|
-
"
|
|
895
|
-
"
|
|
896
|
-
"
|
|
897
|
-
"
|
|
898
|
-
"
|
|
899
|
-
"
|
|
900
|
-
"
|
|
901
|
-
"
|
|
902
|
-
"
|
|
903
|
-
"
|
|
904
|
-
"assistantResize": "CUIYUW_assistantResize",
|
|
905
|
-
"navGroup": "CUIYUW_navGroup",
|
|
906
|
-
"panelTitle": "CUIYUW_panelTitle",
|
|
907
|
-
"dashJourneyStages": "CUIYUW_dashJourneyStages",
|
|
908
|
-
"chapter": "CUIYUW_chapter",
|
|
931
|
+
"bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
|
|
932
|
+
"dashHeroTitle": "CUIYUW_dashHeroTitle",
|
|
933
|
+
"workflowBody": "CUIYUW_workflowBody",
|
|
934
|
+
"bookChipRemove": "CUIYUW_bookChipRemove",
|
|
935
|
+
"wsSelectedText": "CUIYUW_wsSelectedText",
|
|
936
|
+
"navSpacer": "CUIYUW_navSpacer",
|
|
937
|
+
"navTabBadge": "CUIYUW_navTabBadge",
|
|
938
|
+
"navGroupSep": "CUIYUW_navGroupSep",
|
|
939
|
+
"progressBarFill": "CUIYUW_progressBarFill",
|
|
940
|
+
"toolStepStatus": "CUIYUW_toolStepStatus",
|
|
941
|
+
"diffSameBody": "CUIYUW_diffSameBody",
|
|
942
|
+
"volumeGroupHeader": "CUIYUW_volumeGroupHeader",
|
|
943
|
+
"legendOld": "CUIYUW_legendOld",
|
|
909
944
|
"navTabBadgeDone": "CUIYUW_navTabBadgeDone",
|
|
910
945
|
"dashHero": "CUIYUW_dashHero",
|
|
911
|
-
"
|
|
946
|
+
"panelTitle": "CUIYUW_panelTitle",
|
|
947
|
+
"chapterTitle": "CUIYUW_chapterTitle",
|
|
948
|
+
"wsEditor": "CUIYUW_wsEditor",
|
|
949
|
+
"chapterBeats": "CUIYUW_chapterBeats",
|
|
950
|
+
"bookCardName": "CUIYUW_bookCardName",
|
|
951
|
+
"navAboutRow": "CUIYUW_navAboutRow",
|
|
912
952
|
"bookshelfList": "CUIYUW_bookshelfList",
|
|
913
|
-
"
|
|
914
|
-
"
|
|
915
|
-
"
|
|
916
|
-
"
|
|
917
|
-
"
|
|
953
|
+
"bookAdd": "CUIYUW_bookAdd",
|
|
954
|
+
"dropzone": "CUIYUW_dropzone",
|
|
955
|
+
"toolStepName": "CUIYUW_toolStepName",
|
|
956
|
+
"workflowLabel": "CUIYUW_workflowLabel",
|
|
957
|
+
"bookshelfLabel": "CUIYUW_bookshelfLabel",
|
|
958
|
+
"navAboutUpdate": "CUIYUW_navAboutUpdate",
|
|
959
|
+
"todoInfo": "CUIYUW_todoInfo",
|
|
960
|
+
"shelfGrid": "CUIYUW_shelfGrid",
|
|
961
|
+
"assistantStatusBusy": "CUIYUW_assistantStatusBusy",
|
|
962
|
+
"createBookCard": "CUIYUW_createBookCard",
|
|
963
|
+
"workflowDotActive": "CUIYUW_workflowDotActive",
|
|
964
|
+
"diffChange": "CUIYUW_diffChange",
|
|
965
|
+
"liveText": "CUIYUW_liveText",
|
|
966
|
+
"assetStat": "CUIYUW_assetStat",
|
|
967
|
+
"progressLineDone": "CUIYUW_progressLineDone",
|
|
968
|
+
"entry": "CUIYUW_entry",
|
|
918
969
|
"workflowDot": "CUIYUW_workflowDot",
|
|
919
|
-
"navSpacer": "CUIYUW_navSpacer",
|
|
920
|
-
"fileList": "CUIYUW_fileList",
|
|
921
970
|
"bookAddCard": "CUIYUW_bookAddCard",
|
|
922
|
-
"
|
|
923
|
-
"
|
|
924
|
-
"
|
|
925
|
-
"
|
|
926
|
-
"
|
|
927
|
-
"diffChange": "CUIYUW_diffChange",
|
|
928
|
-
"wsPreviewText": "CUIYUW_wsPreviewText",
|
|
929
|
-
"volumeGroupHeader": "CUIYUW_volumeGroupHeader",
|
|
971
|
+
"wsColumn": "CUIYUW_wsColumn",
|
|
972
|
+
"dashStage": "CUIYUW_dashStage",
|
|
973
|
+
"bookCardCoverTitle": "CUIYUW_bookCardCoverTitle",
|
|
974
|
+
"chapterNum": "CUIYUW_chapterNum",
|
|
975
|
+
"meta": "CUIYUW_meta",
|
|
930
976
|
"toolStepDetail": "CUIYUW_toolStepDetail",
|
|
931
|
-
"
|
|
932
|
-
"
|
|
933
|
-
"toolStepIcon": "CUIYUW_toolStepIcon",
|
|
934
|
-
"legendOld": "CUIYUW_legendOld",
|
|
935
|
-
"bookCardBlurb": "CUIYUW_bookCardBlurb",
|
|
936
|
-
"todoText": "CUIYUW_todoText",
|
|
937
|
-
"progress": "CUIYUW_progress",
|
|
938
|
-
"diffColumn": "CUIYUW_diffColumn",
|
|
939
|
-
"headerProgressDot": "CUIYUW_headerProgressDot",
|
|
940
|
-
"pulse": "CUIYUW_pulse",
|
|
941
|
-
"onlyChanges": "CUIYUW_onlyChanges",
|
|
942
|
-
"diffLegend": "CUIYUW_diffLegend",
|
|
943
|
-
"dashHeroAction": "CUIYUW_dashHeroAction",
|
|
944
|
-
"row": "CUIYUW_row",
|
|
945
|
-
"dashStageDot": "CUIYUW_dashStageDot",
|
|
946
|
-
"card": "CUIYUW_card",
|
|
947
|
-
"createBookCard": "CUIYUW_createBookCard",
|
|
948
|
-
"workflowLabel": "CUIYUW_workflowLabel",
|
|
949
|
-
"bookChipRemove": "CUIYUW_bookChipRemove",
|
|
950
|
-
"dropzone": "CUIYUW_dropzone",
|
|
951
|
-
"input": "CUIYUW_input",
|
|
952
|
-
"workflowDotDone": "CUIYUW_workflowDotDone",
|
|
953
|
-
"dropzoneActive": "CUIYUW_dropzoneActive",
|
|
954
|
-
"panelContent": "CUIYUW_panelContent",
|
|
955
|
-
"toolStepActive": "CUIYUW_toolStepActive",
|
|
956
|
-
"wsPage": "CUIYUW_wsPage",
|
|
957
|
-
"chapterPreview": "CUIYUW_chapterPreview",
|
|
958
|
-
"tabBar": "CUIYUW_tabBar",
|
|
959
|
-
"view": "CUIYUW_view",
|
|
960
|
-
"dashFacts": "CUIYUW_dashFacts",
|
|
961
|
-
"bookCardActive": "CUIYUW_bookCardActive",
|
|
962
|
-
"bookCreateForm": "CUIYUW_bookCreateForm",
|
|
963
|
-
"wsSelectedText": "CUIYUW_wsSelectedText",
|
|
964
|
-
"buttonDanger": "CUIYUW_buttonDanger",
|
|
965
|
-
"diffSame": "CUIYUW_diffSame",
|
|
966
|
-
"panel": "CUIYUW_panel"
|
|
977
|
+
"dashJourney": "CUIYUW_dashJourney",
|
|
978
|
+
"diffColumn": "CUIYUW_diffColumn"
|
|
967
979
|
};
|
|
968
980
|
//#endregion
|
|
969
981
|
//#region src/client/panel/AssistantTab.tsx
|
|
@@ -3446,10 +3458,15 @@ window.__ModuleLoader__.load({
|
|
|
3446
3458
|
label: "大世界",
|
|
3447
3459
|
icon: "🌍"
|
|
3448
3460
|
},
|
|
3461
|
+
{
|
|
3462
|
+
id: "roles",
|
|
3463
|
+
label: "角色库",
|
|
3464
|
+
icon: "👥"
|
|
3465
|
+
},
|
|
3449
3466
|
{
|
|
3450
3467
|
id: "characters",
|
|
3451
3468
|
label: "人物志",
|
|
3452
|
-
icon: "
|
|
3469
|
+
icon: "🧾"
|
|
3453
3470
|
},
|
|
3454
3471
|
{
|
|
3455
3472
|
id: "foreshadow",
|
|
@@ -3500,7 +3517,7 @@ window.__ModuleLoader__.load({
|
|
|
3500
3517
|
label: tt("tab.settings"),
|
|
3501
3518
|
icon: "⚙️"
|
|
3502
3519
|
};
|
|
3503
|
-
const PLUGIN_VERSION = "1.1.
|
|
3520
|
+
const PLUGIN_VERSION = "1.1.5";
|
|
3504
3521
|
/** GitHub 仓库地址(关于区块点击跳转)。 */
|
|
3505
3522
|
const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
|
|
3506
3523
|
/** Whether any chapter is being generated right now. */
|
|
@@ -3850,6 +3867,26 @@ window.__ModuleLoader__.load({
|
|
|
3850
3867
|
const [plotlineDraft, setPlotlineDraft] = (0, react.useState)(null);
|
|
3851
3868
|
/** 角色知情度编辑草稿(角色名 → 文本,每行一条)。 */
|
|
3852
3869
|
const [knowledgeDraft, setKnowledgeDraft] = (0, react.useState)({});
|
|
3870
|
+
/** 角色库:AI 提炼候选(null = 未运行;localStorage 持久化,刷新不丢)。 */
|
|
3871
|
+
const [roleCandidates, setRoleCandidates] = (0, react.useState)(() => {
|
|
3872
|
+
try {
|
|
3873
|
+
const raw = window.localStorage.getItem("dsh-novel-forge.role.candidates");
|
|
3874
|
+
if (raw !== null) {
|
|
3875
|
+
const parsed = JSON.parse(raw);
|
|
3876
|
+
return Array.isArray(parsed) && parsed.length > 0 ? parsed : null;
|
|
3877
|
+
}
|
|
3878
|
+
} catch {}
|
|
3879
|
+
return null;
|
|
3880
|
+
});
|
|
3881
|
+
/** 角色库:编辑草稿(null = 不在编辑)。 */
|
|
3882
|
+
const [roleDraft, setRoleDraft] = (0, react.useState)(null);
|
|
3883
|
+
/** 角色库候选持久化:提炼/采纳后写回 localStorage。 */
|
|
3884
|
+
(0, react.useEffect)(() => {
|
|
3885
|
+
try {
|
|
3886
|
+
if (roleCandidates !== null && roleCandidates.length > 0) window.localStorage.setItem("dsh-novel-forge.role.candidates", JSON.stringify(roleCandidates));
|
|
3887
|
+
else window.localStorage.removeItem("dsh-novel-forge.role.candidates");
|
|
3888
|
+
} catch {}
|
|
3889
|
+
}, [roleCandidates]);
|
|
3853
3890
|
/** 全书敏感词检查结果(null = 未运行)。 */
|
|
3854
3891
|
const [sensHits, setSensHits] = (0, react.useState)(null);
|
|
3855
3892
|
const [sensScanned, setSensScanned] = (0, react.useState)(0);
|
|
@@ -4056,6 +4093,8 @@ window.__ModuleLoader__.load({
|
|
|
4056
4093
|
setConfig(status.config);
|
|
4057
4094
|
setConfigDraft(status.config);
|
|
4058
4095
|
setProject(status.project ?? null);
|
|
4096
|
+
if (status.project?.roleStatus !== void 0) setCharCards(status.project.roleStatus);
|
|
4097
|
+
else setCharCards(null);
|
|
4059
4098
|
setGeneratedFiles(status.generatedFiles);
|
|
4060
4099
|
const withDraft = status.project?.chapters.find((c) => c.pendingDraft !== void 0 && c.pendingDraft !== "");
|
|
4061
4100
|
setDraftNo(withDraft?.no ?? null);
|
|
@@ -4196,6 +4235,28 @@ window.__ModuleLoader__.load({
|
|
|
4196
4235
|
setBusyLabel("");
|
|
4197
4236
|
}
|
|
4198
4237
|
};
|
|
4238
|
+
/** 章节复位:generating 卡死 → pending(可重新生成)。 */
|
|
4239
|
+
const handleChapterReset = async (no) => {
|
|
4240
|
+
setBusy(true);
|
|
4241
|
+
setError("");
|
|
4242
|
+
try {
|
|
4243
|
+
await api.chapterReset(no);
|
|
4244
|
+
setProject((prev) => prev === null ? prev : {
|
|
4245
|
+
...prev,
|
|
4246
|
+
chapters: prev.chapters.map((c) => c.no === no ? {
|
|
4247
|
+
...c,
|
|
4248
|
+
status: "pending",
|
|
4249
|
+
error: void 0
|
|
4250
|
+
} : c)
|
|
4251
|
+
});
|
|
4252
|
+
pushProgress(`第 ${no} 章已复位为待生成,可重新生成`, "info");
|
|
4253
|
+
} catch (err) {
|
|
4254
|
+
setError(err.message);
|
|
4255
|
+
pushProgress(`复位失败:${err.message}`, "error");
|
|
4256
|
+
} finally {
|
|
4257
|
+
setBusy(false);
|
|
4258
|
+
}
|
|
4259
|
+
};
|
|
4199
4260
|
/** 剧情线:保存草稿(新增或更新)。 */
|
|
4200
4261
|
const handlePlotlineSave = async () => {
|
|
4201
4262
|
if (plotlineDraft === null) return;
|
|
@@ -4446,26 +4507,94 @@ window.__ModuleLoader__.load({
|
|
|
4446
4507
|
setBusyLabel("");
|
|
4447
4508
|
}
|
|
4448
4509
|
};
|
|
4449
|
-
/**
|
|
4450
|
-
const
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4510
|
+
/** 角色库:AI 从全书提炼角色候选。 */
|
|
4511
|
+
const handleRolesExtract = async () => {
|
|
4512
|
+
setBusy(true);
|
|
4513
|
+
setBusyLabel("✨ 提炼角色库中…");
|
|
4514
|
+
setError("");
|
|
4515
|
+
try {
|
|
4516
|
+
const result = await api.roles({ op: "extract" });
|
|
4517
|
+
const inLibrary = new Set((project?.roles ?? []).map((r) => r.name));
|
|
4518
|
+
const fresh = (result.candidates ?? []).filter((r) => !inLibrary.has(r.name));
|
|
4519
|
+
setRoleCandidates((prev) => {
|
|
4520
|
+
return [...(prev ?? []).filter((p) => !fresh.some((f) => f.name === p.name)), ...fresh];
|
|
4521
|
+
});
|
|
4522
|
+
pushProgress(`AI 提炼出 ${fresh.length} 个新角色(已排除 ${(result.candidates?.length ?? 0) - fresh.length} 个已收录)`, "done");
|
|
4523
|
+
} catch (err) {
|
|
4524
|
+
setError(err.message);
|
|
4525
|
+
pushProgress(`角色提炼失败:${err.message}`, "error");
|
|
4526
|
+
} finally {
|
|
4527
|
+
setBusy(false);
|
|
4528
|
+
setBusyLabel("");
|
|
4529
|
+
}
|
|
4530
|
+
};
|
|
4531
|
+
/** 角色库:采纳候选(或修改后采纳)。 */
|
|
4532
|
+
const handleRoleAdopt = async (role) => {
|
|
4456
4533
|
setBusy(true);
|
|
4457
4534
|
setError("");
|
|
4458
4535
|
try {
|
|
4459
|
-
const result = await api.
|
|
4460
|
-
|
|
4536
|
+
const result = await api.roles({
|
|
4537
|
+
op: "adopt",
|
|
4538
|
+
role
|
|
4539
|
+
});
|
|
4540
|
+
setProject((prev) => prev === null ? prev : {
|
|
4461
4541
|
...prev,
|
|
4462
|
-
|
|
4542
|
+
roles: result.roles,
|
|
4543
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4544
|
+
});
|
|
4545
|
+
setRoleCandidates((prev) => prev === null ? prev : prev.filter((r) => r !== role));
|
|
4546
|
+
pushProgress(`已加入角色库:${role.name}`, "done");
|
|
4547
|
+
} catch (err) {
|
|
4548
|
+
setError(err.message);
|
|
4549
|
+
} finally {
|
|
4550
|
+
setBusy(false);
|
|
4551
|
+
}
|
|
4552
|
+
};
|
|
4553
|
+
/** 角色库:保存编辑草稿。 */
|
|
4554
|
+
const handleRoleSave = async () => {
|
|
4555
|
+
if (roleDraft === null) return;
|
|
4556
|
+
if (roleDraft.name.trim() === "") {
|
|
4557
|
+
setError("角色名不能为空");
|
|
4558
|
+
return;
|
|
4559
|
+
}
|
|
4560
|
+
setBusy(true);
|
|
4561
|
+
setError("");
|
|
4562
|
+
try {
|
|
4563
|
+
const result = await api.roles({
|
|
4564
|
+
op: "update",
|
|
4565
|
+
role: roleDraft
|
|
4566
|
+
});
|
|
4567
|
+
setProject((prev) => prev === null ? prev : {
|
|
4568
|
+
...prev,
|
|
4569
|
+
roles: result.roles,
|
|
4570
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4571
|
+
});
|
|
4572
|
+
setRoleDraft(null);
|
|
4573
|
+
pushProgress(`角色已保存:${roleDraft.name}`, "done");
|
|
4574
|
+
} catch (err) {
|
|
4575
|
+
setError(err.message);
|
|
4576
|
+
} finally {
|
|
4577
|
+
setBusy(false);
|
|
4578
|
+
}
|
|
4579
|
+
};
|
|
4580
|
+
/** 角色库:删除角色。 */
|
|
4581
|
+
const handleRoleRemove = async (name) => {
|
|
4582
|
+
if (!window.confirm(`确定从角色库删除「${name}」?`)) return;
|
|
4583
|
+
setBusy(true);
|
|
4584
|
+
setError("");
|
|
4585
|
+
try {
|
|
4586
|
+
const result = await api.roles({
|
|
4587
|
+
op: "remove",
|
|
4588
|
+
name
|
|
4589
|
+
});
|
|
4590
|
+
setProject((prev) => prev === null ? prev : {
|
|
4591
|
+
...prev,
|
|
4592
|
+
roles: result.roles,
|
|
4463
4593
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4464
4594
|
});
|
|
4465
|
-
pushProgress(
|
|
4595
|
+
pushProgress(`已从角色库删除:${name}`, "info");
|
|
4466
4596
|
} catch (err) {
|
|
4467
4597
|
setError(err.message);
|
|
4468
|
-
pushProgress(`保存知情度失败:${err.message}`, "error");
|
|
4469
4598
|
} finally {
|
|
4470
4599
|
setBusy(false);
|
|
4471
4600
|
}
|
|
@@ -7339,6 +7468,16 @@ window.__ModuleLoader__.load({
|
|
|
7339
7468
|
},
|
|
7340
7469
|
children: tt("plan.write")
|
|
7341
7470
|
}),
|
|
7471
|
+
chapter.status === "generating" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7472
|
+
type: "button",
|
|
7473
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7474
|
+
disabled: busy,
|
|
7475
|
+
onClick: () => {
|
|
7476
|
+
handleChapterReset(chapter.no);
|
|
7477
|
+
},
|
|
7478
|
+
title: "生成卡死/中断时可复位为待生成,重新生成",
|
|
7479
|
+
children: "🔄 复位"
|
|
7480
|
+
}),
|
|
7342
7481
|
(chapter.status === "written" || chapter.status === "rejected") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7343
7482
|
type: "button",
|
|
7344
7483
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
@@ -7776,80 +7915,445 @@ window.__ModuleLoader__.load({
|
|
|
7776
7915
|
pushProgress(`大世界已保存:${w.realms.length} 境界 · ${w.regions.length} 区域 · ${w.factions.length} 势力`, "done");
|
|
7777
7916
|
}
|
|
7778
7917
|
}),
|
|
7779
|
-
activeTab === "
|
|
7918
|
+
activeTab === "roles" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7780
7919
|
className: panel_module_css_default.card,
|
|
7920
|
+
style: {
|
|
7921
|
+
flex: 1,
|
|
7922
|
+
minHeight: 0
|
|
7923
|
+
},
|
|
7781
7924
|
children: [
|
|
7782
7925
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7783
7926
|
className: panel_module_css_default.row,
|
|
7784
|
-
style: {
|
|
7785
|
-
|
|
7927
|
+
style: {
|
|
7928
|
+
justifyContent: "space-between",
|
|
7929
|
+
flexWrap: "wrap"
|
|
7930
|
+
},
|
|
7931
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7786
7932
|
className: panel_module_css_default.cardTitle,
|
|
7787
|
-
children:
|
|
7788
|
-
|
|
7933
|
+
children: [
|
|
7934
|
+
"👥 角色库(",
|
|
7935
|
+
(project?.roles ?? []).length,
|
|
7936
|
+
" 个)"
|
|
7937
|
+
]
|
|
7938
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7789
7939
|
className: panel_module_css_default.row,
|
|
7790
|
-
children:
|
|
7791
|
-
type: "button",
|
|
7792
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7793
|
-
disabled: busy || doneCount === 0,
|
|
7794
|
-
onClick: () => {
|
|
7795
|
-
handleFactsBackfill();
|
|
7796
|
-
},
|
|
7797
|
-
title: "历史章节(编年录功能上线前生成的)批量抽取事实",
|
|
7798
|
-
children: "📥 回填编年录"
|
|
7799
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7940
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7800
7941
|
type: "button",
|
|
7801
7942
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
7802
|
-
disabled: busy ||
|
|
7943
|
+
disabled: busy || doneCount === 0,
|
|
7803
7944
|
onClick: () => {
|
|
7804
|
-
|
|
7945
|
+
handleRolesExtract();
|
|
7805
7946
|
},
|
|
7806
|
-
|
|
7807
|
-
|
|
7947
|
+
title: "AI 扫描大纲/编年录/已写章节,提炼完整角色库(含女主/女配/反派定位)",
|
|
7948
|
+
children: "✨ 从全书提炼角色"
|
|
7949
|
+
})
|
|
7808
7950
|
})]
|
|
7809
7951
|
}),
|
|
7810
|
-
|
|
7811
|
-
className: panel_module_css_default.meta,
|
|
7812
|
-
children: (project?.facts ?? []).length === 0 ? "暂无编年录(生成章节后自动积累人物状态/境界/资源/关系等事实),刷新按钮将在有事实后可用。" : "点击「从编年录刷新」聚合各人物当前状态(境界/资源/伤势/心境)。"
|
|
7813
|
-
}) : charCards.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7952
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7814
7953
|
className: panel_module_css_default.meta,
|
|
7815
|
-
children: "
|
|
7816
|
-
})
|
|
7954
|
+
children: "角色库是全书角色主表:定位(女主/女配/配角/反派)、身份、关系网、成长线、知情度——生成与审稿都会按定位规格刻画互动。"
|
|
7955
|
+
}),
|
|
7956
|
+
roleCandidates !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7817
7957
|
style: {
|
|
7818
7958
|
display: "flex",
|
|
7819
7959
|
flexDirection: "column",
|
|
7820
|
-
gap: 6
|
|
7960
|
+
gap: 6,
|
|
7961
|
+
border: "1px solid var(--nf-info)",
|
|
7962
|
+
borderRadius: 12,
|
|
7963
|
+
padding: 10
|
|
7821
7964
|
},
|
|
7822
|
-
children:
|
|
7823
|
-
|
|
7824
|
-
border: "1px solid var(--nf-border)",
|
|
7825
|
-
borderRadius: 8,
|
|
7826
|
-
padding: "6px 10px",
|
|
7827
|
-
fontSize: 12
|
|
7828
|
-
},
|
|
7829
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7965
|
+
children: [
|
|
7966
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7830
7967
|
className: panel_module_css_default.row,
|
|
7831
|
-
style: {
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7968
|
+
style: {
|
|
7969
|
+
justifyContent: "space-between",
|
|
7970
|
+
flexWrap: "wrap"
|
|
7971
|
+
},
|
|
7972
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
7973
|
+
"✨ AI 提炼候选(",
|
|
7974
|
+
roleCandidates.length,
|
|
7975
|
+
")"
|
|
7976
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7977
|
+
type: "button",
|
|
7978
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7979
|
+
onClick: () => {
|
|
7980
|
+
setRoleCandidates(null);
|
|
7981
|
+
},
|
|
7982
|
+
children: "收起"
|
|
7842
7983
|
})]
|
|
7843
|
-
}),
|
|
7984
|
+
}),
|
|
7985
|
+
roleCandidates.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7844
7986
|
className: panel_module_css_default.meta,
|
|
7845
|
-
children:
|
|
7846
|
-
})
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7987
|
+
children: "未提炼到角色。"
|
|
7988
|
+
}),
|
|
7989
|
+
roleCandidates.map((r, i) => {
|
|
7990
|
+
const label = {
|
|
7991
|
+
protagonist: "主角",
|
|
7992
|
+
female_lead: "女主",
|
|
7993
|
+
female_support: "女配",
|
|
7994
|
+
support: "配角",
|
|
7995
|
+
antagonist: "反派",
|
|
7996
|
+
extra: "路人"
|
|
7997
|
+
}[r.roleLabel];
|
|
7998
|
+
const color = r.roleLabel === "protagonist" ? "var(--nf-success)" : r.roleLabel === "female_lead" ? "var(--nf-accent)" : r.roleLabel === "antagonist" ? "var(--nf-error)" : "var(--nf-text-3)";
|
|
7999
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8000
|
+
style: {
|
|
8001
|
+
border: "1px solid var(--nf-border)",
|
|
8002
|
+
borderRadius: 8,
|
|
8003
|
+
padding: "6px 10px",
|
|
8004
|
+
fontSize: 12
|
|
8005
|
+
},
|
|
8006
|
+
children: [
|
|
8007
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8008
|
+
className: panel_module_css_default.row,
|
|
8009
|
+
style: {
|
|
8010
|
+
justifyContent: "space-between",
|
|
8011
|
+
flexWrap: "wrap"
|
|
8012
|
+
},
|
|
8013
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8014
|
+
style: {
|
|
8015
|
+
display: "flex",
|
|
8016
|
+
alignItems: "center",
|
|
8017
|
+
gap: 6,
|
|
8018
|
+
flexWrap: "wrap"
|
|
8019
|
+
},
|
|
8020
|
+
children: [
|
|
8021
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: r.name }),
|
|
8022
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8023
|
+
className: panel_module_css_default.badge,
|
|
8024
|
+
style: {
|
|
8025
|
+
borderColor: color,
|
|
8026
|
+
color
|
|
8027
|
+
},
|
|
8028
|
+
children: label
|
|
8029
|
+
}),
|
|
8030
|
+
r.identity !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8031
|
+
className: panel_module_css_default.meta,
|
|
8032
|
+
children: r.identity
|
|
8033
|
+
})
|
|
8034
|
+
]
|
|
8035
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8036
|
+
style: {
|
|
8037
|
+
display: "flex",
|
|
8038
|
+
gap: 6
|
|
8039
|
+
},
|
|
8040
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8041
|
+
type: "button",
|
|
8042
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8043
|
+
disabled: busy,
|
|
8044
|
+
onClick: () => {
|
|
8045
|
+
handleRoleAdopt(r);
|
|
8046
|
+
},
|
|
8047
|
+
children: "+ 采纳"
|
|
8048
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8049
|
+
type: "button",
|
|
8050
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8051
|
+
disabled: busy,
|
|
8052
|
+
onClick: () => {
|
|
8053
|
+
setRoleDraft(r);
|
|
8054
|
+
},
|
|
8055
|
+
title: "修改后再采纳(候选列表保留)",
|
|
8056
|
+
children: "✏️ 修改后采纳"
|
|
8057
|
+
})]
|
|
8058
|
+
})]
|
|
8059
|
+
}),
|
|
8060
|
+
r.goals !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8061
|
+
className: panel_module_css_default.meta,
|
|
8062
|
+
children: ["目标:", r.goals]
|
|
8063
|
+
}),
|
|
8064
|
+
r.relations.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8065
|
+
className: panel_module_css_default.meta,
|
|
8066
|
+
children: ["关系:", r.relations.join("、")]
|
|
8067
|
+
})
|
|
8068
|
+
]
|
|
8069
|
+
}, i);
|
|
8070
|
+
})
|
|
8071
|
+
]
|
|
8072
|
+
}),
|
|
8073
|
+
roleDraft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8074
|
+
style: {
|
|
8075
|
+
display: "flex",
|
|
8076
|
+
flexDirection: "column",
|
|
8077
|
+
gap: 8,
|
|
8078
|
+
border: "1px solid var(--nf-accent)",
|
|
8079
|
+
borderRadius: 12,
|
|
8080
|
+
padding: 10
|
|
8081
|
+
},
|
|
8082
|
+
children: [
|
|
8083
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8084
|
+
className: panel_module_css_default.row,
|
|
8085
|
+
style: { flexWrap: "wrap" },
|
|
8086
|
+
children: [
|
|
8087
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8088
|
+
className: panel_module_css_default.field,
|
|
8089
|
+
style: {
|
|
8090
|
+
flex: 1,
|
|
8091
|
+
minWidth: 140
|
|
8092
|
+
},
|
|
8093
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8094
|
+
className: panel_module_css_default.fieldLabel,
|
|
8095
|
+
children: "角色名"
|
|
8096
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8097
|
+
className: panel_module_css_default.input,
|
|
8098
|
+
value: roleDraft.name,
|
|
8099
|
+
onChange: (e) => {
|
|
8100
|
+
setRoleDraft({
|
|
8101
|
+
...roleDraft,
|
|
8102
|
+
name: e.target.value
|
|
8103
|
+
});
|
|
8104
|
+
}
|
|
8105
|
+
})]
|
|
8106
|
+
}),
|
|
8107
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8108
|
+
className: panel_module_css_default.field,
|
|
8109
|
+
style: { flex: 1 },
|
|
8110
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8111
|
+
className: panel_module_css_default.fieldLabel,
|
|
8112
|
+
children: "定位"
|
|
8113
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
8114
|
+
className: panel_module_css_default.input,
|
|
8115
|
+
value: roleDraft.roleLabel,
|
|
8116
|
+
onChange: (e) => {
|
|
8117
|
+
setRoleDraft({
|
|
8118
|
+
...roleDraft,
|
|
8119
|
+
roleLabel: e.target.value
|
|
8120
|
+
});
|
|
8121
|
+
},
|
|
8122
|
+
children: [
|
|
8123
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8124
|
+
value: "protagonist",
|
|
8125
|
+
children: "主角"
|
|
8126
|
+
}),
|
|
8127
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8128
|
+
value: "female_lead",
|
|
8129
|
+
children: "女主"
|
|
8130
|
+
}),
|
|
8131
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8132
|
+
value: "female_support",
|
|
8133
|
+
children: "女配"
|
|
8134
|
+
}),
|
|
8135
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8136
|
+
value: "support",
|
|
8137
|
+
children: "配角"
|
|
8138
|
+
}),
|
|
8139
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8140
|
+
value: "antagonist",
|
|
8141
|
+
children: "反派"
|
|
8142
|
+
}),
|
|
8143
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8144
|
+
value: "extra",
|
|
8145
|
+
children: "路人"
|
|
8146
|
+
})
|
|
8147
|
+
]
|
|
8148
|
+
})]
|
|
8149
|
+
}),
|
|
8150
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8151
|
+
className: panel_module_css_default.field,
|
|
8152
|
+
style: { flex: 2 },
|
|
8153
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8154
|
+
className: panel_module_css_default.fieldLabel,
|
|
8155
|
+
children: "身份"
|
|
8156
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8157
|
+
className: panel_module_css_default.input,
|
|
8158
|
+
value: roleDraft.identity,
|
|
8159
|
+
onChange: (e) => {
|
|
8160
|
+
setRoleDraft({
|
|
8161
|
+
...roleDraft,
|
|
8162
|
+
identity: e.target.value
|
|
8163
|
+
});
|
|
8164
|
+
}
|
|
8165
|
+
})]
|
|
8166
|
+
})
|
|
8167
|
+
]
|
|
8168
|
+
}),
|
|
8169
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8170
|
+
className: panel_module_css_default.field,
|
|
8171
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8172
|
+
className: panel_module_css_default.fieldLabel,
|
|
8173
|
+
children: "目标"
|
|
8174
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8175
|
+
className: panel_module_css_default.textarea,
|
|
8176
|
+
style: { minHeight: 44 },
|
|
8177
|
+
value: roleDraft.goals,
|
|
8178
|
+
onChange: (e) => {
|
|
8179
|
+
setRoleDraft({
|
|
8180
|
+
...roleDraft,
|
|
8181
|
+
goals: e.target.value
|
|
8182
|
+
});
|
|
8183
|
+
}
|
|
8184
|
+
})]
|
|
8185
|
+
}),
|
|
8186
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8187
|
+
className: panel_module_css_default.field,
|
|
8188
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8189
|
+
className: panel_module_css_default.fieldLabel,
|
|
8190
|
+
children: "关系网(每行一条:角色名(关系))"
|
|
8191
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8192
|
+
className: panel_module_css_default.textarea,
|
|
8193
|
+
style: { minHeight: 44 },
|
|
8194
|
+
value: roleDraft.relations.join("\n"),
|
|
8195
|
+
onChange: (e) => {
|
|
8196
|
+
setRoleDraft({
|
|
8197
|
+
...roleDraft,
|
|
8198
|
+
relations: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8199
|
+
});
|
|
8200
|
+
}
|
|
8201
|
+
})]
|
|
8202
|
+
}),
|
|
8203
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8204
|
+
className: panel_module_css_default.field,
|
|
8205
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8206
|
+
className: panel_module_css_default.fieldLabel,
|
|
8207
|
+
children: "成长线(每行一条:阶段:说明)"
|
|
8208
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8209
|
+
className: panel_module_css_default.textarea,
|
|
8210
|
+
style: { minHeight: 44 },
|
|
8211
|
+
value: roleDraft.arc.join("\n"),
|
|
8212
|
+
onChange: (e) => {
|
|
8213
|
+
setRoleDraft({
|
|
8214
|
+
...roleDraft,
|
|
8215
|
+
arc: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8216
|
+
});
|
|
8217
|
+
}
|
|
8218
|
+
})]
|
|
8219
|
+
}),
|
|
8220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8221
|
+
className: panel_module_css_default.field,
|
|
8222
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8223
|
+
className: panel_module_css_default.fieldLabel,
|
|
8224
|
+
children: "知情度(每行一条该角色知道的信息)"
|
|
8225
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8226
|
+
className: panel_module_css_default.textarea,
|
|
8227
|
+
style: { minHeight: 44 },
|
|
8228
|
+
value: roleDraft.knowledge.join("\n"),
|
|
8229
|
+
onChange: (e) => {
|
|
8230
|
+
setRoleDraft({
|
|
8231
|
+
...roleDraft,
|
|
8232
|
+
knowledge: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8233
|
+
});
|
|
8234
|
+
}
|
|
8235
|
+
})]
|
|
8236
|
+
}),
|
|
8237
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8238
|
+
className: panel_module_css_default.row,
|
|
8239
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8240
|
+
type: "button",
|
|
8241
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8242
|
+
disabled: busy,
|
|
8243
|
+
onClick: () => {
|
|
8244
|
+
handleRoleSave();
|
|
8245
|
+
},
|
|
8246
|
+
children: "保存"
|
|
8247
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8248
|
+
type: "button",
|
|
8249
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8250
|
+
onClick: () => {
|
|
8251
|
+
setRoleDraft(null);
|
|
8252
|
+
},
|
|
8253
|
+
children: "取消"
|
|
8254
|
+
})]
|
|
8255
|
+
})
|
|
8256
|
+
]
|
|
8257
|
+
}),
|
|
8258
|
+
(project?.roles ?? []).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8259
|
+
className: panel_module_css_default.meta,
|
|
8260
|
+
children: "角色库为空——点「✨ 从全书提炼角色」自动建立,或手动新增。"
|
|
8261
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8262
|
+
style: {
|
|
8263
|
+
display: "flex",
|
|
8264
|
+
flexDirection: "column",
|
|
8265
|
+
gap: 6
|
|
8266
|
+
},
|
|
8267
|
+
children: (project?.roles ?? []).map((r) => {
|
|
8268
|
+
const label = {
|
|
8269
|
+
protagonist: "主角",
|
|
8270
|
+
female_lead: "女主",
|
|
8271
|
+
female_support: "女配",
|
|
8272
|
+
support: "配角",
|
|
8273
|
+
antagonist: "反派",
|
|
8274
|
+
extra: "路人"
|
|
8275
|
+
}[r.roleLabel];
|
|
8276
|
+
const color = r.roleLabel === "protagonist" ? "var(--nf-success)" : r.roleLabel === "female_lead" ? "var(--nf-accent)" : r.roleLabel === "antagonist" ? "var(--nf-error)" : "var(--nf-text-3)";
|
|
8277
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8278
|
+
style: {
|
|
8279
|
+
border: "1px solid var(--nf-border)",
|
|
8280
|
+
borderRadius: 8,
|
|
8281
|
+
padding: "6px 10px",
|
|
8282
|
+
fontSize: 12
|
|
8283
|
+
},
|
|
8284
|
+
children: [
|
|
8285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8286
|
+
className: panel_module_css_default.row,
|
|
8287
|
+
style: {
|
|
8288
|
+
justifyContent: "space-between",
|
|
8289
|
+
flexWrap: "wrap"
|
|
8290
|
+
},
|
|
8291
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8292
|
+
style: {
|
|
8293
|
+
display: "flex",
|
|
8294
|
+
alignItems: "center",
|
|
8295
|
+
gap: 6,
|
|
8296
|
+
flexWrap: "wrap"
|
|
8297
|
+
},
|
|
8298
|
+
children: [
|
|
8299
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: r.name }),
|
|
8300
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8301
|
+
className: panel_module_css_default.badge,
|
|
8302
|
+
style: {
|
|
8303
|
+
borderColor: color,
|
|
8304
|
+
color
|
|
8305
|
+
},
|
|
8306
|
+
children: label
|
|
8307
|
+
}),
|
|
8308
|
+
r.identity !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8309
|
+
className: panel_module_css_default.meta,
|
|
8310
|
+
children: r.identity
|
|
8311
|
+
})
|
|
8312
|
+
]
|
|
8313
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8314
|
+
style: {
|
|
8315
|
+
display: "flex",
|
|
8316
|
+
gap: 6
|
|
8317
|
+
},
|
|
8318
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8319
|
+
type: "button",
|
|
8320
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8321
|
+
disabled: busy,
|
|
8322
|
+
onClick: () => {
|
|
8323
|
+
setRoleDraft(r);
|
|
8324
|
+
},
|
|
8325
|
+
children: "编辑"
|
|
8326
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8327
|
+
type: "button",
|
|
8328
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8329
|
+
disabled: busy,
|
|
8330
|
+
onClick: () => {
|
|
8331
|
+
handleRoleRemove(r.name);
|
|
8332
|
+
},
|
|
8333
|
+
children: "删除"
|
|
8334
|
+
})]
|
|
8335
|
+
})]
|
|
8336
|
+
}),
|
|
8337
|
+
r.goals !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8338
|
+
className: panel_module_css_default.meta,
|
|
8339
|
+
children: ["目标:", r.goals]
|
|
8340
|
+
}),
|
|
8341
|
+
r.relations.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8342
|
+
className: panel_module_css_default.meta,
|
|
8343
|
+
children: ["关系:", r.relations.join("、")]
|
|
8344
|
+
}),
|
|
8345
|
+
r.arc.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8346
|
+
className: panel_module_css_default.meta,
|
|
8347
|
+
children: ["成长线:", r.arc.join(" → ")]
|
|
8348
|
+
}),
|
|
8349
|
+
r.knowledge.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8350
|
+
className: panel_module_css_default.meta,
|
|
8351
|
+
children: ["知情度:", r.knowledge.join(";")]
|
|
8352
|
+
})
|
|
8353
|
+
]
|
|
8354
|
+
}, r.name);
|
|
8355
|
+
})
|
|
8356
|
+
})
|
|
7853
8357
|
]
|
|
7854
8358
|
}),
|
|
7855
8359
|
activeTab === "characters" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -7857,66 +8361,90 @@ window.__ModuleLoader__.load({
|
|
|
7857
8361
|
children: [
|
|
7858
8362
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7859
8363
|
className: panel_module_css_default.row,
|
|
7860
|
-
style: {
|
|
7861
|
-
justifyContent: "space-between",
|
|
7862
|
-
flexWrap: "wrap"
|
|
7863
|
-
},
|
|
8364
|
+
style: { justifyContent: "space-between" },
|
|
7864
8365
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7865
8366
|
className: panel_module_css_default.cardTitle,
|
|
7866
|
-
children: "
|
|
7867
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
8367
|
+
children: "人物志(当前状态)"
|
|
8368
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8369
|
+
className: panel_module_css_default.row,
|
|
8370
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8371
|
+
type: "button",
|
|
8372
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8373
|
+
disabled: busy || doneCount === 0,
|
|
8374
|
+
onClick: () => {
|
|
8375
|
+
handleFactsBackfill();
|
|
8376
|
+
},
|
|
8377
|
+
title: "历史章节(编年录功能上线前生成的)批量抽取事实",
|
|
8378
|
+
children: "📥 回填编年录"
|
|
8379
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8380
|
+
type: "button",
|
|
8381
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8382
|
+
disabled: busy || (project?.facts ?? []).length === 0,
|
|
8383
|
+
onClick: () => {
|
|
8384
|
+
handleCharactersRefresh();
|
|
8385
|
+
},
|
|
8386
|
+
children: "↻ 从编年录刷新"
|
|
8387
|
+
})]
|
|
7875
8388
|
})]
|
|
7876
8389
|
}),
|
|
7877
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8390
|
+
charCards === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7878
8391
|
className: panel_module_css_default.meta,
|
|
7879
|
-
children: "
|
|
7880
|
-
}),
|
|
7881
|
-
(bible?.characters ?? []).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8392
|
+
children: (project?.facts ?? []).length === 0 ? "暂无编年录(生成章节后自动积累人物状态/境界/资源/关系等事实),刷新按钮将在有事实后可用。" : "点击「从编年录刷新」聚合各人物当前状态(境界/资源/伤势/心境)。"
|
|
8393
|
+
}) : charCards.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7882
8394
|
className: panel_module_css_default.meta,
|
|
7883
|
-
children: "
|
|
8395
|
+
children: "未识别到人物信息。"
|
|
7884
8396
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7885
8397
|
style: {
|
|
7886
8398
|
display: "flex",
|
|
7887
8399
|
flexDirection: "column",
|
|
7888
|
-
gap:
|
|
8400
|
+
gap: 6
|
|
7889
8401
|
},
|
|
7890
|
-
children:
|
|
8402
|
+
children: charCards.map((card) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7891
8403
|
style: {
|
|
7892
8404
|
border: "1px solid var(--nf-border)",
|
|
7893
|
-
borderRadius:
|
|
7894
|
-
padding: "
|
|
8405
|
+
borderRadius: 8,
|
|
8406
|
+
padding: "6px 10px",
|
|
7895
8407
|
fontSize: 12
|
|
7896
8408
|
},
|
|
7897
|
-
children: [
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
8409
|
+
children: [
|
|
8410
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8411
|
+
className: panel_module_css_default.row,
|
|
8412
|
+
style: { justifyContent: "space-between" },
|
|
8413
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: card.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8414
|
+
className: panel_module_css_default.meta,
|
|
8415
|
+
children: [
|
|
8416
|
+
card.role === "protagonist" ? "主角" : card.role === "supporting" ? "配角" : card.role === "antagonist" ? "反派" : "其他",
|
|
8417
|
+
" · 出场 ",
|
|
8418
|
+
card.appearances,
|
|
8419
|
+
" 次 · 最近 第 ",
|
|
8420
|
+
card.lastChapter,
|
|
8421
|
+
" 章"
|
|
8422
|
+
]
|
|
8423
|
+
})]
|
|
8424
|
+
}),
|
|
8425
|
+
card.status !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7901
8426
|
className: panel_module_css_default.meta,
|
|
7902
|
-
children:
|
|
7903
|
-
})
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
})]
|
|
8427
|
+
children: ["状态:", card.status]
|
|
8428
|
+
}),
|
|
8429
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8430
|
+
className: panel_module_css_default.row,
|
|
8431
|
+
style: { marginTop: 4 },
|
|
8432
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8433
|
+
type: "button",
|
|
8434
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8435
|
+
onClick: () => {
|
|
8436
|
+
setActiveTab("roles");
|
|
8437
|
+
},
|
|
8438
|
+
title: "在角色库中查看/编辑该角色档案",
|
|
8439
|
+
children: "📖 查看档案"
|
|
8440
|
+
})
|
|
8441
|
+
})
|
|
8442
|
+
]
|
|
7919
8443
|
}, card.name))
|
|
8444
|
+
}),
|
|
8445
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8446
|
+
className: panel_module_css_default.meta,
|
|
8447
|
+
children: "人物志由「道藏」人物名单 + 「编年录」聚合而来,随章节生成自动保持最新。"
|
|
7920
8448
|
})
|
|
7921
8449
|
]
|
|
7922
8450
|
}),
|