Skip to content

Commit 47b9614

Browse files
committed
fix: 修复无法导出纯文本的问题
1 parent 5583ac9 commit 47b9614

File tree

7 files changed

+135
-14
lines changed

7 files changed

+135
-14
lines changed

app/src/components/ui/dialog.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ Dialog.copy = (title = "导出成功", description = "", value = ""): Promise<vo
305305
<DialogHeader>
306306
<DialogTitle>{title}</DialogTitle>
307307
<DialogDescription>{description}</DialogDescription>
308-
<Textarea value={value} />
308+
{/* <Textarea value={value} style={{ height: "300px", minHeigt: "600px" }} /> */}
309+
<pre className="max-h-64 select-text overflow-y-auto rounded-md border p-2">{value}</pre>
309310
<DialogFooter>
310311
<Button
311312
variant="outline"

app/src/core/service/GlobalMenu.tsx

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,19 +277,62 @@ export function GlobalMenu() {
277277
{t("file.plainText")}
278278
</SubTrigger>
279279
<SubContent>
280+
{/* 导出 全部 网状关系 */}
280281
<Item
281282
onClick={() => {
282-
const entities = activeProject!.stageManager.getEntities();
283-
const result = activeProject!.stageExport.getPlainTextByEntities(entities);
283+
if (!activeProject) {
284+
toast.warning(t("file.noProject"));
285+
return;
286+
}
287+
const entities = activeProject.stageManager.getEntities();
288+
const result = activeProject.stageExport.getPlainTextByEntities(entities);
284289
Dialog.copy(t("file.exportSuccess"), "", result);
285290
}}
286291
>
287292
<FileDigit />
288-
{t("file.exportAll")}
293+
{t("file.plainTextType.exportAllNodeGraph")}
289294
</Item>
290-
<Item>
295+
{/* 导出 选中 网状关系 */}
296+
<Item
297+
onClick={() => {
298+
if (!activeProject) {
299+
toast.warning(t("file.noProject"));
300+
return;
301+
}
302+
const entities = activeProject.stageManager.getEntities();
303+
const selectedEntities = entities.filter((entity) => entity.isSelected);
304+
const result = activeProject.stageExport.getPlainTextByEntities(selectedEntities);
305+
Dialog.copy(t("file.exportSuccess"), "", result);
306+
}}
307+
>
291308
<MousePointer2 />
292-
{t("file.exportSelected")}
309+
{t("file.plainTextType.exportSelectedNodeGraph")}
310+
</Item>
311+
{/* 导出 选中 树状关系 (纯文本缩进) */}
312+
<Item
313+
onClick={() => {
314+
const textNode = getOneSelectedTextNodeWhenExportingPlainText(activeProject);
315+
if (textNode) {
316+
const result = activeProject!.stageExport.getTabStringByTextNode(textNode);
317+
Dialog.copy(t("file.exportSuccess"), "", result);
318+
}
319+
}}
320+
>
321+
<MousePointer2 />
322+
{t("file.plainTextType.exportSelectedNodeTree")}
323+
</Item>
324+
{/* 导出 选中 树状关系 (Markdown格式) */}
325+
<Item
326+
onClick={() => {
327+
const textNode = getOneSelectedTextNodeWhenExportingPlainText(activeProject);
328+
if (textNode) {
329+
const result = activeProject!.stageExport.getMarkdownStringByTextNode(textNode);
330+
Dialog.copy(t("file.exportSuccess"), "", result);
331+
}
332+
}}
333+
>
334+
<MousePointer2 />
335+
{t("file.plainTextType.exportSelectedNodeTreeMarkdown")}
293336
</Item>
294337
</SubContent>
295338
</Sub>
@@ -868,3 +911,36 @@ export async function onOpenFile(uri?: URI, source: string = "unknown") {
868911
},
869912
);
870913
}
914+
915+
/**
916+
* 获取唯一选中的文本节点,用于导出纯文本时。
917+
* 如果不符合情况就提前弹窗错误,并返回null
918+
* @param activeProject
919+
* @returns
920+
*/
921+
function getOneSelectedTextNodeWhenExportingPlainText(activeProject: Project | undefined): TextNode | null {
922+
if (!activeProject) {
923+
toast.warning("请先打开工程文件");
924+
return null;
925+
}
926+
const entities = activeProject.stageManager.getEntities();
927+
const selectedEntities = entities.filter((entity) => entity.isSelected);
928+
if (selectedEntities.length === 0) {
929+
toast.warning("没有选中节点");
930+
return null;
931+
} else if (selectedEntities.length === 1) {
932+
const result = selectedEntities[0];
933+
if (!(result instanceof TextNode)) {
934+
toast.warning("必须选中文本节点,而不是其他类型的节点");
935+
return null;
936+
}
937+
if (!activeProject.graphMethods.isTree(result)) {
938+
toast.warning("不符合树形结构");
939+
return null;
940+
}
941+
return result;
942+
} else {
943+
toast.warning(`只能选择一个节点,你选中了${selectedEntities.length}个节点`);
944+
return null;
945+
}
946+
}

app/src/core/service/dataGenerateService/stageExportEngine/stageExportEngine.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Project, service } from "@/core/Project";
22
import { ConnectableEntity } from "@/core/stage/stageObject/abstract/ConnectableEntity";
33
import { Entity } from "@/core/stage/stageObject/abstract/StageEntity";
44
import { TextNode } from "@/core/stage/stageObject/entity/TextNode";
5+
import { EntityDetailsTool } from "../../dataManageService/entityDetailsService/entityDetailsTool";
56

67
/**
78
* 专注于导出各种格式内容的引擎
@@ -32,8 +33,8 @@ export class StageExport {
3233
continue;
3334
}
3435
nodesContent += node.text + "\n";
35-
if (node.details.trim()) {
36-
nodesContent += "\t" + node.details + "\n";
36+
if (EntityDetailsTool.from(node).isNotEmpty()) {
37+
nodesContent += "\t" + EntityDetailsTool.from(node).toMarkdown() + "\n";
3738
}
3839
const childTextNodes = this.project.graphMethods
3940
.nodeChildrenArray(node)
@@ -125,17 +126,17 @@ export class StageExport {
125126
} else {
126127
stringResult += `**${node.text}**\n\n`;
127128
}
128-
if (node.details.trim()) {
129-
stringResult += `${node.details}\n\n`;
129+
if (EntityDetailsTool.from(node).isNotEmpty()) {
130+
stringResult += `${EntityDetailsTool.from(node).toMarkdown()}\n\n`;
130131
}
131132
return stringResult;
132133
}
133134

134135
private getTabText(node: TextNode, level: number): string {
135136
let stringResult = "";
136137
stringResult += `${"\t".repeat(Math.max(level - 1, 0))}${node.text}\n`;
137-
if (node.details.trim()) {
138-
stringResult += `${"\t".repeat(level)}${node.details}\n`;
138+
if (EntityDetailsTool.from(node).isNotEmpty()) {
139+
stringResult += `${"\t".repeat(level)}${EntityDetailsTool.from(node).toMarkdown()}\n`;
139140
}
140141
return stringResult;
141142
}

app/src/core/service/dataManageService/copyEngine/copyEngineText.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ export class CopyEngineText {
6969
// 只是普通的文本
7070
if (item.length > 3000) {
7171
entity = new TextNode(this.project, {
72-
text: "粘贴板文字过长(超过3000字符),已写入节点详细信息",
72+
text: "粘贴板文字过长(超过3000字符),已写入节点详细信息,但详细信息目前还在重构中",
7373
collisionBox,
7474
// [ { type: 'p', children: [{ text: 'Serialize just this paragraph.' }] },
75-
details: item.split("\n").map((line) => ({ type: "p", children: [{ text: line }] })),
75+
// details: item.split("\n").map((line) => ({ type: "p", children: [{ text: line }] })),
76+
// TODO: 将超长文本写入详细信息
7677
});
7778
} else {
7879
entity = new TextNode(this.project, {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Entity } from "@/core/stage/stageObject/abstract/StageEntity";
2+
3+
export class EntityDetailsTool {
4+
private entity: Entity;
5+
6+
constructor(entity: Entity) {
7+
this.entity = entity;
8+
}
9+
10+
static from(entity: Entity): EntityDetailsTool {
11+
return new EntityDetailsTool(entity);
12+
}
13+
14+
isEmpty(): boolean {
15+
return this.entity.details.length === 0;
16+
}
17+
18+
isNotEmpty(): boolean {
19+
return this.entity.details.length > 0;
20+
}
21+
22+
toMarkdown(): string {
23+
console.log(this.entity.details);
24+
let result = "";
25+
for (const p of this.entity.details) {
26+
if (p.type === "") {
27+
result += p.value;
28+
}
29+
}
30+
return result;
31+
}
32+
}

app/src/locales/en.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,11 @@ globalMenu:
637637
export: Export
638638
exportAsSVG: Export as SVG
639639
exportAll: Export All Content
640+
plainTextType:
641+
exportAllNodeGraph: Export All Node Graph as Plain Text
642+
exportSelectedNodeGraph: Export Selected Node Graph as Plain Text
643+
exportSelectedNodeTree: Export Selected Node Tree as Plain Text
644+
exportSelectedNodeTreeMarkdown: Export Selected Node Tree as Markdown
640645
exportSelected: Export Selected Content
641646
plainText: Plain Text
642647
exportSuccess: Export Successful

app/src/locales/zh_CN.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ globalMenu:
2020
export: 导出
2121
exportAsSVG: 导出为 SVG
2222
exportAll: 导出全部内容
23+
plainTextType:
24+
exportAllNodeGraph: 导出 全部的 网状关系
25+
exportSelectedNodeGraph: 导出 选中的 网状关系
26+
exportSelectedNodeTree: 导出 选中的 树状关系(纯文本缩进)
27+
exportSelectedNodeTreeMarkdown: 导出 选中的 树状关系(Markdown格式)
2328
exportSelected: 导出选中内容
2429
plainText: 纯文本
2530
exportSuccess: 导出成功

0 commit comments

Comments
 (0)