chenpei 8591ad3233 🎨 集成前端代码到后端仓库
✨ 新增功能:
- 将完整的前端Vue项目集成到后端仓库
- 创建 frontend/ 目录存放前端代码
- 排除了 .git、node_modules 等不必要文件

🎯 集成优势:
- 一个仓库包含完整前后端代码
- 简化部署和维护流程
- 方便版本同步和管理
- 减少仓库管理复杂度

📁 项目结构:
- backend/: Java Spring Boot 后端
- frontend/: Vue.js 前端项目
- docker/: 容器配置
- docs/: 各种部署文档

🚀 现在只需克隆一个仓库就能获得:
- JmalCloud 公共空间版后端
- 配套的前端界面
- 完整的Docker部署配置
- 详细的部署文档
2025-08-24 12:10:33 +08:00

168 lines
4.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>EPUB.js Spreads Example</title>
<script src="./jszip@3.10.1.min.js"></script>
<script src="./epubjs@0.3.88.min.js"></script>
<link rel="stylesheet" type="text/css" href="./epub.css">
</head>
<body>
<!-- <div id="title"></div> -->
<select id="toc"></select>
<div id="viewer" class="spreads"></div>
<a id="prev" href="#prev" class="arrow">‹</a>
<a id="next" href="#next" class="arrow">›</a>
<script>
var params =
URLSearchParams &&
new URLSearchParams(document.location.search.substring(1))
var url =
params && params.get("url") && decodeURIComponent(params.get("url"))
var currentSectionIndex =
params && params.get("loc") ? params.get("loc") : undefined
let blob = fetch(url).then((res) => res.blob())
var book = ePub(
blob.then((blob) => blob.arrayBuffer()),
{
restore: true,
reload: true,
spreads: true,
}
)
var rendition = book.renderTo("viewer", {
width: "100%",
height: 600,
spread: "always",
})
rendition.display(currentSectionIndex);
book.ready.then(function() {
var next = document.getElementById("next");
next.addEventListener("click", function(e){
book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
e.preventDefault();
}, false);
var prev = document.getElementById("prev");
prev.addEventListener("click", function(e){
book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
e.preventDefault();
}, false);
var keyListener = function(e){
// Left Key
if ((e.keyCode || e.which) == 37) {
book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
}
// Right Key
if ((e.keyCode || e.which) == 39) {
book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
}
};
rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false);
})
var title = document.getElementById("title");
rendition.on("rendered", function(section){
var current = book.navigation && book.navigation.get(section.href);
if (current) {
var $select = document.getElementById("toc");
var $selected = $select.querySelector("option[selected]");
if ($selected) {
$selected.removeAttribute("selected");
}
var $options = $select.querySelectorAll("option");
for (var i = 0; i < $options.length; ++i) {
let selected = $options[i].getAttribute("ref") === current.href;
if (selected) {
$options[i].setAttribute("selected", "");
}
}
}
});
rendition.on("relocated", function(location){
console.log(location);
var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
if (location.atEnd) {
next.style.visibility = "hidden";
} else {
next.style.visibility = "visible";
}
if (location.atStart) {
prev.style.visibility = "hidden";
} else {
prev.style.visibility = "visible";
}
});
rendition.on("layout", function(layout) {
let viewer = document.getElementById("viewer");
if (layout.spread) {
viewer.classList.remove('single');
} else {
viewer.classList.add('single');
}
});
window.addEventListener("unload", function () {
console.log("unloading");
this.book.destroy();
});
book.loaded.navigation.then(function(toc){
var $select = document.getElementById("toc"),
docfrag = document.createDocumentFragment();
toc.forEach(function(chapter) {
var option = document.createElement("option");
option.textContent = chapter.label;
option.setAttribute("ref", chapter.href);
docfrag.appendChild(option);
});
$select.appendChild(docfrag);
$select.onchange = function(){
var index = $select.selectedIndex,
url = $select.options[index].getAttribute("ref");
rendition.display(url);
return false;
};
});
</script>
</body>
</html>