From 615ff93d6b4f688a956d487e7756a509fe26f1ff Mon Sep 17 00:00:00 2001 From: Song Date: Sun, 13 Sep 2020 23:50:16 +0800 Subject: [PATCH] :construction: save work --- .gitignore | 5 +- app.js | 6 +- knexfile.js | 22 +++++++ .../20200913222330_initialize_database.js | 13 ++++ models/message.js | 19 ++++++ package.json | 6 +- routes.js => routers/index.js | 22 +------ routers/message.js | 59 +++++++++++++++++++ utils/database.js | 9 +++ utils/utils.js | 33 +++++++++++ utils.js => utils/wechat.js | 25 +++----- views/info.ejs | 10 ++++ views/message.ejs | 4 +- 13 files changed, 191 insertions(+), 42 deletions(-) create mode 100644 knexfile.js create mode 100644 migrations/20200913222330_initialize_database.js create mode 100644 models/message.js rename routes.js => routers/index.js (71%) create mode 100644 routers/message.js create mode 100644 utils/database.js create mode 100644 utils/utils.js rename utils.js => utils/wechat.js (58%) create mode 100644 views/info.ejs diff --git a/.gitignore b/.gitignore index 68e55d7..8ab0022 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .idea node_modules package-lock.json -.env \ No newline at end of file +.env +data.db +data.db-journal +.vscode \ No newline at end of file diff --git a/app.js b/app.js index e424146..ed27c56 100644 --- a/app.js +++ b/app.js @@ -5,8 +5,9 @@ const logger = require("morgan"); const http = require("http"); require("dotenv").config(); -const indexRouter = require("./routes"); -const requestToken = require("./utils").requestToken; +const indexRouter = require("./routers/index"); +const messageRouter = require("./routers/message"); +const requestToken = require("./utils/wechat").requestToken; const app = express(); @@ -26,6 +27,7 @@ app.use(cookieParser()); app.use(express.static(path.join(__dirname, "public"))); app.use("/", indexRouter); +app.use("/message", messageRouter); const server = http.createServer(app); diff --git a/knexfile.js b/knexfile.js new file mode 100644 index 0000000..04a01eb --- /dev/null +++ b/knexfile.js @@ -0,0 +1,22 @@ +module.exports = { + development: { + client: "sqlite3", + connection: { + filename: "./data.db", + }, + }, + + staging: { + client: "sqlite3", + connection: { + filename: "./data.db", + }, + }, + + production: { + client: "sqlite3", + connection: { + filename: "./data.db", + }, + }, +}; diff --git a/migrations/20200913222330_initialize_database.js b/migrations/20200913222330_initialize_database.js new file mode 100644 index 0000000..f3e1ef4 --- /dev/null +++ b/migrations/20200913222330_initialize_database.js @@ -0,0 +1,13 @@ +exports.up = function (knex) { + return knex.schema.createTable("messages", (tableBuilder) => { + tableBuilder.uuid("id").primary(); + tableBuilder.string("title"); + tableBuilder.string("status"); + tableBuilder.string("created_by"); + tableBuilder.string("created_time"); + tableBuilder.string("description"); + tableBuilder.text("content"); + }); +}; + +exports.down = function (knex) {}; diff --git a/models/message.js b/models/message.js new file mode 100644 index 0000000..1a573d0 --- /dev/null +++ b/models/message.js @@ -0,0 +1,19 @@ +const db = require("../utils/database").db; +const { v4: uuid } = require("uuid"); + +class Message { + create(message) { + message.id = uuid(); + return db("messages").insert(message); + } + + getById(id) { + return db("messages").where("id", id); + } + + deleteById(id) { + return db("messages").where("id", id).del(); + } +} + +module.exports.Message = new Message(); diff --git a/package.json b/package.json index d942950..bca64de 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,11 @@ "dotenv": "^8.2.0", "ejs": "^3.1.5", "express": "~4.16.1", - "morgan": "~1.9.1" + "knex": "^0.21.5", + "marked": "^1.1.1", + "morgan": "~1.9.1", + "sqlite3": "^5.0.0", + "uuid": "^8.3.0" }, "devDependencies": { "prettier": "^2.1.1" diff --git a/routes.js b/routers/index.js similarity index 71% rename from routes.js rename to routers/index.js index 799021a..adb1302 100644 --- a/routes.js +++ b/routers/index.js @@ -2,20 +2,14 @@ const express = require("express"); const router = express.Router(); const crypto = require("crypto"); const fs = require("fs"); -const pushMessage = require("./utils").pushMessage; router.all("/", (req, res, next) => { fs.promises .access("./.env") .then(() => { - res.render("message", { - message: "服务已在运行,本次访问已被记录。", + res.render("info", { + message: "服务已在运行。", }); - pushMessage( - req, - res, - `请注意,ip 地址为 ${req.ip} 的用户访问了你的消息通知服务,如果非你本人,则你的私有消息通知服务可能已被泄露,当前版本无法阻止其他用户通过本系统向你发送消息。` - ); }) .catch(() => { res.render("configure"); @@ -47,7 +41,7 @@ router.post("/configure", (req, res, next) => { process.exit(); }) .catch((e) => { - res.render("message", { + res.render("info", { message: "在尝试写入 .env 文件时发生错误:" + e, }); }); @@ -68,14 +62,4 @@ router.all("/verify", (req, res, next) => { } }); -router.all("/push", (req, res, next) => { - let content = req.query.content || req.body.content; - pushMessage(req, res, content); -}); - -router.all("/:content", (req, res, next) => { - let content = req.params.content; - pushMessage(req, res, content); -}); - module.exports = router; diff --git a/routers/message.js b/routers/message.js new file mode 100644 index 0000000..5d56f88 --- /dev/null +++ b/routers/message.js @@ -0,0 +1,59 @@ +const express = require("express"); +const lexer = require("marked").lexer; +const parser = require("marked").parser; +const Message = require("../models/message").Message; +const pushWeChatMessage = require("../utils/wechat").pushWeChatMessage; +const formatTime = require("../utils/utils").formatTime; + +const router = express.Router(); + +function md2html(markdown) { + return parser(lexer(markdown)); +} + +router.get("/:description", (req, res, next) => { + req.query.description = req.params.description; + next(); +}); + +router.all("/", (req, res) => { + let message = { + title: req.query.title || req.body.title || "无标题", + status: 1, + created_by: "系统", // TODO + created_time: formatTime(), + description: req.query.description || req.body.description, + content: md2html(req.query.content || req.body.content), + }; + + Message.create(message) + .then((value) => { + console.log(value); + pushWeChatMessage(message.description, message.link) + .then((response) => { + res.json(response); + }) + .catch((reason) => { + res.json(reason); + }); + }) + .catch((reason) => { + res.json(reason); + }); +}); + +router.get("/detail/:id", (req, res) => { + const id = req.params.id; + Message.getById(id) + .then((value) => { + console.log(value); + res.render("message", value[0]); + }) + .catch((reason) => { + res.render("info", { + message: "获取该消息时发生了错误:" + reason, + }); + }); +}); + +module.exports = router; diff --git a/utils/database.js b/utils/database.js new file mode 100644 index 0000000..59911ce --- /dev/null +++ b/utils/database.js @@ -0,0 +1,9 @@ +const knex = require("knex"); +const environment = process.env.NODE_ENV || "development"; +const configuration = require("../knexfile")[environment]; + +const db = knex(configuration); + +module.exports = { + db: db, +}; diff --git a/utils/utils.js b/utils/utils.js new file mode 100644 index 0000000..04093f1 --- /dev/null +++ b/utils/utils.js @@ -0,0 +1,33 @@ +function formatTime(format) { + if (format === undefined) format = "yyyy-MM-dd hh:mm:ss"; + const date = new Date(); + const o = { + "M+": date.getMonth() + 1, + "d+": date.getDate(), + "h+": date.getHours(), + "m+": date.getMinutes(), + "s+": date.getSeconds(), + S: date.getMilliseconds(), + }; + + if (/(y+)/.test(format)) { + format = format.replace( + RegExp.$1, + (date.getFullYear() + "").substr(4 - RegExp.$1.length) + ); + } + + for (let k in o) { + if (new RegExp("(" + k + ")").test(format)) { + format = format.replace( + RegExp.$1, + RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) + ); + } + } + return format; +} + +module.exports = { + formatTime, +}; diff --git a/utils.js b/utils/wechat.js similarity index 58% rename from utils.js rename to utils/wechat.js index 33e70fb..e08be9d 100644 --- a/utils.js +++ b/utils/wechat.js @@ -12,6 +12,7 @@ module.exports = { console.log("Token requested."); token = res.data.access_token; app.locals.access_token = token; + process.env.access_token = token; } else { console.error(res.data); } @@ -19,27 +20,17 @@ module.exports = { return token; }, - pushMessage: function (req, res, content) { + pushWeChatMessage: function (description, link) { // Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl - let access_token = req.app.locals.access_token; + let access_token = process.env.access_token; let request_data = { touser: process.env.OPEN_ID, template_id: process.env.TEMPLATE_ID, }; - request_data.data = { text: { value: content } }; - axios - .post( - `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`, - request_data - ) - .then((response) => { - if (response.data && response.data.errcode === "40001") { - requestToken(req.app); - } - res.json(response.data); - }) - .catch((error) => { - res.json(error); - }); + request_data.data = { text: { value: description } }; + return axios.post( + `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`, + request_data + ); }, }; diff --git a/views/info.ejs b/views/info.ejs new file mode 100644 index 0000000..6051709 --- /dev/null +++ b/views/info.ejs @@ -0,0 +1,10 @@ +<%- include('./header') %> +
+
+

注意

+
+
+ <%= message %> +
+
+<%- include('./footer') %> \ No newline at end of file diff --git a/views/message.ejs b/views/message.ejs index 6051709..e2ba5ea 100644 --- a/views/message.ejs +++ b/views/message.ejs @@ -1,10 +1,10 @@ <%- include('./header') %> -
+

注意

- <%= message %> +
<%- include('./footer') %> \ No newline at end of file