use requestAnimationFrame for hover popup

This commit is contained in:
taDuc
2026-05-27 03:18:11 +07:00
parent 184abb25b4
commit 3d21d078cf
33 changed files with 2210 additions and 423 deletions
+173 -218
View File
@@ -409,8 +409,7 @@ function EditorPageContent() {
const [previewWikiError, setPreviewWikiError] = useState<string | null>(null); const [previewWikiError, setPreviewWikiError] = useState<string | null>(null);
// State loading riêng cho wiki preview sidebar. // State loading riêng cho wiki preview sidebar.
const [isPreviewWikiLoading, setIsPreviewWikiLoading] = useState(false); const [isPreviewWikiLoading, setIsPreviewWikiLoading] = useState(false);
const [previewFeaturePopupAnchor, setPreviewFeaturePopupAnchor] = useState<MapFeaturePayload | null>(null); const [previewPinnedWikiPopupAnchor, setPreviewPinnedWikiPopupAnchor] = useState<MapFeaturePayload | null>(null);
const [previewExpandedEntityId, setPreviewExpandedEntityId] = useState<string | null>(null);
const [previewActiveEntityId, setPreviewActiveEntityId] = useState<string | null>(null); const [previewActiveEntityId, setPreviewActiveEntityId] = useState<string | null>(null);
const [isPreviewEntitySidebarOpen, setIsPreviewEntitySidebarOpen] = useState(false); const [isPreviewEntitySidebarOpen, setIsPreviewEntitySidebarOpen] = useState(false);
const [focusedPresentPlace, setFocusedPresentPlace] = useState<PresentPlaceSelection | null>(null); const [focusedPresentPlace, setFocusedPresentPlace] = useState<PresentPlaceSelection | null>(null);
@@ -422,7 +421,7 @@ function EditorPageContent() {
}); });
const [isGlobalLoading, setIsGlobalLoading] = useState(false); const [isGlobalLoading, setIsGlobalLoading] = useState(false);
const [previewLinkEntityPopup, setPreviewLinkEntityPopup] = useState<PreviewLinkEntityPopupState | null>(null); const [previewLinkEntityPopup, setPreviewLinkEntityPopup] = useState<PreviewLinkEntityPopupState | null>(null);
const [previewEntityFocusToken, setPreviewEntityFocusToken] = useState(0); const [previewEntityFocusToken, setPreviewEntityFocusToken] = useState<number | null>(null);
const [previewSidebarWidth, setPreviewSidebarWidth] = useState<number>(() => { const [previewSidebarWidth, setPreviewSidebarWidth] = useState<number>(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const saved = localStorage.getItem("public-wiki-sidebar-width"); const saved = localStorage.getItem("public-wiki-sidebar-width");
@@ -442,6 +441,7 @@ function EditorPageContent() {
// Ref giữ object URL hiện tại để revoke khi đổi/xóa ảnh, tránh leak bộ nhớ. // Ref giữ object URL hiện tại để revoke khi đổi/xóa ảnh, tránh leak bộ nhớ.
const imageOverlayObjectUrlRef = useRef<string | null>(null); const imageOverlayObjectUrlRef = useRef<string | null>(null);
const previewLinkEntityPopupRef = useRef<HTMLDivElement | null>(null); const previewLinkEntityPopupRef = useRef<HTMLDivElement | null>(null);
const previewPinnedWikiPopupRef = useRef<HTMLDivElement | null>(null);
// Cập nhật stage/step được chọn trong sidebar replay. // Cập nhật stage/step được chọn trong sidebar replay.
const handleReplaySelectionChange = useCallback((stageId: number | null, stepIndex: number | null) => { const handleReplaySelectionChange = useCallback((stageId: number | null, stepIndex: number | null) => {
setReplaySelection({ stageId, stepIndex }); setReplaySelection({ stageId, stepIndex });
@@ -483,7 +483,7 @@ function EditorPageContent() {
essential: true, essential: true,
}); });
setFocusedPresentPlace(place); setFocusedPresentPlace(place);
setPreviewFeaturePopupAnchor(null); setPreviewPinnedWikiPopupAnchor(null);
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
}, [getCurrentMapInstance]); }, [getCurrentMapInstance]);
const previewReturnModeRef = useRef<EditorMode>("select"); const previewReturnModeRef = useRef<EditorMode>("select");
@@ -1026,7 +1026,8 @@ function EditorPageContent() {
const clearPreviewViewerState = useCallback(() => { const clearPreviewViewerState = useCallback(() => {
setPreviewActiveEntityId(null); setPreviewActiveEntityId(null);
setIsPreviewEntitySidebarOpen(false); setIsPreviewEntitySidebarOpen(false);
setPreviewFeaturePopupAnchor(null); setPreviewEntityFocusToken(null);
setPreviewPinnedWikiPopupAnchor(null);
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
setPreviewWikiError(null); setPreviewWikiError(null);
closeReplayPreviewWikiPanel(); closeReplayPreviewWikiPanel();
@@ -1335,20 +1336,6 @@ function EditorPageContent() {
replayPreviewWikiRows, replayPreviewWikiRows,
] ]
); );
const previewFeaturePopupEntityIds = useMemo(() => {
if (!previewFeaturePopupAnchor) return [];
return previewRelations.geometryEntityIds[String(previewFeaturePopupAnchor.featureId)] || [];
}, [previewFeaturePopupAnchor, previewRelations.geometryEntityIds]);
const previewFeaturePopupEntities = useMemo(
() => previewFeaturePopupEntityIds
.map((entityId) => previewRelations.entitiesById[entityId] || null)
.filter((entity): entity is Entity => Boolean(entity)),
[previewFeaturePopupEntityIds, previewRelations.entitiesById]
);
useEffect(() => {
setPreviewExpandedEntityId(null);
}, [previewFeaturePopupAnchor]);
// Wiki snapshot đang được step preview yêu cầu mở. // Wiki snapshot đang được step preview yêu cầu mở.
const replayPreviewActiveWikiSnapshot = useMemo(() => { const replayPreviewActiveWikiSnapshot = useMemo(() => {
if (!replayPreviewActiveWikiId) return null; if (!replayPreviewActiveWikiId) return null;
@@ -1516,7 +1503,7 @@ function EditorPageContent() {
const renderedFeature = mapRenderDraft.features.find((item) => String(item.properties.id) === geometryId) || null; const renderedFeature = mapRenderDraft.features.find((item) => String(item.properties.id) === geometryId) || null;
setSelectedFeatureIds(renderedFeature ? [renderedFeature.properties.id] : []); setSelectedFeatureIds(renderedFeature ? [renderedFeature.properties.id] : []);
setFocusedPresentPlace(null); setFocusedPresentPlace(null);
setPreviewFeaturePopupAnchor(null); setPreviewPinnedWikiPopupAnchor(null);
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
}, [ }, [
activeTimelineFilterEnabled, activeTimelineFilterEnabled,
@@ -1566,10 +1553,11 @@ function EditorPageContent() {
setPreviewActiveEntityId(id); setPreviewActiveEntityId(id);
setIsPreviewEntitySidebarOpen(true); setIsPreviewEntitySidebarOpen(true);
setPreviewWikiError(null); setPreviewWikiError(null);
setPreviewPinnedWikiPopupAnchor(null);
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
if (options?.focusMap !== false) { if (options?.focusMap === true) {
setPreviewEntityFocusToken((prev) => prev + 1); setPreviewEntityFocusToken((prev) => (prev ?? 0) + 1);
} }
if (options?.selectGeometry && options.sourceFeatureId != null) { if (options?.selectGeometry && options.sourceFeatureId != null) {
setSelectedFeatureIds([options.sourceFeatureId]); setSelectedFeatureIds([options.sourceFeatureId]);
@@ -1584,11 +1572,103 @@ function EditorPageContent() {
setSelectedFeatureIds, setSelectedFeatureIds,
]); ]);
const previewPinnedWikiPopupRows = useMemo(() => {
if (!previewPinnedWikiPopupAnchor) return [];
const entityIds = previewRelations.geometryEntityIds[String(previewPinnedWikiPopupAnchor.featureId)] || [];
return entityIds.flatMap((entityId) => {
const entity = previewRelations.entitiesById[entityId] || null;
if (!entity) return [];
const linkedWikis = previewRelations.entityWikisById[entity.id] || [];
if (!linkedWikis.length) {
return [{ entity, wiki: null as Wiki | null, quote: "" }];
}
return linkedWikis.map((wiki) => ({
entity,
wiki,
quote: extractWikiBlockquoteText(wiki.content),
}));
});
}, [
previewPinnedWikiPopupAnchor,
previewRelations.entitiesById,
previewRelations.entityWikisById,
previewRelations.geometryEntityIds,
]);
const handlePreviewMapFeatureClick = useCallback((payload: MapFeaturePayload | null) => { const handlePreviewMapFeatureClick = useCallback((payload: MapFeaturePayload | null) => {
if (!isAnyPreviewMode) return; if (!isAnyPreviewMode) return;
setPreviewFeaturePopupAnchor(payload);
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
}, [isAnyPreviewMode]);
if (!payload) {
setPreviewPinnedWikiPopupAnchor(null);
return;
}
const entityIds = previewRelations.geometryEntityIds[String(payload.featureId)] || [];
const rows = entityIds.flatMap((entityId) => {
const entity = previewRelations.entitiesById[entityId] || null;
if (!entity) return [];
const linkedWikis = previewRelations.entityWikisById[entity.id] || [];
if (!linkedWikis.length) {
return [{ entity, wiki: null as Wiki | null }];
}
return linkedWikis.map((wiki) => ({ entity, wiki }));
});
if (!rows.length) {
setPreviewPinnedWikiPopupAnchor(null);
return;
}
if (rows.length === 1) {
const row = rows[0];
selectReplayPreviewEntity(row.entity.id, {
sourceFeatureId: payload.featureId,
preferredWikiId: row.wiki?.id,
focusMap: false,
selectGeometry: false,
});
setPreviewPinnedWikiPopupAnchor(null);
return;
}
setPreviewPinnedWikiPopupAnchor(payload);
}, [
isAnyPreviewMode,
previewRelations.entitiesById,
previewRelations.entityWikisById,
previewRelations.geometryEntityIds,
selectReplayPreviewEntity,
]);
const getPreviewHoverPopupContent = useCallback((feature: Feature) => {
if (!isAnyPreviewMode) return null;
const entityIds = normalizeFeatureEntityIds(feature);
const entitiesForFeature = entityIds
.map((entityId) => previewRelations.entitiesById[entityId] || null)
.filter((entity): entity is Entity => Boolean(entity));
if (!entitiesForFeature.length) return null;
return {
rows: entitiesForFeature.flatMap((entity) => {
const linkedWikis = previewRelations.entityWikisById[entity.id] || [];
if (!linkedWikis.length) {
return [{ title: entity.name || String(entity.id), quote: "" }];
}
return linkedWikis.map((wiki) => ({
title: entity.name || String(entity.id),
quote: extractWikiBlockquoteText(wiki.content),
}));
}),
};
}, [isAnyPreviewMode, previewRelations.entitiesById, previewRelations.entityWikisById]);
useEffect(() => { useEffect(() => {
if (!previewLinkEntityPopup) return; if (!previewLinkEntityPopup) return;
@@ -1610,6 +1690,26 @@ function EditorPageContent() {
}; };
}, [previewLinkEntityPopup]); }, [previewLinkEntityPopup]);
useEffect(() => {
if (!previewPinnedWikiPopupAnchor) return;
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") setPreviewPinnedWikiPopupAnchor(null);
};
const handlePointerDown = (event: PointerEvent) => {
const target = event.target as Node | null;
if (target && previewPinnedWikiPopupRef.current?.contains(target)) return;
setPreviewPinnedWikiPopupAnchor(null);
};
window.addEventListener("keydown", handleKeyDown);
window.addEventListener("pointerdown", handlePointerDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
window.removeEventListener("pointerdown", handlePointerDown);
};
}, [previewPinnedWikiPopupAnchor]);
// Điều hướng link wiki nội bộ trong preview nhưng chỉ trong phạm vi snapshot preview. // Điều hướng link wiki nội bộ trong preview nhưng chỉ trong phạm vi snapshot preview.
const handleReplayPreviewWikiLinkRequest = useCallback(({ slug, rect }: { slug: string; rect: DOMRect }) => { const handleReplayPreviewWikiLinkRequest = useCallback(({ slug, rect }: { slug: string; rect: DOMRect }) => {
const nextSlug = String(slug || "").trim(); const nextSlug = String(slug || "").trim();
@@ -1629,6 +1729,7 @@ function EditorPageContent() {
selectReplayPreviewEntity(linkedEntities[0].id, { selectReplayPreviewEntity(linkedEntities[0].id, {
preferredWikiId: match.id, preferredWikiId: match.id,
preferredWikiSlug: nextSlug, preferredWikiSlug: nextSlug,
focusMap: false,
}); });
return; return;
} }
@@ -3031,6 +3132,7 @@ function EditorPageContent() {
onHideFeature={handleHideGeometryLocal} onHideFeature={handleHideGeometryLocal}
onUpdateFeature={editor.updateFeature} onUpdateFeature={editor.updateFeature}
allowGeometryEditing={!isAnyPreviewMode} allowGeometryEditing={!isAnyPreviewMode}
allowFeatureSelection={!isAnyPreviewMode}
backgroundVisibility={backgroundVisibility} backgroundVisibility={backgroundVisibility}
geometryVisibility={effectiveGeometryVisibility} geometryVisibility={effectiveGeometryVisibility}
applyGeometryBindingFilter={ applyGeometryBindingFilter={
@@ -3041,6 +3143,8 @@ function EditorPageContent() {
: geometryBindingFilterEnabled : geometryBindingFilterEnabled
} }
onFeatureClick={isAnyPreviewMode ? handlePreviewMapFeatureClick : undefined} onFeatureClick={isAnyPreviewMode ? handlePreviewMapFeatureClick : undefined}
hoverPopupEnabled={isAnyPreviewMode}
getHoverPopupContent={getPreviewHoverPopupContent}
focusFeatureCollection={ focusFeatureCollection={
isAnyPreviewMode isAnyPreviewMode
@@ -3084,6 +3188,7 @@ function EditorPageContent() {
dialog={replayPreview.dialog} dialog={replayPreview.dialog}
toasts={replayPreview.toasts} toasts={replayPreview.toasts}
sidebarOpen={isReplayPreviewWikiSidebarOpen} sidebarOpen={isReplayPreviewWikiSidebarOpen}
sidebarWidth={previewSidebarWidth}
playbackSpeed={replayPreview.playbackSpeed} playbackSpeed={replayPreview.playbackSpeed}
activeStepLabel={replayPreviewActiveStepLabel} activeStepLabel={replayPreviewActiveStepLabel}
activeStepNumber={replayPreview.activeStepNumber} activeStepNumber={replayPreview.activeStepNumber}
@@ -3115,6 +3220,7 @@ function EditorPageContent() {
sidebarWidth={previewSidebarWidth} sidebarWidth={previewSidebarWidth}
onSidebarWidthChange={setPreviewSidebarWidth} onSidebarWidthChange={setPreviewSidebarWidth}
maxDragWidth={typeof window !== "undefined" ? Math.min(800, window.innerWidth - 340) : 800} maxDragWidth={typeof window !== "undefined" ? Math.min(800, window.innerWidth - 340) : 800}
compactHeader
/> />
</aside> </aside>
) : null} ) : null}
@@ -3148,102 +3254,38 @@ function EditorPageContent() {
/> />
</aside> </aside>
) : null} ) : null}
{isAnyPreviewMode && previewFeaturePopupAnchor && previewFeaturePopupEntities.length > 0 ? ( {isAnyPreviewMode && previewPinnedWikiPopupAnchor && previewPinnedWikiPopupRows.length > 0 ? (
<div <div
ref={previewPinnedWikiPopupRef}
className="absolute z-30 w-[320px] max-w-[calc(100vw-2rem)]" className="absolute z-30 w-[320px] max-w-[calc(100vw-2rem)]"
style={{ style={{
left: clampNumber(previewFeaturePopupAnchor.point.x + 18, 16, typeof window !== "undefined" ? window.innerWidth - 340 : previewFeaturePopupAnchor.point.x + 18), left: clampNumber(previewPinnedWikiPopupAnchor.point.x + 18, 16, typeof window !== "undefined" ? window.innerWidth - 340 : previewPinnedWikiPopupAnchor.point.x + 18),
top: clampNumber(previewFeaturePopupAnchor.point.y - 8, 16, typeof window !== "undefined" ? window.innerHeight - 280 : previewFeaturePopupAnchor.point.y - 8), top: clampNumber(previewPinnedWikiPopupAnchor.point.y - 8, 16, typeof window !== "undefined" ? window.innerHeight - 280 : previewPinnedWikiPopupAnchor.point.y - 8),
}} }}
> >
<div className="overflow-hidden rounded-xl border border-white/10 bg-slate-950/95 shadow-xl backdrop-blur"> <div className="overflow-hidden rounded-xl border border-white/10 bg-slate-950/95 shadow-xl backdrop-blur">
{(() => { <div className="max-h-[300px] overflow-y-auto p-3">
// 1. Expanded entity (nested wiki selection) <div className="grid gap-2">
if (previewExpandedEntityId) { {previewPinnedWikiPopupRows.map(({ entity, wiki, quote }) => (
const entity = previewRelations.entitiesById[previewExpandedEntityId];
if (!entity) return null;
const wikis = previewRelations.entityWikisById[previewExpandedEntityId] || [];
return (
<div className="p-3">
<div className="flex items-center gap-2 mb-3">
<button <button
type="button" key={`${entity.id}:${wiki?.id || "entity-only"}`}
onClick={() => setPreviewExpandedEntityId(null)}
className="inline-flex h-6 w-6 items-center justify-center rounded-md border border-white/10 bg-white/[0.03] text-xs text-slate-300 hover:bg-white/[0.08]"
>
&larr;
</button>
<span className="text-[11px] font-bold text-slate-400 uppercase tracking-widest truncate max-w-[180px]">
{entity.name}
</span>
</div>
<div className="text-sm font-bold text-white mb-2">Chọn Wiki bài viết:</div>
<div className="grid gap-2 max-h-[200px] overflow-y-auto pr-1">
{wikis.map((wiki) => (
<button
key={wiki.id}
type="button" type="button"
onClick={() => { onClick={() => {
selectReplayPreviewEntity(entity.id, { selectReplayPreviewEntity(entity.id, {
sourceFeatureId: previewFeaturePopupAnchor.featureId, sourceFeatureId: previewPinnedWikiPopupAnchor.featureId,
preferredWikiId: wiki.id, preferredWikiId: wiki?.id,
focusMap: true, focusMap: false,
selectGeometry: true, selectGeometry: false,
}); });
setPreviewFeaturePopupAnchor(null);
setPreviewExpandedEntityId(null);
}} }}
className="w-full rounded-lg border border-white/10 bg-white/[0.03] px-3 py-2.5 text-left text-sm text-slate-200 transition hover:border-sky-400/40 hover:bg-sky-500/10" className="w-full rounded-lg border border-white/10 bg-white/[0.03] px-3 py-3 text-left transition hover:border-sky-400/40 hover:bg-sky-500/10"
> >
📄 {wiki.title} <div className="truncate text-sm font-semibold text-white">
</button> {entity.name || String(entity.id)}
))}
</div>
</div>
);
}
// 2. Case 1: Exactly 1 entity bound to geometry
if (previewFeaturePopupEntities.length === 1) {
const singleEntity = previewFeaturePopupEntities[0];
const entityWikis = previewRelations.entityWikisById[singleEntity.id] || [];
if (entityWikis.length === 1) {
const singleWiki = entityWikis[0];
const blockquoteMatch = singleWiki.content
? singleWiki.content.match(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/)
: null;
let previewSummary = blockquoteMatch ? blockquoteMatch[1].trim() : "";
if (!previewSummary) {
const pMatch = singleWiki.content
? singleWiki.content.match(/<p[^>]*>([\s\S]*?)<\/p>/)
: null;
previewSummary = pMatch ? pMatch[1].trim() : "";
}
if (!previewSummary) {
previewSummary = singleEntity.description || "Không có mô tả hay tóm tắt.";
}
const cleanSummaryText = previewSummary
.replace(/<[^>]*>/g, "")
.replace(/&nbsp;/gi, " ")
.replace(/\u00a0/g, " ")
.replace(/&amp;/gi, "&")
.replace(/&lt;/gi, "<")
.replace(/&gt;/gi, ">")
.replace(/&quot;/gi, '"')
.replace(/&#39;/g, "'")
.trim();
return (
<div className="p-4 flex flex-col gap-3">
<div>
<div className="text-base font-bold text-white mt-1">
{singleEntity.name}
</div>
</div> </div>
{quote ? (
<div <div
className="text-sm text-slate-300 italic pl-3 leading-relaxed pr-1" className="mt-2 pl-3 pr-1 text-sm italic leading-relaxed text-slate-300"
style={{ style={{
borderLeft: "3px solid rgba(56, 189, 248, 0.4)", borderLeft: "3px solid rgba(56, 189, 248, 0.4)",
display: "-webkit-box", display: "-webkit-box",
@@ -3253,123 +3295,13 @@ function EditorPageContent() {
whiteSpace: "normal", whiteSpace: "normal",
}} }}
> >
{cleanSummaryText} {quote}
</div> </div>
<button ) : null}
type="button"
onClick={() => {
selectReplayPreviewEntity(singleEntity.id, {
sourceFeatureId: previewFeaturePopupAnchor.featureId,
focusMap: true,
selectGeometry: true,
});
setPreviewFeaturePopupAnchor(null);
}}
className="w-full rounded-lg bg-sky-500 hover:bg-sky-600 px-3 py-2 text-center text-xs font-semibold text-white transition shadow-lg shadow-sky-500/20"
>
Xem chi tiết Wiki &rarr;
</button>
</div>
);
} else if (entityWikis.length > 1) {
return (
<div className="p-3">
<div className="border-b border-white/10 pb-2 mb-2">
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
Entity
</div>
<div className="text-base font-bold text-white">
{singleEntity.name}
</div>
<div className="text-xs text-slate-400 mt-1">
Thực thể này nhiều Wiki liên kết. Chọn đ đc:
</div>
</div>
<div className="grid gap-2 max-h-[200px] overflow-y-auto pr-1">
{entityWikis.map((wiki) => (
<button
key={wiki.id}
type="button"
onClick={() => {
selectReplayPreviewEntity(singleEntity.id, {
sourceFeatureId: previewFeaturePopupAnchor.featureId,
preferredWikiId: wiki.id,
focusMap: true,
selectGeometry: true,
});
setPreviewFeaturePopupAnchor(null);
}}
className="w-full rounded-lg border border-white/10 bg-white/[0.03] px-3 py-2.5 text-left text-sm text-slate-200 transition hover:border-sky-400/40 hover:bg-sky-500/10"
>
📄 {wiki.title}
</button> </button>
))} ))}
</div> </div>
</div> </div>
);
}
}
// 3. Case 2: Multiple entities bound to geometry
return (
<div>
<div className="border-b border-white/10 px-4 py-3">
<div className="text-sm font-semibold text-white">Related Entities</div>
<div className="mt-1 text-xs text-slate-400">
Geometry #{String(previewFeaturePopupAnchor.featureId)}
</div>
</div>
<div className="max-h-[252px] overflow-y-auto">
<div className="grid gap-2 p-3">
{previewFeaturePopupEntities.map((entity) => {
const entityWikis = previewRelations.entityWikisById[entity.id] || [];
return (
<button
key={entity.id}
type="button"
onClick={() => {
if (entityWikis.length > 1) {
setPreviewExpandedEntityId(entity.id);
} else {
selectReplayPreviewEntity(entity.id, {
sourceFeatureId: previewFeaturePopupAnchor.featureId,
focusMap: true,
selectGeometry: true,
});
setPreviewFeaturePopupAnchor(null);
}
}}
className="w-full rounded-lg border border-white/10 bg-white/[0.03] px-3 py-3 text-left transition hover:border-sky-400/40 hover:bg-sky-500/10"
>
<div className="flex items-center justify-between gap-2">
<div className="truncate text-sm font-semibold text-white">
{entity.name}
</div>
{entityWikis.length > 1 ? (
<span className="text-[10px] bg-sky-500/20 text-sky-300 px-1.5 py-0.5 rounded-full font-medium">
{entityWikis.length} Wikis
</span>
) : null}
</div>
<div
className="mt-1 text-xs leading-5 text-slate-400"
style={{
display: "-webkit-box",
WebkitLineClamp: 2,
WebkitBoxOrient: "vertical",
overflow: "hidden",
}}
>
{entity.description?.trim() || "Không có mô tả."}
</div>
</button>
);
})}
</div>
</div>
</div>
);
})()}
</div> </div>
</div> </div>
) : null} ) : null}
@@ -3422,7 +3354,10 @@ function EditorPageContent() {
key={entity.id} key={entity.id}
type="button" type="button"
onClick={() => { onClick={() => {
selectReplayPreviewEntity(entity.id, { preferredWikiSlug: previewLinkEntityPopup.slug }); selectReplayPreviewEntity(entity.id, {
preferredWikiSlug: previewLinkEntityPopup.slug,
focusMap: false,
});
setPreviewLinkEntityPopup(null); setPreviewLinkEntityPopup(null);
}} }}
className="rounded-lg px-3 py-2 text-left text-sm text-gray-700 transition hover:bg-gray-50 hover:text-gray-900 dark:text-gray-200 dark:hover:bg-white/[0.04] dark:hover:text-white" className="rounded-lg px-3 py-2 text-left text-sm text-gray-700 transition hover:bg-gray-50 hover:text-gray-900 dark:text-gray-200 dark:hover:bg-white/[0.04] dark:hover:text-white"
@@ -3702,6 +3637,26 @@ function snapshotWikiToWiki(snapshot: WikiSnapshot, wikiCache: Record<string, Wi
}; };
} }
function extractWikiBlockquoteText(content: string | null | undefined): string {
if (!content) return "";
const blockquoteMatch = content.match(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/i);
const rawText = blockquoteMatch?.[1]?.trim() || "";
if (!rawText) return "";
return rawText
.replace(/<[^>]*>/g, "")
.replace(/&nbsp;/gi, " ")
.replace(/\u00a0/g, " ")
.replace(/&amp;/gi, "&")
.replace(/&lt;/gi, "<")
.replace(/&gt;/gi, ">")
.replace(/&quot;/gi, '"')
.replace(/&#39;/g, "'")
.replace(/\s+/g, " ")
.trim();
}
function pushUniqueString(target: Record<string, string[]>, key: string, value: string) { function pushUniqueString(target: Record<string, string[]>, key: string, value: string) {
if (!target[key]) { if (!target[key]) {
target[key] = [value]; target[key] = [value];
+4 -2
View File
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useState } from "react"; import { memo, useState } from "react";
import type { UndoAction } from "@/uhm/lib/editor/state/useEditorState"; import type { UndoAction } from "@/uhm/lib/editor/state/useEditorState";
import type { EditorMode } from "@/uhm/lib/editor/session/sessionTypes"; import type { EditorMode } from "@/uhm/lib/editor/session/sessionTypes";
@@ -49,7 +49,7 @@ type Props = {
onRemoveImageOverlay: () => void; onRemoveImageOverlay: () => void;
}; };
export default function Editor({ function Editor({
mode, mode,
setMode, setMode,
entityStatus, entityStatus,
@@ -190,3 +190,5 @@ export default function Editor({
</div> </div>
); );
} }
export default memo(Editor);
+17
View File
@@ -12,6 +12,7 @@ import { setupMapLayers } from "./map/useMapLayers";
import { useMapInteraction } from "./map/useMapInteraction"; import { useMapInteraction } from "./map/useMapInteraction";
import { useMapSync } from "./map/useMapSync"; import { useMapSync } from "./map/useMapSync";
import { bindImageOverlayInteractions, type MapImageOverlay } from "./map/imageOverlay"; import { bindImageOverlayInteractions, type MapImageOverlay } from "./map/imageOverlay";
import { useMapHoverPopup, type MapHoverPopupContent } from "./map/useMapHoverPopup";
export type MapFeaturePayload = { export type MapFeaturePayload = {
featureId: string | number; featureId: string | number;
@@ -56,6 +57,9 @@ type MapProps = {
fitToDraftBounds?: boolean; fitToDraftBounds?: boolean;
fitBoundsKey?: string | number | null; fitBoundsKey?: string | number | null;
onFeatureClick?: ((payload: MapFeaturePayload | null) => void) | undefined; onFeatureClick?: ((payload: MapFeaturePayload | null) => void) | undefined;
hoverPopupEnabled?: boolean;
getHoverPopupContent?: (feature: Feature) => MapHoverPopupContent | null;
allowFeatureSelection?: boolean;
focusFeatureCollection?: FeatureCollection | null; focusFeatureCollection?: FeatureCollection | null;
focusRequestKey?: string | number | null; focusRequestKey?: string | number | null;
focusPadding?: number | import("maplibre-gl").PaddingOptions; focusPadding?: number | import("maplibre-gl").PaddingOptions;
@@ -93,6 +97,9 @@ const Map = memo(forwardRef<MapHandle, MapProps>(function Map({
fitToDraftBounds = false, fitToDraftBounds = false,
fitBoundsKey = null, fitBoundsKey = null,
onFeatureClick, onFeatureClick,
hoverPopupEnabled = false,
getHoverPopupContent,
allowFeatureSelection = true,
focusFeatureCollection = null, focusFeatureCollection = null,
focusRequestKey = null, focusRequestKey = null,
focusPadding, focusPadding,
@@ -118,6 +125,7 @@ const Map = memo(forwardRef<MapHandle, MapProps>(function Map({
const onSetModeRef = useRef(onSetMode); const onSetModeRef = useRef(onSetMode);
// Ref callback click feature mới nhất cho tooltip/panel ngoài map. // Ref callback click feature mới nhất cho tooltip/panel ngoài map.
const onFeatureClickRef = useRef<MapProps["onFeatureClick"]>(onFeatureClick); const onFeatureClickRef = useRef<MapProps["onFeatureClick"]>(onFeatureClick);
const getHoverPopupContentRef = useRef<MapProps["getHoverPopupContent"]>(getHoverPopupContent);
// Ref callback create mới nhất khi drawing engine tạo feature. // Ref callback create mới nhất khi drawing engine tạo feature.
const onCreateRef = useRef<MapProps["onCreateFeature"]>(onCreateFeature); const onCreateRef = useRef<MapProps["onCreateFeature"]>(onCreateFeature);
// Ref callback add geometry global vào project mới nhất cho context menu select. // Ref callback add geometry global vào project mới nhất cho context menu select.
@@ -142,6 +150,7 @@ const Map = memo(forwardRef<MapHandle, MapProps>(function Map({
useEffect(() => { onSelectFeatureIdsRef.current = onSelectFeatureIds; }, [onSelectFeatureIds]); useEffect(() => { onSelectFeatureIdsRef.current = onSelectFeatureIds; }, [onSelectFeatureIds]);
useEffect(() => { onSetModeRef.current = onSetMode; }, [onSetMode]); useEffect(() => { onSetModeRef.current = onSetMode; }, [onSetMode]);
useEffect(() => { onFeatureClickRef.current = onFeatureClick; }, [onFeatureClick]); useEffect(() => { onFeatureClickRef.current = onFeatureClick; }, [onFeatureClick]);
useEffect(() => { getHoverPopupContentRef.current = getHoverPopupContent; }, [getHoverPopupContent]);
useEffect(() => { onCreateRef.current = onCreateFeature; }, [onCreateFeature]); useEffect(() => { onCreateRef.current = onCreateFeature; }, [onCreateFeature]);
useEffect(() => { onAddFeatureToProjectRef.current = onAddFeatureToProject; }, [onAddFeatureToProject]); useEffect(() => { onAddFeatureToProjectRef.current = onAddFeatureToProject; }, [onAddFeatureToProject]);
useEffect(() => { onDeleteRef.current = onDeleteFeature; }, [onDeleteFeature]); useEffect(() => { onDeleteRef.current = onDeleteFeature; }, [onDeleteFeature]);
@@ -201,6 +210,7 @@ const Map = memo(forwardRef<MapHandle, MapProps>(function Map({
onBindGeometriesRef, onBindGeometriesRef,
localFeatureIdsRef, localFeatureIdsRef,
onAddFeatureToProjectRef, onAddFeatureToProjectRef,
allowFeatureSelection,
}); });
// Hook đồng bộ draft/layer/filter/highlight từ React state xuống MapLibre source/layer. // Hook đồng bộ draft/layer/filter/highlight từ React state xuống MapLibre source/layer.
@@ -229,6 +239,13 @@ const Map = memo(forwardRef<MapHandle, MapProps>(function Map({
isPreviewMode: isPreviewMode || mode === "preview" || mode === "replay" || mode === "replay_preview", isPreviewMode: isPreviewMode || mode === "preview" || mode === "replay" || mode === "replay_preview",
}); });
useMapHoverPopup({
mapRef,
enabled: hoverPopupEnabled,
renderDraftRef,
getContentRef: getHoverPopupContentRef,
});
useEffect(() => { useEffect(() => {
const map = mapRef.current; const map = mapRef.current;
if (!map || !isMapLoaded) return; if (!map || !isMapLoaded) return;
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useMemo, useState } from "react"; import { useMemo, useState, memo } from "react";
import type { EntityWikiLinkSnapshot } from "@/uhm/types/projects"; import type { EntityWikiLinkSnapshot } from "@/uhm/types/projects";
import type { WikiSnapshot } from "@/uhm/types/wiki"; import type { WikiSnapshot } from "@/uhm/types/wiki";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
@@ -28,7 +28,7 @@ function wikiTitle(w: WikiSnapshot): string {
return t.length ? t : "Untitled wiki"; return t.length ? t : "Untitled wiki";
} }
export default function EntityWikiBindingsPanel({ setLinks }: Props) { function EntityWikiBindingsPanel({ setLinks }: Props) {
const { const {
entityCatalog, entityCatalog,
snapshotEntityRows, snapshotEntityRows,
@@ -476,3 +476,5 @@ function MinusIcon() {
</svg> </svg>
); );
} }
export default memo(EntityWikiBindingsPanel);
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useMemo, useState, type CSSProperties, type KeyboardEvent } from "react"; import { useMemo, useState, memo, type CSSProperties, type KeyboardEvent } from "react";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
import NewBadge from "@/uhm/components/editor/NewBadge"; import NewBadge from "@/uhm/components/editor/NewBadge";
import { normalizeTimelineYearValue } from "@/uhm/lib/utils/timeline"; import { normalizeTimelineYearValue } from "@/uhm/lib/utils/timeline";
@@ -34,7 +34,7 @@ type Props = {
onFocusGeometry?: (geometryId: string) => void; onFocusGeometry?: (geometryId: string) => void;
}; };
export default function GeometryBindingPanel({ function GeometryBindingPanel({
geometries, geometries,
selectedGeometryId, selectedGeometryId,
selectedGeometryChildIds, selectedGeometryChildIds,
@@ -686,3 +686,5 @@ function MinusIcon() {
</svg> </svg>
); );
} }
export default memo(GeometryBindingPanel);
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useMemo, useState, type CSSProperties } from "react"; import { useMemo, useState, memo, type CSSProperties } from "react";
import type { EntitySnapshot } from "@/uhm/types/entities"; import type { EntitySnapshot } from "@/uhm/types/entities";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
import NewBadge from "@/uhm/components/editor/NewBadge"; import NewBadge from "@/uhm/components/editor/NewBadge";
@@ -17,7 +17,7 @@ type Props = {
onDeleteEntity?: (entityId: string) => void; onDeleteEntity?: (entityId: string) => void;
}; };
export default function ProjectEntityRefsPanel({ function ProjectEntityRefsPanel({
onCreateEntityOnly, onCreateEntityOnly,
onUpdateEntity, onUpdateEntity,
hasSelectedGeometry, hasSelectedGeometry,
@@ -673,3 +673,5 @@ function TrashIcon() {
</svg> </svg>
); );
} }
export default memo(ProjectEntityRefsPanel);
@@ -10,6 +10,7 @@ type Props = {
dialog: DialogState | null; dialog: DialogState | null;
toasts: ReplayPreviewToast[]; toasts: ReplayPreviewToast[];
sidebarOpen: boolean; sidebarOpen: boolean;
sidebarWidth?: number;
playbackSpeed: number; playbackSpeed: number;
activeStepLabel: string | null; activeStepLabel: string | null;
activeStepNumber: number | null; activeStepNumber: number | null;
@@ -26,6 +27,7 @@ export default function ReplayPreviewOverlay({
dialog, dialog,
toasts, toasts,
sidebarOpen, sidebarOpen,
sidebarWidth = 420,
playbackSpeed, playbackSpeed,
activeStepLabel, activeStepLabel,
activeStepNumber, activeStepNumber,
@@ -36,6 +38,7 @@ export default function ReplayPreviewOverlay({
onExitPreview, onExitPreview,
}: Props) { }: Props) {
const hasWikiPreview = sidebarOpen; const hasWikiPreview = sidebarOpen;
const rightOffset = hasWikiPreview ? sidebarWidth + 32 : 18;
const shouldRender = const shouldRender =
isPreviewMode || isPreviewMode ||
isPlaying || isPlaying ||
@@ -60,7 +63,7 @@ export default function ReplayPreviewOverlay({
style={{ style={{
position: "absolute", position: "absolute",
top: 72, top: 72,
right: hasWikiPreview ? 454 : 18, right: rightOffset,
display: "grid", display: "grid",
gap: 8, gap: 8,
width: 280, width: 280,
@@ -90,9 +93,9 @@ export default function ReplayPreviewOverlay({
<div <div
style={{ style={{
position: "absolute", position: "absolute",
right: hasWikiPreview ? 472 : 18, left: 18,
right: rightOffset,
bottom: 96, bottom: 96,
width: 380,
borderRadius: 20, borderRadius: 20,
overflow: "hidden", overflow: "hidden",
border: "1px solid rgba(255, 255, 255, 0.1)", border: "1px solid rgba(255, 255, 255, 0.1)",
@@ -102,6 +105,7 @@ export default function ReplayPreviewOverlay({
pointerEvents: "auto", pointerEvents: "auto",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
maxHeight: "calc(100vh - 180px)",
}} }}
> >
{dialog.image_url?.trim() ? ( {dialog.image_url?.trim() ? (
@@ -111,7 +115,7 @@ export default function ReplayPreviewOverlay({
style={{ style={{
width: "100%", width: "100%",
display: "block", display: "block",
maxHeight: 220, maxHeight: 140,
objectFit: "cover", objectFit: "cover",
background: "#020617", background: "#020617",
}} }}
@@ -119,14 +123,15 @@ export default function ReplayPreviewOverlay({
) : null} ) : null}
{dialog.text?.trim() ? ( {dialog.text?.trim() ? (
<div <div
className="ql-editor" className="uhm-replay-dialog-content"
style={{ style={{
padding: "16px", padding: "16px",
color: "#f8fafc", color: "#f8fafc",
fontSize: "14px", fontSize: "14px",
lineHeight: "1.6", lineHeight: "1.6",
overflowY: "auto", overflowY: "auto",
maxHeight: "250px", maxHeight: dialog.image_url?.trim() ? "180px" : "140px",
minHeight: 0,
background: "transparent", background: "transparent",
}} }}
dangerouslySetInnerHTML={{ __html: dialog.text }} dangerouslySetInnerHTML={{ __html: dialog.text }}
@@ -134,6 +139,19 @@ export default function ReplayPreviewOverlay({
) : null} ) : null}
</div> </div>
) : null} ) : null}
<style jsx>{`
.uhm-replay-dialog-content :global(p) {
margin: 0;
}
.uhm-replay-dialog-content :global(p + p) {
margin-top: 6px;
}
.uhm-replay-dialog-content :global(ul),
.uhm-replay-dialog-content :global(ol) {
margin: 0;
padding-left: 20px;
}
`}</style>
{isPreviewMode ? ( {isPreviewMode ? (
<div <div
@@ -1,6 +1,6 @@
"use client"; "use client";
import { type CSSProperties, useMemo, useState } from "react"; import { type CSSProperties, memo, useMemo, useState } from "react";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
import { Feature } from "@/uhm/lib/editor/state/useEditorState"; import { Feature } from "@/uhm/lib/editor/state/useEditorState";
import { import {
@@ -23,7 +23,7 @@ type Props = {
onRerollGeometryId?: (oldId: string | number) => void; onRerollGeometryId?: (oldId: string | number) => void;
}; };
export default function SelectedGeometryPanel({ function SelectedGeometryPanel({
selectedFeatures, selectedFeatures,
onApplyGeometryMetadata, onApplyGeometryMetadata,
changeCount, changeCount,
@@ -466,3 +466,5 @@ function getAllowedGroupIdsForPreset(
return ["polygon"]; return ["polygon"];
} }
export default memo(SelectedGeometryPanel);
+48 -4
View File
@@ -25,6 +25,16 @@ type FeatureLabelInfo = {
}; };
const rasterBaseVisibilityGenerationByMap = new WeakMap<maplibregl.Map, number>(); const rasterBaseVisibilityGenerationByMap = new WeakMap<maplibregl.Map, number>();
const resolverCache = new WeakMap<
FeatureCollection,
Map<number | null | undefined, (feature: Feature) => string | null>
>();
const featureLabelInfoCache = new WeakMap<
Feature,
Map<number | null | undefined, FeatureLabelInfo | null>
>();
export function applyBackgroundLayerVisibility( export function applyBackgroundLayerVisibility(
map: maplibregl.Map, map: maplibregl.Map,
visibility: BackgroundLayerVisibility visibility: BackgroundLayerVisibility
@@ -265,7 +275,7 @@ export function decoratePointFeaturesWithLabels(
labelContext: FeatureCollection = fc, labelContext: FeatureCollection = fc,
timelineYear?: number | null timelineYear?: number | null
): FeatureCollection { ): FeatureCollection {
const getLabel = createFeatureLabelResolver(labelContext, timelineYear); const getLabel = getFeatureLabelResolver(labelContext, timelineYear);
let changed = false; let changed = false;
const nextFeatures = fc.features.map((feature) => { const nextFeatures = fc.features.map((feature) => {
const point_label = getLabel(feature); const point_label = getLabel(feature);
@@ -289,7 +299,7 @@ export function decorateLineFeaturesWithLabels(
labelContext: FeatureCollection = fc, labelContext: FeatureCollection = fc,
timelineYear?: number | null timelineYear?: number | null
): FeatureCollection { ): FeatureCollection {
const getLabel = createFeatureLabelResolver(labelContext, timelineYear); const getLabel = getFeatureLabelResolver(labelContext, timelineYear);
let changed = false; let changed = false;
const nextFeatures = fc.features.map((feature) => { const nextFeatures = fc.features.map((feature) => {
const line_label = isLineGeometry(feature.geometry) ? getLabel(feature) : null; const line_label = isLineGeometry(feature.geometry) ? getLabel(feature) : null;
@@ -315,7 +325,7 @@ export function buildPolygonLabelFeatureCollection(
labelContext: FeatureCollection = fc, labelContext: FeatureCollection = fc,
timelineYear?: number | null timelineYear?: number | null
): FeatureCollection { ): FeatureCollection {
const getLabel = createFeatureLabelResolver(labelContext, timelineYear); const getLabel = getFeatureLabelResolver(labelContext, timelineYear);
const features: Feature[] = []; const features: Feature[] = [];
for (const feature of fc.features) { for (const feature of fc.features) {
@@ -762,6 +772,40 @@ export function roundZoom(value: number): number {
return Math.round(value * 10) / 10; return Math.round(value * 10) / 10;
} }
export function getFeatureLabelResolver(
fc: FeatureCollection,
timelineYear?: number | null
): (feature: Feature) => string | null {
let yearMap = resolverCache.get(fc);
if (!yearMap) {
yearMap = new Map();
resolverCache.set(fc, yearMap);
}
let resolver = yearMap.get(timelineYear);
if (!resolver) {
resolver = createFeatureLabelResolver(fc, timelineYear);
yearMap.set(timelineYear, resolver);
}
return resolver;
}
function getSingleEntityFeatureLabelInfoCached(
feature: Feature,
timelineYear?: number | null
): FeatureLabelInfo | null {
let yearMap = featureLabelInfoCache.get(feature);
if (!yearMap) {
yearMap = new Map();
featureLabelInfoCache.set(feature, yearMap);
}
let info = yearMap.get(timelineYear);
if (info === undefined) {
info = getSingleEntityFeatureLabelInfo(feature, timelineYear);
yearMap.set(timelineYear, info);
}
return info;
}
function createFeatureLabelResolver( function createFeatureLabelResolver(
fc: FeatureCollection, fc: FeatureCollection,
timelineYear?: number | null timelineYear?: number | null
@@ -770,7 +814,7 @@ function createFeatureLabelResolver(
const inheritedLabelsByChildId = new Map<string, FeatureLabelInfo | null>(); const inheritedLabelsByChildId = new Map<string, FeatureLabelInfo | null>();
for (const feature of fc.features) { for (const feature of fc.features) {
const labelInfo = getSingleEntityFeatureLabelInfo(feature, timelineYear); const labelInfo = getSingleEntityFeatureLabelInfoCached(feature, timelineYear);
if (!labelInfo) continue; if (!labelInfo) continue;
directLabelsByFeatureId.set(String(feature.properties.id), labelInfo); directLabelsByFeatureId.set(String(feature.properties.id), labelInfo);
} }
+246
View File
@@ -0,0 +1,246 @@
import { useEffect, useRef } from "react";
import maplibregl from "maplibre-gl";
import type { Feature, FeatureCollection } from "@/uhm/lib/editor/state/useEditorState";
import { FEATURE_STATE_SOURCE_IDS } from "@/uhm/lib/map/constants";
export type MapHoverPopupContent = {
rows: Array<{
title: string;
quote?: string | null;
}>;
};
type UseMapHoverPopupProps = {
mapRef: React.MutableRefObject<maplibregl.Map | null>;
enabled: boolean;
renderDraftRef: React.MutableRefObject<FeatureCollection>;
getContentRef: React.MutableRefObject<((feature: Feature) => MapHoverPopupContent | null) | undefined>;
};
export function useMapHoverPopup({
mapRef,
enabled,
renderDraftRef,
getContentRef,
}: UseMapHoverPopupProps) {
const enabledRef = useRef(enabled);
useEffect(() => {
enabledRef.current = enabled;
}, [enabled]);
useEffect(() => {
const map = mapRef.current;
if (!map) return;
const popup = new maplibregl.Popup({
closeButton: false,
closeOnClick: false,
offset: 12,
className: "uhm-map-hover-popup",
});
let hoveredId: string | null = null;
let frameId: number | null = null;
let pendingEvent: maplibregl.MapMouseEvent | null = null;
const removePopup = () => {
hoveredId = null;
popup.remove();
};
const updatePopup = () => {
frameId = null;
const event = pendingEvent;
pendingEvent = null;
if (!event || !enabledRef.current) {
removePopup();
return;
}
const layerIds = getHoverLayerIds(map);
if (!layerIds.length) {
removePopup();
return;
}
const features = map.queryRenderedFeatures(event.point, { layers: layerIds }) as maplibregl.MapGeoJSONFeature[];
if (!features.length) {
removePopup();
return;
}
const renderedFeature = pickPreferredFeature(features);
const rawId = renderedFeature.id ?? renderedFeature.properties?.id;
if (rawId === undefined || rawId === null) {
removePopup();
return;
}
const id = String(rawId);
const sourceFeature = renderDraftRef.current.features.find((item) => String(item.properties.id) === id);
if (!sourceFeature) {
removePopup();
return;
}
const content = getContentRef.current?.(sourceFeature) || null;
if (!content?.rows?.some((row) => row.title.trim())) {
removePopup();
return;
}
if (id !== hoveredId) {
hoveredId = id;
popup.setDOMContent(buildPopupNode(content));
}
popup.setLngLat(event.lngLat).addTo(map);
stylePopupChrome(popup);
};
const onMouseMove = (event: maplibregl.MapMouseEvent) => {
pendingEvent = event;
if (frameId !== null) return;
frameId = window.requestAnimationFrame(updatePopup);
};
const onMouseOut = () => {
pendingEvent = null;
if (frameId !== null) {
window.cancelAnimationFrame(frameId);
frameId = null;
}
removePopup();
};
map.on("mousemove", onMouseMove);
map.on("mouseout", onMouseOut);
map.on("dragstart", removePopup);
map.on("zoomstart", removePopup);
return () => {
if (frameId !== null) {
window.cancelAnimationFrame(frameId);
}
map.off("mousemove", onMouseMove);
map.off("mouseout", onMouseOut);
map.off("dragstart", removePopup);
map.off("zoomstart", removePopup);
popup.remove();
};
}, [getContentRef, mapRef, renderDraftRef]);
}
function getHoverLayerIds(map: maplibregl.Map): string[] {
const style = map.getStyle();
if (!style?.layers) return [];
return style.layers
.filter((layer) =>
"source" in layer &&
typeof layer.source === "string" &&
FEATURE_STATE_SOURCE_IDS.includes(layer.source as (typeof FEATURE_STATE_SOURCE_IDS)[number])
)
.map((layer) => layer.id);
}
function pickPreferredFeature(features: maplibregl.MapGeoJSONFeature[]) {
return [...features].sort((a, b) => featureSelectPriority(b) - featureSelectPriority(a))[0];
}
function featureSelectPriority(feature: maplibregl.MapGeoJSONFeature) {
const layerId = typeof feature.layer?.id === "string" ? feature.layer.id : "";
const geometryType = feature.geometry?.type;
const source = typeof feature.source === "string" ? feature.source : "";
if (layerId.endsWith("-hit")) return 400;
if (source === "path-arrow-shapes") return 300;
if (geometryType === "LineString" || geometryType === "MultiLineString") return 200;
if (geometryType === "Point" || geometryType === "MultiPoint") return 100;
return 0;
}
function buildPopupNode(content: MapHoverPopupContent): HTMLElement {
const root = document.createElement("div");
root.style.width = "320px";
root.style.maxWidth = "calc(100vw - 2rem)";
root.style.maxHeight = "300px";
root.style.overflowY = "auto";
root.style.padding = "12px";
root.style.border = "1px solid rgba(255, 255, 255, 0.10)";
root.style.borderRadius = "12px";
root.style.background = "rgba(2, 6, 23, 0.95)";
root.style.boxShadow = "0 18px 36px rgba(0, 0, 0, 0.35)";
root.style.backdropFilter = "blur(8px)";
root.style.color = "#e2e8f0";
const grid = document.createElement("div");
grid.style.display = "grid";
grid.style.gap = "8px";
root.appendChild(grid);
for (const row of content.rows) {
const titleText = row.title.trim();
if (!titleText) continue;
const card = document.createElement("div");
card.style.width = "100%";
card.style.border = "1px solid rgba(255, 255, 255, 0.10)";
card.style.borderRadius = "8px";
card.style.background = "rgba(255, 255, 255, 0.03)";
card.style.padding = "12px";
card.style.textAlign = "left";
const title = document.createElement("div");
title.textContent = titleText;
title.style.fontSize = "14px";
title.style.fontWeight = "700";
title.style.lineHeight = "20px";
title.style.color = "#ffffff";
title.style.overflow = "hidden";
title.style.textOverflow = "ellipsis";
title.style.whiteSpace = "nowrap";
card.appendChild(title);
const quoteText = row.quote?.trim();
if (quoteText) {
const quote = document.createElement("div");
quote.textContent = quoteText;
quote.style.marginTop = "8px";
quote.style.paddingLeft = "10px";
quote.style.paddingRight = "4px";
quote.style.borderLeft = "3px solid rgba(56, 189, 248, 0.40)";
quote.style.fontSize = "14px";
quote.style.fontStyle = "italic";
quote.style.lineHeight = "20px";
quote.style.color = "#cbd5e1";
quote.style.display = "-webkit-box";
quote.style.webkitLineClamp = "4";
quote.style.webkitBoxOrient = "vertical";
quote.style.overflow = "hidden";
quote.style.whiteSpace = "normal";
card.appendChild(quote);
}
grid.appendChild(card);
}
return root;
}
function stylePopupChrome(popup: maplibregl.Popup) {
const element = popup.getElement();
const content = element.querySelector(".maplibregl-popup-content") as HTMLElement | null;
if (content) {
content.style.padding = "0";
content.style.borderRadius = "12px";
content.style.background = "transparent";
content.style.boxShadow = "none";
}
for (const tip of Array.from(element.querySelectorAll(".maplibregl-popup-tip")) as HTMLElement[]) {
tip.style.display = "none";
}
}
+4 -1
View File
@@ -38,6 +38,7 @@ type UseMapInteractionProps = {
onBindGeometriesRef?: React.MutableRefObject<((targetId: string | number, sourceIds: (string | number)[]) => void) | undefined>; onBindGeometriesRef?: React.MutableRefObject<((targetId: string | number, sourceIds: (string | number)[]) => void) | undefined>;
localFeatureIdsRef?: React.MutableRefObject<(string | number)[] | undefined>; localFeatureIdsRef?: React.MutableRefObject<(string | number)[] | undefined>;
onAddFeatureToProjectRef?: React.MutableRefObject<((feature: FeatureCollection["features"][number]) => void) | undefined>; onAddFeatureToProjectRef?: React.MutableRefObject<((feature: FeatureCollection["features"][number]) => void) | undefined>;
allowFeatureSelection?: boolean;
}; };
export function useMapInteraction({ export function useMapInteraction({
@@ -57,6 +58,7 @@ export function useMapInteraction({
onBindGeometriesRef, onBindGeometriesRef,
localFeatureIdsRef, localFeatureIdsRef,
onAddFeatureToProjectRef, onAddFeatureToProjectRef,
allowFeatureSelection = true,
}: UseMapInteractionProps) { }: UseMapInteractionProps) {
const editingEngineRef = useRef<ReturnType<typeof createEditingEngine> | null>(null); const editingEngineRef = useRef<ReturnType<typeof createEditingEngine> | null>(null);
const engineBindingsRef = useRef<Partial<Record<EditorMode, EngineBinding>>>({}); const engineBindingsRef = useRef<Partial<Record<EditorMode, EngineBinding>>>({});
@@ -223,7 +225,8 @@ export function useMapInteraction({
if (!Array.isArray(localIds)) return true; if (!Array.isArray(localIds)) return true;
return localIds.some((localId) => String(localId) === String(id)); return localIds.some((localId) => String(localId) === String(id));
} }
: undefined : undefined,
() => allowFeatureSelection
); );
const cleanupPoint = initPoint( const cleanupPoint = initPoint(
+355 -21
View File
@@ -54,23 +54,27 @@ export default function TimelineBar({
const lastTriggerTimeRef = useRef<number>(0); const lastTriggerTimeRef = useRef<number>(0);
const commitYearChange = useCallback((nextVal: number) => { const commitYearChange = useCallback((nextVal: number) => {
if (nextVal === lastTriggeredYearRef.current) return; const clamped = clampYearValue(Math.trunc(nextVal), lower, upper);
lastTriggeredYearRef.current = nextVal; if (!Number.isFinite(clamped)) return;
lastTriggeredYearRef.current = clamped;
lastTriggerTimeRef.current = Date.now(); lastTriggerTimeRef.current = Date.now();
onYearChangeRef.current(nextVal); onYearChangeRef.current(clamped);
if (debounceTimerRef.current) { if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current); clearTimeout(debounceTimerRef.current);
debounceTimerRef.current = null; debounceTimerRef.current = null;
} }
}, []); }, [lower, upper]);
const handleLocalYearChange = useCallback((nextVal: number) => { const handleLocalYearChange = useCallback((nextVal: number) => {
if (!Number.isFinite(nextVal)) {
return;
}
const clamped = clampYearValue(Math.trunc(nextVal), lower, upper); const clamped = clampYearValue(Math.trunc(nextVal), lower, upper);
localYearRef.current = clamped; localYearRef.current = clamped;
setLocalYear(clamped); setLocalYear(clamped);
const now = Date.now(); const now = Date.now();
if (now - lastTriggerTimeRef.current >= 1000) { if (now - lastTriggerTimeRef.current >= 100) {
commitYearChange(clamped); commitYearChange(clamped);
} else { } else {
if (debounceTimerRef.current) { if (debounceTimerRef.current) {
@@ -78,7 +82,7 @@ export default function TimelineBar({
} }
debounceTimerRef.current = setTimeout(() => { debounceTimerRef.current = setTimeout(() => {
commitYearChange(clamped); commitYearChange(clamped);
}, 1000); }, 100);
} }
}, [lower, upper, commitYearChange]); }, [lower, upper, commitYearChange]);
@@ -87,6 +91,12 @@ export default function TimelineBar({
setLocalYear(null); setLocalYear(null);
}, [commitYearChange]); }, [commitYearChange]);
useEffect(() => {
if (localYear !== null) return;
localYearRef.current = safeYear;
lastTriggeredYearRef.current = safeYear;
}, [localYear, safeYear]);
const startChangingYear = (direction: number) => { const startChangingYear = (direction: number) => {
if (effectiveDisabled) return; if (effectiveDisabled) return;
const nextVal = localYearRef.current + direction; const nextVal = localYearRef.current + direction;
@@ -163,23 +173,14 @@ export default function TimelineBar({
</span> </span>
</button> </button>
) : null} ) : null}
<span className={styles.labelBounds}>{formatYear(lower)}</span> <CanvasTimelineRuler
<input year={displayYear}
type="range" onYearChange={handleLocalYearChange}
min={lower} onYearCommit={finishLocalYearChange}
max={upper} minYear={lower}
step={1} maxYear={upper}
value={displayYear}
onChange={(event) => handleLocalYearChange(Number(event.target.value))}
onMouseUp={finishLocalYearChange}
onTouchEnd={finishLocalYearChange}
disabled={effectiveDisabled} disabled={effectiveDisabled}
className={styles.slider}
aria-label="Timeline year"
/> />
<span className={styles.labelBoundsRight}>
{formatYear(upper)}
</span>
<div className={styles.numberWrapper}> <div className={styles.numberWrapper}>
<input <input
type="number" type="number"
@@ -259,3 +260,336 @@ function formatYear(year: number): string {
} }
return `${year}`; return `${year}`;
} }
interface CanvasRulerProps {
year: number;
onYearChange: (year: number) => void;
onYearCommit: () => void;
minYear: number;
maxYear: number;
disabled?: boolean;
}
function CanvasTimelineRuler({
year,
onYearChange,
onYearCommit,
minYear,
maxYear,
disabled = false,
}: CanvasRulerProps) {
const containerRef = useRef<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
// Visible span (in years)
const [span, setSpan] = useState(400); // default show 400 years
// Dimensions
const [dimensions, setDimensions] = useState({ width: 0, height: 48 });
// Internal tracker for current display year to decouple render lag
const displayYearRef = useRef(year);
// Dragging state
const dragRef = useRef<{
isDragging: boolean;
startX: number;
startYear: number;
hasDragged: boolean;
} | null>(null);
// Sync dimensions using ResizeObserver
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const observer = new ResizeObserver((entries) => {
if (!entries || !entries[0]) return;
const { width, height } = entries[0].contentRect;
setDimensions({ width, height: height || 48 });
});
observer.observe(container);
return () => observer.disconnect();
}, []);
// Draw the ruler on canvas
const drawYear = useCallback((currentYear: number) => {
const canvas = canvasRef.current;
if (!canvas || dimensions.width === 0) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const dpr = window.devicePixelRatio || 1;
const width = dimensions.width;
const height = dimensions.height;
ctx.clearRect(0, 0, width, height);
ctx.save();
ctx.scale(dpr, dpr);
// Center year is the selected year
const startYear = currentYear - span / 2;
const endYear = currentYear + span / 2;
const yearToX = (y: number) => {
return ((y - startYear) / span) * width;
};
// Determine tick step based on span
let majorStep = 100;
let mediumStep = 10;
let minorStep = 1;
if (span > 3000) {
majorStep = 1000;
mediumStep = 100;
minorStep = 10;
} else if (span > 1500) {
majorStep = 500;
mediumStep = 50;
minorStep = 10;
} else if (span > 600) {
majorStep = 100;
mediumStep = 20;
minorStep = 5;
} else if (span > 200) {
majorStep = 100;
mediumStep = 10;
minorStep = 1;
} else if (span > 60) {
majorStep = 50;
mediumStep = 10;
minorStep = 1;
} else {
majorStep = 10;
mediumStep = 5;
minorStep = 1;
}
// Ticks drawing bounds
const firstMajor = Math.floor(startYear / majorStep) * majorStep;
const lastMajor = Math.ceil(endYear / majorStep) * majorStep;
const pixelsPerYear = width / span;
const showMinor = pixelsPerYear * minorStep >= 3;
const showMedium = pixelsPerYear * mediumStep >= 5;
// Draw ruler track baseline
ctx.beginPath();
ctx.moveTo(0, height - 8);
ctx.lineTo(width, height - 8);
ctx.strokeStyle = "rgba(255, 255, 255, 0.15)";
ctx.lineWidth = 1;
ctx.stroke();
// 1. Draw minor & medium ticks
ctx.beginPath();
for (let y = Math.floor(startYear); y <= Math.ceil(endYear); y++) {
if (y < minYear || y > maxYear) continue;
const isMajor = y % majorStep === 0;
const isMedium = y % mediumStep === 0;
const isMinor = y % minorStep === 0;
if (isMajor) continue;
let tickHeight = 0;
if (isMedium && showMedium) {
tickHeight = 7;
ctx.strokeStyle = "rgba(255, 255, 255, 0.35)";
} else if (isMinor && showMinor) {
tickHeight = 4;
ctx.strokeStyle = "rgba(255, 255, 255, 0.12)";
}
if (tickHeight > 0) {
const x = yearToX(y);
ctx.moveTo(x, height - 8);
ctx.lineTo(x, height - 8 - tickHeight);
}
}
ctx.lineWidth = 1;
ctx.stroke();
// 2. Draw major ticks and labels
ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
ctx.font = "600 10px system-ui, -apple-system, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "top";
for (let y = firstMajor; y <= lastMajor; y += majorStep) {
if (y < minYear || y > maxYear) continue;
const x = yearToX(y);
// Draw tick line
ctx.beginPath();
ctx.moveTo(x, height - 8);
ctx.lineTo(x, height - 20);
ctx.strokeStyle = "rgba(255, 255, 255, 0.65)";
ctx.lineWidth = 1.25;
ctx.stroke();
// Draw label
const label = formatYear(y);
ctx.fillText(label, x, height - 33);
}
// 3. Draw needle indicator in the center
const needleX = width / 2;
ctx.beginPath();
ctx.moveTo(needleX, 0);
ctx.lineTo(needleX, height - 4);
ctx.strokeStyle = "#10b981";
ctx.lineWidth = 2;
ctx.shadowColor = "rgba(16, 185, 129, 0.6)";
ctx.shadowBlur = 6;
ctx.stroke();
// Draw needle head triangle
ctx.fillStyle = "#10b981";
ctx.beginPath();
ctx.moveTo(needleX - 5, 0);
ctx.lineTo(needleX + 5, 0);
ctx.lineTo(needleX, 6);
ctx.closePath();
ctx.fill();
ctx.restore();
}, [span, dimensions, minYear, maxYear]);
// Redraw when dimensions change
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas || dimensions.width === 0) return;
const dpr = window.devicePixelRatio || 1;
canvas.width = dimensions.width * dpr;
canvas.height = dimensions.height * dpr;
drawYear(displayYearRef.current);
}, [dimensions, drawYear]);
// Redraw when span changes
useEffect(() => {
drawYear(displayYearRef.current);
}, [span, drawYear]);
// Sync externally changed year
useEffect(() => {
if (!dragRef.current || !dragRef.current.isDragging) {
displayYearRef.current = year;
drawYear(year);
}
}, [year, drawYear]);
const handleWheel = (e: React.WheelEvent) => {
if (disabled) return;
e.preventDefault();
const zoomFactor = e.deltaY > 0 ? 1.15 : 0.85;
const nextSpan = Math.max(10, Math.min(10000, span * zoomFactor));
setSpan(Math.round(nextSpan));
};
const handlePointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {
if (disabled) return;
e.preventDefault();
try {
e.currentTarget.setPointerCapture(e.pointerId);
} catch {}
dragRef.current = {
isDragging: true,
startX: e.clientX,
startYear: displayYearRef.current,
hasDragged: false,
};
};
const handlePointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {
if (!dragRef.current || !dragRef.current.isDragging) return;
e.preventDefault();
const dx = e.clientX - dragRef.current.startX;
if (Math.abs(dx) > 3) {
dragRef.current.hasDragged = true;
}
const yearsPerPixel = span / dimensions.width;
const deltaYears = -dx * yearsPerPixel;
const nextYear = clampYearValue(Math.round(dragRef.current.startYear + deltaYears), minYear, maxYear);
if (nextYear !== displayYearRef.current) {
displayYearRef.current = nextYear;
// Draw synchronously at 60fps
requestAnimationFrame(() => {
drawYear(displayYearRef.current);
});
onYearChange(nextYear);
}
};
const handlePointerUp = (e: React.PointerEvent<HTMLCanvasElement>) => {
if (!dragRef.current) return;
e.preventDefault();
try {
e.currentTarget.releasePointerCapture(e.pointerId);
} catch {}
const dragInfo = dragRef.current;
dragRef.current = null;
if (!dragInfo.hasDragged) {
// Click to jump
const canvas = canvasRef.current;
if (canvas) {
const rect = canvas.getBoundingClientRect();
const clickedX = e.clientX - rect.left;
const centerYear = displayYearRef.current;
const startYear = centerYear - span / 2;
const clickedYear = clampYearValue(
Math.round(startYear + (clickedX / rect.width) * span),
minYear,
maxYear
);
displayYearRef.current = clickedYear;
drawYear(clickedYear);
onYearChange(clickedYear);
}
}
onYearCommit();
};
return (
<div
ref={containerRef}
style={{
flex: 1,
height: 44,
position: "relative",
background: "rgba(255, 255, 255, 0.04)",
borderRadius: 22,
border: "1px solid rgba(255, 255, 255, 0.08)",
overflow: "hidden",
cursor: disabled ? "not-allowed" : "ew-resize",
}}
onWheel={handleWheel}
>
<canvas
ref={canvasRef}
style={{
display: "block",
width: "100%",
height: "100%",
}}
onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
onPointerCancel={handlePointerUp}
/>
</div>
);
}
+11 -4
View File
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState, memo } from "react";
import "react-quill-new/dist/quill.snow.css"; import "react-quill-new/dist/quill.snow.css";
import type { Entity } from "@/uhm/api/entities"; import type { Entity } from "@/uhm/api/entities";
@@ -22,6 +22,7 @@ type Props = {
sidebarWidth?: number; sidebarWidth?: number;
onSidebarWidthChange?: (width: number) => void; onSidebarWidthChange?: (width: number) => void;
maxDragWidth?: number; maxDragWidth?: number;
compactHeader?: boolean;
}; };
function escapeHtml(input: string): string { function escapeHtml(input: string): string {
@@ -50,6 +51,7 @@ function slugifyHeading(raw: string): string {
if (!input.length) return ""; if (!input.length) return "";
return input return input
.toLowerCase() .toLowerCase()
.replace(/đ/g, "d")
.normalize("NFKD") .normalize("NFKD")
.replace(/[\u0300-\u036f]/g, "") .replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9]+/g, "-") .replace(/[^a-z0-9]+/g, "-")
@@ -122,7 +124,7 @@ function prepareWikiHtml(inputHtml: string): { html: string; toc: TocItem[] } {
return { html: doc.body.innerHTML, toc }; return { html: doc.body.innerHTML, toc };
} }
export default function PublicWikiSidebar({ function PublicWikiSidebar({
entity, entity,
wiki, wiki,
isLoading, isLoading,
@@ -132,6 +134,7 @@ export default function PublicWikiSidebar({
sidebarWidth, sidebarWidth,
onSidebarWidthChange, onSidebarWidthChange,
maxDragWidth, maxDragWidth,
compactHeader = false,
}: Props) { }: Props) {
const contentRootRef = useRef<HTMLDivElement | null>(null); const contentRootRef = useRef<HTMLDivElement | null>(null);
const tocContainerRef = useRef<HTMLDivElement | null>(null); const tocContainerRef = useRef<HTMLDivElement | null>(null);
@@ -311,6 +314,7 @@ export default function PublicWikiSidebar({
> >
<div style={{ display: "flex", alignItems: "start", justifyContent: "space-between", gap: 12 }}> <div style={{ display: "flex", alignItems: "start", justifyContent: "space-between", gap: 12 }}>
<div style={{ minWidth: 0, flex: 1 }}> <div style={{ minWidth: 0, flex: 1 }}>
{compactHeader ? null : (
<div <div
style={{ style={{
fontSize: 10, fontSize: 10,
@@ -322,9 +326,10 @@ export default function PublicWikiSidebar({
> >
Wiki Wiki
</div> </div>
)}
<div <div
style={{ style={{
marginTop: 4, marginTop: compactHeader ? 0 : 4,
fontSize: 18, fontSize: 18,
fontWeight: 700, fontWeight: 700,
lineHeight: 1.3, lineHeight: 1.3,
@@ -345,7 +350,7 @@ export default function PublicWikiSidebar({
{entity.description.trim()} {entity.description.trim()}
</div> </div>
) : null} ) : null}
{wiki?.title?.trim() && wiki.title.trim() !== entity?.name?.trim() ? ( {!compactHeader && wiki?.title?.trim() && wiki.title.trim() !== entity?.name?.trim() ? (
<div <div
style={{ style={{
marginTop: 6, marginTop: 6,
@@ -638,3 +643,5 @@ export default function PublicWikiSidebar({
</div> </div>
); );
} }
export default memo(PublicWikiSidebar);
+6 -4
View File
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useCallback, useEffect, useMemo, useRef, useState, type ComponentProps } from "react"; import { useCallback, useEffect, useMemo, useRef, useState, memo, type ComponentProps } from "react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import "react-quill-new/dist/quill.snow.css"; import "react-quill-new/dist/quill.snow.css";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
@@ -64,7 +64,7 @@ function clampTitle(title: string) {
return t.length ? t.slice(0, 120) : "Untitled wiki"; return t.length ? t.slice(0, 120) : "Untitled wiki";
} }
export default function WikiSidebarPanel({ projectId, setWikis, onRemoveWiki }: Props) { function WikiSidebarPanel({ projectId, setWikis, onRemoveWiki }: Props) {
const { wikis, requestedActiveId } = useEditorStore( const { wikis, requestedActiveId } = useEditorStore(
useShallow((state) => ({ useShallow((state) => ({
wikis: state.snapshotWikis, wikis: state.snapshotWikis,
@@ -1001,8 +1001,7 @@ export default function WikiSidebarPanel({ projectId, setWikis, onRemoveWiki }:
</div> </div>
</div> </div>
<span <span
className={`text-[11px] font-semibold px-2 py-0.5 rounded-full border ${ className={`text-[11px] font-semibold px-2 py-0.5 rounded-full border ${w.source === "local"
w.source === "local"
? "border-emerald-300/60 text-emerald-600 dark:text-emerald-300" ? "border-emerald-300/60 text-emerald-600 dark:text-emerald-300"
: "border-blue-300/60 text-blue-600 dark:text-blue-300" : "border-blue-300/60 text-blue-600 dark:text-blue-300"
}`} }`}
@@ -1110,6 +1109,7 @@ function slugifyWikiTitle(raw: string): string {
if (!input.length) return ""; if (!input.length) return "";
return input return input
.toLowerCase() .toLowerCase()
.replace(/đ/g, "d")
.normalize("NFKD") .normalize("NFKD")
.replace(/[\u0300-\u036f]/g, "") .replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9]+/g, "-") .replace(/[^a-z0-9]+/g, "-")
@@ -1149,3 +1149,5 @@ function downloadTextFile(filename: string, contents: string, mime: string): voi
a.remove(); a.remove();
window.setTimeout(() => URL.revokeObjectURL(url), 0); window.setTimeout(() => URL.revokeObjectURL(url), 0);
} }
export default memo(WikiSidebarPanel);
+10 -1
View File
@@ -26,6 +26,15 @@ export function isFeatureVisibleAtYear(feature: Feature, year: number): boolean
return true; return true;
} }
function getFastHash(str: string | null | undefined): number {
if (!str) return 0;
let hash = 5381;
for (let i = 0; i < str.length; i++) {
hash = (hash * 33) ^ str.charCodeAt(i);
}
return hash >>> 0;
}
// Chuẩn hóa wiki snapshot để so sánh dirty-state ổn định, không phụ thuộc thứ tự mảng. // Chuẩn hóa wiki snapshot để so sánh dirty-state ổn định, không phụ thuộc thứ tự mảng.
export function normalizeWikisForCompare(input: WikiSnapshot[] | null | undefined) { export function normalizeWikisForCompare(input: WikiSnapshot[] | null | undefined) {
const list = Array.isArray(input) ? input : []; const list = Array.isArray(input) ? input : [];
@@ -43,7 +52,7 @@ export function normalizeWikisForCompare(input: WikiSnapshot[] | null | undefine
source: w.source, source: w.source,
title: typeof w.title === "string" ? w.title.trim() : "", title: typeof w.title === "string" ? w.title.trim() : "",
slug: typeof w.slug === "string" ? w.slug : null, slug: typeof w.slug === "string" ? w.slug : null,
doc: w.doc === null ? null : typeof w.doc === "string" ? w.doc.trim() : null, docHash: typeof w.doc === "string" ? getFastHash(w.doc.trim()) : 0,
})) }))
.sort((a, b) => a.id.localeCompare(b.id)); .sort((a, b) => a.id.localeCompare(b.id));
} }
+18 -4
View File
@@ -21,7 +21,8 @@ export function initSelect(
onBindGeometries?: (targetId: string | number, sourceIds: (string | number)[]) => void, onBindGeometries?: (targetId: string | number, sourceIds: (string | number)[]) => void,
onFeatureClick?: (payload: SelectFeatureClickPayload | null) => void, onFeatureClick?: (payload: SelectFeatureClickPayload | null) => void,
onAddToProject?: (feature: maplibregl.MapGeoJSONFeature) => void, onAddToProject?: (feature: maplibregl.MapGeoJSONFeature) => void,
isLocalFeature?: (id: string | number) => boolean isLocalFeature?: (id: string | number) => boolean,
allowFeatureSelection?: () => boolean
) { ) {
const FEATURE_STATE_SOURCES = [ const FEATURE_STATE_SOURCES = [
@@ -85,21 +86,34 @@ export function initSelect(
}) as maplibregl.MapGeoJSONFeature[]; }) as maplibregl.MapGeoJSONFeature[];
if (!features.length) { if (!features.length) {
if (allowFeatureSelection && !allowFeatureSelection()) {
onFeatureClick?.(null);
return;
}
clearSelection(); clearSelection();
onFeatureClick?.(null); onFeatureClick?.(null);
return; return;
} }
const additive = !!e.originalEvent?.altKey;
const feature = pickPreferredFeature(features); const feature = pickPreferredFeature(features);
const id = feature.id ?? feature.properties?.id;
if (id === undefined || id === null) return;
if (allowFeatureSelection && !allowFeatureSelection()) {
onFeatureClick?.({
featureId: id,
point: { x: e.point.x, y: e.point.y },
lngLat: { lng: e.lngLat.lng, lat: e.lngLat.lat },
});
return;
}
const additive = !!e.originalEvent?.altKey;
const didSelect = selectFeature(feature, additive); const didSelect = selectFeature(feature, additive);
if (!didSelect) { if (!didSelect) {
onFeatureClick?.(null); onFeatureClick?.(null);
return; return;
} }
const id = feature.id ?? feature.properties?.id;
if (id === undefined || id === null) return;
onFeatureClick?.({ onFeatureClick?.({
featureId: id, featureId: id,
point: { x: e.point.x, y: e.point.y }, point: { x: e.point.x, y: e.point.y },
@@ -0,0 +1,60 @@
<h1>Chiến tranh Nguyên Mông Đại Việt lần 1</h1>
<p><b>Chiến tranh Mông Nguyên Đại Việt lần thứ nhất</b> hay <b>Kháng chiến chống Mông Nguyên lần thứ nhất</b> là cách người Việt Nam gọi cuộc chiến đấu của quân dân <a href="__missing__">Đại Việt</a> chống lại quân đội của <a href="__missing__">đế quốc Mông Cổ</a> do <a href="__missing__">Uriyangqatai</a> (Ngột Lương Hợp Thai) chỉ huy vào trong khoảng thời gian nửa tháng cuối tháng 1 năm <a href="__missing__">1258</a> (hay năm Nguyên Phong thứ 7.</p>
<p>Cuộc chiến mở đầu với <a href="__missing__">trận Bình Lệ Nguyên</a>, sau đó là <a href="__missing__">trận Phù Lỗ</a>. Quân Mông Cổ thắng 2 trận này, nhưng họ không diệt được đạo quân chủ lực của nhà Trần. Quân Mông Cổ tiến vào kinh thành của Đại Việt trong 9 ngày. Quân đội nhà Trần đã phản công, đại phá quân Mông trong <a href="__missing__">trận Đông Bộ Đầu</a> khiến cho đội quân này phải chạy về phía Bắc, sau đó còn phải hứng chịu một cuộc tập kích khác của thủ lĩnh miền núi là <a href="__missing__">Hà Bổng</a>. Cuộc chiến này đã kết thúc với <a href="__missing__">chiến thắng</a> của nước Đại Việt, ghi dấu công lao của vua <a href="__missing__">Trần Thái Tông</a> trong việc lãnh đạo quân dân Đại Việt chiến đấu chống quân đội <a href="__missing__">Mông Cổ</a>.</p>
<h2>Bối cảnh</h2><a href="__missing__"></a>Bản đồ Đại Việt, Mông Cổ, Nam Tống, năm 1257
<p>Vào năm 1206, <a href="__missing__">Thành Cát Tư Hãn</a> đã thành công trong việc thống nhất các bộ lạc Mông Cổ, từ đó <a href="__missing__">Đế quốc Mông Cổ</a> liên tục thực hiện nhiều cuộc chiến nhằm mở rộng đế quốc của mình. 50 năm sau, đến đời Đại hãn thứ 4, tức <a href="__missing__">Mông Kha</a>, ông đã tiến hành các chiến dịch tấn công nước <a href="__missing__">Nam Tống</a> (<a href="__missing__">Trung Quốc</a>). Mông Kha muốn đánh vào sườn nhà Tống thông qua việc cử em trai là <a href="__missing__">Hốt Tất Liệt</a> đánh <a href="__missing__">Đại Lý</a>. Đánh Đại Lý xong vào năm 1253, Hốt Tất Liệt trở về, ra lệnh cho <a href="__missing__">Ngột Lương Hợp Thai</a> ở lại đánh các nước chưa hàng phục.</p>
<p>Đến năm 1257, việc chiếm Đại Việt nằm trong chiến lược tổng thể của quân đội Mông Cổ nhằm tiêu diệt Nam Tống. Bốn cánh quân Mông Cổ sẽ tấn công <a href="__missing__">Nam Tống</a> từ những địa điểm khác nhau từ phía Nam và phía Tây. Nắm quyền chỉ huy 3 cánh quân kia là <a href="__missing__">Mông Kha</a>, <a href="__missing__">Hốt Tất Liệt</a> và <a href="__missing__">Tháp Sát Nhi</a>. Cánh quân còn lại cánh quân thứ tư, sau khi chiếm <a href="__missing__">Đại Việt</a> sẽ đánh thốc vào Nam Tống từ mạn cực Nam. Tổng chỉ huy của cánh quân thứ tư là <a href="__missing__">Ngột Lương Hợp Thai</a>. Nhà Trần (Đại Việt) được thành lập vào năm 1225, đến thời điểm nhà Nguyên xâm phạm, đã có nền hòa bình 180 năm kể từ khi nhà Tống xâm lược vào năm 1076.</p>
<h2>Lực lượng</h2>
<ul><li>Theo Tập sử biên niên của Rasìd ud-Dìn: Quân đội của Ngột Lương Hợp Thai gồm <a href="__missing__">kỵ binh</a> Mông Cổ và 20.000 quân sĩ người Di (thuộc nước <a href="__missing__">Đại Lý</a> vừa bị Mông Cổ chinh phục). Không có số liệu chính xác về số kỵ binh Mông Cổ, nhưng theo Rasìd ud-Dìn (Tập sử biên niên) cho biết rằng ban đầu Hốt Tất Liệt và Ngột Lương Hợp Thai đã đem 3 vạn quân xuống đánh Đại Lý (Vân Nam), sau đó Hốt Tất Liệt đi hướng khác, còn Ngột Lương Hợp Thai đánh tiếp sang Đại Việt, khi tiến lên châu Ngạc gặp Hốt Tất Liệt thì quân số còn lại không quá 5.000. Như vậy, trừ đi số tổn thất khi đánh Đại Lý và số kỵ binh đi theo Hốt Tất Liệt, thì số kỵ binh Mông Cổ khi tiến đánh Đại Việt sẽ vào khoảng 10.000 là hợp lý. Cộng thêm quân người Di thì tổng số quân của Mông Cổ có khoảng 30.000. Tiên phong là tướng <a href="__missing__">Aju</a> và <a href="__missing__">Cacakdu</a> (Triệu Triệt Đô hay Triệt Triệt Đô). Ngoài ra, đội quân này còn có phò mã của Mông Cổ là <a href="__missing__">Quaidu</a> (Hoài Đô). Đi tiên phong là <a href="__missing__">Đoàn Hưng Trí</a> vua <a href="__missing__">Đại Lý</a> đã đầu hàng.</li><li>Theo sách <i>Nghệ thuật đánh giặc giữ nước của dân tộc Việt Nam</i> thì quân Mông Cổ có khoảng 1 đến 2 vạn, cộng với 2 vạn quân <a href="__missing__">Đại Lý</a> được Mông Cổ trưng dụng, tổng số là khoảng 3 đến 4 vạn.[<i><a href="__missing__">cần dẫn nguồn</a></i>]</li><li>Quân Đại Việt, gồm quân cấm vệ và quân địa phương, có khoảng 10 vạn, trong đó có 2 vạn cấm quân (lực lượng chủ lực đóng ở gần kinh thành) và 8 vạn sương quân (quân đóng ở các địa phương). Quân Trần có đủ các binh chủng <a href="__missing__">bộ binh</a>, <a href="__missing__">kỵ binh</a>, <a href="__missing__">tượng binh</a> và <a href="__missing__">thủy binh</a> đã được thao luyện chu đáo. 2 vạn cấm quân có thể huy động toàn bộ, nhưng 8 vạn sương quân thì phải đóng quân rải khắp trên lãnh thổ cả nước, bao gồm việc ngăn ngừa nổi loạn, chống đạo tặc, canh gác biên giới và lăng tẩm... nên nhà Trần chỉ có thể tập trung được một bộ phận sương quân để tác chiến với Mông Cổ. Ước tính tổng binh lực của nhà Trần trong cuộc chiến này vào khoảng 6 vạn.</li></ul><a href="__missing__"></a>Hình ảnh một chiến binh thiện chiến Mông Cổ, với ngựa, giáp trụ, cung tên,...
<p>Đạo quân của Ngột Lương Hợp Thai không thật đông nếu nhìn về số lượng tuyệt đối, họ chỉ bằng 1/2 quân số nhà Trần. Tuy vậy, quân Mông Cổ, như đã được chứng minh trong quá trình tác chiến của mình, hầu như luôn thua sút về quân số so với đối phương của họ, ít nhất là theo tỷ lệ 1:2, tức là nhiều ra thì số quân của họ cũng chỉ bằng một nửa so với đối phương (Mông Cổ là nước ít dân, dù huy động hầu hết trai tráng thì họ cũng chỉ có khoảng 15 20 vạn quân). Tuy ít hơn về số lượng nhưng quân Mông Cổ có lợi thế hơn hẳn về kỵ binh. Theo Đại Việt sử ký toàn thư, quân Trần có vài nghìn kị binh, còn quân Mông Cổ có khoảng 1 vạn kị binh.</p>
<p>Ngoài ra, kỵ binh Mông Cổ cũng giỏi hơn về kỹ năng chiến đấu. Người Mông Cổ là dân tộc du mục sống bằng chăn nuôi và săn bắn, nên từ nhỏ đã phải liên tục tập cưỡi ngựa và bắn cung để sinh tồn, hình thức <i>"thao luyện kị binh cả đời"</i> này không thể có được trong một đất nước sống bằng nông nghiệp - ngư nghiệp như Đại Việt. Con trai Mông Cổ từ khi 3 tuổi đã bắt đầu học cưỡi ngựa, khi 4 - 5 tuổi thì nhận <a href="__missing__">cây cung</a> đầu tiên của mình. Suốt cuộc đời, người Mông Cổ dành phần lớn thời gian trên yên ngựa để săn bắn và chiến đấu. Trong các chiến dịch quân sự, người Mông Cổ còn có thể buộc mình vào yên ngựa để vừa ngủ vừa cưỡi, nhờ đó đạt được tốc độ hành quân cao. Các chiến binh Mông Cổ được ca ngợi là có sức chịu đựng phi thường, ai cũng sở hữu nhiều loại vũ khí và bắn thành thạo cung tên.</p>
<p><a href="__missing__">Kỵ binh</a> là binh chủng lợi hại bậc nhất thời trung cổ, có tính cơ động hơn hẳn bộ binh, cho phép quân Mông Cổ nhanh chóng tập trung lực lượng đánh vào chỗ mỏng yếu của đối phương, hoặc sẽ rút lui nhanh nếu thấy bất lợi. <a href="__missing__">Sóng biển (chiến thuật kỵ binh)</a> là cách tác chiến lợi hại của quân Mông Cổ, họ bao vây đội hình quân đối phương bằng cách bố trí kỵ binh theo tuyến dài, thực hiện chiến đấu <a href="__missing__">bao vây</a> linh hoạt. Khi quân thù mạnh hơn thì họ sẽ <a href="__missing__">phân tán lực lượng</a>, khi thời cơ thích hợp họ sẽ hợp lại và tiến hành bao vây đối phương. Chỉ với 100 <a href="__missing__">kỵ binh</a> có thể bao vây 1.000 bộ binh, và 1.000 kỵ binh có thể triển khai thành một tuyến dài hơn 30 dặm. Chiến thuật này là hình thức <a href="__missing__">tác chiến cơ động</a>: Quân Mông Cổ liên tục phi ngựa để giữ khoảng cách, không để đối phương tiếp cận, vũ khí sử dụng chủ yếu là <a href="__missing__">cung tên</a> để bắn quân địch từ xa. Khi quân đối phương chạy tới gần để <a href="__missing__">cận chiến</a>, quân Mông Cổ sẽ phi ngựa rút nhanh về phía sau, và chiến đấu theo <a href="__missing__">Chiến thuật Parthia</a> (vừa phi ngựa vừa bắn tên), nếu còn đường lui thì họ luôn tránh việc cận chiến. Chiến thuật này vừa khai thác tối đa lợi thế về tài năng cưỡi ngựa bắn cung của người Mông Cổ, vừa giảm tối đa nguy hiểm khi đánh cận chiến. Một kỵ binh Mông Cổ có thể dùng cung tên bắn hạ vài binh sĩ đối phương từ xa cả trăm mét, trong khi đối phương chỉ có gươm giáo thì cự ly tác chiến chỉ được vài mét, nên không thể đánh trả được.</p>
<p>Với lợi thế chiến thuật này, có những trận đánh quân Mông Cổ chỉ đông bằng 1/4 đối phương mà vẫn chiến thắng (như <a href="__missing__">Trận sông Kalka</a>, <a href="__missing__">trận Mohi</a>,...), hoặc như <a href="__missing__">Chiến tranh Mông-Kim</a>, Mông Cổ chỉ có khoảng 12 vạn quân mà đã đánh bại quân đội gần 1 triệu người của <a href="__missing__">nhà Kim</a>. Huy động 3 vạn quân (trong đó 1 vạn là kỵ binh Mông Cổ) là tương đương 1/7 binh lực của toàn nước Mông Cổ huy động đánh nước <a href="__missing__">Nam Tống</a> (trong khi Nam Tống đất rộng và đông dân gấp 20 lần Đại Việt). Dựa trên thực tế đó, các tướng Mông Cổ cho rằng với nước nhỏ như Đại Việt thì chỉ cần 3 vạn quân là quá đủ để chinh phạt rồi.</p>
<p>Một đặc điểm nữa của đạo quân này là trong thành phần lãnh đạo, nó quy tụ tới 50 chư vương của triều đình Mông Cổ và phò mã Mông Cổ tên là Quaidu. Đây là những sĩ quan có liên hệ huyết thống hoặc hôn nhân với gia đình của Thành Cát Tư Hãn, gia tộc đang thống trị Mông Cổ. Nhà sử học cổ trung đại người <a href="__missing__">Ba Tư</a> là <a href="__missing__">Rasid ud-Din</a> chép:</p>
<p>Tuy nhiên, quân Mông Cổ có nhược điểm lớn bắt nguồn từ chính ưu điểm của họ:</p>
<ul><li>Do gấp rút tấn công nên quân Mông Cổ chỉ có kị binh và bộ binh, không chuẩn bị thủy binh, nên khi gặp sông ngòi thì không tiến quân được.</li><li>Do chú trọng việc tác chiến cơ động, hành quân phải thật nhanh nên quân Mông Cổ không mang theo dân phu để vận tải lương thực, xây dựng doanh trại (do dân phu phải khuân vác nặng nên đi khá chậm, nếu đi cùng dân phu thì kỵ binh không hành quân nhanh được). Tất cả những gì cần thiết cho việc chiến đấu, sinh hoạt và ăn uống đều được quân Mông Cổ mang theo trên lưng ngựa. Với cách này, quân Mông Cổ chỉ có thể mang theo rất ít lương thực (chỉ đủ ăn vài ngày), khi đánh vào lãnh thổ đối phương thì họ sẽ cướp lương thực của dân bản địa để nuôi sống quân lính. Đây là chiến thuật mà Mông Cổ thường áp dụng trong các cuộc chiến trước đó và tỏ ra khá hiệu quả. Nhưng nhà Trần đã nhận ra điểm yếu của chiến thuật này và chuẩn bị sẵn kế hoạch "<a href="__missing__">vườn không nhà trống</a>" để đối phó. Triều đình nhà Trần đã sớm ra lệnh cho người dân cất giấu hết lương thực trong các kho, khiến quân Mông Cổ không cướp được lương thực và dần bị suy yếu.</li></ul>
<h2>Diễn biến</h2><a href="__missing__"></a>
<p>Đội quân của Ngột Lương Hợp Thai sau khi chiếm được Đại Lý, rồi đóng binh ở A Mễ (阿迷, nay là <a href="__missing__">Khai Viễn</a><a href="__missing__">châu Hồng Hà</a> tỉnh <a href="__missing__">Vân Nam</a>) phía Bắc Đại Việt, sai hai sứ giả đến dụ hàng Đại Việt. Nhà Trần đã nhốt hai viên sứ giả vào ngục và trói bằng dây tre. Theo Nguyên sử: Ngột Lương Hợp Thai không thấy tin tức hai viên sứ giả này, bèn sai tướng là Triệt Triệt Đô cùng đem 3000 quân, chia đường tiến binh tấn công Đại Việt. Đến tháng Mười âm năm <a href="__missing__">Đinh Tỵ</a> quân Nguyên Mông tiến tới áp sát biên giới (vùng <a href="__missing__">ải Lê Hoa</a>). Tháng Chín âm năm 1257, chủ <a href="__missing__">trại Quy Hóa</a> là Hà Khuất báo tin có sứ Nguyên sang. Vua Trần không nghe lời dụ hàng, xuống chiếu ra lệnh đem quân thủy bộ ra ngăn giữ biên giới (vùng ải Lê Hoa, <a href="__missing__">núi Mai Lĩnh</a>), theo sự tiết chế của <a href="__missing__">Trần Quốc Tuấn</a> và truyền cả nước sắm sửa vũ khí.</p>
<h3>Trận Bình Lệ Nguyên</h3>
<p>Ngột Lương Hợp Thai chia quân làm hai cánh, một cánh do mình chỉ huy và cánh quân còn lại do Triệt Triệt Đô chỉ huy, chia đường tiến xuống sông Thao ở vùng Kinh Bắc, Đại Việt. Viên tướng này dùng con trai là A Truật sang giúp và dòm ngó tình hình. Nhà Trần bày nhiều lớp phòng thủ, A Truật trở về báo, liền tiến quân đi gấp, sai Triệt Triệt Đô làm tiên phong, A Truật ở sau làm điện, đến tháng 12 năm 1257, hai đạo quân hợp lại với nhau. Đến tháng Chạp năm Đinh Tỵ (1257), quân đội Mông Cổ xâm lấn đồng Bình Lệ, vua Trần Thái Tông tự mình dẫn theo sáu đạo cấm quân (Thiên Thuộc, Thiên Chương, Thánh Dực, Chương Thánh, Thần Sách, Củng Thần), cộng thêm sương quân ở các địa phương gần kinh thành để chống lại.</p>
<p>Quân Mông Cổ giáp trận quân Đại Việt do đích thân <a href="__missing__">Trần Thái Tông</a> (Trần Cảnh) ngự giá thân chinh chỉ huy tại Bình Lệ Nguyên (nay là huyện <a href="__missing__">Bình Xuyên</a> tỉnh Vĩnh Phúc). Đó là ngày <a href="__missing__">17 tháng 1</a> năm <a href="__missing__">1258</a>.</p>
<p>Quân đội <a href="__missing__">nhà Trần</a> bày tượng binh, kỵ binh và bộ binh bên bờ <a href="__missing__">sông Hồng</a> đợi giặc, tượng binh dàn hàng ngang tại tiền quân che chắn cho lớp bộ binh, kỵ binh phía sau, <a href="__missing__">thủy quân</a> dọc sông Hồng để có thể khi thua sẽ rút quân an toàn. Quân Mông Cổ chia làm ba đội để sang sông, Triệt Triệt Đô dẫn 5.000 quân làm quân tiên phong, Ngột Lương Hợp Thai cầm đại quân đi giữa, phò mã Hoài Đô và A Truật giữ hậu quân. Đội chủ lực của Ngột Lương Hợp Thai lấy những hàng binh Đại Lý dàn ở các hàng phía trước để làm bia đỡ hứng chịu thương vong, kỵ binh Mông Cổ đi phía sau để hỗ trợ và tung đòn quyết định. Ngột Lương Hợp Thai dặn Quỳ Thủ Soạn và viên tiên phong là Triệt Triệt Đô:</p>
<p>Nhưng Triệt Triệt Đô vừa qua sông đã ập lại đánh ngay. Trần Thái Tông tự làm tướng, đốc chiến đi trước xông pha tên đạn, sai tượng binh tiến ra giao chiến. Con Hợp Thai là A Truật (18 tuổi) ra lệnh cho kỵ binh bắn tên vào mắt voi, khiến voi đau và hoảng sợ, quay lại dày xéo đội hình quân Trần. Quân Trần nao núng, Trần Thái Tông ngoảnh trông hai bên, chỉ có tướng Lê Tần cưỡi ngựa một mình ra vào trận, sắc mặt không thay đổi. Lúc ấy, có người khuyên vua Trần dừng lại để chỉ huy chiến đấu. Lê Trần cố sức can vua: <i>"Nay thì bệ hạ chỉ đánh một ván dốc túi thôi! Hãy nên tạm lánh chúng, sao lại có thể dễ dàng tin lời người ta thế!"</i>. Bấy giờ, vua Trần mới lui quân đóng ở sông Lô, Lê Tần giữ phía sau. Quân Mông Cổ bắn loạn xạ, Lê Tần lấy ván thuyền che cho vua Trần khỏi trúng tên giặc. Thế quân Mông rất mạnh, do không chiếm được thuyền của Đại Việt, vua Trần vẫn bảo tồn được lực lượng và lui về giữ sông Thiên Mạc.</p>
<p>Quân Trần thất lợi nhưng chủ động rút lui. <a href="__missing__">Trần Thái Tông</a> và tướng <a href="__missing__">Lê Tần</a> lui tới sách Cụ Bản, gặp tướng <a href="__missing__">Phạm Cự Chích</a> đem viện binh tới cứu. Quân Mông Cổ giết được Phạm Cự Chích, nhưng vua Trần đã chạy thoát ra bến Lãnh Mỹ, rồi xuôi thuyền về Phù Lỗ. Không bắt được bộ chỉ huy nhà Trần, Ngột Lương Hợp Thai nổi giận. Triệt Triệt Đô uống thuốc độc tự sát do không nghe lệnh, để vua Trần chạy thoát.</p>
<h3>Quân Trần rút lui</h3>
<p>Khi vua Thái Tông triệt binh về <a href="__missing__">sông Thiên Mạc</a>, Lê Tần đã thảo luận với ông về những chuyện cơ mật, không mấy người biết tới. Khi ấy, Thái Tông cũng ngự thuyền nhỏ tới thuyền của em là <a href="__missing__">Thái uý</a><a href="__missing__">Trần Nhật Hiệu</a> để hỏi ý Nhật Hiệu về kiến về kế sách giữ nước. Nhật Hiệu ngồi dựa vào mạn thuyền, không thể nào đứng lên được và đưa ngón tay xuống chấm nước rồi ghi hai chữ "nhập Tống" trên mạn thuyền (tức là nên chạy sang lánh ở đất <a href="__missing__">Nam Tống</a>). Thái Tông bèn hỏi về tình hình của quân Tinh Cương dưới quyền Nhật Hiệu, thì Nhật Hiệu đáp lại: <i>"Không gọi được chúng đến</i>". Thế rồi, nhà vua lại ngự thuyền đến chỗ <a href="__missing__">Thái sư</a><a href="__missing__">Trần Thủ Độ</a>. Khi nghe câu hỏi của nhà vua, Thủ Độ tâu:</p>
<p>Ngày hôm sau, ngày <a href="__missing__">18 tháng 1</a> năm <a href="__missing__">1258</a>, hai bên chạm trán một lần nữa tại Phù Lỗ, vua Trần đã chặt cầu Phù Lỗ từ trước.</p>
<p>Hai bên đối mặt nhau qua một con sông (<a href="__missing__">sông Cà Lồ</a>) mà bày trận, quân Mông Cổ vẫn là người qua sông phá trận. Quân Mông muốn qua sông nhưng không có thuyền bè, bèn men theo bờ sông bắn tên xuống nước, thấy chỗ nào tên bắn xuống mà không nổi lên tức là cạn, rồi dùng kị binh băng qua sông. Quân Trần vẫn tiếp tục gặp bất lợi, nhưng một lần nữa họ lại chủ động rút lui. Sau đó, quân Trần lại chủ động rút khỏi <a href="__missing__">Thăng Long</a>.</p>
<p>Quân Mông Cổ chiếm được kinh đô Đại Việt sau 2 trận đánh. Nguyên sử chép: <i>Ngột Lương Hợp Thai cũng phá quân bộ, lại cùng A Thuật hội đánh, đại phá chúng, rồi vào nước này. Nhật Quýnh (chỉ vua Trần) trốn chạy ra hải đảo. Bắt gặp sứ giả ngày trước ở trong ngục, bị dây tre trói lằn vào da thịt, lúc cởi trói ra, một sứ giả chết, do đó làm cỏ thành này.</i></p>
<h3>Quân Trần phản công</h3><a href="__missing__"></a>Sa đồ trận Quy Hóa năm 1257 nơi Hà Bổng chỉ huy tập kích quân Nguyên Mông
<p>Chiếm được kinh đô chỉ sau hai trận đánh, nhưng kho tàng trống rỗng là vấn đề lớn đối với đội quân Mông Cổ. Những cuộc cướp bóc để kiếm lương ở vùng ngoại vi và phụ cận không có nhiều kết quả, quân Mông Cổ lâm vào tình trạng thiếu thốn lương thực.</p>
<p>Nửa đêm ngày <a href="__missing__">28 tháng 1</a> năm <a href="__missing__">1258</a>, từ nơi trú quân (Thiên Mạc) trên <a href="__missing__">Hoàng Giang</a>, Trần Thái Tông cùng Thái tử Trần Hoảng ngự lâu thuyền ngược sông, bất ngờ đánh thẳng vào quân Mông Cổ. Quân Mông Cổ cho rằng lực lượng quân Trần đã kiệt quệ sau trận thua đầu nên rất chủ quan, do đó khi bị tập kích đã không kịp trở tay, bị thua to. Sau khi bị phá tan tại <a href="__missing__">Đông Bộ Đầu</a>, quân Mông Cổ không giữ nổi Thăng Long nữa. Chúng đồng loạt tháo chạy thẳng về <a href="__missing__">Vân Nam</a>.</p>
<p>Như khi mới tiến quân vào, quân Mông Cổ rút chạy theo dọc sông Thao, nhưng theo con đường bộ ở phía tả ngạn. Quân Mông rút lui quá nhanh, ngoài cả dự tính của nhà Trần khiến vua Trần chưa kịp bố trí lực lượng đón đánh. Tuy nhiên khi đến Quy Hóa (vùng <a href="__missing__">Lào Cai</a>, <a href="__missing__">Yên Bái</a>), quân Mông bị chủ trại là <a href="__missing__">Hà Bổng</a> một thổ quan <a href="__missing__">người Tày</a> - tập kích kịch liệt. Trong số quân của Hà Bổng có những người Thái chạy từ nước <a href="__missing__">Đại Lý</a> vừa bị Mông Cổ diệt sang theo Đại Việt, muốn trả thù người Mông Cổ nên đã đánh rất hăng khiến quân Mông Cổ khốn đốn; chỉ vì số quân của Hà Bổng ít người nên thiệt hại của quân Mông Cổ không lớn. Trên đường rút về, do sợ bị quân Trần truy đuổi đằng sau, quân Mông Cổ cố rút nhanh và không cướp phá dân chúng, do đó người Việt mỉa mai gọi là "giặc Bụt".</p>
<h3>Kết cục</h3>
<p>Theo <a href="__missing__">Nguyên sử</a> - Ngột Lương Hợp Thai truyện và Kinh thế đại điển tự lục chép rằng: sau khi bỏ Thăng Long, người Mông Cổ đã chạy về thành Áp Xích, trên đất của 37 bộ Quỷ Phương (Đại Lý), và điều này có nghĩa là Mông Cổ đã không đạt được mục tiêu là chiếm Đại Việt để làm bàn đạp đánh vào lưng Nam Tống. Ngột Lương Hợp Thai truyện cũng cho biết, Uriyangqatai đóng quân ở Áp Xích, sau khi có lệnh của Mông Kha thì mới đi theo đường trại Hoành Sơn để tiến vào châu Ngạc của Tống và hội quân với <a href="__missing__">Hốt Tất Liệt</a>. Nguyên sử lại viết: <i>quân ở lại 9 ngày, vì khí hậu nóng nực nên rút quân về. Lại sai hai sứ giả đi gọi Nhật Cảnh về (chỉ vua Trần). Nhật Cảnh thấy kinh đô bị phá hủy, rất giận, ép sứ giả quay về</i>. Thực tế, quân Mông Cổ đánh Đại Việt vào tháng 1, đúng vào lúc giữa <a href="__missing__">mùa đông</a> ở miền Bắc Việt Nam, do vậy không thể có chuyện "khí hậu nóng nực nên rút quân về" như Nguyên sử chép được.</p>
<p>Các khám phá địa chất gần đây cho thấy khoảng năm 1257 hoặc đầu 1258, <a href="__missing__">núi lửa Samalas</a> ở Indonesia xảy ra phun trào lớn, làm khí hậu thế giới bị biến động. Một số ý kiến cho rằng quân Mông ra lệnh rút quân là do thời tiết trở nên khắc nghiệt bởi ảnh hưởng từ vụ phun trào. Tuy nhiên, các ý kiến này là không hợp lý. Thứ nhất, đúng là vụ phun trào núi lửa Samalas làm khí hậu ấm lên trong mấy tháng do hiệu ứng của khí sunfat, nhưng mức gia tăng nhiệt độ chỉ ở mức mấy độ C, chỉ có thể làm mùa đông bớt lạnh chứ không thể biến mùa đông thành "mùa hè nóng nực" được. Thứ hai, ảnh hưởng của vụ phun trào cũng diễn ra tương tự ở lãnh thổ nước <a href="__missing__">Nam Tống</a> đang bị Mông Cổ chinh phạt vào cùng thời điểm, nhưng không hề thấy quân Mông Cổ rút khỏi Nam Tống vì lý do thời tiết.</p>
<p>Thiệt hại của quân Mông Cổ, tùy theo nguồn tài liệu mà chênh lệch từ già nửa cho tới khoảng 2/3:</p>
<ul><li>Theo <a href="__missing__">Rashid-al-Din</a>, đạo quân ba vạn kỵ binh Mông Cổ của Ngột Lương Hợp Thai kéo xuống Vân Nam, trước khi tiến lên châu Ngạc, còn lại không quá 5000 người, không rõ thiệt hại trong chiến tranh với Đại Việt là bao nhiêu.</li><li><i>Nguyên sử</i>, <i>Ngột Lương Hợp Thai truyện</i> và bài bia ký A Truật thì chép rằng: khi thâm nhập đất Tống, đoàn quân này còn lại 3.000 kị binh Mông Cổ và 1 vạn quân <a href="__missing__">Thoán Bặc</a>.</li></ul>
<h3>Sau cuộc chiến</h3>
<p>Vua Trần Thái Tông hồi kinh, trăm họ Đại Việt nghiệp yên như cũ. Định công phong tước, cho Lê Tần (hay Lê Phụ Trần) làm Ngự sử đại phu và đem công chúa Chiêu Thánh gả cho. Vua nói: <i>Trẫm không có khanh thì làm gì có được ngày nay. Khanh nên cố gắng để cùng hưởng phúc sau này.</i> Cùng năm đó (1258), vua Trần Thái Tông truyền ngôi cho thái tử Hoảng, tức Trần Thánh Tông.</p>
<p>Năm 1258, ngay khi vừa bị đuổi chạy về đến Vân Nam, Uriyangqatai (Ngột Lương Hợp Thai) đã sai ngay hai sứ sang dụ vua Thái Tông vào chầu. Căm phẫn vì thấy kinh đô Thăng Long bị tàn phá, Thái Tông với khí thế của người chiến thắng, đã sai trói hai sứ lại, đuổi về.</p>
<p>Vua Trần sai sứ giả sang thông hiếu với nhà Tống. Sai Lê Phụ Trần làm sứ, Bác Lãm làm phó sang nhà Nguyên, rốt cuộc định ba năm một kỳ cống làm lệ thường. Theo Nguyên sử: Tháng 2 ngày mậu ngọ năm thứ 8, Nhật Cảnh (vua Trần) truyền nước cho con trưởng là Quang Bính, đổi niên hiệu Thiệu Long. Mùa hạ, Quang Bính sai con rể (Lê Phụ Trần) cùng người nước này đem phương vật đến, Ngột Lương Hợp Thai hộ tống đến sở quan, sai riêng <a href="__missing__">Nột Lạt Đinh</a> đến dụ chúng, nói: <i>"Trước ta sai sứ giả đến giao hảo, các ngươi bắt giữ mà không cho quay về, ta do đó phát binh năm trước. Vì vua của nước ngươi đứng trốn ở đồng cỏ, lại lệnh cho hai sứ giả đến gọi về nước, ngươi lại ép sứ giả ta trở về. Nay sai riêng sứ giả đến dụ, nếu các ngươi thực lòng nội thuộc, thì vua nước ngươi phải tự mình đến, nếu vẫn không chừa, sớm đến báo cho ta"</i>. Quang Bính nói: <i>"Nước nhỏ thật lòng thờ Nhà vua, thì nước lớn lấy gì đối đãi nước nhỏ?"</i>. Nột Lạt Đích về báo. Bấy giờ Vương chư hầu là Bất Hoa giữ Vân Nam, Ngột Lương Cáp Thai nói với Vương, lại sai Nột Lạt Đinh đến dụ, sai sứ giả cùng đến. Quang Bính bèn thực lòng nạp thuộc, lại nói: <i>"Đợi ban ân đức, liền sai con em làm con tin"</i>. Vương lệnh cho Nột Lạt Đinh lên ngựa đưa tin vào tấu lên.</p>
<p>Theo sử gia <a href="__missing__">Lê Tắc</a>, người viết quyển sử <a href="__missing__">An Nam chí lược</a>, có chép về bức thư vua Nguyên gửi cho <a href="__missing__">vua Trần</a> năm 1275: "<i>Theo chế độ của tổ tông đã quy định, phàm các nước Nội phụ thì vua phải thân hành tới chầu, gửi con em làm con tin, biên nạp dân số, nộp thuế lệ, mộ dân trợ binh và vẫn đặt quan <a href="__missing__">Đạt lỗ hoa xích</a> để thống trị; sáu điều nói trên, năm trước đã có lời dụ cho khanh biết rồi, thế mà qui phụ đã hơn 15 năm, khanh chưa từng tới triều kiến một lần nào, và các điều quy định đến nay vẫn chưa thi hành, tuy rằng ba năm tới cống hiến một lần, nhưng các đồ cống hiến đều không dùng được</i>". Như vậy, mang tiếng là một nước phải triều cống, nhưng đó chỉ là trên danh nghĩa, còn thực tế Đại Việt là một nước tự chủ, không thi hành theo sáu điều quy định của Mông Cổ về nước Nội phụ của Mông Cổ.</p>
<h2>Nhận định</h2>
<p>Các tác giả của <a href="__missing__">Nguyên sử</a>, phần Hiến Tông bản kỷ chỉ chép vắn tắt:</p><i>"Mùa đông tháng 11, Ngột Lương Hợp Thai đánh vào Giao Chỉ, đi vào nước nó. Chúa An Nam là Trần Nhật Cảnh trốn vào hải đảo, [Mông Cổ] bèn rút quân về"</i>. (ghi chép của Nguyên sử để tránh kị huý đã không công nhận đây là thất bại mà chỉ nói tránh là "Mông Cổ rút quân về", không nhắc đến việc quân Mông Cổ bại trận ở <a href="__missing__">Đông Bộ Đầu</a> và bị tập kích khi rút về. Vua Trần cũng không hề "trốn vào hải đảo" như Nguyên sử viết mà đã trực tiếp chỉ huy <a href="__missing__">trận Đông Bộ Đầu</a> phản công đánh bại quân Mông Cổ)
<p>Trong <i><a href="__missing__">Đại Việt sử ký toàn thư</a></i>, Kỷ nhà Trần, phần Thái Tông hoàng đế, có bình luận:</p> "<i>...lúc đó, người Nguyên mới lấy <a href="__missing__">Vân Nam</a>, du binh xâm lược đến, không có ý lấy nước ta.</i>" Bình luận "quân Nguyên không có ý lấy nước ta" trong Đại Việt sử ký toàn thư ngày nay bị bác bỏ. Các sử gia trong đế quốc Mông Cổ như Rashid al-Din và <a href="__missing__">Lê Tắc</a> (tác giả <a href="__missing__">An Nam chí lược</a>) đều công nhận rằng Mông Kha muốn chiếm Đại Việt làm bàn đạp để đánh thọc vào châu Ung, châu Quế phía nam nước Tống. Chính <a href="__missing__">Nguyên sử</a> cũng ghi: <i>"Uriangqadai vào Giao Chỉ định kế lâu dài.</i>" Nếu chiến dịch này chỉ là để cướp bóc, không phải để chiếm lãnh thổ thì quân Mông không cần phải huy động tới 3 vạn quân, và Mông Kha cũng đã không cử tới 50 chư vương của triều đình Mông Cổ, có cả phò mã Mông Cổ tên là Quaidu tham gia chỉ huy đội quân này.
<p>Lời cẩn án của các sử quan thời Nguyễn chép trong Khâm định Việt sử thông giám cương mục:</p><i>Trận này thế giặc rất mạnh, thế mà Sử cũ chỉ chép rằng nhà vua tiến quân đánh được giặc, không chép rõ cái cớ sở dĩ đánh được như thế nào cả. Tham khảo sách Nguyên sử loại biên và sách Cương mục tục biên (Trung Quốc) đều chép rằng: Ngột Lương Hợp Thai đã bình được nước Đại Lý, kéo quân sang nước ta, ba lần sai sứ đến dụ nhà vua đầu hàng, đều không thấy sứ thần trở về, bấy giờ mới chia đường tiến quân, nhân thế thắng, kéo vào đô thành nước ta, khi vào, thấy ba người sứ sai sang trước còn bị giam ở trong ngục, người nào cũng bị những thanh tre bó chặt vào mình sát hẳn đến da, khi cởi trói ra, thì một người đã bị chết, họ liền giết hết cả dân trong thành. Đóng quân ở đây được 9 ngày, vì không chịu được nóng nực, phải rút về. Lại sai sứ giả đến chiêu an, vua Thái Tông giận họ tàn phá, nên lại sai trói hai sứ giả đưa trả lại.</i>
<p>Sử gia Trần Xuân Sinh cho rằng: <a href="__missing__">Ngột Lương Hợp Thai</a> là tướng giỏi, khi thấy không giữ nổi Thăng Long đã rút sớm về Vân Nam để bảo toàn lực lượng là thượng sách.</p>
<p>Việc quân Mông Cổ thất bại ở Đại Việt cũng đã giúp Nam Tống tránh được việc bị đánh kẹp từ phía Nam để có thể tập trung binh lực đối phó Mông Cổ ở phía Bắc. Quy mô đạo quân của Ngột Lương Hợp Thai có thể nói là không lớn, chỉ cỡ 3 vạn. Nhưng xét về hậu quả của thất bại đối với toàn thể chiến lược xâm lăng đất Tống theo bốn con đường cũng như sự thất bại quá chóng vánh, sử gia <a href="__missing__">Hà Văn Tấn</a> có nhận định rằng:</p> "<i>Có lẽ...trong đời chinh chiến của mình, chưa bao giờ Uriangqadai bị thua nhục nhã như lần này.</i>"
<p>Sử liệu Trung Quốc thời Nguyên, Minh không chấp nhận họ là nước lớn mà lại thất bại, nên đã quy kết nguyên nhân thất bại của quân Mông Cổ là do thời tiết nóng nực của Đại Việt. Trong Nguyên văn loại, quyển 41, Kinh thế đại điển tự lục (bản Thương vụ ấn thư quán 1958, trang 563) chép rằng: <i>"[Quân Mông Cổ] ở lại chín ngày, vì nóng nực, rút quân về"</i>. Còn <a href="__missing__">Nguyên sử</a> trong quyển 209, An Nam truyện cũng viết là <i>"Quân ở lại chín ngày, vì khí hậu uất nhiệt bèn rút quân về"</i>. Thực tế, quân Mông Cổ đánh Đại Việt vào tháng 1, đúng vào lúc giữa <a href="__missing__">mùa đông</a> ở miền Bắc Việt Nam, do vậy không thể có chuyện "khí hậu nóng nực nên rút quân về" như Nguyên sử và Kinh thế đại điển tự lục chép được.</p>
<p>Chiến thắng của quân dân Đại Việt trong cuộc kháng chiến chống Nguyên Mông lần thứ nhất đã ghi dấu công lao của vua Trần Thái Tông. Sau này vua <a href="__missing__">Trần Nhân Tông</a> về thăm Long Hưng, trông thấy vẻ uy nghi đường vệ của lăng Thái Tông, đã ghi lại dư âm của chiến thắng năm 1258 trong niên hiệu Nguyên Phong bằng mấy câu thơ trong bài "Xuân Nhật yết Chiêu Lăng":</p> Tì hổ thiên môn túc Y quan thất phẩm thông Bạch đầu quân sĩ tại Vãng vãng thuyết Nguyên Phong Dịch: Nghìn cửa quân tì hổ uy vũ Các quan thất phẩm áo đầy đủ. Quân sĩ người đầu bạc vẫn còn, Thường thường kể chuyện thời Nguyên Phong
<ul><li>Các tác giả phương Tây Peter D. Sharrock và Vũ Hồng Liên (người Anh gốc Việt) đã nhận xét về kết quả cuộc chiến năm 1258:</li></ul>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Kháng chiến chống Nguyên Mông lần thứ 2</a></li><li><a href="__missing__">Kháng chiến chống Nguyên Mông lần thứ 3</a></li><li><a href="__missing__">Trần Thái Tông</a></li><li><a href="__missing__">Trần Thủ Độ</a></li><li><a href="__missing__">Lê Phụ Trần</a></li><li><a href="__missing__">Lê Tắc</a></li></ul>
<h2>Ghi chú</h2>
<ol><li><a href="__missing__">↑</a> Niên hiệu của vua Trần Thái Tông.</li><li><a href="__missing__">↑</a> Trích từ <a href="__missing__">Tổ chức và chiến thuật quân sự của quân đội Đế quốc Mông Cổ</a>, phần <i>Giáo dục và Đào tạo</i></li><li><a href="__missing__">↑</a> Trong lần xâm lấn Đại Việt lần thứ 2, trong quân của Thoát Hoan cũng có hai thân vương Mông Cổ là Tích Lệ Cơ và Đại vương Giảo Kì. Tuy vậy, khi này, Tích Lệ Cơ đang bị tội và bị phái đi phục vụ trong đạo quân xâm lược như một biện pháp trừng phạt.</li><li><a href="__missing__">↑</a> Số liệu của sách Nguyên sử</li><li><a href="__missing__">↑</a> Quy Hóa: Xưa thuộc bộ Tân Hưng, nhà Lý gọi là Đăng Châu; nhà Trần gọi là trại Quy Hóa; nhà Lê đổi làm phủ; bây giờ cũng theo như cũ, thuộc tỉnh Hưng Hóa, lời chú của các sử quan trong Khâm định Việt sử thông giám cương mục</li><li><a href="__missing__">↑</a> Quân Tinh Cương: Tức quân tuyển trong những người ở làng Tinh Cương do Nhật Hiệu thống lĩnh. Trích lời chú trong sách Khâm định Việt sử thông giám cương mục.</li><li><a href="__missing__">↑</a> Đoạn sông Hồng chảy qua <a href="__missing__">Lý Nhân</a>, Hà Nam.</li><li><a href="__missing__">↑</a> Nay là dốc Hàng Than, Hà Nội</li></ol>
<h2>Chú thích</h2>
<ol><li><a href="__missing__">↑</a> Nhà Trần khi đó có 100.000 quân trên cả nước, gồm 2 vạn cấm quân và 8 vạn sương quân. Tất cả cấm quân và khoảng 1 nửa sương quân được huy động</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a><a href="__missing__">Đại Việt Sử ký Toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế</li><li><a href="__missing__">1</a><a href="__missing__">2</a> Hội khoa học lịch sử Việt Nam, Viện sử học, <i>Nhà Trần và con người thời Trần</i>, trang 139</li><li><a href="__missing__">1</a><a href="__missing__">2</a> Nguyên sử, phần Liệt truyện, Ngoại di, An Nam</li><li><a href="__missing__">↑</a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr 263</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a> Hà Văn Tấn và Phạm thị Tâm, sách đã dẫn, tr 61</li><li><a href="__missing__">↑</a><a href="__missing__">Trần Quốc Vượng</a> và <a href="__missing__">Hà Văn Tấn</a>, Lịch sử chế độ phong kiến Việt Nam, tập 1, trang 382.</li><li><a href="__missing__">↑</a><a href="__missing__">Nguyên sử, quyển 21, Tốc Bất Đài (Ngột Lương Hợp Thai)</a>.</li><li><a href="__missing__">↑</a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr283</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a><a href="__missing__">4</a><a href="__missing__">5</a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr283, 284</li><li><a href="__missing__">↑</a><a href="__missing__">Đại Việt sử ký toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế chép trận đánh diễn ra ngày 12 tháng 12 năm <a href="__missing__">Đinh Tỵ</a>.</li><li><a href="__missing__">↑</a> Hà Văn Tấn và Phạm Thị Tâm, sách đã dẫn, tr 68</li><li><a href="__missing__">↑</a> Hà Văn Tấn và Phạm Thị Tâm, sách đã dẫn, tr 69</li><li><a href="__missing__">↑</a><a href="__missing__">"Chú thích của Đại Việt Sử Ký Toàn Thư"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 25 tháng 5 năm 2011. Truy cập ngày 31 tháng 3 năm 2012.</li><li><a href="__missing__">↑</a><a href="__missing__">Đại Việt sử ký toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế chép trận đánh diễn ra ngày 24 tháng 12 năm <a href="__missing__">Đinh Tỵ</a>.</li><li><a href="__missing__">↑</a> Trần Xuân Sinh, sách đã dẫn, tr 82</li><li><a href="__missing__">↑</a> Trần Xuân Sinh, sách đã dẫn, tr 84</li><li><a href="__missing__">↑</a><a href="__missing__">Lavigne và đồng nghiệp 2013</a>, tr.&nbsp;16746.Lỗi sfn: không có mục tiêu: CITEREFLavigneDegeaiKomorowskiGuillet2013 (<a href="__missing__">trợ giúp</a>)</li><li><a href="__missing__">↑</a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr 285</li><li><a href="__missing__">↑</a> An Nam chí lược, Viện đại học Huế, Ủy ban phiên dịch sử liệu, 1961, bản điện tử, tr 19</li><li><a href="__missing__">↑</a><a href="__missing__">Lê Mạnh Thát</a> (2004), <i>Toàn tập Trần Thái Tông</i>, Nhà xuất bản Tổng hợp TP Hồ Chí Minh, các trang 78-83.</li><li><a href="__missing__">↑</a> Khâm định việt sử thông giám cương mục, Nhà xuất bản Giáo dục - Hà Nội, 1998, quyển VI</li><li><a href="__missing__">↑</a> Trần Xuân Sinh, sách đã dẫn, tr 83</li><li><a href="__missing__">↑</a><a href="__missing__">http://vanhoanghean.com.vn/index.php?option=com_k2&amp;view=item&amp;id=4142:b%E1%BB%8B-coi-th%C6%B0%E1%BB%9Dng-hay-t%E1%BB%B1-coi-th%C6%B0%E1%BB%9Dng-</a>?</li><li><a href="__missing__">↑</a> Peter D. Sharrock (2014). <a href="__missing__"><i>Descending Dragon, Rising Tiger: A History of Vietnam</i></a> (bằng tiếng Anh). Reaktion Book. <a href="__missing__">ISBN</a>&nbsp;<a href="__missing__">1780233884</a>. {{<a href="__missing__">Chú thích sách</a>}}: Đã bỏ qua tham số không rõ |đồng tác giả= (<a href="__missing__">trợ giúp</a>)</li></ol>
<h2>Tham khảo</h2>
<ul><li><a href="__missing__">Đại Việt Sử ký Toàn thư</a>, Nhà xuất bản thời đại, 2013</li><li>An Nam chí lược, Lê Tắc</li><li>Việt sử tiêu án, <a href="__missing__">Ngô Thì Sĩ</a></li><li>Khâm định Việt sử thông giám cương mục, Nhà xuất bản giáo dục HN, 1998</li><li>Hà Văn Tân và Phạm Thị Tâm (1972), <i>Cuộc kháng chiến chống xâm lược Nguyên Mông thế kỷ XIII</i>, Nhà xuất bản Quân đội Nhân dân, bản in lại năm 2003, Chương III: "Cuộc kháng chiến lần thứ nhất", trang 66 88</li><li>Trần Xuân Sinh (2006), <i>Thuyết Trần</i>, Nhà xuất bản Hải Phòng</li><li>Hội khoa học <a href="__missing__">lịch sử Việt Nam</a>, Viện sử học, <i>Nhà Trần và con người thời Trần</i>, Trung tâm <a href="__missing__">UNESCO</a> thông tin tư liệu, lịch sử và <a href="__missing__">văn hóa Việt Nam</a>, <a href="__missing__">2004</a></li></ul><a href="__missing__">Cổng thông tin</a>:
<ul><li><a href="__missing__">Quân sự</a></li><li><a href="__missing__">Lịch sử</a></li><li><a href="__missing__">Việt Nam</a></li></ul>
@@ -0,0 +1,60 @@
<h1>Chiến tranh Nguyên Mông Đại Việt lần 1</h1>
<p><b>Chiến tranh Mông Nguyên Đại Việt lần thứ nhất</b> hay <b>Kháng chiến chống Mông Nguyên lần thứ nhất</b> là cách người Việt Nam gọi cuộc chiến đấu của quân dân <a href="__missing__">Đại Việt</a> chống lại quân đội của <a href="__missing__">đế quốc Mông Cổ</a> do <a href="__missing__">Uriyangqatai</a> (Ngột Lương Hợp Thai) chỉ huy vào trong khoảng thời gian nửa tháng cuối tháng 1 năm <a href="__missing__">1258</a> (hay năm Nguyên Phong thứ 7.</p>
<p>Cuộc chiến mở đầu với <a href="__missing__">trận Bình Lệ Nguyên</a>, sau đó là <a href="__missing__">trận Phù Lỗ</a>. Quân Mông Cổ thắng 2 trận này, nhưng họ không diệt được đạo quân chủ lực của nhà Trần. Quân Mông Cổ tiến vào kinh thành của Đại Việt trong 9 ngày. Quân đội nhà Trần đã phản công, đại phá quân Mông trong <a href="__missing__">trận Đông Bộ Đầu</a> khiến cho đội quân này phải chạy về phía Bắc, sau đó còn phải hứng chịu một cuộc tập kích khác của thủ lĩnh miền núi là <a href="__missing__">Hà Bổng</a>. Cuộc chiến này đã kết thúc với <a href="__missing__">chiến thắng</a> của nước Đại Việt, ghi dấu công lao của vua <a href="__missing__">Trần Thái Tông</a> trong việc lãnh đạo quân dân Đại Việt chiến đấu chống quân đội <a href="__missing__">Mông Cổ</a>.</p>
<h2>Bối cảnh</h2><a href="__missing__"></a>Bản đồ Đại Việt, Mông Cổ, Nam Tống, năm 1257
<p>Vào năm 1206, <a href="__missing__">Thành Cát Tư Hãn</a> đã thành công trong việc thống nhất các bộ lạc Mông Cổ, từ đó <a href="__missing__">Đế quốc Mông Cổ</a> liên tục thực hiện nhiều cuộc chiến nhằm mở rộng đế quốc của mình. 50 năm sau, đến đời Đại hãn thứ 4, tức <a href="__missing__">Mông Kha</a>, ông đã tiến hành các chiến dịch tấn công nước <a href="__missing__">Nam Tống</a> (<a href="__missing__">Trung Quốc</a>). Mông Kha muốn đánh vào sườn nhà Tống thông qua việc cử em trai là <a href="__missing__">Hốt Tất Liệt</a> đánh <a href="__missing__">Đại Lý</a>. Đánh Đại Lý xong vào năm 1253, Hốt Tất Liệt trở về, ra lệnh cho <a href="__missing__">Ngột Lương Hợp Thai</a> ở lại đánh các nước chưa hàng phục.</p>
<p>Đến năm 1257, việc chiếm Đại Việt nằm trong chiến lược tổng thể của quân đội Mông Cổ nhằm tiêu diệt Nam Tống. Bốn cánh quân Mông Cổ sẽ tấn công <a href="__missing__">Nam Tống</a> từ những địa điểm khác nhau từ phía Nam và phía Tây. Nắm quyền chỉ huy 3 cánh quân kia là <a href="__missing__">Mông Kha</a>, <a href="__missing__">Hốt Tất Liệt</a><a href="__missing__">Tháp Sát Nhi</a>. Cánh quân còn lại cánh quân thứ tư, sau khi chiếm <a href="__missing__">Đại Việt</a> sẽ đánh thốc vào Nam Tống từ mạn cực Nam. Tổng chỉ huy của cánh quân thứ tư là <a href="__missing__">Ngột Lương Hợp Thai</a>. Nhà Trần (Đại Việt) được thành lập vào năm 1225, đến thời điểm nhà Nguyên xâm phạm, đã có nền hòa bình 180 năm kể từ khi nhà Tống xâm lược vào năm 1076.</p>
<h2>Lực lượng</h2>
<ul><li>Theo Tập sử biên niên của Rasìd ud-Dìn: Quân đội của Ngột Lương Hợp Thai gồm <a href="__missing__">kỵ binh</a> Mông Cổ và 20.000 quân sĩ người Di (thuộc nước <a href="__missing__">Đại Lý</a> vừa bị Mông Cổ chinh phục). Không có số liệu chính xác về số kỵ binh Mông Cổ, nhưng theo Rasìd ud-Dìn (Tập sử biên niên) cho biết rằng ban đầu Hốt Tất Liệt và Ngột Lương Hợp Thai đã đem 3 vạn quân xuống đánh Đại Lý (Vân Nam), sau đó Hốt Tất Liệt đi hướng khác, còn Ngột Lương Hợp Thai đánh tiếp sang Đại Việt, khi tiến lên châu Ngạc gặp Hốt Tất Liệt thì quân số còn lại không quá 5.000. Như vậy, trừ đi số tổn thất khi đánh Đại Lý và số kỵ binh đi theo Hốt Tất Liệt, thì số kỵ binh Mông Cổ khi tiến đánh Đại Việt sẽ vào khoảng 10.000 là hợp lý. Cộng thêm quân người Di thì tổng số quân của Mông Cổ có khoảng 30.000. Tiên phong là tướng <a href="__missing__">Aju</a><a href="__missing__">Cacakdu</a> (Triệu Triệt Đô hay Triệt Triệt Đô). Ngoài ra, đội quân này còn có phò mã của Mông Cổ là <a href="__missing__">Quaidu</a> (Hoài Đô). Đi tiên phong là <a href="__missing__">Đoàn Hưng Trí</a> vua <a href="__missing__">Đại Lý</a> đã đầu hàng.</li><li>Theo sách <i>Nghệ thuật đánh giặc giữ nước của dân tộc Việt Nam</i> thì quân Mông Cổ có khoảng 1 đến 2 vạn, cộng với 2 vạn quân <a href="__missing__">Đại Lý</a> được Mông Cổ trưng dụng, tổng số là khoảng 3 đến 4 vạn.[<i><a href="__missing__">cần dẫn nguồn</a></i>]</li><li>Quân Đại Việt, gồm quân cấm vệ và quân địa phương, có khoảng 10 vạn, trong đó có 2 vạn cấm quân (lực lượng chủ lực đóng ở gần kinh thành) và 8 vạn sương quân (quân đóng ở các địa phương). Quân Trần có đủ các binh chủng <a href="__missing__">bộ binh</a>, <a href="__missing__">kỵ binh</a>, <a href="__missing__">tượng binh</a><a href="__missing__">thủy binh</a> đã được thao luyện chu đáo. 2 vạn cấm quân có thể huy động toàn bộ, nhưng 8 vạn sương quân thì phải đóng quân rải khắp trên lãnh thổ cả nước, bao gồm việc ngăn ngừa nổi loạn, chống đạo tặc, canh gác biên giới và lăng tẩm... nên nhà Trần chỉ có thể tập trung được một bộ phận sương quân để tác chiến với Mông Cổ. Ước tính tổng binh lực của nhà Trần trong cuộc chiến này vào khoảng 6 vạn.</li></ul><a href="__missing__"></a>Hình ảnh một chiến binh thiện chiến Mông Cổ, với ngựa, giáp trụ, cung tên,...
<p>Đạo quân của Ngột Lương Hợp Thai không thật đông nếu nhìn về số lượng tuyệt đối, họ chỉ bằng 1/2 quân số nhà Trần. Tuy vậy, quân Mông Cổ, như đã được chứng minh trong quá trình tác chiến của mình, hầu như luôn thua sút về quân số so với đối phương của họ, ít nhất là theo tỷ lệ 1:2, tức là nhiều ra thì số quân của họ cũng chỉ bằng một nửa so với đối phương (Mông Cổ là nước ít dân, dù huy động hầu hết trai tráng thì họ cũng chỉ có khoảng 15 20 vạn quân). Tuy ít hơn về số lượng nhưng quân Mông Cổ có lợi thế hơn hẳn về kỵ binh. Theo Đại Việt sử ký toàn thư, quân Trần có vài nghìn kị binh, còn quân Mông Cổ có khoảng 1 vạn kị binh.</p>
<p>Ngoài ra, kỵ binh Mông Cổ cũng giỏi hơn về kỹ năng chiến đấu. Người Mông Cổ là dân tộc du mục sống bằng chăn nuôi và săn bắn, nên từ nhỏ đã phải liên tục tập cưỡi ngựa và bắn cung để sinh tồn, hình thức <i>"thao luyện kị binh cả đời"</i> này không thể có được trong một đất nước sống bằng nông nghiệp - ngư nghiệp như Đại Việt. Con trai Mông Cổ từ khi 3 tuổi đã bắt đầu học cưỡi ngựa, khi 4 - 5 tuổi thì nhận <a href="__missing__">cây cung</a> đầu tiên của mình. Suốt cuộc đời, người Mông Cổ dành phần lớn thời gian trên yên ngựa để săn bắn và chiến đấu. Trong các chiến dịch quân sự, người Mông Cổ còn có thể buộc mình vào yên ngựa để vừa ngủ vừa cưỡi, nhờ đó đạt được tốc độ hành quân cao. Các chiến binh Mông Cổ được ca ngợi là có sức chịu đựng phi thường, ai cũng sở hữu nhiều loại vũ khí và bắn thành thạo cung tên.</p>
<p><a href="__missing__">Kỵ binh</a> là binh chủng lợi hại bậc nhất thời trung cổ, có tính cơ động hơn hẳn bộ binh, cho phép quân Mông Cổ nhanh chóng tập trung lực lượng đánh vào chỗ mỏng yếu của đối phương, hoặc sẽ rút lui nhanh nếu thấy bất lợi. <a href="__missing__">Sóng biển (chiến thuật kỵ binh)</a> là cách tác chiến lợi hại của quân Mông Cổ, họ bao vây đội hình quân đối phương bằng cách bố trí kỵ binh theo tuyến dài, thực hiện chiến đấu <a href="__missing__">bao vây</a> linh hoạt. Khi quân thù mạnh hơn thì họ sẽ <a href="__missing__">phân tán lực lượng</a>, khi thời cơ thích hợp họ sẽ hợp lại và tiến hành bao vây đối phương. Chỉ với 100 <a href="__missing__">kỵ binh</a> có thể bao vây 1.000 bộ binh, và 1.000 kỵ binh có thể triển khai thành một tuyến dài hơn 30 dặm. Chiến thuật này là hình thức <a href="__missing__">tác chiến cơ động</a>: Quân Mông Cổ liên tục phi ngựa để giữ khoảng cách, không để đối phương tiếp cận, vũ khí sử dụng chủ yếu là <a href="__missing__">cung tên</a> để bắn quân địch từ xa. Khi quân đối phương chạy tới gần để <a href="__missing__">cận chiến</a>, quân Mông Cổ sẽ phi ngựa rút nhanh về phía sau, và chiến đấu theo <a href="__missing__">Chiến thuật Parthia</a> (vừa phi ngựa vừa bắn tên), nếu còn đường lui thì họ luôn tránh việc cận chiến. Chiến thuật này vừa khai thác tối đa lợi thế về tài năng cưỡi ngựa bắn cung của người Mông Cổ, vừa giảm tối đa nguy hiểm khi đánh cận chiến. Một kỵ binh Mông Cổ có thể dùng cung tên bắn hạ vài binh sĩ đối phương từ xa cả trăm mét, trong khi đối phương chỉ có gươm giáo thì cự ly tác chiến chỉ được vài mét, nên không thể đánh trả được.</p>
<p>Với lợi thế chiến thuật này, có những trận đánh quân Mông Cổ chỉ đông bằng 1/4 đối phương mà vẫn chiến thắng (như <a href="__missing__">Trận sông Kalka</a>, <a href="__missing__">trận Mohi</a>,...), hoặc như <a href="__missing__">Chiến tranh Mông-Kim</a>, Mông Cổ chỉ có khoảng 12 vạn quân mà đã đánh bại quân đội gần 1 triệu người của <a href="__missing__">nhà Kim</a>. Huy động 3 vạn quân (trong đó 1 vạn là kỵ binh Mông Cổ) là tương đương 1/7 binh lực của toàn nước Mông Cổ huy động đánh nước <a href="__missing__">Nam Tống</a> (trong khi Nam Tống đất rộng và đông dân gấp 20 lần Đại Việt). Dựa trên thực tế đó, các tướng Mông Cổ cho rằng với nước nhỏ như Đại Việt thì chỉ cần 3 vạn quân là quá đủ để chinh phạt rồi.</p>
<p>Một đặc điểm nữa của đạo quân này là trong thành phần lãnh đạo, nó quy tụ tới 50 chư vương của triều đình Mông Cổ và phò mã Mông Cổ tên là Quaidu. Đây là những sĩ quan có liên hệ huyết thống hoặc hôn nhân với gia đình của Thành Cát Tư Hãn, gia tộc đang thống trị Mông Cổ. Nhà sử học cổ trung đại người <a href="__missing__">Ba Tư</a><a href="__missing__">Rasid ud-Din</a> chép:</p>
<p>Tuy nhiên, quân Mông Cổ có nhược điểm lớn bắt nguồn từ chính ưu điểm của họ:</p>
<ul><li>Do gấp rút tấn công nên quân Mông Cổ chỉ có kị binh và bộ binh, không chuẩn bị thủy binh, nên khi gặp sông ngòi thì không tiến quân được.</li><li>Do chú trọng việc tác chiến cơ động, hành quân phải thật nhanh nên quân Mông Cổ không mang theo dân phu để vận tải lương thực, xây dựng doanh trại (do dân phu phải khuân vác nặng nên đi khá chậm, nếu đi cùng dân phu thì kỵ binh không hành quân nhanh được). Tất cả những gì cần thiết cho việc chiến đấu, sinh hoạt và ăn uống đều được quân Mông Cổ mang theo trên lưng ngựa. Với cách này, quân Mông Cổ chỉ có thể mang theo rất ít lương thực (chỉ đủ ăn vài ngày), khi đánh vào lãnh thổ đối phương thì họ sẽ cướp lương thực của dân bản địa để nuôi sống quân lính. Đây là chiến thuật mà Mông Cổ thường áp dụng trong các cuộc chiến trước đó và tỏ ra khá hiệu quả. Nhưng nhà Trần đã nhận ra điểm yếu của chiến thuật này và chuẩn bị sẵn kế hoạch "<a href="__missing__">vườn không nhà trống</a>" để đối phó. Triều đình nhà Trần đã sớm ra lệnh cho người dân cất giấu hết lương thực trong các kho, khiến quân Mông Cổ không cướp được lương thực và dần bị suy yếu.</li></ul>
<h2>Diễn biến</h2><a href="__missing__"></a>
<p>Đội quân của Ngột Lương Hợp Thai sau khi chiếm được Đại Lý, rồi đóng binh ở A Mễ (阿迷, nay là <a href="__missing__">Khai Viễn</a><a href="__missing__">châu Hồng Hà</a> tỉnh <a href="__missing__">Vân Nam</a>) phía Bắc Đại Việt, sai hai sứ giả đến dụ hàng Đại Việt. Nhà Trần đã nhốt hai viên sứ giả vào ngục và trói bằng dây tre. Theo Nguyên sử: Ngột Lương Hợp Thai không thấy tin tức hai viên sứ giả này, bèn sai tướng là Triệt Triệt Đô cùng đem 3000 quân, chia đường tiến binh tấn công Đại Việt. Đến tháng Mười âm năm <a href="__missing__">Đinh Tỵ</a> quân Nguyên Mông tiến tới áp sát biên giới (vùng <a href="__missing__">ải Lê Hoa</a>). Tháng Chín âm năm 1257, chủ <a href="__missing__">trại Quy Hóa</a> là Hà Khuất báo tin có sứ Nguyên sang. Vua Trần không nghe lời dụ hàng, xuống chiếu ra lệnh đem quân thủy bộ ra ngăn giữ biên giới (vùng ải Lê Hoa, <a href="__missing__">núi Mai Lĩnh</a>), theo sự tiết chế của <a href="__missing__">Trần Quốc Tuấn</a> và truyền cả nước sắm sửa vũ khí.</p>
<h3>Trận Bình Lệ Nguyên</h3>
<p>Ngột Lương Hợp Thai chia quân làm hai cánh, một cánh do mình chỉ huy và cánh quân còn lại do Triệt Triệt Đô chỉ huy, chia đường tiến xuống sông Thao ở vùng Kinh Bắc, Đại Việt. Viên tướng này dùng con trai là A Truật sang giúp và dòm ngó tình hình. Nhà Trần bày nhiều lớp phòng thủ, A Truật trở về báo, liền tiến quân đi gấp, sai Triệt Triệt Đô làm tiên phong, A Truật ở sau làm điện, đến tháng 12 năm 1257, hai đạo quân hợp lại với nhau. Đến tháng Chạp năm Đinh Tỵ (1257), quân đội Mông Cổ xâm lấn đồng Bình Lệ, vua Trần Thái Tông tự mình dẫn theo sáu đạo cấm quân (Thiên Thuộc, Thiên Chương, Thánh Dực, Chương Thánh, Thần Sách, Củng Thần), cộng thêm sương quân ở các địa phương gần kinh thành để chống lại.</p>
<p>Quân Mông Cổ giáp trận quân Đại Việt do đích thân <a href="__missing__">Trần Thái Tông</a> (Trần Cảnh) ngự giá thân chinh chỉ huy tại Bình Lệ Nguyên (nay là huyện <a href="__missing__">Bình Xuyên</a> tỉnh Vĩnh Phúc). Đó là ngày <a href="__missing__">17 tháng 1</a> năm <a href="__missing__">1258</a>.</p>
<p>Quân đội <a href="__missing__">nhà Trần</a> bày tượng binh, kỵ binh và bộ binh bên bờ <a href="__missing__">sông Hồng</a> đợi giặc, tượng binh dàn hàng ngang tại tiền quân che chắn cho lớp bộ binh, kỵ binh phía sau, <a href="__missing__">thủy quân</a> dọc sông Hồng để có thể khi thua sẽ rút quân an toàn. Quân Mông Cổ chia làm ba đội để sang sông, Triệt Triệt Đô dẫn 5.000 quân làm quân tiên phong, Ngột Lương Hợp Thai cầm đại quân đi giữa, phò mã Hoài Đô và A Truật giữ hậu quân. Đội chủ lực của Ngột Lương Hợp Thai lấy những hàng binh Đại Lý dàn ở các hàng phía trước để làm bia đỡ hứng chịu thương vong, kỵ binh Mông Cổ đi phía sau để hỗ trợ và tung đòn quyết định. Ngột Lương Hợp Thai dặn Quỳ Thủ Soạn và viên tiên phong là Triệt Triệt Đô:</p>
<p>Nhưng Triệt Triệt Đô vừa qua sông đã ập lại đánh ngay. Trần Thái Tông tự làm tướng, đốc chiến đi trước xông pha tên đạn, sai tượng binh tiến ra giao chiến. Con Hợp Thai là A Truật (18 tuổi) ra lệnh cho kỵ binh bắn tên vào mắt voi, khiến voi đau và hoảng sợ, quay lại dày xéo đội hình quân Trần. Quân Trần nao núng, Trần Thái Tông ngoảnh trông hai bên, chỉ có tướng Lê Tần cưỡi ngựa một mình ra vào trận, sắc mặt không thay đổi. Lúc ấy, có người khuyên vua Trần dừng lại để chỉ huy chiến đấu. Lê Trần cố sức can vua: <i>"Nay thì bệ hạ chỉ đánh một ván dốc túi thôi! Hãy nên tạm lánh chúng, sao lại có thể dễ dàng tin lời người ta thế!"</i>. Bấy giờ, vua Trần mới lui quân đóng ở sông Lô, Lê Tần giữ phía sau. Quân Mông Cổ bắn loạn xạ, Lê Tần lấy ván thuyền che cho vua Trần khỏi trúng tên giặc. Thế quân Mông rất mạnh, do không chiếm được thuyền của Đại Việt, vua Trần vẫn bảo tồn được lực lượng và lui về giữ sông Thiên Mạc.</p>
<p>Quân Trần thất lợi nhưng chủ động rút lui. <a href="__missing__">Trần Thái Tông</a> và tướng <a href="__missing__">Lê Tần</a> lui tới sách Cụ Bản, gặp tướng <a href="__missing__">Phạm Cự Chích</a> đem viện binh tới cứu. Quân Mông Cổ giết được Phạm Cự Chích, nhưng vua Trần đã chạy thoát ra bến Lãnh Mỹ, rồi xuôi thuyền về Phù Lỗ. Không bắt được bộ chỉ huy nhà Trần, Ngột Lương Hợp Thai nổi giận. Triệt Triệt Đô uống thuốc độc tự sát do không nghe lệnh, để vua Trần chạy thoát.</p>
<h3>Quân Trần rút lui</h3>
<p>Khi vua Thái Tông triệt binh về <a href="__missing__">sông Thiên Mạc</a>, Lê Tần đã thảo luận với ông về những chuyện cơ mật, không mấy người biết tới. Khi ấy, Thái Tông cũng ngự thuyền nhỏ tới thuyền của em là <a href="__missing__">Thái uý</a><a href="__missing__">Trần Nhật Hiệu</a> để hỏi ý Nhật Hiệu về kiến về kế sách giữ nước. Nhật Hiệu ngồi dựa vào mạn thuyền, không thể nào đứng lên được và đưa ngón tay xuống chấm nước rồi ghi hai chữ "nhập Tống" trên mạn thuyền (tức là nên chạy sang lánh ở đất <a href="__missing__">Nam Tống</a>). Thái Tông bèn hỏi về tình hình của quân Tinh Cương dưới quyền Nhật Hiệu, thì Nhật Hiệu đáp lại: <i>"Không gọi được chúng đến</i>". Thế rồi, nhà vua lại ngự thuyền đến chỗ <a href="__missing__">Thái sư</a><a href="__missing__">Trần Thủ Độ</a>. Khi nghe câu hỏi của nhà vua, Thủ Độ tâu:</p>
<p>Ngày hôm sau, ngày <a href="__missing__">18 tháng 1</a> năm <a href="__missing__">1258</a>, hai bên chạm trán một lần nữa tại Phù Lỗ, vua Trần đã chặt cầu Phù Lỗ từ trước.</p>
<p>Hai bên đối mặt nhau qua một con sông (<a href="__missing__">sông Cà Lồ</a>) mà bày trận, quân Mông Cổ vẫn là người qua sông phá trận. Quân Mông muốn qua sông nhưng không có thuyền bè, bèn men theo bờ sông bắn tên xuống nước, thấy chỗ nào tên bắn xuống mà không nổi lên tức là cạn, rồi dùng kị binh băng qua sông. Quân Trần vẫn tiếp tục gặp bất lợi, nhưng một lần nữa họ lại chủ động rút lui. Sau đó, quân Trần lại chủ động rút khỏi <a href="__missing__">Thăng Long</a>.</p>
<p>Quân Mông Cổ chiếm được kinh đô Đại Việt sau 2 trận đánh. Nguyên sử chép: <i>Ngột Lương Hợp Thai cũng phá quân bộ, lại cùng A Thuật hội đánh, đại phá chúng, rồi vào nước này. Nhật Quýnh (chỉ vua Trần) trốn chạy ra hải đảo. Bắt gặp sứ giả ngày trước ở trong ngục, bị dây tre trói lằn vào da thịt, lúc cởi trói ra, một sứ giả chết, do đó làm cỏ thành này.</i></p>
<h3>Quân Trần phản công</h3><a href="__missing__"></a>Sa đồ trận Quy Hóa năm 1257 nơi Hà Bổng chỉ huy tập kích quân Nguyên Mông
<p>Chiếm được kinh đô chỉ sau hai trận đánh, nhưng kho tàng trống rỗng là vấn đề lớn đối với đội quân Mông Cổ. Những cuộc cướp bóc để kiếm lương ở vùng ngoại vi và phụ cận không có nhiều kết quả, quân Mông Cổ lâm vào tình trạng thiếu thốn lương thực.</p>
<p>Nửa đêm ngày <a href="__missing__">28 tháng 1</a> năm <a href="__missing__">1258</a>, từ nơi trú quân (Thiên Mạc) trên <a href="__missing__">Hoàng Giang</a>, Trần Thái Tông cùng Thái tử Trần Hoảng ngự lâu thuyền ngược sông, bất ngờ đánh thẳng vào quân Mông Cổ. Quân Mông Cổ cho rằng lực lượng quân Trần đã kiệt quệ sau trận thua đầu nên rất chủ quan, do đó khi bị tập kích đã không kịp trở tay, bị thua to. Sau khi bị phá tan tại <a href="__missing__">Đông Bộ Đầu</a>, quân Mông Cổ không giữ nổi Thăng Long nữa. Chúng đồng loạt tháo chạy thẳng về <a href="__missing__">Vân Nam</a>.</p>
<p>Như khi mới tiến quân vào, quân Mông Cổ rút chạy theo dọc sông Thao, nhưng theo con đường bộ ở phía tả ngạn. Quân Mông rút lui quá nhanh, ngoài cả dự tính của nhà Trần khiến vua Trần chưa kịp bố trí lực lượng đón đánh. Tuy nhiên khi đến Quy Hóa (vùng <a href="__missing__">Lào Cai</a>, <a href="__missing__">Yên Bái</a>), quân Mông bị chủ trại là <a href="__missing__">Hà Bổng</a> một thổ quan <a href="__missing__">người Tày</a> - tập kích kịch liệt. Trong số quân của Hà Bổng có những người Thái chạy từ nước <a href="__missing__">Đại Lý</a> vừa bị Mông Cổ diệt sang theo Đại Việt, muốn trả thù người Mông Cổ nên đã đánh rất hăng khiến quân Mông Cổ khốn đốn; chỉ vì số quân của Hà Bổng ít người nên thiệt hại của quân Mông Cổ không lớn. Trên đường rút về, do sợ bị quân Trần truy đuổi đằng sau, quân Mông Cổ cố rút nhanh và không cướp phá dân chúng, do đó người Việt mỉa mai gọi là "giặc Bụt".</p>
<h3>Kết cục</h3>
<p>Theo <a href="__missing__">Nguyên sử</a> - Ngột Lương Hợp Thai truyện và Kinh thế đại điển tự lục chép rằng: sau khi bỏ Thăng Long, người Mông Cổ đã chạy về thành Áp Xích, trên đất của 37 bộ Quỷ Phương (Đại Lý), và điều này có nghĩa là Mông Cổ đã không đạt được mục tiêu là chiếm Đại Việt để làm bàn đạp đánh vào lưng Nam Tống. Ngột Lương Hợp Thai truyện cũng cho biết, Uriyangqatai đóng quân ở Áp Xích, sau khi có lệnh của Mông Kha thì mới đi theo đường trại Hoành Sơn để tiến vào châu Ngạc của Tống và hội quân với <a href="__missing__">Hốt Tất Liệt</a>. Nguyên sử lại viết: <i>quân ở lại 9 ngày, vì khí hậu nóng nực nên rút quân về. Lại sai hai sứ giả đi gọi Nhật Cảnh về (chỉ vua Trần). Nhật Cảnh thấy kinh đô bị phá hủy, rất giận, ép sứ giả quay về</i>. Thực tế, quân Mông Cổ đánh Đại Việt vào tháng 1, đúng vào lúc giữa <a href="__missing__">mùa đông</a> ở miền Bắc Việt Nam, do vậy không thể có chuyện "khí hậu nóng nực nên rút quân về" như Nguyên sử chép được.</p>
<p>Các khám phá địa chất gần đây cho thấy khoảng năm 1257 hoặc đầu 1258, <a href="__missing__">núi lửa Samalas</a> ở Indonesia xảy ra phun trào lớn, làm khí hậu thế giới bị biến động. Một số ý kiến cho rằng quân Mông ra lệnh rút quân là do thời tiết trở nên khắc nghiệt bởi ảnh hưởng từ vụ phun trào. Tuy nhiên, các ý kiến này là không hợp lý. Thứ nhất, đúng là vụ phun trào núi lửa Samalas làm khí hậu ấm lên trong mấy tháng do hiệu ứng của khí sunfat, nhưng mức gia tăng nhiệt độ chỉ ở mức mấy độ C, chỉ có thể làm mùa đông bớt lạnh chứ không thể biến mùa đông thành "mùa hè nóng nực" được. Thứ hai, ảnh hưởng của vụ phun trào cũng diễn ra tương tự ở lãnh thổ nước <a href="__missing__">Nam Tống</a> đang bị Mông Cổ chinh phạt vào cùng thời điểm, nhưng không hề thấy quân Mông Cổ rút khỏi Nam Tống vì lý do thời tiết.</p>
<p>Thiệt hại của quân Mông Cổ, tùy theo nguồn tài liệu mà chênh lệch từ già nửa cho tới khoảng 2/3:</p>
<ul><li>Theo <a href="__missing__">Rashid-al-Din</a>, đạo quân ba vạn kỵ binh Mông Cổ của Ngột Lương Hợp Thai kéo xuống Vân Nam, trước khi tiến lên châu Ngạc, còn lại không quá 5000 người, không rõ thiệt hại trong chiến tranh với Đại Việt là bao nhiêu.</li><li><i>Nguyên sử</i>, <i>Ngột Lương Hợp Thai truyện</i> và bài bia ký A Truật thì chép rằng: khi thâm nhập đất Tống, đoàn quân này còn lại 3.000 kị binh Mông Cổ và 1 vạn quân <a href="__missing__">Thoán Bặc</a>.</li></ul>
<h3>Sau cuộc chiến</h3>
<p>Vua Trần Thái Tông hồi kinh, trăm họ Đại Việt nghiệp yên như cũ. Định công phong tước, cho Lê Tần (hay Lê Phụ Trần) làm Ngự sử đại phu và đem công chúa Chiêu Thánh gả cho. Vua nói: <i>Trẫm không có khanh thì làm gì có được ngày nay. Khanh nên cố gắng để cùng hưởng phúc sau này.</i> Cùng năm đó (1258), vua Trần Thái Tông truyền ngôi cho thái tử Hoảng, tức Trần Thánh Tông.</p>
<p>Năm 1258, ngay khi vừa bị đuổi chạy về đến Vân Nam, Uriyangqatai (Ngột Lương Hợp Thai) đã sai ngay hai sứ sang dụ vua Thái Tông vào chầu. Căm phẫn vì thấy kinh đô Thăng Long bị tàn phá, Thái Tông với khí thế của người chiến thắng, đã sai trói hai sứ lại, đuổi về.</p>
<p>Vua Trần sai sứ giả sang thông hiếu với nhà Tống. Sai Lê Phụ Trần làm sứ, Bác Lãm làm phó sang nhà Nguyên, rốt cuộc định ba năm một kỳ cống làm lệ thường. Theo Nguyên sử: Tháng 2 ngày mậu ngọ năm thứ 8, Nhật Cảnh (vua Trần) truyền nước cho con trưởng là Quang Bính, đổi niên hiệu Thiệu Long. Mùa hạ, Quang Bính sai con rể (Lê Phụ Trần) cùng người nước này đem phương vật đến, Ngột Lương Hợp Thai hộ tống đến sở quan, sai riêng <a href="__missing__">Nột Lạt Đinh</a> đến dụ chúng, nói: <i>"Trước ta sai sứ giả đến giao hảo, các ngươi bắt giữ mà không cho quay về, ta do đó phát binh năm trước. Vì vua của nước ngươi đứng trốn ở đồng cỏ, lại lệnh cho hai sứ giả đến gọi về nước, ngươi lại ép sứ giả ta trở về. Nay sai riêng sứ giả đến dụ, nếu các ngươi thực lòng nội thuộc, thì vua nước ngươi phải tự mình đến, nếu vẫn không chừa, sớm đến báo cho ta"</i>. Quang Bính nói: <i>"Nước nhỏ thật lòng thờ Nhà vua, thì nước lớn lấy gì đối đãi nước nhỏ?"</i>. Nột Lạt Đích về báo. Bấy giờ Vương chư hầu là Bất Hoa giữ Vân Nam, Ngột Lương Cáp Thai nói với Vương, lại sai Nột Lạt Đinh đến dụ, sai sứ giả cùng đến. Quang Bính bèn thực lòng nạp thuộc, lại nói: <i>"Đợi ban ân đức, liền sai con em làm con tin"</i>. Vương lệnh cho Nột Lạt Đinh lên ngựa đưa tin vào tấu lên.</p>
<p>Theo sử gia <a href="__missing__">Lê Tắc</a>, người viết quyển sử <a href="__missing__">An Nam chí lược</a>, có chép về bức thư vua Nguyên gửi cho <a href="__missing__">vua Trần</a> năm 1275: "<i>Theo chế độ của tổ tông đã quy định, phàm các nước Nội phụ thì vua phải thân hành tới chầu, gửi con em làm con tin, biên nạp dân số, nộp thuế lệ, mộ dân trợ binh và vẫn đặt quan <a href="__missing__">Đạt lỗ hoa xích</a> để thống trị; sáu điều nói trên, năm trước đã có lời dụ cho khanh biết rồi, thế mà qui phụ đã hơn 15 năm, khanh chưa từng tới triều kiến một lần nào, và các điều quy định đến nay vẫn chưa thi hành, tuy rằng ba năm tới cống hiến một lần, nhưng các đồ cống hiến đều không dùng được</i>". Như vậy, mang tiếng là một nước phải triều cống, nhưng đó chỉ là trên danh nghĩa, còn thực tế Đại Việt là một nước tự chủ, không thi hành theo sáu điều quy định của Mông Cổ về nước Nội phụ của Mông Cổ.</p>
<h2>Nhận định</h2>
<p>Các tác giả của <a href="__missing__">Nguyên sử</a>, phần Hiến Tông bản kỷ chỉ chép vắn tắt:</p><i>"Mùa đông tháng 11, Ngột Lương Hợp Thai đánh vào Giao Chỉ, đi vào nước nó. Chúa An Nam là Trần Nhật Cảnh trốn vào hải đảo, [Mông Cổ] bèn rút quân về"</i>. (ghi chép của Nguyên sử để tránh kị huý đã không công nhận đây là thất bại mà chỉ nói tránh là "Mông Cổ rút quân về", không nhắc đến việc quân Mông Cổ bại trận ở <a href="__missing__">Đông Bộ Đầu</a> và bị tập kích khi rút về. Vua Trần cũng không hề "trốn vào hải đảo" như Nguyên sử viết mà đã trực tiếp chỉ huy <a href="__missing__">trận Đông Bộ Đầu</a> phản công đánh bại quân Mông Cổ)
<p>Trong <i><a href="__missing__">Đại Việt sử ký toàn thư</a></i>, Kỷ nhà Trần, phần Thái Tông hoàng đế, có bình luận:</p> "<i>...lúc đó, người Nguyên mới lấy <a href="__missing__">Vân Nam</a>, du binh xâm lược đến, không có ý lấy nước ta.</i>" Bình luận "quân Nguyên không có ý lấy nước ta" trong Đại Việt sử ký toàn thư ngày nay bị bác bỏ. Các sử gia trong đế quốc Mông Cổ như Rashid al-Din và <a href="__missing__">Lê Tắc</a> (tác giả <a href="__missing__">An Nam chí lược</a>) đều công nhận rằng Mông Kha muốn chiếm Đại Việt làm bàn đạp để đánh thọc vào châu Ung, châu Quế phía nam nước Tống. Chính <a href="__missing__">Nguyên sử</a> cũng ghi: <i>"Uriangqadai vào Giao Chỉ định kế lâu dài.</i>" Nếu chiến dịch này chỉ là để cướp bóc, không phải để chiếm lãnh thổ thì quân Mông không cần phải huy động tới 3 vạn quân, và Mông Kha cũng đã không cử tới 50 chư vương của triều đình Mông Cổ, có cả phò mã Mông Cổ tên là Quaidu tham gia chỉ huy đội quân này.
<p>Lời cẩn án của các sử quan thời Nguyễn chép trong Khâm định Việt sử thông giám cương mục:</p><i>Trận này thế giặc rất mạnh, thế mà Sử cũ chỉ chép rằng nhà vua tiến quân đánh được giặc, không chép rõ cái cớ sở dĩ đánh được như thế nào cả. Tham khảo sách Nguyên sử loại biên và sách Cương mục tục biên (Trung Quốc) đều chép rằng: Ngột Lương Hợp Thai đã bình được nước Đại Lý, kéo quân sang nước ta, ba lần sai sứ đến dụ nhà vua đầu hàng, đều không thấy sứ thần trở về, bấy giờ mới chia đường tiến quân, nhân thế thắng, kéo vào đô thành nước ta, khi vào, thấy ba người sứ sai sang trước còn bị giam ở trong ngục, người nào cũng bị những thanh tre bó chặt vào mình sát hẳn đến da, khi cởi trói ra, thì một người đã bị chết, họ liền giết hết cả dân trong thành. Đóng quân ở đây được 9 ngày, vì không chịu được nóng nực, phải rút về. Lại sai sứ giả đến chiêu an, vua Thái Tông giận họ tàn phá, nên lại sai trói hai sứ giả đưa trả lại.</i>
<p>Sử gia Trần Xuân Sinh cho rằng: <a href="__missing__">Ngột Lương Hợp Thai</a> là tướng giỏi, khi thấy không giữ nổi Thăng Long đã rút sớm về Vân Nam để bảo toàn lực lượng là thượng sách.</p>
<p>Việc quân Mông Cổ thất bại ở Đại Việt cũng đã giúp Nam Tống tránh được việc bị đánh kẹp từ phía Nam để có thể tập trung binh lực đối phó Mông Cổ ở phía Bắc. Quy mô đạo quân của Ngột Lương Hợp Thai có thể nói là không lớn, chỉ cỡ 3 vạn. Nhưng xét về hậu quả của thất bại đối với toàn thể chiến lược xâm lăng đất Tống theo bốn con đường cũng như sự thất bại quá chóng vánh, sử gia <a href="__missing__">Hà Văn Tấn</a> có nhận định rằng:</p> "<i>Có lẽ...trong đời chinh chiến của mình, chưa bao giờ Uriangqadai bị thua nhục nhã như lần này.</i>"
<p>Sử liệu Trung Quốc thời Nguyên, Minh không chấp nhận họ là nước lớn mà lại thất bại, nên đã quy kết nguyên nhân thất bại của quân Mông Cổ là do thời tiết nóng nực của Đại Việt. Trong Nguyên văn loại, quyển 41, Kinh thế đại điển tự lục (bản Thương vụ ấn thư quán 1958, trang 563) chép rằng: <i>"[Quân Mông Cổ] ở lại chín ngày, vì nóng nực, rút quân về"</i>. Còn <a href="__missing__">Nguyên sử</a> trong quyển 209, An Nam truyện cũng viết là <i>"Quân ở lại chín ngày, vì khí hậu uất nhiệt bèn rút quân về"</i>. Thực tế, quân Mông Cổ đánh Đại Việt vào tháng 1, đúng vào lúc giữa <a href="__missing__">mùa đông</a> ở miền Bắc Việt Nam, do vậy không thể có chuyện "khí hậu nóng nực nên rút quân về" như Nguyên sử và Kinh thế đại điển tự lục chép được.</p>
<p>Chiến thắng của quân dân Đại Việt trong cuộc kháng chiến chống Nguyên Mông lần thứ nhất đã ghi dấu công lao của vua Trần Thái Tông. Sau này vua <a href="__missing__">Trần Nhân Tông</a> về thăm Long Hưng, trông thấy vẻ uy nghi đường vệ của lăng Thái Tông, đã ghi lại dư âm của chiến thắng năm 1258 trong niên hiệu Nguyên Phong bằng mấy câu thơ trong bài "Xuân Nhật yết Chiêu Lăng":</p> Tì hổ thiên môn túc Y quan thất phẩm thông Bạch đầu quân sĩ tại Vãng vãng thuyết Nguyên Phong Dịch: Nghìn cửa quân tì hổ uy vũ Các quan thất phẩm áo đầy đủ. Quân sĩ người đầu bạc vẫn còn, Thường thường kể chuyện thời Nguyên Phong
<ul><li>Các tác giả phương Tây Peter D. Sharrock và Vũ Hồng Liên (người Anh gốc Việt) đã nhận xét về kết quả cuộc chiến năm 1258:</li></ul>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Kháng chiến chống Nguyên Mông lần thứ 2</a></li><li><a href="__missing__">Kháng chiến chống Nguyên Mông lần thứ 3</a></li><li><a href="__missing__">Trần Thái Tông</a></li><li><a href="__missing__">Trần Thủ Độ</a></li><li><a href="__missing__">Lê Phụ Trần</a></li><li><a href="__missing__">Lê Tắc</a></li></ul>
<h2>Ghi chú</h2>
<ol><li><a href="__missing__"></a> Niên hiệu của vua Trần Thái Tông.</li><li><a href="__missing__"></a> Trích từ <a href="__missing__">Tổ chức và chiến thuật quân sự của quân đội Đế quốc Mông Cổ</a>, phần <i>Giáo dục và Đào tạo</i></li><li><a href="__missing__"></a> Trong lần xâm lấn Đại Việt lần thứ 2, trong quân của Thoát Hoan cũng có hai thân vương Mông Cổ là Tích Lệ Cơ và Đại vương Giảo Kì. Tuy vậy, khi này, Tích Lệ Cơ đang bị tội và bị phái đi phục vụ trong đạo quân xâm lược như một biện pháp trừng phạt.</li><li><a href="__missing__"></a> Số liệu của sách Nguyên sử</li><li><a href="__missing__"></a> Quy Hóa: Xưa thuộc bộ Tân Hưng, nhà Lý gọi là Đăng Châu; nhà Trần gọi là trại Quy Hóa; nhà Lê đổi làm phủ; bây giờ cũng theo như cũ, thuộc tỉnh Hưng Hóa, lời chú của các sử quan trong Khâm định Việt sử thông giám cương mục</li><li><a href="__missing__"></a> Quân Tinh Cương: Tức quân tuyển trong những người ở làng Tinh Cương do Nhật Hiệu thống lĩnh. Trích lời chú trong sách Khâm định Việt sử thông giám cương mục.</li><li><a href="__missing__"></a> Đoạn sông Hồng chảy qua <a href="__missing__">Lý Nhân</a>, Hà Nam.</li><li><a href="__missing__"></a> Nay là dốc Hàng Than, Hà Nội</li></ol>
<h2>Chú thích</h2>
<ol><li><a href="__missing__"></a> Nhà Trần khi đó có 100.000 quân trên cả nước, gồm 2 vạn cấm quân và 8 vạn sương quân. Tất cả cấm quân và khoảng 1 nửa sương quân được huy động</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a><a href="__missing__">Đại Việt Sử ký Toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế</li><li><a href="__missing__">1</a><a href="__missing__">2</a> Hội khoa học lịch sử Việt Nam, Viện sử học, <i>Nhà Trần và con người thời Trần</i>, trang 139</li><li><a href="__missing__">1</a><a href="__missing__">2</a> Nguyên sử, phần Liệt truyện, Ngoại di, An Nam</li><li><a href="__missing__"></a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr 263</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a> Hà Văn Tấn và Phạm thị Tâm, sách đã dẫn, tr 61</li><li><a href="__missing__"></a><a href="__missing__">Trần Quốc Vượng</a><a href="__missing__">Hà Văn Tấn</a>, Lịch sử chế độ phong kiến Việt Nam, tập 1, trang 382.</li><li><a href="__missing__"></a><a href="__missing__">Nguyên sử, quyển 21, Tốc Bất Đài (Ngột Lương Hợp Thai)</a>.</li><li><a href="__missing__"></a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr283</li><li><a href="__missing__">1</a><a href="__missing__">2</a><a href="__missing__">3</a><a href="__missing__">4</a><a href="__missing__">5</a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr283, 284</li><li><a href="__missing__"></a><a href="__missing__">Đại Việt sử ký toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế chép trận đánh diễn ra ngày 12 tháng 12 năm <a href="__missing__">Đinh Tỵ</a>.</li><li><a href="__missing__"></a> Hà Văn Tấn và Phạm Thị Tâm, sách đã dẫn, tr 68</li><li><a href="__missing__"></a> Hà Văn Tấn và Phạm Thị Tâm, sách đã dẫn, tr 69</li><li><a href="__missing__"></a><a href="__missing__">"Chú thích của Đại Việt Sử Ký Toàn Thư"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 25 tháng 5 năm 2011. Truy cập ngày 31 tháng 3 năm 2012.</li><li><a href="__missing__"></a><a href="__missing__">Đại Việt sử ký toàn thư</a>, Bản Kỷ, Kỷ Nhà Trần, mục Thái Tông Hoàng đế chép trận đánh diễn ra ngày 24 tháng 12 năm <a href="__missing__">Đinh Tỵ</a>.</li><li><a href="__missing__"></a> Trần Xuân Sinh, sách đã dẫn, tr 82</li><li><a href="__missing__"></a> Trần Xuân Sinh, sách đã dẫn, tr 84</li><li><a href="__missing__"></a><a href="__missing__">Lavigne và đồng nghiệp 2013</a>, tr.&nbsp;16746.Lỗi sfn: không có mục tiêu: CITEREFLavigneDegeaiKomorowskiGuillet2013 (<a href="__missing__">trợ giúp</a>)</li><li><a href="__missing__"></a> Đại Việt sử ký toàn thư, Nhà xuất bản thời đại, 2013, tr 285</li><li><a href="__missing__"></a> An Nam chí lược, Viện đại học Huế, Ủy ban phiên dịch sử liệu, 1961, bản điện tử, tr 19</li><li><a href="__missing__"></a><a href="__missing__">Lê Mạnh Thát</a> (2004), <i>Toàn tập Trần Thái Tông</i>, Nhà xuất bản Tổng hợp TP Hồ Chí Minh, các trang 78-83.</li><li><a href="__missing__"></a> Khâm định việt sử thông giám cương mục, Nhà xuất bản Giáo dục - Hà Nội, 1998, quyển VI</li><li><a href="__missing__"></a> Trần Xuân Sinh, sách đã dẫn, tr 83</li><li><a href="__missing__"></a><a href="__missing__">http://vanhoanghean.com.vn/index.php?option=com_k2&amp;view=item&amp;id=4142:b%E1%BB%8B-coi-th%C6%B0%E1%BB%9Dng-hay-t%E1%BB%B1-coi-th%C6%B0%E1%BB%9Dng-</a>?</li><li><a href="__missing__"></a> Peter D. Sharrock (2014). <a href="__missing__"><i>Descending Dragon, Rising Tiger: A History of Vietnam</i></a> (bằng tiếng Anh). Reaktion Book. <a href="__missing__">ISBN</a>&nbsp;<a href="__missing__">1780233884</a>. {{<a href="__missing__">Chú thích sách</a>}}: Đã bỏ qua tham số không rõ |đồng tác giả= (<a href="__missing__">trợ giúp</a>)</li></ol>
<h2>Tham khảo</h2>
<ul><li><a href="__missing__">Đại Việt Sử ký Toàn thư</a>, Nhà xuất bản thời đại, 2013</li><li>An Nam chí lược, Lê Tắc</li><li>Việt sử tiêu án, <a href="__missing__">Ngô Thì Sĩ</a></li><li>Khâm định Việt sử thông giám cương mục, Nhà xuất bản giáo dục HN, 1998</li><li>Hà Văn Tân và Phạm Thị Tâm (1972), <i>Cuộc kháng chiến chống xâm lược Nguyên Mông thế kỷ XIII</i>, Nhà xuất bản Quân đội Nhân dân, bản in lại năm 2003, Chương III: "Cuộc kháng chiến lần thứ nhất", trang 66 88</li><li>Trần Xuân Sinh (2006), <i>Thuyết Trần</i>, Nhà xuất bản Hải Phòng</li><li>Hội khoa học <a href="__missing__">lịch sử Việt Nam</a>, Viện sử học, <i>Nhà Trần và con người thời Trần</i>, Trung tâm <a href="__missing__">UNESCO</a> thông tin tư liệu, lịch sử và <a href="__missing__">văn hóa Việt Nam</a>, <a href="__missing__">2004</a></li></ul><a href="__missing__">Cổng thông tin</a>:
<ul><li><a href="__missing__">Quân sự</a></li><li><a href="__missing__">Lịch sử</a></li><li><a href="__missing__">Việt Nam</a></li></ul>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+13
View File
@@ -0,0 +1,13 @@
<h1>Đại Việt</h1>
<p><b>Đại Việt</b> (<a href="__missing__">chữ Hán</a>: 大越) tức <b>Đại Việt quốc</b> (<a href="__missing__">chữ Hán</a>: 大越國) là <a href="__missing__">quốc hiệu Việt Nam</a> tồn tại trong 2 giai đoạn từ năm <a href="__missing__">1054</a> đến năm <a href="__missing__">1400</a> và từ năm <a href="__missing__">1428</a> đến năm <a href="__missing__">1804</a>.</p>
<h2>Lịch sử</h2>
<p>Tên gọi này chính thức có từ thời trị vì của vua <a href="__missing__">Lý Thánh Tông</a> (1054 1072), vua thứ ba của <a href="__missing__">nhà Lý</a>. Trước đó, kể từ thời kỳ trị vì của <a href="__missing__">Đinh Bộ Lĩnh</a>, quốc hiệu là <a href="__missing__">Đại Cồ Việt</a> (大瞿越) gồm chữ <i>Đại</i> (大) nghĩa là <i>lớn</i> và chữ <i>Cồ</i> (𡚝) cũng cùng nghĩa là <i>lớn</i>.</p>
<p>Năm <a href="__missing__">1400</a>, sau khi thay thế <a href="__missing__">nhà Trần</a>, <a href="__missing__">Hồ Quý Ly</a>, người sáng lập <a href="__missing__">nhà Hồ</a>, đã đổi quốc hiệu thành <a href="__missing__">Đại Ngu</a> (大虞). Năm <a href="__missing__">1407</a>, <a href="__missing__">nhà Minh</a> xâm lược Đại Ngu và cai trị cho đến năm <a href="__missing__">1427</a>. Năm <a href="__missing__">1428</a>, sau khi giành <a href="__missing__">độc lập</a>, <a href="__missing__">Lê Lợi</a> đã lấy lại tên <b>Đại Việt</b> đặt làm quốc hiệu.</p><a href="__missing__"></a>Đại Việt quốc tổng lãm đồ (大越國總覽圖) được cho là bản đồ nước Đại Việt thời Vĩnh Lạc (1403-1424) nhà Minh Trung Quốc. (Nhưng thể hiện các địa danh <a href="__missing__">Đàng Ngoài</a> thời nhà Lê-Trịnh.)
<p>Quốc hiệu Đại Việt tồn tại tổng cộng trong thời gian <a href="__missing__">723</a> năm, bắt đầu từ thời vua <a href="__missing__">Lý Thánh Tông</a> đến thời vua <a href="__missing__">Gia Long</a> (<a href="__missing__">1054</a><a href="__missing__">1804</a>), tên gọi Đại Việt được dùng làm quốc hiệu trong thời kỳ trị vì của các chính quyền <a href="__missing__">nhà Lý</a>, <a href="__missing__">nhà Trần</a>, <a href="__missing__">nhà Hậu Lê</a>, <a href="__missing__">nhà Mạc</a>, <a href="__missing__">nhà Tây Sơn</a> và 3 năm đầu thời <a href="__missing__">nhà Nguyễn</a> (<a href="__missing__">1802</a> <a href="__missing__">1804</a>). Trong quá trình này tên gọi chính thức Đại Việt bị gián đoạn một lần ngắn ngủi 27 năm vào thời nhà Hồ và thời <a href="__missing__">thuộc Minh</a> (1400 1427).</p>
<p>Lịch sử Đại Việt đã xảy ra nhiều trận chiến chống ngoại xâm như: chống quân <a href="__missing__">Tống</a> năm 1076; chống quân <a href="__missing__">Nguyên Mông</a> các năm 1258, 1285 và 1288; chống quân <a href="__missing__">Minh</a> từ năm 1418 1428, chống <a href="__missing__">Thanh</a> năm 1789. Cũng có những thời kỳ đất nước bị chia cắt lâu dài, như <a href="__missing__">Nam Bắc triều</a> từ năm 1533 1592, <a href="__missing__">phân tranh Trịnh Nguyễn</a> từ năm 1627 1786.</p>
<p>Năm <a href="__missing__">1804</a>, vua <a href="__missing__">Gia Long</a> đổi tên nước thành Việt Nam và sau đó là Đại Nam, <a href="__missing__">quốc hiệu</a> Đại Việt không được sử dụng nữa.</p>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Nam Việt</a></li><li><a href="__missing__">Đại Cồ Việt</a></li><li><a href="__missing__">Đại Ngu</a></li><li><a href="__missing__">Đại Nam</a></li><li><a href="__missing__">Việt Nam</a></li></ul>
<h2>Tham khảo</h2>
<h2>Liên kết ngoài</h2>
<ul><li><a href="__missing__">Đại Việt</a> tại <a href="__missing__">Từ điển bách khoa Việt Nam</a></li><li><a href="__missing__">Dai Viet (historical kingdom, Vietnam)</a> tại <i><a href="__missing__">Encyclopædia Britannica</a></i> (bằng tiếng Anh)</li><li><a href="__missing__">Thành lập nhà nước trên biên giới phía nam Trung Quốc: Việt Nam như một đế chế bóng tối và bá quyền, bởi Tường Vũ</a></li></ul>
+13
View File
@@ -0,0 +1,13 @@
<h1>Đại Việt</h1>
<p><b>Đại Việt</b> (<a href="__missing__">chữ Hán</a>: 大越) tức <b>Đại Việt quốc</b> (<a href="__missing__">chữ Hán</a>: 大越國) là <a href="__missing__">quốc hiệu Việt Nam</a> tồn tại trong 2 giai đoạn từ năm <a href="__missing__">1054</a> đến năm <a href="__missing__">1400</a> và từ năm <a href="__missing__">1428</a> đến năm <a href="__missing__">1804</a>.</p>
<h2>Lịch sử</h2>
<p>Tên gọi này chính thức có từ thời trị vì của vua <a href="__missing__">Lý Thánh Tông</a> (1054 1072), vua thứ ba của <a href="__missing__">nhà Lý</a>. Trước đó, kể từ thời kỳ trị vì của <a href="__missing__">Đinh Bộ Lĩnh</a>, quốc hiệu là <a href="__missing__">Đại Cồ Việt</a> (大瞿越) gồm chữ <i>Đại</i> (大) nghĩa là <i>lớn</i> và chữ <i>Cồ</i> (𡚝) cũng cùng nghĩa là <i>lớn</i>.</p>
<p>Năm <a href="__missing__">1400</a>, sau khi thay thế <a href="__missing__">nhà Trần</a>, <a href="__missing__">Hồ Quý Ly</a>, người sáng lập <a href="__missing__">nhà Hồ</a>, đã đổi quốc hiệu thành <a href="__missing__">Đại Ngu</a> (大虞). Năm <a href="__missing__">1407</a>, <a href="__missing__">nhà Minh</a> xâm lược Đại Ngu và cai trị cho đến năm <a href="__missing__">1427</a>. Năm <a href="__missing__">1428</a>, sau khi giành <a href="__missing__">độc lập</a>, <a href="__missing__">Lê Lợi</a> đã lấy lại tên <b>Đại Việt</b> đặt làm quốc hiệu.</p><a href="__missing__"></a>Đại Việt quốc tổng lãm đồ (大越國總覽圖) được cho là bản đồ nước Đại Việt thời Vĩnh Lạc (1403-1424) nhà Minh Trung Quốc. (Nhưng thể hiện các địa danh <a href="__missing__">Đàng Ngoài</a> thời nhà Lê-Trịnh.)
<p>Quốc hiệu Đại Việt tồn tại tổng cộng trong thời gian <a href="__missing__">723</a> năm, bắt đầu từ thời vua <a href="__missing__">Lý Thánh Tông</a> đến thời vua <a href="__missing__">Gia Long</a> (<a href="__missing__">1054</a><a href="__missing__">1804</a>), tên gọi Đại Việt được dùng làm quốc hiệu trong thời kỳ trị vì của các chính quyền <a href="__missing__">nhà Lý</a>, <a href="__missing__">nhà Trần</a>, <a href="__missing__">nhà Hậu Lê</a>, <a href="__missing__">nhà Mạc</a>, <a href="__missing__">nhà Tây Sơn</a> và 3 năm đầu thời <a href="__missing__">nhà Nguyễn</a> (<a href="__missing__">1802</a> <a href="__missing__">1804</a>). Trong quá trình này tên gọi chính thức Đại Việt bị gián đoạn một lần ngắn ngủi 27 năm vào thời nhà Hồ và thời <a href="__missing__">thuộc Minh</a> (1400 1427).</p>
<p>Lịch sử Đại Việt đã xảy ra nhiều trận chiến chống ngoại xâm như: chống quân <a href="__missing__">Tống</a> năm 1076; chống quân <a href="__missing__">Nguyên Mông</a> các năm 1258, 1285 và 1288; chống quân <a href="__missing__">Minh</a> từ năm 1418 1428, chống <a href="__missing__">Thanh</a> năm 1789. Cũng có những thời kỳ đất nước bị chia cắt lâu dài, như <a href="__missing__">Nam Bắc triều</a> từ năm 1533 1592, <a href="__missing__">phân tranh Trịnh Nguyễn</a> từ năm 1627 1786.</p>
<p>Năm <a href="__missing__">1804</a>, vua <a href="__missing__">Gia Long</a> đổi tên nước thành Việt Nam và sau đó là Đại Nam, <a href="__missing__">quốc hiệu</a> Đại Việt không được sử dụng nữa.</p>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Nam Việt</a></li><li><a href="__missing__">Đại Cồ Việt</a></li><li><a href="__missing__">Đại Ngu</a></li><li><a href="__missing__">Đại Nam</a></li><li><a href="__missing__">Việt Nam</a></li></ul>
<h2>Tham khảo</h2>
<h2>Liên kết ngoài</h2>
<ul><li><a href="__missing__">Đại Việt</a> tại <a href="__missing__">Từ điển bách khoa Việt Nam</a></li><li><a href="__missing__">Dai Viet (historical kingdom, Vietnam)</a> tại <i><a href="__missing__">Encyclopædia Britannica</a></i> (bằng tiếng Anh)</li><li><a href="__missing__">Thành lập nhà nước trên biên giới phía nam Trung Quốc: Việt Nam như một đế chế bóng tối và bá quyền, bởi Tường Vũ</a></li></ul>
+103
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+39
View File
@@ -0,0 +1,39 @@
<h1>Thái thượng hoàng</h1>
<p><b>Thái thượng hoàng</b> (<a href="__missing__">chữ Hán</a>: 太上皇), cũng gọi <b>Thái thượng hoàng đế</b> (太上皇帝), giản xưng <b>Thượng Hoàng</b> (上皇), là một tước vị mang ý nghĩa là <i>"Hoàng đế bề trên"</i>, địa vị cơ bản được xem là trên danh vị <a href="__missing__">Hoàng đế</a>.</p>
<p>Danh hiệu này có từ thời <a href="__missing__">nhà Hán</a>, thường chỉ được dùng cho người là cha của Hoàng đế nhưng chưa từng là Hoàng đế. Về sau, các Hoàng đế khi <a href="__missing__">thoái vị</a> cũng được dâng tôn danh hiệu này. Nếu người được tôn vấn còn sống, thì sẽ là [<i>"Thái thượng hoàng"'</i>] hoặc [<i>"Thái thượng hoàng đế"</i>] kèm theo tôn hiệu khác nữa tùy triều đại, sau khi qua đời thì dùng <a href="__missing__">miếu hiệu</a> hoặc <a href="__missing__">thụy hiệu</a>.</p>
<h2>Khái quát</h2>
<h3>Lịch sử</h3>
<p>Trong lịch sử Đông Á, không ít các trường hợp vị <a href="__missing__">quân chủ</a> sẽ <a href="__missing__">thoái vị</a> để nhường ngôi cho người kế vị vì một số lý do chính trị. Từ thời <a href="__missing__">Chiến Quốc</a>, khi các quốc gia chỉ xưng Vương, đã xảy ra trường hợp đầu tiên thời <a href="__missing__">Triệu Vũ Linh vương</a>. Ông ta nhường ngôi cho Thái tử Triệu Hà, lên ngôi sử gọi <a href="__missing__">Triệu Huệ Văn vương</a>, còn bản thân Vũ Linh vương tự xưng 「<b>Chủ phụ</b>; 主父」.</p>
<p>Dù đã thoái vị, song Vũ Linh vương vẫn nắm giữ hết tất cả quyền hành trọng đại trong nước Triệu, do đó cũng khai sinh ra hiện tượng các vị quân chủ tuy nhường ngôi nhưng vẫn thực sự nắm quyền của liên tiếp các triều đại tại Việt Nam, Nhật Bản và bản thân Trung Quốc.</p>
<p>Sau khi <a href="__missing__">Tần Thủy Hoàng</a> thiết lập nên <a href="__missing__">nhà Tần</a>, tạo nên danh xưng <a href="__missing__">Hoàng đế</a>, ông đã truy tôn cha mình là <a href="__missing__">Tần Trang Tương vương</a> làm <b>Thái thượng hoàng</b> (太上皇). Việc làm của Tần Thủy Hoàng khi đó chỉ là truy tôn, do Tần Trang Tương vương đã qua đời từ rất lâu rồi, song Tần Trang Tương vương lại chính là vị [<i>"Thái thượng hoàng"</i>] có danh vị chính thức đầu tiên trong lịch sử các quốc gia Hán Quyển.</p>
<h3>Ý nghĩa</h3>
<p>Vào thời kỳ đầu, danh xưng này biểu thị một trạng thái tôn kính nhưng không thực quyền, sau lại biểu thị sự <i>"bất lực"</i> của Hoàng đế, khi mà phải nhường ngôi cho người khác. Thời <a href="__missing__">nhà Hán</a>, <a href="__missing__">Hán Cao Tổ</a> Lưu Bang dâng tôn cha ruột <a href="__missing__">Lưu Thái Công</a> danh vị Thái thượng hoàng, và Lưu Thái Công là người đầu tiên làm Thượng hoàng khi còn sống (ông mất năm <a href="__missing__">197 TCN</a>, năm thứ 10 triều Hán Cao Tổ). Sau Tần Trang Tương vương cùng Lưu Thái Công, danh xưng này lại mới xuất hiện thời <a href="__missing__">Tấn Huệ Đế</a>. Sau <a href="__missing__">Loạn bát vương</a>, Tấn Huệ Đế bị buộc nhường ngôi cho ông chú <a href="__missing__">Tư Mã Luân</a>, dù trong năm đó Huệ Đế đã trở lại vị trí Hoàng đế như cũ.</p>
<p>Năm <a href="__missing__">471</a>, <a href="__missing__">Bắc Ngụy Hiến Văn Đế</a> bất mãn <a href="__missing__">Phùng Thái hậu</a> chuyên quyền, truyền ngôi cho con trai mới 4 tuổi là <a href="__missing__">Bắc Ngụy Hiếu Văn Đế</a>. Các quan thần tâu rằng:<i>"Tam Hoàng đạm bạc vô vi, cho nên xưng Hoàng; Tây Hán Cao Tổ phụ được tôn làm Thái thượng hoàng, không thống trị thiên hạ, nay Hoàng đế tuổi nhỏ, bệ hạ vẫn nên chấp chính"</i>, do đó, Hiếu Văn Đế tự xưng [<b>Thái thượng hoàng đế</b>; 太上皇帝], mà không phải <i>"Thái thượng hoàng"</i>, biểu thị trạng thái bản thân vẫn nắm quyền điều hình chính sự chứ không phải một vị Hoàng đế thoái vị cùng quẫn.</p>
<p>Thời <a href="__missing__">nhà Đường</a> là triều đại có nhiều Thái thượng hoàng nhất trong lịch sử Trung Quốc. Hầu hết, các vị Thái thượng hoàng đều bị buộc phải làm Thái thượng hoàng, chỉ còn danh vị chứ không còn quyền lực như <a href="__missing__">Đường Huyền Tông</a> Lý Long Cơ, hoặc như các vị <a href="__missing__">Đường Cao Tổ</a> Lý Uyên và <a href="__missing__">Đường Duệ Tông</a> Lý Đán tự mình rút lui, giao toàn bộ triều chính cho các con. Tuy nhiên, cũng có các vị Thái thượng hoàng tuy đã <a href="__missing__">thoái vị</a> nhưng vẫn giữ quyền lực tối cao, như <a href="__missing__">Tống Cao Tông</a>, <a href="__missing__">Tống Hiếu Tông</a> và đặc biệt là <a href="__missing__">Thanh Cao Tông</a>.</p>
<p>Trong <a href="__missing__">lịch sử Việt Nam</a>, <a href="__missing__">nhà Lý</a> có hai trường hợp xuất hiện Thái thượng hoàng, một là tôn xưng do là sinh phụ của Hoàng đế (<a href="__missing__">Sùng Hiền hầu</a>) dù chưa từng là Hoàng đế, và một là bị ép thoái vị (<a href="__missing__">Lý Huệ Tông</a>) để truyền cho con gái <a href="__missing__">Lý Chiêu Hoàng</a>. Thời <a href="__missing__">nhà Trần</a> là triều đại có truyền thống các Hoàng đế nhường ngôi khi con trai đã trưởng thành để về làm Thái thượng hoàng, trừ <a href="__missing__">Trần Thừa</a> ra, còn lại các vị Thái thượng hoàng nhà Trần đều tự xưng <i>"Thái thượng hoàng đế"</i>, biểu thị quyền lực vẫn còn nằm trong tay mình như Bắc Ngụy Hiến Văn Đế. Bằng chứng là những vị Thái thượng hoàng đế rất quyền lực như <a href="__missing__">Trần Minh Tông</a> và <a href="__missing__">Trần Nghệ Tông</a>.</p>
<p><a href="__missing__">Nhà Hồ</a> cũng theo nếp này và đời đầu tiên là <a href="__missing__">Hồ Quý Ly</a> thực hiện việc truyền ngôi lên làm Thái thượng hoàng, nhưng triều đại không tồn tại lâu nên không kéo dài được nếp truyền nối. Sang thời <a href="__missing__">nhà Hậu Lê</a>, Thái thượng hoàng chỉ xuất hiện vào thời <a href="__missing__">Lê trung hưng</a> - khi đó quyền lực của <a href="__missing__">chúa Trịnh</a> đã rất lớn mạnh, các Hoàng đế nhà Lê chỉ là bù nhìn, do đó địa vị của Thái thượng hoàng rất yếu, hầu như đều do các chúa Trịnh bắt ép thoái vị mà có, như <a href="__missing__">Lê Dụ Tông</a>.</p>
<h3>Các trường hợp</h3>
<p>Có trường hợp đặc biệt khi một người chưa bao giờ làm <a href="__missing__">Hoàng đế</a> nhưng vì có <a href="__missing__">con trai</a> làm <a href="__missing__">Hoàng đế</a> nên cũng được tôn là Thái thượng hoàng. Lấy ví dụ như vị Thái thượng hoàng đầu tiên trong <a href="__missing__">lịch sử</a> là <a href="__missing__">Lưu thái công</a> cha ruột của <a href="__missing__">Hán Cao Tổ</a> Lưu Bang. Tại <a href="__missing__">Việt Nam</a>, cũng có <a href="__missing__">Sùng Hiền hầu</a> của <a href="__missing__">nhà Lý</a> cùng <a href="__missing__">Trần Thừa</a> của <a href="__missing__">nhà Trần</a>, hai người đều chưa từng làm Hoàng đế từ trước nhưng được tôn xưng Thái thượng hoàng do con trai lên ngôi.</p>
<p>Thông thường, người truyền ngôi cho Hoàng đế rồi tôn xưng Thái thượng hoàng, nhưng có trường hợp <a href="__missing__">Kim Ai Tông</a> Hoàn Nhan Thủ Tự trong hoàn cảnh nguy cấp sắp bị quân <a href="__missing__">Mông Cổ</a> tấn công đến thành trì cuối cùng là <a href="__missing__">Thái Châu</a>, biết không cứu vãn được tình thế, đã nhường ngôi cho con là <a href="__missing__">Kim Mạt Đế</a> Hoàn Nhan Thừa Lân rồi tự sát vì không muốn bị quân <a href="__missing__">Mông Cổ</a> bắt. Hoàng thân nhà Đường là <a href="__missing__">Lý Uân</a> được quân phiệt <a href="__missing__">Chu Mai</a> ủng hộ làm Hoàng đế ở kinh đô Trường An, tôn <a href="__missing__">Đường Hi Tông</a> đang chạy trốn làm Thái thượng hoàng, nhưng Đường Hi Tông không thừa nhận ngôi vị Thượng hoàng mà cùng các quân phiệt khác tiêu diệt Lý Uân. Ngược lại, <a href="__missing__">Tùy Dạng Đế</a> dù không thừa nhận ngôi vị Thái thượng hoàng do <a href="__missing__">Tùy Cung Đế</a> và <a href="__missing__">Lý Uyên</a> tôn phong, nhưng lại chết trong binh biến. Tại Việt Nam, trong hoàn cảnh <a href="__missing__">nhà Mạc</a> suy tàn, <a href="__missing__">Mạc Mậu Hợp</a> truyền ngôi cho <a href="__missing__">Mạc Toàn</a> rồi tự mình làm tướng cầm quân mà không xưng Thái thượng hoàng. Ngoài ra, cuối đời <a href="__missing__">nhà Trần</a> ở <a href="__missing__">Việt Nam</a>, <a href="__missing__">Trần Nghệ Tông</a> Trần Phủ nhường ngôi cho em trai là <a href="__missing__">Trần Duệ Tông</a> Trần Kính để tự xưng làm Thái thượng hoàng. Đó là việc hi hữu khi vị trí giữa Thái thượng hoàng và Hoàng đế chỉ là anhem. Trường hợp tương tự xảy ra ở <a href="__missing__">Trung Quốc</a> thời <a href="__missing__">nhà Minh</a>, khi <a href="__missing__">Minh Đại Tông</a> tôn anh trai <a href="__missing__">Minh Anh Tông</a> làm Thái thượng hoàng do Anh Tông bị <a href="__missing__">Ngõa La</a> bắt trong <a href="__missing__">Sự biến Thổ Mộc bảo</a>.</p>
<p>Theo cách hiểu thông thường, khi con làm Hoàng đế mà cha còn sống thì cha được tôn làm Thái thượng hoàng, tuy nhiên không phải lúc nào cũng như vậy, còn tùy thuộc vào pháp độ của vương triều. Như có trường hợp cuối đời <a href="__missing__">nhà Thanh</a>, Thuần Hiền thân vương <a href="__missing__">Dịch Hoàn</a> là thân sinh của vua <a href="__missing__">Quang Tự</a> cũng không được tôn xưng Thái thượng hoàng; hay như Thuần Thân vương <a href="__missing__">Tải Phong</a> là cha vua Tuyên Thống (<a href="__missing__">Phổ Nghi</a>) nhưng chỉ đóng vai trò <a href="__missing__">nhiếp chính</a> cho Hoàng đế nhỏ tuổi chứ không làm Thái thượng hoàng. Đây là lý do Quang Tự cùng Tuyên Thống đều đã <i>"nhập tự"</i>, nhận dòng chính thống để kế thừa Đế vị (Quang Tự nhận <a href="__missing__">Hàm Phong</a>, còn Tuyên Thống Đế nhận cả <a href="__missing__">Đồng Trị</a> lẫn Quang Tự). Thời nhà Thanh, vấn đề chính thống rất gay gắt, cả hai người Quang Tự-Tuyên Thống đã nhận dòng chính mới có tư cách kế vị, cho nên xét về mặt pháp lý thì cả Dịch Hoàn cùng Tái Phong dù được kính trọng do là cha ruột của Hoàng đế, song cả hai vị Thân vương này không có tư cách tự xưng Thái thượng hoàng.</p>
<p>Tại Việt Nam, có một danh vị từng tồn tại để chỉ cha ruột của Hoàng đế, nhưng không phải Thái thượng hoàng. Khi ấy, vua <a href="__missing__">Thành Thái</a><a href="__missing__">nhà Nguyễn</a> bị <a href="__missing__">người Pháp</a> ép phải nhường ngôi cho con là vua <a href="__missing__">Duy Tân</a>, và dụ triều đình nhà Nguyễn định việc tôn hiệu cho vị vua Thành Thái thoái vị. Sau khi bàn định lễ chế của nước Đại Nam, người Pháp không chấp nhận ngôi vị [Thái thượng hoàng] vì sẽ khiến tình hình thêm phức tạp, do vậy vua Duy Tân chỉ được phép tôn cha là [<b>Hoàng Phụ Hoàng đế</b>; 皇父皇帝].</p>
<p>Chính những quy tắc phức tạp, phải có tôn ti trong việc tấn tôn vị hiệu này mà sử gia <a href="__missing__">Lê Văn Hưu</a> đã chỉ trích việc <a href="__missing__">Lý Thần Tông</a> tôn cha đẻ Sùng Hiền hầu làm Thái thượng hoàng. Khi ấy, Lý Thần Tông đã được <a href="__missing__">Lý Nhân Tông</a> chọn làm con thừa tự, phong làm <a href="__missing__">Thái tử</a> để kế vị, thì Thần Tông chỉ nên công nhận Nhân Tông mà thôi, nếu Thần Tông lại tôn cha ruột Sùng Hiền hầu thêm nữa thì <i>"hóa ra là hai gốc ư?"</i>. Nguyên văn nhận xét của Lê Văn Hưu:</p>
<h3>Sắc ấn</h3><a href="__missing__">Tập tin:太上皇帝之宝.jpg</a>Ấn <i>"Thái thượng hoàng đế chi bảo"</i> của vua Càn Long
<p>Trong lịch sử, việc tôn xưng Thái thượng hoàng thường không được xem là pháp độ có tính nhất quán ổn định về quy tắc, do vậy một số nguyên tắc về trang phục, lễ nghi của Thái thượng hoàng so với Hoàng đế cũng không mấy rõ ràng. Về cơ bản, có lẽ nghi giá của Thái thượng hoàng đều cùng với Hoàng đế ngang nhau, tuy nhiên các triều đại có truyền thống tôn xưng Thượng hoàng như <a href="__missing__">nhà Trần</a> ở Việt Nam bị lâm vào tình trạng mất mát tư liệu, nên cũng không rõ những nguyên tắc cụ thể về lễ nghi cho một Thái thượng hoàng.</p>
<p>Thời kỳ <a href="__missing__">nhà Thanh</a>, là triều đại lớn cuối cùng ở Trung Quốc xuất hiện một vị Thái thượng hoàng - <a href="__missing__">Càn Long Đế</a>. Tuy ông đã <a href="__missing__">thoái vị</a>, song trên thực tế ông vẫn nắm hết mọi quyền hành cho đến tận khi qua đời, cho nên hẳn nhiên ổng phải thiết lập quy tắc bảo chứng cho sức mạnh đó của mình: ấn bảo.</p>
<p>Năm Càn Long thứ 60 (<a href="__missing__">1795</a>), ngày <a href="__missing__">3 tháng 9</a> (âm lịch), Càn Long Đế đã 85 tuổi, triệu tập các Hoàng tử cùng Vương công Đại thần, ra chỉ tuyên bố lập Hoàng thập ngũ tử <a href="__missing__">Vĩnh Diễm</a> làm <a href="__missing__">Hoàng thái tử</a>, sửa tên thành <i>Ngưng Diễm</i>, lấy năm sau làm năm đầu Gia Khánh. Sang <a href="__missing__">tháng giêng</a> năm ấy, Càn Long Đế tự mình làm lễ nhận bảo tỷ, hạ chỉ có đoạn:</p> 「皇太子于丙辰正月上日即皇帝位。朕亲御太和殿,躬授宝玺,可称朕为太上皇帝。」 Dịch là:<i>"Hoàng thái tử vào ngày Bính Thìn, chính nguyệt kế vị Hoàng đế. Trẫm thân ngự Thái Hòa điện, cung thụ bảo tỉ, có thể gọi Trẫm là Thái thượng hoàng đế"</i>.
<p>Sau đó, Càn Long Đế còn quy định về việc dùng ngọc bảo:</p> 「朕归政后,应用喜字第一号玉宝,刻太上皇帝之宝,即将御制《十全老人之宝说》镌刻作为太上皇帝册,用彰熙朝盛瑞。」 Dịch là:<i>"Sau khi Trẫm quy chính, nên tự dùng ngọc bảo hạng nhất, khắc chữ 'Thái thượng hoàng đế chi bảo', ngự chế 'Thập toàn lão nhân chi bảo thuyết' tuyên khắc thành 'Thái thượng hoàng đế sách', dùng ngọc chương hi triều thịnh"</i>.
<p>Đây là hiện vật duy nhất chứng minh quyền hành của một Thái thượng hoàng trong thế giới Đông Á, ngay cả một chính quyền có nhiều <i>"Thượng hoàng"</i> nhất là Nhật Bản cũng chưa từng có. Ấn bảo của Càn Long Đế được làm bằng <a href="__missing__">bạch ngọc</a> nguyên chất, miệng ấn khắc hình giao long, hình vuông, mặt dưới ấn khắc chữ Hán bằng kiểu <a href="__missing__">chữ triện</a>, xưng quanh ấn có khắc <i>"Tự đề Thái thượng hoàng đế chi bảo"</i> (自题太上皇帝之宝) do đích thân Càn Long Đế sáng tác.</p>
<p>Ấn bảo có diện tích 22.5×22.5&nbsp;cm, thân cao 15&nbsp;cm, miệng ấn cao 7.3&nbsp;cm. Hiện vật đang được lưu giữ tại <a href="__missing__">Bảo tàng Cố cung</a> ở <a href="__missing__">Bắc Kinh</a>.</p>
<h2>Danh sách Thái thượng hoàng</h2>
<h3>Việt Nam</h3>
<h3>Trung Quốc</h3>
<h3>Trung Á</h3>
<h3>Triều Tiên</h3>
<h3>Nhật Bản</h3>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Vua Việt Nam</a></li><li><a href="__missing__">Vô thượng hoàng</a></li><li><a href="__missing__">Thái thượng vương</a></li><li><a href="__missing__">Thái thượng Thiên hoàng</a></li><li><a href="__missing__">Thái thượng Pháp hoàng</a></li><li><a href="__missing__">Thiện nhượng</a></li><li><a href="__missing__">Thái thượng hoàng hậu</a></li><li><a href="__missing__">Thái tổ</a></li><li><a href="__missing__">Thái tông</a></li></ul>
<h2>Tham khảo</h2>
<ul><li>Nguyễn Khắc Thuần (2003), <i>Các đời đế vương Trung Hoa,</i> Nhà xuất bản Giáo dục</li><li>Quỳnh Cư, Đỗ Đức Hùng (2001), <i>Các triều đại Việt Nam</i>, Nhà xuất bản Thanh niên</li><li>Đặng Huy Phúc (2001), <i>Các hoàng đế Trung Hoa,</i> Nhà xuất bản Hà Nội</li><li><i><a href="__missing__">Nước Việt Nam qua từng thời kỳ lịch sử</a><a href="__missing__">Lưu trữ</a> ngày 7 tháng 2 năm 2009 tại <a href="__missing__">Wayback Machine</a></i>, <a href="__missing__">Vietnam Net</a></li><li><i><a href="__missing__">Đại Việt sử ký toàn thư</a></i></li><li><a href="__missing__">Trần Trọng Kim</a>, <i><a href="__missing__">Việt Nam sử lược</a></i></li></ul>
<h2>Chú thích</h2>
<ol><li><a href="__missing__">↑</a> 《史记·卷六·秦始皇本纪》:追尊庄襄王为太上皇。</li><li><a href="__missing__">↑</a> 《魏書·卷六·顯祖紀第六》:帝雅薄時務,常有遺世之心,欲禪位於叔父京兆王子推,語在任城王雲傳,羣臣固請,帝乃止。丙午,冊命太子曰:「昔堯舜之禪天下也,皆由其子不肖。若丹朱、商均能負荷者,豈搜揚仄陋而授之哉?爾雖沖弱,有君人之表,必能恢隆王道,以濟兆民。今使太保、建安王陸馛,太尉源賀持節奉皇帝璽綬,致位於爾躬。其踐昇帝位,克廣洪業,以光祖宗之烈,使朕優遊履道,頤神養性,可不善歟?」丁未,詔曰:「朕承洪業,運屬太平,淮岱率從,四海清晏。是以希心玄古,志存澹泊。躬覽萬務,則損頤神之和;一日或曠,政有淹滯之失。但子有天下,歸尊於父;父有天下,傳之於子。今稽協靈運,考會羣心,爰命儲宮,踐昇大位。朕方優遊恭己,栖心浩然,社稷乂安,克廣其業,不亦善乎?百官有司,其祗奉胤子,以答天休。宣布宇內,咸使聞悉。」於是羣公奏曰:「昔三皇之世,澹泊無為,故稱皇。是以漢高祖,既稱皇帝,尊其父為太上皇,明不統天下。今皇帝幼沖,萬機大政,猶宜陛下總之。謹上尊號太上皇帝。」乃從之。</li><li><a href="__missing__">↑</a><a href="__missing__">Sử ký</a>, <i>Cao Tổ bản kỷ</i></li><li><a href="__missing__">↑</a><a href="__missing__">"Đại Việt Sử ký Toàn thư, Bản kỷ, quyển V"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 25 tháng 5 năm 2011. Truy cập ngày 16 tháng 8 năm 2009.</li><li><a href="__missing__">↑</a> Đặng Huy Phúc, sách đã dẫn, tr 387</li><li><a href="__missing__">↑</a><a href="__missing__">"Đại Việt sử ký toàn thư, quyển XVII"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 13 tháng 6 năm 2023. Truy cập ngày 16 tháng 8 năm 2009.</li><li><a href="__missing__">↑</a> Đặng Huy Phúc, sách đã dẫn, tr 517</li><li><a href="__missing__">↑</a> Đại Nam thực lục chính biên, đệ lục kỷ phụ biên - quyển 29</li><li><a href="__missing__">↑</a><a href="__missing__">Đại Việt sử ký toàn thư-Lý Thần Tông hoàng đế bản kỷ</a></li></ol>
+39
View File
@@ -0,0 +1,39 @@
<h1>Thái thượng hoàng</h1>
<p><b>Thái thượng hoàng</b> (<a href="__missing__">chữ Hán</a>: 太上皇), cũng gọi <b>Thái thượng hoàng đế</b> (太上皇帝), giản xưng <b>Thượng Hoàng</b> (上皇), là một tước vị mang ý nghĩa là <i>"Hoàng đế bề trên"</i>, địa vị cơ bản được xem là trên danh vị <a href="__missing__">Hoàng đế</a>.</p>
<p>Danh hiệu này có từ thời <a href="__missing__">nhà Hán</a>, thường chỉ được dùng cho người là cha của Hoàng đế nhưng chưa từng là Hoàng đế. Về sau, các Hoàng đế khi <a href="__missing__">thoái vị</a> cũng được dâng tôn danh hiệu này. Nếu người được tôn vấn còn sống, thì sẽ là [<i>"Thái thượng hoàng"'</i>] hoặc [<i>"Thái thượng hoàng đế"</i>] kèm theo tôn hiệu khác nữa tùy triều đại, sau khi qua đời thì dùng <a href="__missing__">miếu hiệu</a> hoặc <a href="__missing__">thụy hiệu</a>.</p>
<h2>Khái quát</h2>
<h3>Lịch sử</h3>
<p>Trong lịch sử Đông Á, không ít các trường hợp vị <a href="__missing__">quân chủ</a> sẽ <a href="__missing__">thoái vị</a> để nhường ngôi cho người kế vị vì một số lý do chính trị. Từ thời <a href="__missing__">Chiến Quốc</a>, khi các quốc gia chỉ xưng Vương, đã xảy ra trường hợp đầu tiên thời <a href="__missing__">Triệu Vũ Linh vương</a>. Ông ta nhường ngôi cho Thái tử Triệu Hà, lên ngôi sử gọi <a href="__missing__">Triệu Huệ Văn vương</a>, còn bản thân Vũ Linh vương tự xưng 「<b>Chủ phụ</b>; 主父」.</p>
<p>Dù đã thoái vị, song Vũ Linh vương vẫn nắm giữ hết tất cả quyền hành trọng đại trong nước Triệu, do đó cũng khai sinh ra hiện tượng các vị quân chủ tuy nhường ngôi nhưng vẫn thực sự nắm quyền của liên tiếp các triều đại tại Việt Nam, Nhật Bản và bản thân Trung Quốc.</p>
<p>Sau khi <a href="__missing__">Tần Thủy Hoàng</a> thiết lập nên <a href="__missing__">nhà Tần</a>, tạo nên danh xưng <a href="__missing__">Hoàng đế</a>, ông đã truy tôn cha mình là <a href="__missing__">Tần Trang Tương vương</a> làm <b>Thái thượng hoàng</b> (太上皇). Việc làm của Tần Thủy Hoàng khi đó chỉ là truy tôn, do Tần Trang Tương vương đã qua đời từ rất lâu rồi, song Tần Trang Tương vương lại chính là vị [<i>"Thái thượng hoàng"</i>] có danh vị chính thức đầu tiên trong lịch sử các quốc gia Hán Quyển.</p>
<h3>Ý nghĩa</h3>
<p>Vào thời kỳ đầu, danh xưng này biểu thị một trạng thái tôn kính nhưng không thực quyền, sau lại biểu thị sự <i>"bất lực"</i> của Hoàng đế, khi mà phải nhường ngôi cho người khác. Thời <a href="__missing__">nhà Hán</a>, <a href="__missing__">Hán Cao Tổ</a> Lưu Bang dâng tôn cha ruột <a href="__missing__">Lưu Thái Công</a> danh vị Thái thượng hoàng, và Lưu Thái Công là người đầu tiên làm Thượng hoàng khi còn sống (ông mất năm <a href="__missing__">197 TCN</a>, năm thứ 10 triều Hán Cao Tổ). Sau Tần Trang Tương vương cùng Lưu Thái Công, danh xưng này lại mới xuất hiện thời <a href="__missing__">Tấn Huệ Đế</a>. Sau <a href="__missing__">Loạn bát vương</a>, Tấn Huệ Đế bị buộc nhường ngôi cho ông chú <a href="__missing__">Tư Mã Luân</a>, dù trong năm đó Huệ Đế đã trở lại vị trí Hoàng đế như cũ.</p>
<p>Năm <a href="__missing__">471</a>, <a href="__missing__">Bắc Ngụy Hiến Văn Đế</a> bất mãn <a href="__missing__">Phùng Thái hậu</a> chuyên quyền, truyền ngôi cho con trai mới 4 tuổi là <a href="__missing__">Bắc Ngụy Hiếu Văn Đế</a>. Các quan thần tâu rằng:<i>"Tam Hoàng đạm bạc vô vi, cho nên xưng Hoàng; Tây Hán Cao Tổ phụ được tôn làm Thái thượng hoàng, không thống trị thiên hạ, nay Hoàng đế tuổi nhỏ, bệ hạ vẫn nên chấp chính"</i>, do đó, Hiếu Văn Đế tự xưng [<b>Thái thượng hoàng đế</b>; 太上皇帝], mà không phải <i>"Thái thượng hoàng"</i>, biểu thị trạng thái bản thân vẫn nắm quyền điều hình chính sự chứ không phải một vị Hoàng đế thoái vị cùng quẫn.</p>
<p>Thời <a href="__missing__">nhà Đường</a> là triều đại có nhiều Thái thượng hoàng nhất trong lịch sử Trung Quốc. Hầu hết, các vị Thái thượng hoàng đều bị buộc phải làm Thái thượng hoàng, chỉ còn danh vị chứ không còn quyền lực như <a href="__missing__">Đường Huyền Tông</a> Lý Long Cơ, hoặc như các vị <a href="__missing__">Đường Cao Tổ</a> Lý Uyên và <a href="__missing__">Đường Duệ Tông</a> Lý Đán tự mình rút lui, giao toàn bộ triều chính cho các con. Tuy nhiên, cũng có các vị Thái thượng hoàng tuy đã <a href="__missing__">thoái vị</a> nhưng vẫn giữ quyền lực tối cao, như <a href="__missing__">Tống Cao Tông</a>, <a href="__missing__">Tống Hiếu Tông</a> và đặc biệt là <a href="__missing__">Thanh Cao Tông</a>.</p>
<p>Trong <a href="__missing__">lịch sử Việt Nam</a>, <a href="__missing__">nhà Lý</a> có hai trường hợp xuất hiện Thái thượng hoàng, một là tôn xưng do là sinh phụ của Hoàng đế (<a href="__missing__">Sùng Hiền hầu</a>) dù chưa từng là Hoàng đế, và một là bị ép thoái vị (<a href="__missing__">Lý Huệ Tông</a>) để truyền cho con gái <a href="__missing__">Lý Chiêu Hoàng</a>. Thời <a href="__missing__">nhà Trần</a> là triều đại có truyền thống các Hoàng đế nhường ngôi khi con trai đã trưởng thành để về làm Thái thượng hoàng, trừ <a href="__missing__">Trần Thừa</a> ra, còn lại các vị Thái thượng hoàng nhà Trần đều tự xưng <i>"Thái thượng hoàng đế"</i>, biểu thị quyền lực vẫn còn nằm trong tay mình như Bắc Ngụy Hiến Văn Đế. Bằng chứng là những vị Thái thượng hoàng đế rất quyền lực như <a href="__missing__">Trần Minh Tông</a><a href="__missing__">Trần Nghệ Tông</a>.</p>
<p><a href="__missing__">Nhà Hồ</a> cũng theo nếp này và đời đầu tiên là <a href="__missing__">Hồ Quý Ly</a> thực hiện việc truyền ngôi lên làm Thái thượng hoàng, nhưng triều đại không tồn tại lâu nên không kéo dài được nếp truyền nối. Sang thời <a href="__missing__">nhà Hậu Lê</a>, Thái thượng hoàng chỉ xuất hiện vào thời <a href="__missing__">Lê trung hưng</a> - khi đó quyền lực của <a href="__missing__">chúa Trịnh</a> đã rất lớn mạnh, các Hoàng đế nhà Lê chỉ là bù nhìn, do đó địa vị của Thái thượng hoàng rất yếu, hầu như đều do các chúa Trịnh bắt ép thoái vị mà có, như <a href="__missing__">Lê Dụ Tông</a>.</p>
<h3>Các trường hợp</h3>
<p>Có trường hợp đặc biệt khi một người chưa bao giờ làm <a href="__missing__">Hoàng đế</a> nhưng vì có <a href="__missing__">con trai</a> làm <a href="__missing__">Hoàng đế</a> nên cũng được tôn là Thái thượng hoàng. Lấy ví dụ như vị Thái thượng hoàng đầu tiên trong <a href="__missing__">lịch sử</a><a href="__missing__">Lưu thái công</a> cha ruột của <a href="__missing__">Hán Cao Tổ</a> Lưu Bang. Tại <a href="__missing__">Việt Nam</a>, cũng có <a href="__missing__">Sùng Hiền hầu</a> của <a href="__missing__">nhà Lý</a> cùng <a href="__missing__">Trần Thừa</a> của <a href="__missing__">nhà Trần</a>, hai người đều chưa từng làm Hoàng đế từ trước nhưng được tôn xưng Thái thượng hoàng do con trai lên ngôi.</p>
<p>Thông thường, người truyền ngôi cho Hoàng đế rồi tôn xưng Thái thượng hoàng, nhưng có trường hợp <a href="__missing__">Kim Ai Tông</a> Hoàn Nhan Thủ Tự trong hoàn cảnh nguy cấp sắp bị quân <a href="__missing__">Mông Cổ</a> tấn công đến thành trì cuối cùng là <a href="__missing__">Thái Châu</a>, biết không cứu vãn được tình thế, đã nhường ngôi cho con là <a href="__missing__">Kim Mạt Đế</a> Hoàn Nhan Thừa Lân rồi tự sát vì không muốn bị quân <a href="__missing__">Mông Cổ</a> bắt. Hoàng thân nhà Đường là <a href="__missing__">Lý Uân</a> được quân phiệt <a href="__missing__">Chu Mai</a> ủng hộ làm Hoàng đế ở kinh đô Trường An, tôn <a href="__missing__">Đường Hi Tông</a> đang chạy trốn làm Thái thượng hoàng, nhưng Đường Hi Tông không thừa nhận ngôi vị Thượng hoàng mà cùng các quân phiệt khác tiêu diệt Lý Uân. Ngược lại, <a href="__missing__">Tùy Dạng Đế</a> dù không thừa nhận ngôi vị Thái thượng hoàng do <a href="__missing__">Tùy Cung Đế</a><a href="__missing__">Lý Uyên</a> tôn phong, nhưng lại chết trong binh biến. Tại Việt Nam, trong hoàn cảnh <a href="__missing__">nhà Mạc</a> suy tàn, <a href="__missing__">Mạc Mậu Hợp</a> truyền ngôi cho <a href="__missing__">Mạc Toàn</a> rồi tự mình làm tướng cầm quân mà không xưng Thái thượng hoàng. Ngoài ra, cuối đời <a href="__missing__">nhà Trần</a><a href="__missing__">Việt Nam</a>, <a href="__missing__">Trần Nghệ Tông</a> Trần Phủ nhường ngôi cho em trai là <a href="__missing__">Trần Duệ Tông</a> Trần Kính để tự xưng làm Thái thượng hoàng. Đó là việc hi hữu khi vị trí giữa Thái thượng hoàng và Hoàng đế chỉ là anhem. Trường hợp tương tự xảy ra ở <a href="__missing__">Trung Quốc</a> thời <a href="__missing__">nhà Minh</a>, khi <a href="__missing__">Minh Đại Tông</a> tôn anh trai <a href="__missing__">Minh Anh Tông</a> làm Thái thượng hoàng do Anh Tông bị <a href="__missing__">Ngõa La</a> bắt trong <a href="__missing__">Sự biến Thổ Mộc bảo</a>.</p>
<p>Theo cách hiểu thông thường, khi con làm Hoàng đế mà cha còn sống thì cha được tôn làm Thái thượng hoàng, tuy nhiên không phải lúc nào cũng như vậy, còn tùy thuộc vào pháp độ của vương triều. Như có trường hợp cuối đời <a href="__missing__">nhà Thanh</a>, Thuần Hiền thân vương <a href="__missing__">Dịch Hoàn</a> là thân sinh của vua <a href="__missing__">Quang Tự</a> cũng không được tôn xưng Thái thượng hoàng; hay như Thuần Thân vương <a href="__missing__">Tải Phong</a> là cha vua Tuyên Thống (<a href="__missing__">Phổ Nghi</a>) nhưng chỉ đóng vai trò <a href="__missing__">nhiếp chính</a> cho Hoàng đế nhỏ tuổi chứ không làm Thái thượng hoàng. Đây là lý do Quang Tự cùng Tuyên Thống đều đã <i>"nhập tự"</i>, nhận dòng chính thống để kế thừa Đế vị (Quang Tự nhận <a href="__missing__">Hàm Phong</a>, còn Tuyên Thống Đế nhận cả <a href="__missing__">Đồng Trị</a> lẫn Quang Tự). Thời nhà Thanh, vấn đề chính thống rất gay gắt, cả hai người Quang Tự-Tuyên Thống đã nhận dòng chính mới có tư cách kế vị, cho nên xét về mặt pháp lý thì cả Dịch Hoàn cùng Tái Phong dù được kính trọng do là cha ruột của Hoàng đế, song cả hai vị Thân vương này không có tư cách tự xưng Thái thượng hoàng.</p>
<p>Tại Việt Nam, có một danh vị từng tồn tại để chỉ cha ruột của Hoàng đế, nhưng không phải Thái thượng hoàng. Khi ấy, vua <a href="__missing__">Thành Thái</a><a href="__missing__">nhà Nguyễn</a> bị <a href="__missing__">người Pháp</a> ép phải nhường ngôi cho con là vua <a href="__missing__">Duy Tân</a>, và dụ triều đình nhà Nguyễn định việc tôn hiệu cho vị vua Thành Thái thoái vị. Sau khi bàn định lễ chế của nước Đại Nam, người Pháp không chấp nhận ngôi vị [Thái thượng hoàng] vì sẽ khiến tình hình thêm phức tạp, do vậy vua Duy Tân chỉ được phép tôn cha là [<b>Hoàng Phụ Hoàng đế</b>; 皇父皇帝].</p>
<p>Chính những quy tắc phức tạp, phải có tôn ti trong việc tấn tôn vị hiệu này mà sử gia <a href="__missing__">Lê Văn Hưu</a> đã chỉ trích việc <a href="__missing__">Lý Thần Tông</a> tôn cha đẻ Sùng Hiền hầu làm Thái thượng hoàng. Khi ấy, Lý Thần Tông đã được <a href="__missing__">Lý Nhân Tông</a> chọn làm con thừa tự, phong làm <a href="__missing__">Thái tử</a> để kế vị, thì Thần Tông chỉ nên công nhận Nhân Tông mà thôi, nếu Thần Tông lại tôn cha ruột Sùng Hiền hầu thêm nữa thì <i>"hóa ra là hai gốc ư?"</i>. Nguyên văn nhận xét của Lê Văn Hưu:</p>
<h3>Sắc ấn</h3><a href="__missing__">Tập tin:太上皇帝之宝.jpg</a>Ấn <i>"Thái thượng hoàng đế chi bảo"</i> của vua Càn Long
<p>Trong lịch sử, việc tôn xưng Thái thượng hoàng thường không được xem là pháp độ có tính nhất quán ổn định về quy tắc, do vậy một số nguyên tắc về trang phục, lễ nghi của Thái thượng hoàng so với Hoàng đế cũng không mấy rõ ràng. Về cơ bản, có lẽ nghi giá của Thái thượng hoàng đều cùng với Hoàng đế ngang nhau, tuy nhiên các triều đại có truyền thống tôn xưng Thượng hoàng như <a href="__missing__">nhà Trần</a> ở Việt Nam bị lâm vào tình trạng mất mát tư liệu, nên cũng không rõ những nguyên tắc cụ thể về lễ nghi cho một Thái thượng hoàng.</p>
<p>Thời kỳ <a href="__missing__">nhà Thanh</a>, là triều đại lớn cuối cùng ở Trung Quốc xuất hiện một vị Thái thượng hoàng - <a href="__missing__">Càn Long Đế</a>. Tuy ông đã <a href="__missing__">thoái vị</a>, song trên thực tế ông vẫn nắm hết mọi quyền hành cho đến tận khi qua đời, cho nên hẳn nhiên ổng phải thiết lập quy tắc bảo chứng cho sức mạnh đó của mình: ấn bảo.</p>
<p>Năm Càn Long thứ 60 (<a href="__missing__">1795</a>), ngày <a href="__missing__">3 tháng 9</a> (âm lịch), Càn Long Đế đã 85 tuổi, triệu tập các Hoàng tử cùng Vương công Đại thần, ra chỉ tuyên bố lập Hoàng thập ngũ tử <a href="__missing__">Vĩnh Diễm</a> làm <a href="__missing__">Hoàng thái tử</a>, sửa tên thành <i>Ngưng Diễm</i>, lấy năm sau làm năm đầu Gia Khánh. Sang <a href="__missing__">tháng giêng</a> năm ấy, Càn Long Đế tự mình làm lễ nhận bảo tỷ, hạ chỉ có đoạn:</p> 「皇太子于丙辰正月上日即皇帝位。朕亲御太和殿,躬授宝玺,可称朕为太上皇帝。」 Dịch là:<i>"Hoàng thái tử vào ngày Bính Thìn, chính nguyệt kế vị Hoàng đế. Trẫm thân ngự Thái Hòa điện, cung thụ bảo tỉ, có thể gọi Trẫm là Thái thượng hoàng đế"</i>.
<p>Sau đó, Càn Long Đế còn quy định về việc dùng ngọc bảo:</p> 「朕归政后,应用喜字第一号玉宝,刻太上皇帝之宝,即将御制《十全老人之宝说》镌刻作为太上皇帝册,用彰熙朝盛瑞。」 Dịch là:<i>"Sau khi Trẫm quy chính, nên tự dùng ngọc bảo hạng nhất, khắc chữ 'Thái thượng hoàng đế chi bảo', ngự chế 'Thập toàn lão nhân chi bảo thuyết' tuyên khắc thành 'Thái thượng hoàng đế sách', dùng ngọc chương hi triều thịnh"</i>.
<p>Đây là hiện vật duy nhất chứng minh quyền hành của một Thái thượng hoàng trong thế giới Đông Á, ngay cả một chính quyền có nhiều <i>"Thượng hoàng"</i> nhất là Nhật Bản cũng chưa từng có. Ấn bảo của Càn Long Đế được làm bằng <a href="__missing__">bạch ngọc</a> nguyên chất, miệng ấn khắc hình giao long, hình vuông, mặt dưới ấn khắc chữ Hán bằng kiểu <a href="__missing__">chữ triện</a>, xưng quanh ấn có khắc <i>"Tự đề Thái thượng hoàng đế chi bảo"</i> (自题太上皇帝之宝) do đích thân Càn Long Đế sáng tác.</p>
<p>Ấn bảo có diện tích 22.5×22.5&nbsp;cm, thân cao 15&nbsp;cm, miệng ấn cao 7.3&nbsp;cm. Hiện vật đang được lưu giữ tại <a href="__missing__">Bảo tàng Cố cung</a><a href="__missing__">Bắc Kinh</a>.</p>
<h2>Danh sách Thái thượng hoàng</h2>
<h3>Việt Nam</h3>
<h3>Trung Quốc</h3>
<h3>Trung Á</h3>
<h3>Triều Tiên</h3>
<h3>Nhật Bản</h3>
<h2>Xem thêm</h2>
<ul><li><a href="__missing__">Vua Việt Nam</a></li><li><a href="__missing__">Vô thượng hoàng</a></li><li><a href="__missing__">Thái thượng vương</a></li><li><a href="__missing__">Thái thượng Thiên hoàng</a></li><li><a href="__missing__">Thái thượng Pháp hoàng</a></li><li><a href="__missing__">Thiện nhượng</a></li><li><a href="__missing__">Thái thượng hoàng hậu</a></li><li><a href="__missing__">Thái tổ</a></li><li><a href="__missing__">Thái tông</a></li></ul>
<h2>Tham khảo</h2>
<ul><li>Nguyễn Khắc Thuần (2003), <i>Các đời đế vương Trung Hoa,</i> Nhà xuất bản Giáo dục</li><li>Quỳnh Cư, Đỗ Đức Hùng (2001), <i>Các triều đại Việt Nam</i>, Nhà xuất bản Thanh niên</li><li>Đặng Huy Phúc (2001), <i>Các hoàng đế Trung Hoa,</i> Nhà xuất bản Hà Nội</li><li><i><a href="__missing__">Nước Việt Nam qua từng thời kỳ lịch sử</a><a href="__missing__">Lưu trữ</a> ngày 7 tháng 2 năm 2009 tại <a href="__missing__">Wayback Machine</a></i>, <a href="__missing__">Vietnam Net</a></li><li><i><a href="__missing__">Đại Việt sử ký toàn thư</a></i></li><li><a href="__missing__">Trần Trọng Kim</a>, <i><a href="__missing__">Việt Nam sử lược</a></i></li></ul>
<h2>Chú thích</h2>
<ol><li><a href="__missing__"></a> 《史记·卷六·秦始皇本纪》:追尊庄襄王为太上皇。</li><li><a href="__missing__"></a> 《魏書·卷六·顯祖紀第六》:帝雅薄時務,常有遺世之心,欲禪位於叔父京兆王子推,語在任城王雲傳,羣臣固請,帝乃止。丙午,冊命太子曰:「昔堯舜之禪天下也,皆由其子不肖。若丹朱、商均能負荷者,豈搜揚仄陋而授之哉?爾雖沖弱,有君人之表,必能恢隆王道,以濟兆民。今使太保、建安王陸馛,太尉源賀持節奉皇帝璽綬,致位於爾躬。其踐昇帝位,克廣洪業,以光祖宗之烈,使朕優遊履道,頤神養性,可不善歟?」丁未,詔曰:「朕承洪業,運屬太平,淮岱率從,四海清晏。是以希心玄古,志存澹泊。躬覽萬務,則損頤神之和;一日或曠,政有淹滯之失。但子有天下,歸尊於父;父有天下,傳之於子。今稽協靈運,考會羣心,爰命儲宮,踐昇大位。朕方優遊恭己,栖心浩然,社稷乂安,克廣其業,不亦善乎?百官有司,其祗奉胤子,以答天休。宣布宇內,咸使聞悉。」於是羣公奏曰:「昔三皇之世,澹泊無為,故稱皇。是以漢高祖,既稱皇帝,尊其父為太上皇,明不統天下。今皇帝幼沖,萬機大政,猶宜陛下總之。謹上尊號太上皇帝。」乃從之。</li><li><a href="__missing__"></a><a href="__missing__">Sử ký</a>, <i>Cao Tổ bản kỷ</i></li><li><a href="__missing__"></a><a href="__missing__">"Đại Việt Sử ký Toàn thư, Bản kỷ, quyển V"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 25 tháng 5 năm 2011. Truy cập ngày 16 tháng 8 năm 2009.</li><li><a href="__missing__"></a> Đặng Huy Phúc, sách đã dẫn, tr 387</li><li><a href="__missing__"></a><a href="__missing__">"Đại Việt sử ký toàn thư, quyển XVII"</a>. <a href="__missing__">Bản gốc</a> lưu trữ ngày 13 tháng 6 năm 2023. Truy cập ngày 16 tháng 8 năm 2009.</li><li><a href="__missing__"></a> Đặng Huy Phúc, sách đã dẫn, tr 517</li><li><a href="__missing__"></a> Đại Nam thực lục chính biên, đệ lục kỷ phụ biên - quyển 29</li><li><a href="__missing__"></a><a href="__missing__">Đại Việt sử ký toàn thư-Lý Thần Tông hoàng đế bản kỷ</a></li></ol>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long