mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-01 22:53:29 +08:00
629 lines
26 KiB
HTML
629 lines
26 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<%- include("./component/header.html"); %>
|
|
<!-- 书籍信息部分 -->
|
|
<style>
|
|
.main {
|
|
width: 80vw !important;
|
|
max-width: initial !important;
|
|
}
|
|
|
|
#container {
|
|
margin-top: 50px;
|
|
}
|
|
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: 4fr 6fr;
|
|
place-items: center;
|
|
grid-gap: 1rem;
|
|
margin: 0 auto;
|
|
max-width: 800px;
|
|
}
|
|
|
|
#bookImage {
|
|
/* width: 100%; */
|
|
height: auto;
|
|
max-height: 300px;
|
|
margin-bottom: 20px;
|
|
margin-top: 60px;
|
|
}
|
|
|
|
.group-button>* {
|
|
vertical-align: middle;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
#favorties-button {
|
|
width: 32px;
|
|
height: 32px;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#favorties-button:hover {
|
|
transform: scale(1.2);
|
|
}
|
|
|
|
.download-link {
|
|
user-select: none;
|
|
font-size: 1.1em;
|
|
}
|
|
#download-icon {
|
|
width: 0px;
|
|
height: 1.2em;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
opacity: 0;
|
|
transition: all 0.3s;
|
|
position: relative;
|
|
}
|
|
.download-link:hover #download-icon {
|
|
width: 1.2em;
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
<!-- 文件下载部分 -->
|
|
<style>
|
|
.download-container {
|
|
padding-top: 5px;
|
|
padding-bottom: 5px;
|
|
}
|
|
|
|
#file-container {
|
|
width: min(80vw, 650px);
|
|
margin: 0 auto;
|
|
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
grid-gap: 10px;
|
|
padding: 10px;
|
|
}
|
|
|
|
.file-item {
|
|
text-align: left;
|
|
background-color: #e6e6e6;
|
|
padding: 15px 20px;
|
|
border-radius: 5px;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.file-item:hover {
|
|
text-align: left;
|
|
background-color: #dfdfdf;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.file-detail {
|
|
margin-top: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.file-object {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
place-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.file-object>.file-object-item {
|
|
border: solid 2px #c6c6c6;
|
|
border-radius: 5px;
|
|
padding: 5px 8px;
|
|
min-width: 135px;
|
|
/* max-width: 150px; */
|
|
width: 80%;
|
|
height: 60px;
|
|
position: relative;
|
|
font-size: 14px;
|
|
display: inline-block;
|
|
transition: all 0.2s;
|
|
user-select: none;
|
|
}
|
|
|
|
.file-object>.file-object-item:hover {
|
|
/* transform: scale(1.03); */
|
|
border-color: #5e5e5e;
|
|
}
|
|
|
|
.file-object>.file-object-item>.file-object-item-title {
|
|
height: 20px;
|
|
}
|
|
.file-object>.file-object-item>.file-object-item-title>* {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.file-object>.file-object-item img {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.file-object>.file-object-item .outdated-feedback {
|
|
width: 20px;
|
|
height: 20px;
|
|
position: absolute;
|
|
right: 2px;
|
|
top: 2px;
|
|
cursor: pointer;
|
|
}
|
|
.file-object>.file-object-item .outdated-feedback>.outdated-feedback-tip {
|
|
display: none;
|
|
position: absolute;
|
|
width: max-content;
|
|
background: aliceblue;
|
|
padding: 3px 5px;
|
|
border: 2px solid grey;
|
|
border-radius: 4px;
|
|
z-index: 99999;
|
|
margin-left: 5px;
|
|
font-family: initial;
|
|
}
|
|
.file-object>.file-object-item .outdated-feedback:hover .outdated-feedback-tip {
|
|
display: initial;
|
|
}
|
|
.file-object>.file-object-item .outdated-feedback img {
|
|
opacity: 0.5;
|
|
transition: all 0.18s;
|
|
}
|
|
.file-object>.file-object-item .outdated-feedback:hover img {
|
|
opacity: 1;
|
|
}
|
|
|
|
.file-object>.file-object-item>.file-object-item-content {
|
|
height: 20px;
|
|
display: grid;
|
|
place-items: center;
|
|
}
|
|
|
|
.file-object>.file-object-item>.file-object-item-link {
|
|
height: 20px;
|
|
display: grid;
|
|
place-items: center;
|
|
}
|
|
|
|
/* 统一 */
|
|
.bold {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.size12 {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.size14 {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.size16 {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.size20 {
|
|
font-size: 20px;
|
|
}
|
|
|
|
.overflow-hide {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
display: block;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<%- include("./component/navbar.html"); %>
|
|
<main class="main">
|
|
<!-- <h1><%= headText %></h1> -->
|
|
<div id="container"></div>
|
|
<hr style="opacity: 0.3; margin-top: 30px; margin-bottom: 25px;">
|
|
<div class="download-container">
|
|
<h3 id="scrollTarget">下载这本书</h3>
|
|
<div id="file-container"></div>
|
|
</div>
|
|
<p style="font-size: 12px;">
|
|
* 由于直链下载成本很高,为降低运营成本,目前仅提供给登录用户使用。
|
|
</p>
|
|
</main>
|
|
<%- include("./component/footer.html"); %>
|
|
|
|
<!-- 获取参数 -->
|
|
<script src="/assets/javascripts/getParams.js"></script>
|
|
<!-- 点击复制及反馈样式 -->
|
|
<script src="/assets/javascripts/cssUtils.js"></script>
|
|
<script>
|
|
var requestParams = getParams();
|
|
var searchbox = document.getElementById("searchInput");
|
|
var bookId = Number(requestParams["id"]) ?? "";
|
|
if (bookId === "") {
|
|
location.href = "/search";
|
|
}
|
|
</script>
|
|
<script>
|
|
// 由于多个请求之后都需要调用该方法,为避免多次压缩,使用计数器,等最后一个请求完成后执行一次
|
|
var requestCount = 2;
|
|
function doFontmin() {
|
|
if (--requestCount == 0) {
|
|
console.log("开始获取字体");
|
|
fontmin(getPageText());
|
|
}
|
|
}
|
|
</script>
|
|
<script>
|
|
// 获取书籍信息
|
|
getRequest("/book/get", { id: bookId })
|
|
.then(function (response) {
|
|
var axiosData = response.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
console.log(data)
|
|
if (data.description == "") {
|
|
data.description = "暂无描述";
|
|
}
|
|
document.getElementById("container").innerHTML = `
|
|
<div class="grid">
|
|
<div style="width: 100%;">
|
|
<img id="bookImage" src="${data.thumbnail == "" ? "/assets/image/svg/no_photo.svg" : data.thumbnail}" alt="书籍缩略图">
|
|
</div>
|
|
<div style="text-align: left; min-height: 80%; min-width: 200px;">
|
|
<h1>${data.bookName}</h1>
|
|
<p>
|
|
作者:${data.author}<br>
|
|
所属分类:<a href="/category?id=${data.category.id}">${data.category.name}</a><br>
|
|
语言:${data.language}<br>
|
|
出版社:${data.publishingHouse}<br>
|
|
</p>
|
|
<div class="group-button">
|
|
<img id="favorties-button" src="/assets/image/svg/favorites_empty.svg" style="visibility: hidden; opacity: 1; transition: all 0.3s;" title="点击收藏/取消收藏" onclick="alert('请先登录!')" />
|
|
<!-- 预加载图片 --><img src="/assets/image/svg/favorites_fill.svg" style="display: none;" />
|
|
|
|
<a class="download-link" href="javaScript:scrollToTarget()"><img id="download-icon" src="/assets/image/svg/download.svg" /><span>下载这本书</span></a>
|
|
<!--<a class="download-link" href="/download/?bookId=${data.id}"><img id="download-icon" src="/assets/image/svg/download.svg" /><span>下载这本书</span></a>-->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h2>书本介绍</h2>
|
|
<p>${data.description}</p>
|
|
<h2>版权信息</h2>
|
|
<p>${data.copyright}</p>
|
|
</div>`;
|
|
|
|
// 获取用户收藏信息
|
|
getUserFavouritesStatus();
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
alert("无法连接到服务器,请检查网络连接!");
|
|
}).finally(function () {
|
|
doFontmin();
|
|
});
|
|
</script>
|
|
<script>
|
|
// 显示收藏还是取消收藏图标
|
|
var favortiesIcon = false;
|
|
// 获取用户收藏信息
|
|
function getUserFavouritesStatus() {
|
|
localStorageUtils.checkLocalStorage();
|
|
|
|
if (!localStorageUtils.getLoginStatus()) {
|
|
// 用户未登录
|
|
$("#favorties-button").css("visibility", "visible");
|
|
return;
|
|
}
|
|
postRequest("/book/getFavoritesStatus", { token: localStorageUtils.getToken(), bookId: bookId })
|
|
.then(function (responseData) {
|
|
var axiosData = responseData.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
console.log(data)
|
|
if (data.status == 1) {
|
|
// 用户已收藏
|
|
console.log("已收藏");
|
|
favortiesIcon = true;
|
|
} else {
|
|
// 用户没有收藏本书
|
|
console.log("没有收藏");
|
|
favortiesIcon = false;
|
|
}
|
|
toggleDisplayButton();
|
|
} else {
|
|
if (data.errCode == "20004") {
|
|
// 登录过期,小问题,这里不弹窗显示
|
|
localStorageUtils.userLogout();
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
// alert("无法连接到服务器,请检查网络连接!");
|
|
}).finally(function () {
|
|
$("#favorties-button").css("visibility", "visible");
|
|
});
|
|
}
|
|
</script>
|
|
<script>
|
|
// 正在请求标记
|
|
var requestingFlag = false;
|
|
// 添加收藏/取消收藏
|
|
function toggleFavorites(toggleStatus) {
|
|
if (requestingFlag) return;
|
|
requestingFlag = true;
|
|
$("#favorties-button").css("opacity", "0.3");
|
|
postRequest("/book/toggleFavorites", { token: localStorageUtils.getToken(), bookId: bookId, status: toggleStatus ? 1 : 0 })
|
|
.then(function (responseData) {
|
|
var axiosData = responseData.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
console.log(data)
|
|
if (data == "success") {
|
|
if (toggleStatus) {
|
|
console.log("收藏成功");
|
|
favortiesIcon = true;
|
|
} else {
|
|
console.log("取消收藏成功");
|
|
favortiesIcon = false;
|
|
}
|
|
} else {
|
|
console.log("操作失败");
|
|
}
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
// alert("无法连接到服务器,请检查网络连接!");
|
|
}).finally(function () {
|
|
setTimeout(toggleDisplayButton, 500);
|
|
});
|
|
}
|
|
|
|
function toggleDisplayButton() {
|
|
requestingFlag = false;
|
|
$("#favorties-button").attr("src", "");
|
|
$("#favorties-button").css("opacity", "1");
|
|
if (favortiesIcon) {
|
|
$("#favorties-button").attr("src", "/assets/image/svg/favorites_fill.svg");
|
|
$("#favorties-button").attr("onclick", "toggleFavorites(false)");
|
|
} else {
|
|
$("#favorties-button").attr("src", "/assets/image/svg/favorites_empty.svg");
|
|
$("#favorties-button").attr("onclick", "toggleFavorites(true)");
|
|
}
|
|
}
|
|
</script>
|
|
<!-- 页面滚动 -->
|
|
<script>
|
|
$(".download-container").css("transition", "0.5s");
|
|
$(".download-container").css("border-radius", "20px");
|
|
function scrollToTarget() {
|
|
$('html, body').animate({
|
|
scrollTop: $("#scrollTarget").offset().top
|
|
}, 600);
|
|
setTimeout(function () {
|
|
$(".download-container").css("background-color", "#6DA122");
|
|
$(".download-container").css("transform", "scale(1.05)");
|
|
setTimeout(function () {
|
|
$(".download-container").css("background-color", "");
|
|
$(".download-container").css("transform", "");
|
|
}, 500);
|
|
}, 500);
|
|
}
|
|
</script>
|
|
<!-- 获取文件下载链接信息 -->
|
|
<script>
|
|
var direckLinkInfo = {};
|
|
// 获取文件信息
|
|
function getFileInfo() {
|
|
function stringifyFileSize(nBytes = 0) {
|
|
// 美化输出文件大小
|
|
let sOutput = nBytes + " bytes";
|
|
const aMultiples = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
for (nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
|
|
sOutput = nApprox.toFixed(2) + " " + aMultiples[nMultiple];
|
|
}
|
|
return sOutput;
|
|
}
|
|
function getLinkDOM(fileObjectInfo) {
|
|
// 获取文件下载链接DOM
|
|
var iconSrc = "/assets/image/svg/direct_link.svg", title = fileObjectInfo.storageMediumForDisplay, content = "", downloadLink = "";
|
|
if(fileObjectInfo.fileShareCode != "" && fileObjectInfo.fileShareCode != null) {
|
|
content = `<span>提取码: <span class="click2copy" style="user-select: all; cursor: pointer;">${fileObjectInfo.fileShareCode}</span> </span>`; // 最后一个 是为了保证选中时不会选中后面的回车
|
|
downloadLink = `<a class="baiduNetdiskLink" share-code="${fileObjectInfo.fileShareCode}" share-link="${fileObjectInfo.filePath}" style="cursor: pointer;" title="复制提取码并前往">前往</a>`;
|
|
} else {
|
|
downloadLink = `<a href="${fileObjectInfo.filePath}" target="_blank">前往</a>`;
|
|
}
|
|
switch (fileObjectInfo.storageMediumForDisplay) {
|
|
case "腾讯云对象存储":
|
|
title = "直链下载";
|
|
if (!localStorageUtils.getLoginStatus()) {
|
|
downloadLink = "<span><a href='{}'>登录</a>后方可使用</span>".replace("{}", "/login?redirect=" + encodeURIComponent(location.pathname + location.search));
|
|
} else {
|
|
content = `<span style="font-size: 12px;"><nobr>每次点击都会扣减下载次数</nobr></span>`;
|
|
downloadLink = `<a style="cursor: pointer;" onclick="getDirectLink(${fileObjectInfo.id});">下载</a>`;
|
|
}
|
|
break;
|
|
case "百度网盘":
|
|
iconSrc = "/assets/image/svg/baidu_netdisk.svg";
|
|
break;
|
|
case "阿里云盘":
|
|
iconSrc = "/assets/image/svg/aliyun_drive.svg";
|
|
break;
|
|
default:
|
|
title = fileObjectInfo.storageMediumForDisplay;
|
|
downloadLink = `<a href="${fileObjectInfo.filePath}" target="_blank">前往</a>`;
|
|
break;
|
|
}
|
|
var dom = `<div class="file-object-item">
|
|
<div class="file-object-item-title">
|
|
<img src="${iconSrc}"/> <span>${title}</span>
|
|
</div>
|
|
<div class="file-object-item-content">${content}</div>
|
|
<div class="file-object-item-link">${downloadLink}</div>
|
|
<div class="outdated-feedback">
|
|
<img src="/assets/image/svg/feedback.svg" onclick="linkFeedback(${fileObjectInfo.fileId},${fileObjectInfo.id});"/>
|
|
<span class="outdated-feedback-tip">链接失效?点击反馈!</span>
|
|
</div>
|
|
</div>`.replace(/\ [ ]+?/g,"").replace(/[\n]/g,"") //去掉多余空格、换行
|
|
// console.log(dom);
|
|
return dom;
|
|
}
|
|
getRequest("/file/getFileByBookId", { bookId: bookId })
|
|
.then(function (response) {
|
|
var axiosData = response.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
console.log(data);
|
|
|
|
// 先处理文件对象
|
|
var fileObjectList = {};
|
|
for (let i = 0; i < data.fileObject.length; i++) {
|
|
const element = data.fileObject[i];
|
|
if (!fileObjectList[element.fileId])
|
|
fileObjectList[element.fileId] = [];
|
|
fileObjectList[element.fileId].push(getLinkDOM(element));
|
|
|
|
direckLinkInfo[element.id] = element;
|
|
}
|
|
console.log(fileObjectList);
|
|
|
|
// 再处理文件
|
|
var fileContainer = document.getElementById("file-container");
|
|
var innerHtmlList = [];
|
|
for (let i = 0; i < data.file.length; i++) {
|
|
const fileInfo = data.file[i];
|
|
innerHtmlList.push(`
|
|
<div class="file-item">
|
|
<div class="file-title">
|
|
<span class="file-name size20">${fileInfo.fileName}</span><span class="file-ext size16">${fileInfo.fileExt == "" ? "" : ("." + fileInfo.fileExt)}</span>
|
|
<span class="file-size size14" style="padding-left: 30px;">${stringifyFileSize(fileInfo.fileSize)}</span>
|
|
</div>
|
|
<div class="file-detail">
|
|
<span class="file-copyright size14 overflow-hide">${fileInfo.source == "" ? "" : ("来源信息:" + fileInfo.source) }</span>
|
|
<span class="file-copyright size14" style="margin-top: 12px; display: block;">下载地址:</span>
|
|
</div>
|
|
<div class="file-object">
|
|
${fileObjectList[fileInfo.id] ? fileObjectList[fileInfo.id].join('') : "暂无可用下载链接"}
|
|
</div>
|
|
</div>`
|
|
);
|
|
}
|
|
|
|
fileContainer.innerHTML = innerHtmlList.join("");
|
|
|
|
if (innerHtmlList.length == 0) {
|
|
var fileItem = document.createElement("div");
|
|
fileItem.className = "file-item";
|
|
fileItem.style.textAlign = "center";
|
|
fileItem.innerHTML = "暂无可用文件源";
|
|
fileContainer.appendChild(fileItem);
|
|
}
|
|
|
|
// 最后绑定点击复制事件
|
|
// 点击复制
|
|
$(".click2copy").click(function (e) {
|
|
copyToClipboard($(this).text());
|
|
showTip(e, "复制成功");
|
|
});
|
|
|
|
//
|
|
$(".baiduNetdiskLink").click(function (e) {
|
|
copyToClipboard($(this).attr("share-code"));
|
|
showTip(e, "提取码已复制到剪切板");
|
|
var shareLink = $(this).attr("share-link");
|
|
setTimeout(function () {
|
|
window.open(shareLink);
|
|
}, 500);
|
|
});
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
alert("无法连接到服务器,请检查网络连接!");
|
|
}).finally(function () {
|
|
doFontmin();
|
|
});
|
|
}
|
|
getFileInfo();
|
|
</script>
|
|
<script>
|
|
// 获取直链下载链接,并下载该文件
|
|
async function getDirectLink(fileObjectId) {
|
|
var fileObject = direckLinkInfo[fileObjectId];
|
|
console.log("fileObject", fileObject);
|
|
|
|
if(!localStorageUtils.getLoginStatus()) {
|
|
alert("请先登录!");
|
|
return;
|
|
}
|
|
|
|
var fileNameForUser = `${fileObject.fileName}.${fileObject.fileType}`;
|
|
var fileKeyForCos = fileObject.filePath;
|
|
|
|
var visitorId = await getVisitorId();
|
|
postRequest("/file/object/cos/get", { fileSha1: fileObject.fileSha1, fileNameAndExt: fileNameForUser, token: localStorageUtils.getToken(), visitorId: visitorId, expireMinute: 30 })
|
|
.then(function (response) {
|
|
var axiosData = response.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
console.log(data);
|
|
// let guid = data.guid;
|
|
var downloadLink = document.createElement("a");
|
|
downloadLink.href = data.url;
|
|
downloadLink.target = "_blank";
|
|
console.log(downloadLink);
|
|
downloadLink.click();
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
alert("无法连接到服务器,请检查网络连接!");
|
|
});
|
|
}
|
|
</script>
|
|
<script>
|
|
// 链接失效反馈
|
|
async function linkFeedback(fileId, fileObjectId) {
|
|
if (!confirm("确定这个下载链接失效了吗?(没失效的链接不可以乱点着玩儿哦)"))
|
|
return;
|
|
|
|
if (!localStorageUtils.getLoginStatus()) {
|
|
if (confirm("您尚未登录,登录后反馈处理更快,是否前往登录?")) {
|
|
location.href = "/login?redirect=" + encodeURIComponent(location.pathname + location.search);
|
|
return;
|
|
}
|
|
}
|
|
|
|
var visitorId = await getVisitorId();
|
|
postRequest("/file/object/FailureFeedback", { bookId: bookId, fileId: fileId, fileObjectId: fileObjectId, token: localStorageUtils.getToken(), visitorId: visitorId })
|
|
.then(function (response) {
|
|
var axiosData = response.data;
|
|
var status = axiosData.status;
|
|
var data = axiosData.data;
|
|
if (status === "success") {
|
|
// console.log(data);
|
|
if (data) {
|
|
alert("真棒!反馈成功!");
|
|
} else {
|
|
alert("反馈失败,请稍后再试!");
|
|
}
|
|
} else {
|
|
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
|
|
}
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
alert("无法连接到服务器,请检查网络连接!");
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |