mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-15 21:01:40 +08:00
继续搭建前端nodejs框架,添加字体动态压缩
This commit is contained in:
10
README.md
10
README.md
@@ -5,3 +5,13 @@
|
|||||||
当前项目为 https://books.only4.work 网站源代码,你也可以通过这个项目搭建一个属于自己的电子书分享与管理平台。
|
当前项目为 https://books.only4.work 网站源代码,你也可以通过这个项目搭建一个属于自己的电子书分享与管理平台。
|
||||||
|
|
||||||
[接口文档](api.md)
|
[接口文档](api.md)
|
||||||
|
|
||||||
|
## 前端
|
||||||
|
|
||||||
|
开发使用 nodemon,代码变动后自动重启。
|
||||||
|
|
||||||
|
使用以下代码安装 nodemon
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i nodemon -g
|
||||||
|
```
|
@@ -12,18 +12,10 @@ let dotenv = require('dotenv');
|
|||||||
dotenv.config('./env');
|
dotenv.config('./env');
|
||||||
// console.log(process.env);
|
// console.log(process.env);
|
||||||
|
|
||||||
// 取得API路径
|
|
||||||
global.site = process.env.site;
|
|
||||||
global.API_PREFIX = process.env.API_PREFIX;
|
|
||||||
if(!global.API_PREFIX) {
|
|
||||||
console.log('API_PREFIX is not defined');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.log("[API_PREFIX] " + global.API_PREFIX);
|
|
||||||
|
|
||||||
// 引入路由文件
|
// 引入路由文件
|
||||||
var routes = require('./routes/search');
|
var indexRoute = require('./routes/index');
|
||||||
var test = require('./routes/test');
|
var fontminRoute = require('./routes/fontmin');
|
||||||
|
const { copyFileSync } = require('fs');
|
||||||
|
|
||||||
// 创建应用
|
// 创建应用
|
||||||
var app = express();
|
var app = express();
|
||||||
@@ -42,8 +34,8 @@ app.use(cookieParser());
|
|||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
app.use('/search', routes);
|
app.use('/', indexRoute);
|
||||||
app.use('/test', test);
|
app.use('/fontmin', fontminRoute);
|
||||||
|
|
||||||
// 捕获404并转发到错误处理程序 catch 404 and forward to error handler
|
// 捕获404并转发到错误处理程序 catch 404 and forward to error handler
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
@@ -62,7 +54,8 @@ if (app.get('env') === 'development') {
|
|||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.render('error', {
|
res.render('error', {
|
||||||
message: err.message,
|
message: err.message,
|
||||||
error: err
|
error: err,
|
||||||
|
title: '出错啦'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -87,5 +80,28 @@ var server = app.listen(app.get('port'), function () {
|
|||||||
|
|
||||||
// 引入站点配置文件
|
// 引入站点配置文件
|
||||||
global.site = require("./settings.json");
|
global.site = require("./settings.json");
|
||||||
console.log(global.site);
|
|
||||||
|
// 取得API路径
|
||||||
|
if (!global.site) {
|
||||||
|
console.log('settings.json is not defined');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// console.log("[global.site]");
|
||||||
|
// console.log(JSON.stringify(global.site));
|
||||||
|
console.log(" ***************************** 启动成功 ***************************** ");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 注册SIGINT信号事件
|
||||||
|
process.on('SIGINT', function () {
|
||||||
|
console.clear();
|
||||||
|
console.log(" ***************************** 正在清理 ***************************** ");
|
||||||
|
|
||||||
|
require('./cleanup.js');
|
||||||
|
|
||||||
|
console.log(" ************************* 清理完毕,已退出 ************************* ");
|
||||||
|
console.log('Exit now!');
|
||||||
|
|
||||||
|
process.exit();
|
||||||
|
// return true;
|
||||||
});
|
});
|
22
bookshelfplus-frontend/cleanup.js
Normal file
22
bookshelfplus-frontend/cleanup.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
var fontminPath = path.join(__dirname, 'public/fontmin');
|
||||||
|
if (fs.existsSync(fontminPath)) {
|
||||||
|
console.log("Cleaning up temporary files: public/fontmin/*.ttf");
|
||||||
|
let files = fs.readdirSync(fontminPath);
|
||||||
|
files.forEach((file, index) => {
|
||||||
|
if (file.endsWith('.ttf')) {
|
||||||
|
let curPath = fontminPath + "/" + file;
|
||||||
|
fs.unlinkSync(curPath); //删除文件
|
||||||
|
console.log(" | removed file: " + file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("Temporary files cleared successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
module.exports = cleanup;
|
@@ -4,23 +4,25 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node app",
|
"start": "node app",
|
||||||
"dev": "set NODE_ENV=development & node app",
|
"dev": "nodemon app",
|
||||||
"prod": "set NODE_ENV=production & node app"
|
"prod": "set NODE_ENV=production & pm2 start app.js --name bookshelfplus-frontend",
|
||||||
|
"clean": "node cleanup.js"
|
||||||
},
|
},
|
||||||
"description": "书栖网",
|
"description": "书栖网",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.15.0",
|
"body-parser": "^1.15.0",
|
||||||
"cookie-parser": "^1.4.0",
|
"cookie-parser": "^1.4.0",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"debug": "^2.2.0",
|
"debug": "^2.2.0",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"ejs": "^3.1.6",
|
"ejs": "^3.1.6",
|
||||||
"element-plus": "^1.2.0-beta.6",
|
"element-plus": "^1.2.0-beta.6",
|
||||||
"express": "^4.14.0",
|
"express": "^4.14.0",
|
||||||
|
"fontmin": "^0.9.9",
|
||||||
|
"fs": "^0.0.1-security",
|
||||||
|
"gulp-rename": "^2.0.0",
|
||||||
"morgan": "^1.7.0",
|
"morgan": "^1.7.0",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"serve-favicon": "^2.3.0"
|
"serve-favicon": "^2.3.0"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"nodemon": "^2.0.15"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
3
bookshelfplus-frontend/public/assets/lib/axios/0.20.0/axios.min.js
vendored
Normal file
3
bookshelfplus-frontend/public/assets/lib/axios/0.20.0/axios.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,16 +1,16 @@
|
|||||||
/* 字体引入 */
|
/* 字体引入 */
|
||||||
@font-face {
|
/* @font-face {
|
||||||
font-family: HarmonyOS_Sans;
|
font-family: HarmonyOS_Sans;
|
||||||
src: url("../fonts/HarmonyOS_Sans_SC_Regular.ttf") format("truetype");
|
src: url("../fonts/HarmonyOS_Sans_SC_Regular.ttf") format("truetype");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
} */
|
||||||
|
|
||||||
/* 全局样式 */
|
/* 全局样式 */
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: HarmonyOS_Sans;
|
font-family: bookshelfplusFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
@@ -30,6 +30,8 @@ hr {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-grid {
|
.navbar-grid {
|
||||||
@@ -49,6 +51,7 @@ hr {
|
|||||||
.navbar-grid .grid-item a,
|
.navbar-grid .grid-item a,
|
||||||
.navbar-grid .grid-item a:visited {
|
.navbar-grid .grid-item a:visited {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-grid .grid-item * {
|
.navbar-grid .grid-item * {
|
||||||
|
1
bookshelfplus-frontend/public/fontmin/.gitignore
vendored
Normal file
1
bookshelfplus-frontend/public/fontmin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.ttf
|
90
bookshelfplus-frontend/routes/fontmin.js
Normal file
90
bookshelfplus-frontend/routes/fontmin.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
'use strict';
|
||||||
|
var express = require('express');
|
||||||
|
var router = express.Router();
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
var rename = require('gulp-rename');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
// refer: https://blog.csdn.net/qq_36812165/article/details/108363511 , https://github.com/font-size/node-fontmin-project
|
||||||
|
|
||||||
|
// 设置可用字体
|
||||||
|
const fonts = [
|
||||||
|
{ font: 'HarmonyOS_Sans_SC_Regular', name: 'HarmonyOS Sans' },
|
||||||
|
]
|
||||||
|
|
||||||
|
// 路径是以 app.js 所在路径为准的
|
||||||
|
var destPath = './public/fontmin/'; // 输出路径
|
||||||
|
|
||||||
|
// 转化参数设置
|
||||||
|
router.use(bodyParser.json());
|
||||||
|
|
||||||
|
router.use(bodyParser.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
// post 接口
|
||||||
|
router.post('/getfont', function (request, response) {
|
||||||
|
const params = request.body
|
||||||
|
const font = params.font || "HarmonyOS_Sans_SC_Regular"
|
||||||
|
const text = params.text
|
||||||
|
// 如果传递的font字体在后台没有就返回400
|
||||||
|
const item = fonts.find(e => e.font === font)
|
||||||
|
|
||||||
|
var targetFileName = require('crypto').createHash('md5').update(text).digest('hex') + '.ttf';
|
||||||
|
var exists = fs.existsSync(destPath + "/" + targetFileName);
|
||||||
|
if (exists) {
|
||||||
|
response.send({
|
||||||
|
url: '/fontmin/' + targetFileName,
|
||||||
|
font: font,
|
||||||
|
info: "使用已生成字体"
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (item && text) {
|
||||||
|
fontmin(font, text, targetFileName, function (e) {
|
||||||
|
if (e === 'done') {
|
||||||
|
// 拼接参数 返回请求
|
||||||
|
let back = {
|
||||||
|
url: '/fontmin/' + targetFileName,
|
||||||
|
font: font,
|
||||||
|
info: "新生成字体"
|
||||||
|
}
|
||||||
|
response.send(back);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
response.status(400);
|
||||||
|
response.send(JSON.stringify({
|
||||||
|
"errMsg": '没有请求的字体文件或没有传递文字'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
||||||
|
function fontmin(font, text, targetFileName, callback) {
|
||||||
|
const Fontmin = require('fontmin')
|
||||||
|
var srcPath = `./fonts/${font}.ttf`; // 字体源文件
|
||||||
|
var text = text || '';
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
var fontmin = new Fontmin()
|
||||||
|
.src(srcPath) // 输入配置
|
||||||
|
.use(rename(targetFileName))
|
||||||
|
.use(Fontmin.glyph({ // 字型提取插件
|
||||||
|
text: text // 所需文字
|
||||||
|
}))
|
||||||
|
// .use(Fontmin.ttf2eot()) // eot 转换插件
|
||||||
|
// .use(Fontmin.ttf2woff()) // woff 转换插件
|
||||||
|
// .use(Fontmin.ttf2svg()) // svg 转换插件
|
||||||
|
// .use(Fontmin.css()) // css 生成插件
|
||||||
|
.dest(destPath); // 输出配置
|
||||||
|
|
||||||
|
// 执行
|
||||||
|
fontmin.run(function (err, files, stream) {
|
||||||
|
if (err) // 异常捕捉
|
||||||
|
console.error(err);
|
||||||
|
return callback('done') // 成功
|
||||||
|
});
|
||||||
|
}
|
29
bookshelfplus-frontend/routes/index.js
Normal file
29
bookshelfplus-frontend/routes/index.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
'use strict';
|
||||||
|
var express = require('express');
|
||||||
|
var router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', function (req, res) {
|
||||||
|
res.render('index', {
|
||||||
|
title: site.title
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/search', function (req, res) {
|
||||||
|
res.render('search', {
|
||||||
|
title: "搜一下"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/category', function (req, res) {
|
||||||
|
res.render('category', {
|
||||||
|
title: "书籍分类"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/about', function (req, res) {
|
||||||
|
res.render('about', {
|
||||||
|
title: "关于"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
@@ -1,13 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
var express = require('express');
|
|
||||||
var router = express.Router();
|
|
||||||
|
|
||||||
/* GET home page. */
|
|
||||||
router.get('/', function (req, res) {
|
|
||||||
res.render('search', {
|
|
||||||
title: site.title,
|
|
||||||
page: "首页"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
@@ -1,12 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
var express = require('express');
|
|
||||||
var router = express.Router();
|
|
||||||
|
|
||||||
/* GET home page. */
|
|
||||||
router.get('/', function (req, res) {
|
|
||||||
res.render('test', {
|
|
||||||
title: "测试页 | " + site.title
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
@@ -2,53 +2,24 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<%- include("./component/header.html"); %>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>书栖网正在建设中</title>
|
|
||||||
<link rel="stylesheet" href="./assets/stylesheets/style.css">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="navbar">
|
<%- include("./component/navbar.html"); %>
|
||||||
<div class="navbar-grid">
|
|
||||||
<div class="grid-item"></div>
|
|
||||||
<div class="grid-item">
|
|
||||||
<nobr>
|
|
||||||
<h1>书栖网</h1>
|
|
||||||
</nobr>
|
|
||||||
</div>
|
|
||||||
<div class="grid-item exnarrowHide" style="text-align: right; color: white;">
|
|
||||||
<span class="narrowHide" style="color: #a5a5a5;">计算机类电子书👉</span>
|
|
||||||
<a href="https://github.com/only-4/computer-related-books" target="_blank">GitHub</a>
|
|
||||||
/
|
|
||||||
<a href="https://gitee.com/only4/computer-related-books" target="_blank">Gitee</a>
|
|
||||||
</div>
|
|
||||||
<div class="grid-item"></div>
|
|
||||||
</div>
|
|
||||||
<!-- <ul><li></li><li></li></ul> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="main" align="center">
|
<div class="main" align="center">
|
||||||
<div class="siteTitle">
|
<div class="siteTitle">
|
||||||
<nobr>
|
<h1>书栖网</h1>
|
||||||
<h1>书栖网</h1><!-- 这里不留空否则会出现一个空格 --><span> 网站正在建设中</span>
|
|
||||||
</nobr>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="searchBox">
|
|
||||||
<input id="searchInput" type="text" placeholder="只需两步:搜索、下载 就这么简单" />
|
|
||||||
<input id="searchButton" type="button" value="搜一下" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sloganBox">
|
<div class="sloganBox">
|
||||||
<p class="emphasize">
|
<p class="emphasize">
|
||||||
一个没有任何门槛的计算机类电子书下载平台
|
一个完全免费无门槛的计算机类电子书下载网站
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="font-weight: bold;">随便唠唠</p>
|
<h2>随便唠唠</h2>
|
||||||
<p>本网站是“计算机类电子书”仓库的前身,我们希望能够搭建一个电子书共享平台,供大家在学习中方便搜索以及下载。</p>
|
<p>本网站是“计算机类电子书”仓库的前身,我们希望能够搭建一个电子书共享平台,供大家在学习中方便搜索以及下载。</p>
|
||||||
<p>目前市面上的网站下载有很多门槛,要么是收费,要么是要关注公众号等等。我们要做的就是一个没有任何门槛的下载平台。</p>
|
<p>目前市面上的网站下载有很多门槛,要么是收费,要么是要关注公众号等等。我们要做的就是一个没有任何门槛的下载平台。</p>
|
||||||
<p style="font-weight: bold; color: crimson;">我们承诺,这个网站从出生到消失,永不投放广告,永远不会让您付费或者关注公众号来进行下载,甚至也不投放收款二维码,永远是这样。</p>
|
<p style="font-weight: bold; color: crimson;">我们承诺,这个网站从出生到消失,永不投放广告,永远不会让您付费或者关注公众号来进行下载,甚至也不投放收款二维码,永远是这样。</p>
|
||||||
@@ -69,44 +40,14 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<p>最后,还是要说一下版权的问题。我们十分重视版权。我们所整理的电子书全部来自于互联网,其中部分来自于下载站、公众号等。如果其中包含您的作品,且您不希望我们将您的作品作为免费分享出来,请联系<span>contact@only4.work</span>并提供相应证明材料,我们核实后将会第一时间删除。同时,您在本网站上下载的所有电子书文件,仅供学习交流使用,不可二次传播,特别是不可设置扫码关注等门槛二次分享。
|
<p>最后,还是要说一下版权的问题。我们十分重视版权。我们所整理的电子书全部来自于互联网,其中部分来自于下载站、公众号等。如果其中包含您的作品,且您不希望我们将您的作品作为免费分享出来,请联系<span>contact@only4.work</span>并提供相应证明材料,我们核实后将会第一时间删除。同时,您在本网站上下载的所有电子书文件,仅供学习交流使用,不可二次传播,特别是不可设置扫码关注等门槛二次分享。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>书栖网 • 2021-2022</p>
|
<h2>特别说明</h2>
|
||||||
|
<p>本站电子书由“张小弟之家”整理,出于方便学习之目的,您从本站下载的电子书仅供学习交流使用,如需他用请联系原作者。<a href="https://gitee.com/only4/computer-related-books" target="_blank">查看同步更新Gitee仓库</a></p>
|
||||||
|
<p>由于信息量较大,我们无法做到一一确认相关电子书的权属管理,如本站不慎侵犯了您的权利,请发送邮件至<b>contact@only4.work</b>,来信请注明相关链接以及您的相关证明材料,我们收到邮件后会第一时间与您取得联系并积极处理,多谢理解!</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<%- include("./component/footer.html"); %>
|
||||||
// /**
|
|
||||||
// * 内容改变时并不会触发事件,但是在失去焦点的时候会触发。
|
|
||||||
// */
|
|
||||||
// $("#inputid").change(function () {
|
|
||||||
// console.log($(this).val());
|
|
||||||
// });
|
|
||||||
// /**
|
|
||||||
// * 只要文本类容发生改变,就会触发该事件
|
|
||||||
// */
|
|
||||||
// $("#inputid").bind("input propertychange", function () {
|
|
||||||
// console.log($(this).val());
|
|
||||||
// });
|
|
||||||
|
|
||||||
// 搜索框文字改变事件(实时)
|
|
||||||
$("#searchInput").bind("input propertychange", function () {
|
|
||||||
if ($('#searchInput').val() !== "")
|
|
||||||
$('#searchInput').val("这个功能还没做呢,再等等吧");
|
|
||||||
});
|
|
||||||
|
|
||||||
// 搜索框获得焦点事件
|
|
||||||
$('#searchInput').focus(() => {
|
|
||||||
$('#searchInput').val("");
|
|
||||||
$('#searchInput').attr('placeholder', "不好意思,功能还没做好,现在还不能搜索哦")
|
|
||||||
})
|
|
||||||
|
|
||||||
// 搜索框失去焦点事件
|
|
||||||
$('#searchInput').blur((that) => {
|
|
||||||
$('#searchInput').val("");
|
|
||||||
$('#searchInput').attr('placeholder', "只需两步:搜索、下载 就这么简单")
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
21
bookshelfplus-frontend/views/category.html
Normal file
21
bookshelfplus-frontend/views/category.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<%- include("./component/header.html"); %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("./component/navbar.html"); %>
|
||||||
|
|
||||||
|
<h1><%= title %></h1>
|
||||||
|
|
||||||
|
<main class="main">
|
||||||
|
<div id="container">
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<%- include("./component/footer.html"); %>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -1,11 +1,45 @@
|
|||||||
<footer>
|
<div class="footer">
|
||||||
<hr />
|
<hr>
|
||||||
<p>
|
<p>书栖网 • 2021-2022</p>
|
||||||
<% site.footer.link.forEach(function(link){ %>
|
</div>
|
||||||
<span><a href="<%= link.url; %>" target="<%= link.target %>"><%= link.text; %></a></span>
|
|
||||||
<% }); %>
|
<!-- https://gist.github.com/macbookandrew/f33dbbc0aa582d0515919dc5fb95c00a -->
|
||||||
</p>
|
<script>
|
||||||
<p>
|
// 获取网页上的所有文字
|
||||||
Copyright © 2021-2022 <%= site.title; %> All Rights Reserved.
|
// refer: https://www.cnblogs.com/yzeng/p/8268731.html
|
||||||
</p>
|
function getPageText() {
|
||||||
</footer>
|
var str = document.documentElement.innerText;
|
||||||
|
str += "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 数字和英文全部包含进去
|
||||||
|
var res = [].filter.call(str, (s, i, o) => o.indexOf(s) == i).sort().join('').trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
function fontmin(text) {
|
||||||
|
// 设置post type
|
||||||
|
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||||
|
// 接口地址
|
||||||
|
axios.post('/fontmin/getfont', { text: text, font: "" })
|
||||||
|
.then(function (response) {
|
||||||
|
// 当接口成功返回时,动态设置css
|
||||||
|
let styleDom = document.createElement('style');
|
||||||
|
styleDom.type = 'text/css';
|
||||||
|
const cssText = `
|
||||||
|
@font-face {
|
||||||
|
font-family: bookshelfplusFont;
|
||||||
|
src: url("${response.data.url}") format("truetype");
|
||||||
|
}
|
||||||
|
`
|
||||||
|
styleDom.appendChild(document.createTextNode(cssText));
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(styleDom)
|
||||||
|
console.log("字体加载成功");
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log("字体加载失败", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
var allText = getPageText();
|
||||||
|
console.log(allText);
|
||||||
|
fontmin(allText);
|
||||||
|
});
|
||||||
|
</script>
|
@@ -1,7 +1,10 @@
|
|||||||
<!-- StyleSheets -->
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="/stylesheets/main.css">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<title><%= title; %></title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./assets/stylesheets/style.css">
|
||||||
|
<!-- <script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script> -->
|
||||||
|
<script src="./assets/lib/jquery/3.6.0/jquery.min.js"></script>
|
||||||
|
|
||||||
<!-- JavaScripts -->
|
<script src="./assets/lib/axios/0.20.0/axios.min.js"></script>
|
||||||
<!-- jQuery 3.6.0 -->
|
|
||||||
<script src="/lib/jquery/3.6.0/jquery.min.js"></script>
|
|
17
bookshelfplus-frontend/views/component/navbar.html
Normal file
17
bookshelfplus-frontend/views/component/navbar.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-grid">
|
||||||
|
<div class="grid-item"></div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<nobr>
|
||||||
|
<h1 onclick="location.href='/'" style="cursor: pointer;">书栖网</h1>
|
||||||
|
</nobr>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item exnarrowHide" style="text-align: right; color: white;">
|
||||||
|
<a class="narrowHide" href="/">首页</a>
|
||||||
|
<a href="/category">分类</a>
|
||||||
|
<a href="/search">搜索</a>
|
||||||
|
<a class="narrowHide" href="/about">关于</a>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title></title>
|
|
||||||
<%- include("./component/header.html"); %>
|
<%- include("./component/header.html"); %>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<%- include("./component/navbar.html"); %>
|
||||||
<h1><%= message %></h1>
|
<h1><%= message %></h1>
|
||||||
<h2><%= error.status %></h2>
|
<h2><%= error.status %></h2>
|
||||||
<pre><%= error.stack %></pre>
|
<pre><%= error.stack %></pre>
|
||||||
|
82
bookshelfplus-frontend/views/index.html
Normal file
82
bookshelfplus-frontend/views/index.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<%- include("./component/header.html"); %>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<%- include("./component/navbar.html"); %>
|
||||||
|
|
||||||
|
<div class="main" align="center">
|
||||||
|
<div class="siteTitle">
|
||||||
|
<h1>书栖网</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="searchBox">
|
||||||
|
<input id="searchInput" type="text" placeholder="只需两步:搜索、下载 就这么简单" />
|
||||||
|
<input id="searchButton" type="button" value="搜一下" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sloganBox">
|
||||||
|
<p class="emphasize">
|
||||||
|
一个完全免费无门槛的计算机类电子书下载网站
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 30vh;"></div>
|
||||||
|
|
||||||
|
<%- include("./component/footer.html"); %>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// /**
|
||||||
|
// * 内容改变时并不会触发事件,但是在失去焦点的时候会触发。
|
||||||
|
// */
|
||||||
|
// $("#inputid").change(function () {
|
||||||
|
// console.log($(this).val());
|
||||||
|
// });
|
||||||
|
// /**
|
||||||
|
// * 只要文本类容发生改变,就会触发该事件
|
||||||
|
// */
|
||||||
|
// $("#inputid").bind("input propertychange", function () {
|
||||||
|
// console.log($(this).val());
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // 搜索框文字改变事件(实时)
|
||||||
|
// $("#searchInput").bind("input propertychange", function () {
|
||||||
|
// if ($('#searchInput').val() !== "")
|
||||||
|
// $('#searchInput').val("这个功能还没做呢,再等等吧");
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 搜索框获得焦点事件
|
||||||
|
$('#searchInput').focus(() => {
|
||||||
|
// $('#searchInput').val("");
|
||||||
|
$('#searchInput').attr('placeholder', "在这里输入您想搜索的电子书吧")
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索框失去焦点事件
|
||||||
|
$('#searchInput').blur((that) => {
|
||||||
|
// $('#searchInput').val("");
|
||||||
|
$('#searchInput').attr('placeholder', "只需两步:搜索、下载 就这么简单")
|
||||||
|
})
|
||||||
|
|
||||||
|
// 文本框回车事件
|
||||||
|
$('#searchInput').keydown(function (e) {
|
||||||
|
var curKey = e.which;
|
||||||
|
if (curKey == 13) {
|
||||||
|
$("#searchButton").click();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 搜索按钮点击事件
|
||||||
|
$('#searchButton').click(function () {
|
||||||
|
if ($('#searchInput').val() !== "") {
|
||||||
|
location.href = "search?keyword=" + encodeURIComponent($('#searchInput').val());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@@ -2,151 +2,20 @@
|
|||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title><%= page + " | " + title; %></title>
|
|
||||||
<%- include("./component/header.html"); %>
|
<%- include("./component/header.html"); %>
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" />
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<%- include("./component/navbar.html"); %>
|
||||||
|
|
||||||
<h1><%= title %></h1>
|
<h1><%= title %></h1>
|
||||||
<p>本站电子书由“张小弟之家”整理,出于方便学习之目的,您从本站下载的电子书仅供学习交流使用,如需他用请联系原作者。<a href="https://gitee.com/only4/computer-related-books" target="_blank">查看同步更新Gitee仓库</a></p>
|
|
||||||
<p>由于信息量较大,我们无法做到一一确认相关电子书的权属管理,如本站不慎侵犯了您的权利,请发送邮件至<b>contact@only4.work</b>,来信请注明相关链接以及您的相关证明材料,我们收到邮件后会第一时间与您取得联系并积极处理,多谢理解!</p>
|
|
||||||
|
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="cateTable"></div>
|
|
||||||
<div id="itemTable"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
function getDefaultGridDictTemplate() {
|
|
||||||
return {
|
|
||||||
columns: [],
|
|
||||||
//data: '',
|
|
||||||
|
|
||||||
// 搜索
|
|
||||||
search: true,
|
|
||||||
|
|
||||||
// 分页
|
|
||||||
pagination: {
|
|
||||||
limit: 10
|
|
||||||
},
|
|
||||||
|
|
||||||
// 排序
|
|
||||||
sort: true,
|
|
||||||
|
|
||||||
// 可调整列宽
|
|
||||||
resizable: true,
|
|
||||||
|
|
||||||
// 自适应
|
|
||||||
fixedHeader: true,
|
|
||||||
//height: '400px',
|
|
||||||
|
|
||||||
server: {},
|
|
||||||
|
|
||||||
language: {
|
|
||||||
search: {
|
|
||||||
placeholder: '🔍 搜索一下'
|
|
||||||
},
|
|
||||||
pagination: {
|
|
||||||
previous: '上一页',
|
|
||||||
next: '下一页',
|
|
||||||
navigate: (page, pages) => `第 ${page} 页,共 ${pages} 页`,
|
|
||||||
page: (e) => "第" + e + "页",
|
|
||||||
showing: "显示结果:第",
|
|
||||||
to: "-",
|
|
||||||
of: "条结果,共",
|
|
||||||
results: "条结果"
|
|
||||||
},
|
|
||||||
sort: {
|
|
||||||
sortAsc: "按升序排序",
|
|
||||||
sortDesc: "按降序排序"
|
|
||||||
},
|
|
||||||
loading: "数据正在加载中...",
|
|
||||||
noRecordsFound: "无结果",
|
|
||||||
error: "出错了"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
let cateTableDict = getDefaultGridDictTemplate();
|
|
||||||
cateTableDict.columns = [
|
|
||||||
{
|
|
||||||
name: '分类',
|
|
||||||
sort: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '分类简介',
|
|
||||||
sort: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '操作',
|
|
||||||
sort: false,
|
|
||||||
formatter: (cell, row) => {
|
|
||||||
return gridjs.h('button', {
|
|
||||||
className: 'py-2 mb-4 px-4 border rounded-md text-white bg-blue-600',
|
|
||||||
onClick: () => alert(`Editing "${row.cells[0].data}" "${row.cells[1].data}"`)
|
|
||||||
}, '查看');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
cateTableDict.server = {
|
|
||||||
url: '/api/getCategoryList?cateLevel=1&parentCateId=', //+'page=1&perpage=20',
|
|
||||||
then: data => data.result.reduce((result, element) => {
|
|
||||||
//console.log(result, element);
|
|
||||||
result.push({
|
|
||||||
分类: element.cateId,
|
|
||||||
分类: element.cateName,
|
|
||||||
分类简介: element.cateDescription,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}, [ /* reduce result的初始值 */])
|
|
||||||
};
|
|
||||||
|
|
||||||
let cateTable = new gridjs.Grid(cateTableDict);
|
|
||||||
cateTable.render(document.getElementById('cateTable'));
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
let itemTableDict = getDefaultGridDictTemplate();
|
|
||||||
itemTableDict.columns = [
|
|
||||||
{
|
|
||||||
name: '书名',
|
|
||||||
sort: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '简介',
|
|
||||||
sort: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '操作',
|
|
||||||
formatter: (cell, row) => {
|
|
||||||
return gridjs.h('button', {
|
|
||||||
className: 'py-2 mb-4 px-4 border rounded-md text-white bg-blue-600',
|
|
||||||
onClick: () => alert(`Editing "${row.cells[0].data}" "${row.cells[1].data}"`)
|
|
||||||
}, '查看详情');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
itemTableDict.server = {
|
|
||||||
url: '/api/getBookList',
|
|
||||||
then: data => data.result.reduce((result, element) => {
|
|
||||||
result.push({
|
|
||||||
书名: element.书名,
|
|
||||||
简介: element.书籍简介,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}, [ /* reduce result的初始值 */])
|
|
||||||
};
|
|
||||||
|
|
||||||
let itemTable = new gridjs.Grid(itemTableDict);
|
|
||||||
itemTable.render(document.getElementById('itemTable'));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<%- include("./component/footer.html"); %>
|
<%- include("./component/footer.html"); %>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -1,67 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title><%= title; %></title>
|
|
||||||
<%- include("./component/header.html"); %>
|
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" />
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1><%= title %></h1>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<el-row>
|
|
||||||
<el-button>Default</el-button>
|
|
||||||
<el-button type="primary">Primary</el-button>
|
|
||||||
<el-button type="success">Success</el-button>
|
|
||||||
<el-button type="info">Info</el-button>
|
|
||||||
<el-button type="warning">Warning</el-button>
|
|
||||||
<el-button type="danger">Danger</el-button>
|
|
||||||
<el-button>中文</el-button>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-button plain>Plain</el-button>
|
|
||||||
<el-button type="primary" plain>Primary</el-button>
|
|
||||||
<el-button type="success" plain>Success</el-button>
|
|
||||||
<el-button type="info" plain>Info</el-button>
|
|
||||||
<el-button type="warning" plain>Warning</el-button>
|
|
||||||
<el-button type="danger" plain>Danger</el-button>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-button round>Round</el-button>
|
|
||||||
<el-button type="primary" round>Primary</el-button>
|
|
||||||
<el-button type="success" round>Success</el-button>
|
|
||||||
<el-button type="info" round>Info</el-button>
|
|
||||||
<el-button type="warning" round>Warning</el-button>
|
|
||||||
<el-button type="danger" round>Danger</el-button>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-button :icon="Search" circle></el-button>
|
|
||||||
<el-button type="primary" :icon="Edit" circle></el-button>
|
|
||||||
<el-button type="success" :icon="Check" circle></el-button>
|
|
||||||
<el-button type="info" :icon="Message" circle></el-button>
|
|
||||||
<el-button type="warning" :icon="Star" circle></el-button>
|
|
||||||
<el-button type="danger" :icon="Delete" circle></el-button>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
<script type="module">
|
|
||||||
import {
|
|
||||||
Search,
|
|
||||||
Edit,
|
|
||||||
Check,
|
|
||||||
Message,
|
|
||||||
Star,
|
|
||||||
Delete,
|
|
||||||
} from 'element' //from '@element-plus/icons-vue'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<%- include("./component/footer.html"); %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Reference in New Issue
Block a user